Commit 1d47d78e9fe018c44e8c55e9f4948eba0761585b

Authored by Evgeniy Dushistov
1 parent f13b3ca3

add emulation of at91sam9263 cpu, plus sdram, plus nor flash connected to this cpu

Makefile.target
... ... @@ -411,7 +411,7 @@ obj-sparc-y += cs4231.o eccmemctl.o sbi.o sun4c_intctl.o
411 411 endif
412 412  
413 413 obj-arm-y = integratorcp.o versatilepb.o smc91c111.o arm_pic.o arm_timer.o
414   -obj-arm-y += pflash_atmel.o
  414 +obj-arm-y += pflash_atmel.o at91sam9.o
415 415 obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
416 416 obj-arm-y += versatile_pci.o
417 417 obj-arm-y += realview_gic.o realview.o arm_sysctl.o mpcore.o
... ...
hw/at91sam9.c 0 → 100644
  1 +/*
  2 + * Atmel at91sam9263 cpu + NOR flash + SDRAM emulation
  3 + * Written by Evgeniy Dushistov
  4 + * This code is licenced under the GPL.
  5 + */
  6 +
  7 +#include <stdio.h>
  8 +#include <stdlib.h>
  9 +
  10 +#include "hw.h"
  11 +#include "arm-misc.h"
  12 +#include "primecell.h"
  13 +#include "devices.h"
  14 +#include "net.h"
  15 +#include "sysemu.h"
  16 +#include "flash.h"
  17 +#include "boards.h"
  18 +#include "qemu-char.h"
  19 +#include "qemu-timer.h"
  20 +
  21 +#include "at91sam9263_defs.h"
  22 +
  23 +//#define AT91_TRACE_ON
  24 +//#define AT91_DEBUG_ON
  25 +
  26 +#define ARM_AIC_CPU_IRQ 0
  27 +#define ARM_AIC_CPU_FIQ 1
  28 +
  29 +#define NOR_FLASH_SIZE (1024 * 1024 * 8)
  30 +#define AT91SAM9263EK_SDRAM_SIZE (1024 * 1024 * 64)
  31 +#define AT91SAM9263EK_SDRAM_OFF 0x20000000
  32 +#define AT91SAM9263EK_NORFLASH_OFF 0x10000000
  33 +
  34 +#ifdef AT91_DEBUG_ON
  35 +# define DEBUG(f, a...) { \
  36 + printf ("at91 (%s, %d): %s:", \
  37 + __FILE__, __LINE__, __func__); \
  38 + printf (f, ## a); \
  39 + }
  40 +#else
  41 +# define DEBUG(f, a...) do { } while (0)
  42 +#endif
  43 +
  44 +#ifdef AT91_TRACE_ON
  45 +static FILE *trace_file;
  46 +# define TRACE(f, a...) do { \
  47 + fprintf (trace_file, f, ## a); \
  48 + } while (0)
  49 +#else
  50 +# define TRACE(f, a...) do { } while (0)
  51 +#endif
  52 +
  53 +
  54 +struct dbgu_state {
  55 + CharDriverState *chr;
  56 +};
  57 +
  58 +struct at91sam9_state {
  59 + uint32_t pmc_regs[28];
  60 + uint32_t dbgu_regs[0x124 / 4];
  61 + uint32_t bus_matrix_regs[0x100 / 4];
  62 + uint32_t ccfg_regs[(0x01FC - 0x0110 + 1) / sizeof(uint32_t)];
  63 + uint32_t pio_regs[(AT91_PMC_BASE - AT91_PIO_BASE) / sizeof(uint32_t)];
  64 + uint32_t sdramc0_regs[(AT91_SMC0_BASE - AT91_SDRAMC0_BASE) / sizeof(uint32_t)];
  65 + uint32_t smc0_regs[(AT91_ECC1_BASE - AT91_SMC0_BASE) / sizeof(uint32_t)];
  66 + uint32_t pitc_regs[80];
  67 + uint32_t aic_regs[(AT91_PIO_BASE - AT91_AIC_BASE) / sizeof(uint32_t)];
  68 + uint32_t usart0_regs[0x1000 / sizeof(uint32_t)];
  69 + struct dbgu_state dbgu;
  70 + pflash_t *norflash;
  71 + ram_addr_t internal_sram;
  72 + QEMUTimer *dbgu_tr_timer;
  73 + ptimer_state *pitc_timer;
  74 + int timer_active;
  75 + CPUState *env;
  76 + qemu_irq *qirq;
  77 + uint64_t char_transmit_time;
  78 +};
  79 +
  80 +static uint32_t at91_pmc_read(void *opaque, target_phys_addr_t offset)
  81 +{
  82 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  83 + TRACE("pmc read offset %X\n", offset);
  84 + return sam9->pmc_regs[offset / 4];
  85 +}
  86 +
  87 +static void at91_pmc_write(void *opaque, target_phys_addr_t offset,
  88 + uint32_t value)
  89 +{
  90 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  91 +
  92 + TRACE("pmc write offset %X, value %X\n", offset, value);
  93 + switch (offset / 4) {
  94 + case AT91_PMC_MCKR:
  95 + sam9->pmc_regs[AT91_PMC_MCKR] = value;
  96 + switch (value & AT91_PMC_CSS) {
  97 + case 1:
  98 + //Main clock is selected
  99 + sam9->pmc_regs[AT91_PMC_SR] |= AT91_PMC_MCKRDY | AT91_PMC_MOSCS;
  100 + break;
  101 + default:
  102 + DEBUG("unimplemented\n");
  103 + break;
  104 + }
  105 + break;
  106 + case AT91_PMC_MOR:
  107 + sam9->pmc_regs[AT91_PMC_MOR] = value;
  108 + if (value & 1) {
  109 + sam9->pmc_regs[AT91_PMC_SR] |= AT91_PMC_MOSCS;
  110 + }
  111 + break;
  112 + case AT91_PMC_PLLAR:
  113 + sam9->pmc_regs[AT91_PMC_PLLAR] = value;
  114 + sam9->pmc_regs[AT91_PMC_SR] |= AT91_PMC_LOCKA;
  115 + break;
  116 + case AT91_PMC_PLLBR:
  117 + sam9->pmc_regs[AT91_PMC_PLLBR] = value;
  118 + sam9->pmc_regs[AT91_PMC_SR] |= AT91_PMC_LOCKB;
  119 + break;
  120 + case AT91_PMC_PCER:
  121 + sam9->pmc_regs[AT91_PMC_PCER] |= value;
  122 + break;
  123 + default:
  124 + //DEBUG("unimplemented, offset %X\n", offset);
  125 + break;
  126 + }
  127 +}
  128 +
  129 +static uint32_t at91_dbgu_read(void *opaque, target_phys_addr_t offset)
  130 +{
  131 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  132 +
  133 + offset /= 4;
  134 + if (offset == AT91_DBGU_RHR) {
  135 + sam9->dbgu_regs[AT91_DBGU_SR] &= (uint32_t)~1;
  136 + }/* else if (offset == AT91_DBGU_SR)*/
  137 +
  138 + return sam9->dbgu_regs[offset];
  139 +}
  140 +
  141 +static void at91_dbgu_state_changed(struct at91sam9_state *sam9)
  142 +{
  143 + if ((sam9->aic_regs[AT91_AIC_IECR] & (1 << AT91_PERIPH_SYS_ID)) &&
  144 + (sam9->dbgu_regs[AT91_DBGU_IMR] & sam9->dbgu_regs[AT91_DBGU_SR])) {
  145 + sam9->aic_regs[AT91_AIC_ISR] = AT91_PERIPH_SYS_ID;
  146 + sam9->aic_regs[AT91_AIC_IVR] = sam9->aic_regs[AT91_AIC_SVR0 + AT91_PERIPH_SYS_ID];
  147 + qemu_irq_raise(sam9->qirq[0]);
  148 + }
  149 +}
  150 +
  151 +static void dbgu_serial_end_xmit(void *opaque)
  152 +{
  153 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  154 + sam9->dbgu_regs[AT91_DBGU_SR] |= (AT91_US_TXEMPTY | AT91_US_TXRDY);
  155 + at91_dbgu_state_changed(sam9);
  156 +}
  157 +
  158 +static void at91_dbgu_write(void *opaque, target_phys_addr_t offset,
  159 + uint32_t value)
  160 +{
  161 + unsigned char ch;
  162 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  163 +
  164 + switch (offset / 4) {
  165 + case AT91_DBGU_CR:
  166 + sam9->dbgu_regs[AT91_DBGU_CR] = value;
  167 + if (value & AT91_US_TXEN)
  168 + sam9->dbgu_regs[AT91_DBGU_SR] |= AT91_US_TXRDY | AT91_US_TXEMPTY;
  169 + if (value & AT91_US_TXDIS)
  170 + sam9->dbgu_regs[AT91_DBGU_SR] &= ~(AT91_US_TXRDY | AT91_US_TXEMPTY);
  171 + break;
  172 + case AT91_DBGU_IER:
  173 + sam9->dbgu_regs[AT91_DBGU_IMR] |= value;
  174 + at91_dbgu_state_changed(sam9);
  175 + break;
  176 + case AT91_DBGU_IDR:
  177 + sam9->dbgu_regs[AT91_DBGU_IMR] &= ~value;
  178 + break;
  179 + case AT91_DBGU_THR:
  180 + sam9->dbgu_regs[AT91_DBGU_THR] = value;
  181 + sam9->dbgu_regs[AT91_DBGU_SR] &= ~(AT91_US_TXEMPTY | AT91_US_TXRDY);
  182 + ch = value;
  183 + if (sam9->dbgu.chr)
  184 + qemu_chr_write(sam9->dbgu.chr, &ch, 1);
  185 +// qemu_mod_timer(sam9->dbgu_tr_timer , qemu_get_clock(vm_clock) + sam9->char_transmit_time);
  186 + dbgu_serial_end_xmit(sam9);
  187 + break;
  188 + default:
  189 + //DEBUG("unimplemented\n");
  190 + break;
  191 + }
  192 +}
  193 +
  194 +static int at91_dbgu_can_receive(void *opaque)
  195 +{
  196 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  197 +
  198 + return (sam9->dbgu_regs[AT91_DBGU_SR] & AT91_US_RXRDY) == 0;
  199 +}
  200 +
  201 +static void at91_dbgu_receive(void *opaque, const uint8_t *buf, int size)
  202 +{
  203 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  204 + int i;
  205 + /*! \todo if not one character we need wait before irq handled,
  206 + but from other hand at91_dbgu_can_receive should prevent this
  207 + */
  208 + for (i = 0; i < size; ++i) {
  209 + sam9->dbgu_regs[AT91_DBGU_RHR] = buf[i];
  210 + sam9->dbgu_regs[AT91_DBGU_SR] |= AT91_US_RXRDY;
  211 + at91_dbgu_state_changed(sam9);
  212 + }
  213 +}
  214 +
  215 +static void at91_dbgu_event(void *opaque, int event)
  216 +{
  217 + DEBUG("begin\n");
  218 +}
  219 +
  220 +static uint32_t at91_bus_matrix_read(void *opaque, target_phys_addr_t offset)
  221 +{
  222 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  223 +
  224 + TRACE("bus_matrix read offset %X\n", offset);
  225 + return sam9->bus_matrix_regs[offset / 4];
  226 +}
  227 +
  228 +static void at91_bus_matrix_write(void *opaque, target_phys_addr_t offset,
  229 + uint32_t value)
  230 +{
  231 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  232 +
  233 + TRACE("bus_matrix write offset %X, value %X\n", offset, value);
  234 + switch (offset) {
  235 + case MATRIX_MRCR:
  236 + DEBUG("write to MATRIX mrcr reg\n");
  237 + if (value & (AT91C_MATRIX_RCA926I | AT91C_MATRIX_RCA926D)) {
  238 + cpu_register_physical_memory(0x0, 80 * 1024, sam9->internal_sram | IO_MEM_RAM);
  239 + }
  240 + break;
  241 + default:
  242 + DEBUG("unimplemented\n");
  243 + break;
  244 + }
  245 +}
  246 +
  247 +static void at91_init_pmc(struct at91sam9_state *sam9)
  248 +{
  249 + DEBUG("begin\n");
  250 + sam9->pmc_regs[AT91_PMC_MCKR] = 0;
  251 + sam9->pmc_regs[AT91_PMC_MOR] = 0;
  252 + sam9->pmc_regs[AT91_PMC_SR] = 0x08;
  253 + sam9->pmc_regs[AT91_PMC_PLLAR] = 0x3F00;
  254 + sam9->pmc_regs[AT91_PMC_PLLBR] = 0x3F00;
  255 +}
  256 +
  257 +static void at91_init_bus_matrix(struct at91sam9_state *sam9)
  258 +{
  259 + DEBUG("begin\n");
  260 + memset(&sam9->bus_matrix_regs, 0, sizeof(sam9->bus_matrix_regs));
  261 +}
  262 +
  263 +static void at91_init_dbgu(struct at91sam9_state *sam9, CharDriverState *chr)
  264 +{
  265 + DEBUG("begin\n");
  266 +
  267 + memset(&sam9->dbgu_regs, 0, sizeof(sam9->dbgu_regs));
  268 + sam9->dbgu_regs[AT91_DBGU_SR] = AT91_US_TXEMPTY | AT91_US_TXRDY;
  269 +
  270 + sam9->dbgu.chr = chr;
  271 + sam9->dbgu_tr_timer = qemu_new_timer(vm_clock, (QEMUTimerCB *)dbgu_serial_end_xmit, sam9);
  272 +// sam9->char_transmit_time = (get_ticks_per_sec() / 115200) * 10;
  273 + if (chr)
  274 + qemu_chr_add_handlers(chr, at91_dbgu_can_receive,
  275 + at91_dbgu_receive,
  276 + at91_dbgu_event, sam9);
  277 +}
  278 +
  279 +static uint32_t at91_ccfg_read(void *opaque, target_phys_addr_t offset)
  280 +{
  281 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  282 +
  283 + TRACE("ccfg read offset %X\n", offset);
  284 + return sam9->ccfg_regs[offset / sizeof(sam9->ccfg_regs[0])];
  285 +}
  286 +
  287 +static void at91_ccfg_write(void *opaque, target_phys_addr_t offset,
  288 + uint32_t value)
  289 +{
  290 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  291 +
  292 + TRACE("ccfg write offset %X, value %X\n", offset, value);
  293 + sam9->ccfg_regs[offset / sizeof(sam9->ccfg_regs[0])] = value;
  294 +}
  295 +
  296 +static uint32_t at91_pio_read(void *opaque, target_phys_addr_t offset)
  297 +{
  298 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  299 +
  300 + TRACE("pio read offset %X\n", offset);
  301 + return sam9->pio_regs[offset / sizeof(sam9->pio_regs[0])];
  302 +}
  303 +
  304 +static void at91_pio_write(void *opaque, target_phys_addr_t offset,
  305 + uint32_t value)
  306 +{
  307 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  308 +
  309 + TRACE("pio write offset %X, value %X\n", offset, value);
  310 + sam9->pio_regs[offset / sizeof(sam9->pio_regs[0])] = value;
  311 +}
  312 +
  313 +static uint32_t at91_sdramc0_read(void *opaque, target_phys_addr_t offset)
  314 +{
  315 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  316 +
  317 + TRACE("sdramc0 read offset %X\n", offset);
  318 + return sam9->sdramc0_regs[offset / sizeof(sam9->sdramc0_regs[0])];
  319 +}
  320 +
  321 +static void at91_sdramc0_write(void *opaque, target_phys_addr_t offset,
  322 + uint32_t value)
  323 +{
  324 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  325 +
  326 + TRACE("sdramc0 write offset %X, value %X\n", offset, value);
  327 + sam9->sdramc0_regs[offset / sizeof(sam9->sdramc0_regs[0])] = value;
  328 +}
  329 +
  330 +static uint32_t at91_smc0_read(void *opaque, target_phys_addr_t offset)
  331 +{
  332 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  333 +
  334 + TRACE("smc0 read offset %X\n", offset);
  335 + return sam9->smc0_regs[offset / sizeof(sam9->smc0_regs[0])];
  336 +}
  337 +
  338 +static void at91_smc0_write(void *opaque, target_phys_addr_t offset,
  339 + uint32_t value)
  340 +{
  341 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  342 +
  343 + TRACE("smc0 write offset %X, value %X\n", offset, value);
  344 + sam9->smc0_regs[offset / sizeof(sam9->smc0_regs[0])] = value;
  345 +}
  346 +
  347 +static void at91_pitc_timer_tick(void * opaque)
  348 +{
  349 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  350 + uint64_t val = ptimer_get_count(sam9->pitc_timer);
  351 +
  352 + unsigned int tick = (sam9->pitc_regs[AT91_PITC_PIIR] >> 20) + 1;
  353 + sam9->pitc_regs[AT91_PITC_PIIR] = (val & ((1 << 21) - 1)) | (tick << 20);
  354 + sam9->pitc_regs[AT91_PITC_PIVR] = sam9->pitc_regs[AT91_PITC_PIIR];
  355 +
  356 + if ((sam9->pitc_regs[AT91_PITC_MR] & AT91_PTIC_MR_PITIEN) &&
  357 + (sam9->aic_regs[AT91_AIC_IECR] & (1 << AT91_PERIPH_SYS_ID)) &&
  358 + !sam9->pitc_regs[AT91_PITC_SR]) {
  359 + sam9->aic_regs[AT91_AIC_ISR] = AT91_PERIPH_SYS_ID;
  360 + sam9->aic_regs[AT91_AIC_IVR] = sam9->aic_regs[AT91_AIC_SVR0 + AT91_PERIPH_SYS_ID];
  361 +
  362 + sam9->pitc_regs[AT91_PITC_SR] = 1;
  363 + qemu_irq_raise(sam9->qirq[0]);
  364 + }
  365 +}
  366 +
  367 +static uint32_t at91_pitc_read(void *opaque, target_phys_addr_t offset)
  368 +{
  369 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  370 + int pitc_enable = !!(sam9->pitc_regs[AT91_PITC_MR] & AT91_PTIC_MR_PITEN);
  371 + int idx;
  372 +
  373 + idx = offset / sizeof(sam9->pitc_regs[0]);
  374 + switch (idx) {
  375 + case AT91_PITC_SR:
  376 +// DEBUG("read sr: %X\n", sam9->pitc_regs[idx]);
  377 + break;
  378 + case AT91_PITC_PIVR:
  379 + if (pitc_enable) {
  380 +// DEBUG("clear sr\n");
  381 + sam9->pitc_regs[AT91_PITC_SR] = 0;
  382 + } else {
  383 +// DEBUG("pitc disabled\n");
  384 + break;
  385 + }
  386 + case AT91_PITC_PIIR:
  387 + if (pitc_enable) {
  388 + uint64_t val = ptimer_get_count(sam9->pitc_timer);
  389 + unsigned int tick = (sam9->pitc_regs[AT91_PITC_PIIR] >> 20);
  390 + uint32_t res = (tick << 20) | (val & ((1 << 21) - 1));
  391 +
  392 + if (idx == AT91_PITC_PIVR)
  393 + tick = 0;
  394 + sam9->pitc_regs[AT91_PITC_PIIR] = (tick << 20) | (val & ((1 << 21) - 1));
  395 + sam9->pitc_regs[AT91_PITC_PIVR] = sam9->pitc_regs[AT91_PITC_PIIR];
  396 + TRACE("pitc read offset %X, value %X\n", offset, res);
  397 + return res;
  398 + } else {
  399 +// DEBUG("pitc disabled\n");
  400 + break;
  401 + }
  402 +
  403 + default:
  404 + /*nothing*/break;
  405 + }
  406 + TRACE("pitc read offset %X, value %X\n", offset, sam9->pitc_regs[idx]);
  407 +
  408 + return sam9->pitc_regs[idx];
  409 +}
  410 +
  411 +static void at91_pitc_write(void *opaque, target_phys_addr_t offset,
  412 + uint32_t value)
  413 +{
  414 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  415 +
  416 + TRACE("pitc write offset %X, value %X\n", offset, value);
  417 + int idx = offset / sizeof(sam9->pitc_regs[0]);
  418 + switch (idx) {
  419 + case AT91_PITC_MR: {
  420 + int pitc_enable = !!(value & AT91_PTIC_MR_PITEN);
  421 + unsigned int period = value & 0xFFFFF;
  422 +
  423 + //DEBUG("set period %u, int enabled? %d\n", period, !!(value & AT91_PTIC_MR_PITIEN));
  424 +
  425 + if (pitc_enable && period != 0) {
  426 + sam9->timer_active = 1;
  427 + //! \todo get real value from PLL
  428 + ptimer_set_freq(sam9->pitc_timer, (100 * 1000 * 1000) / 16);
  429 + ptimer_set_limit(sam9->pitc_timer, period, 1);
  430 + ptimer_run(sam9->pitc_timer, 0);
  431 + } else if (sam9->timer_active) {
  432 + TRACE("disable timer\n");
  433 + sam9->pitc_regs[AT91_PITC_PIVR] = 0;
  434 + ptimer_stop(sam9->pitc_timer);
  435 + }
  436 + }
  437 + break;
  438 + default:
  439 + TRACE("unhandled register %d\n", idx);
  440 + break;
  441 + }
  442 + sam9->pitc_regs[idx] = value;
  443 +}
  444 +
  445 +static void at91_init_pitc(struct at91sam9_state *sam9)
  446 +{
  447 + QEMUBH *bh;
  448 +
  449 + DEBUG("begin\n");
  450 + memset(&sam9->pitc_regs, 0, sizeof(sam9->pitc_regs));
  451 + sam9->pitc_regs[AT91_PITC_MR] = 0xFFFFF;
  452 + bh = qemu_bh_new(at91_pitc_timer_tick, sam9);
  453 + sam9->pitc_timer = ptimer_init(bh);
  454 +}
  455 +
  456 +static uint32_t at91_aic_read(void *opaque, target_phys_addr_t offset)
  457 +{
  458 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  459 + unsigned int idx = offset / sizeof(sam9->aic_regs[0]);
  460 + if (idx == AT91_AIC_IVR) {
  461 + qemu_irq_lower(sam9->qirq[0]);
  462 + } else if (idx == AT91_AIC_ISR) {
  463 + uint32_t val = sam9->aic_regs[idx];
  464 + sam9->aic_regs[idx] = 0;
  465 + return val;
  466 + }
  467 +
  468 + return sam9->aic_regs[idx];
  469 +}
  470 +
  471 +static void at91_aic_write(void *opaque, target_phys_addr_t offset,
  472 + uint32_t value)
  473 +{
  474 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  475 + unsigned int idx = offset / sizeof(sam9->aic_regs[0]);
  476 +
  477 + switch (idx) {
  478 + case AT91_AIC_IECR:
  479 + sam9->aic_regs[idx] |= value;
  480 + break;
  481 + case AT91_AIC_IDCR:
  482 + sam9->aic_regs[idx] |= value;
  483 + sam9->aic_regs[AT91_AIC_IECR] &= ~value;
  484 + break;
  485 + case AT91_AIC_IVR://ignore write
  486 + break;
  487 + case AT91_AIC_EOICR:
  488 +// DEBUG("we write to end of interrupt reg\n");
  489 + break;
  490 + default:
  491 + sam9->aic_regs[idx] = value;
  492 + break;
  493 + }
  494 +}
  495 +
  496 +static uint32_t at91_usart_read(void *opaque, target_phys_addr_t offset)
  497 +{
  498 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  499 + DEBUG("we read from %X\n", offset);
  500 + return sam9->usart0_regs[offset / sizeof(uint32_t)];
  501 +}
  502 +
  503 +static void at91_usart_write(void *opaque, target_phys_addr_t offset,
  504 + uint32_t value)
  505 +{
  506 + struct at91sam9_state *sam9 = (struct at91sam9_state *)opaque;
  507 + DEBUG("we write to %X: %X\n", offset, value);
  508 + sam9->usart0_regs[offset / sizeof(uint32_t)] = value;
  509 +}
  510 +
  511 +
  512 +struct ip_block {
  513 + target_phys_addr_t offset;
  514 + target_phys_addr_t end_offset;
  515 + uint32_t (*read_func)(void *, target_phys_addr_t);
  516 + void (*write_func)(void *, target_phys_addr_t, uint32_t);
  517 +};
  518 +
  519 +static struct ip_block ip_blocks[] = {
  520 + {AT91_USART0_BASE - AT91_PERIPH_BASE, AT91_USART0_BASE - AT91_PERIPH_BASE + 0x1000, at91_usart_read, at91_usart_write},
  521 + {AT91_SDRAMC0_BASE - AT91_PERIPH_BASE, AT91_SMC0_BASE - AT91_PERIPH_BASE, at91_sdramc0_read, at91_sdramc0_write},
  522 + {AT91_SMC0_BASE - AT91_PERIPH_BASE, AT91_ECC1_BASE - AT91_PERIPH_BASE, at91_smc0_read, at91_smc0_write},
  523 + {AT91_BUS_MATRIX_BASE - AT91_PERIPH_BASE, AT91_CCFG_BASE - AT91_PERIPH_BASE, at91_bus_matrix_read, at91_bus_matrix_write},
  524 + {AT91_CCFG_BASE - AT91_PERIPH_BASE, AT91_DBGU_BASE - AT91_PERIPH_BASE, at91_ccfg_read, at91_ccfg_write},
  525 + {AT91_DBGU_BASE - AT91_PERIPH_BASE, AT91_AIC_BASE - AT91_PERIPH_BASE, at91_dbgu_read, at91_dbgu_write},
  526 + {AT91_AIC_BASE - AT91_PERIPH_BASE, AT91_PIO_BASE - AT91_PERIPH_BASE, at91_aic_read, at91_aic_write},
  527 + {AT91_PIO_BASE - AT91_PERIPH_BASE, AT91_PMC_BASE - AT91_PERIPH_BASE, at91_pio_read, at91_pio_write},
  528 + {AT91_PMC_BASE - AT91_PERIPH_BASE, AT91_RSTC_BASE - AT91_PERIPH_BASE, at91_pmc_read, at91_pmc_write},
  529 + {AT91_PITC_BASE - AT91_PERIPH_BASE, AT91_WDT_BASE - AT91_PERIPH_BASE, at91_pitc_read, at91_pitc_write},
  530 +};
  531 +
  532 +static uint32_t at91_periph_read(void *opaque, target_phys_addr_t offset)
  533 +{
  534 + int i;
  535 +
  536 + for (i = 0; i < ARRAY_SIZE(ip_blocks); ++i)
  537 + if (offset >= ip_blocks[i].offset && offset < ip_blocks[i].end_offset)
  538 + return ip_blocks[i].read_func(opaque, offset - ip_blocks[i].offset);
  539 + DEBUG("read from unsupported periph addr %X\n", offset);
  540 + return 0xFFFFFFFFUL;
  541 +}
  542 +
  543 +static void at91_periph_write(void *opaque, target_phys_addr_t offset,
  544 + uint32_t value)
  545 +{
  546 + int i;
  547 +
  548 + for (i = 0; i < ARRAY_SIZE(ip_blocks); ++i)
  549 + if (offset >= ip_blocks[i].offset && offset < ip_blocks[i].end_offset) {
  550 + ip_blocks[i].write_func(opaque, offset - ip_blocks[i].offset, value);
  551 + return;
  552 + }
  553 + DEBUG("write to unsupported periph: addr %X, val %X\n", offset, value);
  554 +}
  555 +
  556 +/* Input 0 is IRQ and input 1 is FIQ. */
  557 +static void arm_aic_cpu_handler(void *opaque, int irq, int level)
  558 +{
  559 + CPUState *env = (CPUState *)opaque;
  560 + switch (irq) {
  561 + case ARM_AIC_CPU_IRQ:
  562 + if (level)
  563 + cpu_interrupt(env, CPU_INTERRUPT_HARD);
  564 + else
  565 + cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
  566 + break;
  567 + case ARM_AIC_CPU_FIQ:
  568 + if (level)
  569 + cpu_interrupt(env, CPU_INTERRUPT_FIQ);
  570 + else
  571 + cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ);
  572 + break;
  573 + default:
  574 + hw_error("arm_pic_cpu_handler: Bad interrput line %d\n", irq);
  575 + }
  576 +}
  577 +
  578 +static void at91_aic_init(struct at91sam9_state *sam9)
  579 +{
  580 + memset(&sam9->aic_regs[0], 0, sizeof(sam9->aic_regs));
  581 + sam9->qirq = qemu_allocate_irqs(arm_aic_cpu_handler, sam9->env, 2);
  582 +}
  583 +
  584 +static CPUReadMemoryFunc *at91_periph_readfn[] = {
  585 + at91_periph_read,
  586 + at91_periph_read,
  587 + at91_periph_read
  588 +};
  589 +
  590 +static CPUWriteMemoryFunc *at91_periph_writefn[] = {
  591 + at91_periph_write,
  592 + at91_periph_write,
  593 + at91_periph_write
  594 +};
  595 +
  596 +
  597 +static void at91sam9_init(ram_addr_t ram_size,
  598 + const char *boot_device,
  599 + const char *kernel_filename,
  600 + const char *kernel_cmdline,
  601 + const char *initrd_filename,
  602 + const char *cpu_model)
  603 +{
  604 + CPUState *env;
  605 + DriveInfo *dinfo;
  606 + struct at91sam9_state *sam9;
  607 + int iomemtype;
  608 +
  609 + DEBUG("begin, ram_size %llu\n", (unsigned long long)ram_size);
  610 +#ifdef TRACE_ON
  611 + trace_file = fopen("/tmp/trace.log", "w");
  612 +#endif
  613 + if (!cpu_model)
  614 + cpu_model = "arm926";
  615 + env = cpu_init(cpu_model);
  616 + if (!env) {
  617 + fprintf(stderr, "Unable to find CPU definition\n");
  618 + exit(EXIT_FAILURE);
  619 + }
  620 + /* SDRAM at chipselect 1. */
  621 + cpu_register_physical_memory(AT91SAM9263EK_SDRAM_OFF, AT91SAM9263EK_SDRAM_SIZE,
  622 + qemu_ram_alloc(AT91SAM9263EK_SDRAM_SIZE) | IO_MEM_RAM);
  623 +
  624 + sam9 = (struct at91sam9_state *)qemu_mallocz(sizeof(*sam9));
  625 + if (!sam9) {
  626 + fprintf(stderr, "allocation failed\n");
  627 + exit(EXIT_FAILURE);
  628 + }
  629 + sam9->env = env;
  630 + /* Internal SRAM */
  631 + sam9->internal_sram = qemu_ram_alloc(80 * 1024);
  632 + cpu_register_physical_memory(0x00300000, 80 * 1024, sam9->internal_sram | IO_MEM_RAM);
  633 +
  634 + /*Internal Peripherals */
  635 + iomemtype = cpu_register_io_memory(at91_periph_readfn, at91_periph_writefn, sam9);
  636 + cpu_register_physical_memory(0xF0000000, 0xFFFFFFFF - 0xF0000000, iomemtype);
  637 +
  638 + at91_init_pmc(sam9);
  639 + at91_init_bus_matrix(sam9);
  640 + memset(&sam9->ccfg_regs, 0, sizeof(sam9->ccfg_regs));
  641 + memset(&sam9->pio_regs, 0, sizeof(sam9->pio_regs));
  642 + memset(&sam9->sdramc0_regs, 0, sizeof(sam9->sdramc0_regs));
  643 + memset(&sam9->smc0_regs, 0, sizeof(sam9->smc0_regs));
  644 + at91_init_dbgu(sam9, serial_hds[0]);
  645 + at91_init_pitc(sam9);
  646 + at91_aic_init(sam9);
  647 + memset(sam9->usart0_regs, 0, sizeof(sam9->usart0_regs));
  648 +
  649 + /*
  650 + we use variant of booting from external memory (NOR FLASH),
  651 + it mapped to 0x0 at start, and also it is accessable from 0x10000000 address
  652 + */
  653 + dinfo = drive_get(IF_PFLASH, 0, 0);
  654 + if (dinfo) {
  655 + ram_addr_t nor_flash_mem = qemu_ram_alloc(NOR_FLASH_SIZE);
  656 + if (!nor_flash_mem) {
  657 + fprintf(stderr, "allocation failed\n");
  658 + exit(EXIT_FAILURE);
  659 + }
  660 +
  661 + sam9->norflash = pflash_cfi_atmel_register(AT91SAM9263EK_NORFLASH_OFF,
  662 + nor_flash_mem,
  663 + dinfo->bdrv,
  664 + 4 * 1024 * 2, 8,
  665 + 32 * 1024 * 2,
  666 + (135 - 8),
  667 + 2, 0x001F, 0x01D6, 0, 0);
  668 +
  669 + if (!sam9->norflash) {
  670 + fprintf(stderr, "qemu: error registering flash memory.\n");
  671 + exit(EXIT_FAILURE);
  672 + }
  673 +
  674 + DEBUG("register flash at 0x0\n");
  675 + //register only part of flash, to prevent conflict with internal sram
  676 + cpu_register_physical_memory(0x0, 100 * 1024 /*NOR_FLASH_SIZE*/,
  677 + nor_flash_mem | IO_MEM_ROMD);
  678 + } else {
  679 + fprintf(stderr, "qemu: can not start without flash.\n");
  680 + exit(EXIT_FAILURE);
  681 + }
  682 + env->regs[15] = 0x0;
  683 +}
  684 +
  685 +static QEMUMachine at91sam9263ek_machine = {
  686 + .name = "at91sam9263ek",
  687 + .desc = "Atmel at91sam9263ek board (ARM926EJ-S)",
  688 + .init = at91sam9_init,
  689 +};
  690 +
  691 +static void at91sam9_machine_init(void)
  692 +{
  693 + qemu_register_machine(&at91sam9263ek_machine);
  694 +}
  695 +
  696 +machine_init(at91sam9_machine_init)
... ...
hw/at91sam9263_defs.h 0 → 100644
  1 +#ifndef _HW_AT91SAM9263_DEFS_H_
  2 +#define _HW_AT91SAM9263_DEFS_H_
  3 +
  4 +/* base periph addresses */
  5 +#define AT91_PERIPH_BASE 0xF0000000
  6 +#define AT91_USART0_BASE 0xFFF8C000
  7 +#define AT91_SDRAMC0_BASE 0xFFFFE200
  8 +#define AT91_SMC0_BASE 0xFFFFE400
  9 +#define AT91_ECC1_BASE 0xFFFFE600
  10 +#define AT91_BUS_MATRIX_BASE 0xFFFFEC00
  11 +#define AT91_CCFG_BASE 0xFFFFED10
  12 +#define AT91_DBGU_BASE 0xFFFFEE00
  13 +#define AT91_AIC_BASE 0xFFFFF000
  14 +#define AT91_PIO_BASE 0xFFFFF200
  15 +#define AT91_PMC_BASE 0xFFFFFC00
  16 +#define AT91_RSTC_BASE 0xFFFFFD00
  17 +#define AT91_PITC_BASE 0xFFFFFD30
  18 +#define AT91_WDT_BASE 0xFFFFFD40
  19 +
  20 +/* PMC registers */
  21 +#define AT91_PMC_SR (0x68 / sizeof(uint32_t))
  22 +#define AT91_PMC_MCKR (0x0020 / sizeof(uint32_t))
  23 +#define AT91_PMC_MOR (0x30 / sizeof(uint32_t))
  24 +#define AT91_PMC_CSS (0x3 << 0) // (PMC) Programmable Clock Selection
  25 +#define AT91_PMC_MCKRDY (0x1 << 3) // (PMC) Master Clock Status/Enable/Disable/Mask
  26 +#define AT91_PMC_MOSCS (0x1 << 0) // (PMC) MOSC Status/Enable/Disable/Mask
  27 +#define AT91_CKGR_MOSCEN (0x1 << 0) // (CKGR) Main Oscillator Enable
  28 +#define AT91_PMC_PLLAR (0x0028 / sizeof(uint32_t))
  29 +#define AT91_PMC_PLLBR (0x002C / sizeof(uint32_t))
  30 +#define AT91_PMC_LOCKA (0x1 << 1) // (PMC) PLL A Status/Enable/Disable/Mask
  31 +#define AT91_PMC_LOCKB (0x1 << 2) // (PMC) PLL B Status/Enable/Disable/Mask
  32 +#define AT91_PMC_PCER (0x10 / sizeof(uint32_t))
  33 +
  34 +/*dbgu registers */
  35 +#define AT91_DBGU_CR 0x0
  36 +#define AT91_DBGU_MR (4 / sizeof(uint32_t))
  37 +#define AT91_DBGU_IER (8 / sizeof(uint32_t))
  38 +#define AT91_DBGU_IDR (0xC / sizeof(uint32_t))
  39 +#define AT91_DBGU_IMR (0x10 / sizeof(uint32_t))
  40 +#define AT91_DBGU_SR (0x14 / sizeof(uint32_t))
  41 +#define AT91_DBGU_RHR (0x18 / sizeof(uint32_t))
  42 +#define AT91_DBGU_THR (0x001C / sizeof(uint32_t))
  43 +#define AT91_DBGU_BRGR (0x0020 / sizeof(uint32_t))
  44 +
  45 +
  46 +// -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register --------
  47 +#define AT91_US_RSTRX (0x1 << 2) // (DBGU) Reset Receiver
  48 +#define AT91_US_RSTTX (0x1 << 3) // (DBGU) Reset Transmitter
  49 +#define AT91_US_RXEN (0x1 << 4) // (DBGU) Receiver Enable
  50 +#define AT91_US_RXDIS (0x1 << 5) // (DBGU) Receiver Disable
  51 +#define AT91_US_TXEN (0x1 << 6) // (DBGU) Transmitter Enable
  52 +#define AT91_US_TXDIS (0x1 << 7) // (DBGU) Transmitter Disable
  53 +#define AT91_US_RSTSTA (0x1 << 8) // (DBGU) Reset Status Bits
  54 +// -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register --------
  55 +#define AT91_US_RXRDY (0x1 << 0) // (DBGU) RXRDY Interrupt
  56 +#define AT91_US_TXRDY (0x1 << 1) // (DBGU) TXRDY Interrupt
  57 +#define AT91_US_ENDRX (0x1 << 3) // (DBGU) End of Receive Transfer Interrupt
  58 +#define AT91_US_ENDTX (0x1 << 4) // (DBGU) End of Transmit Interrupt
  59 +#define AT91_US_OVRE (0x1 << 5) // (DBGU) Overrun Interrupt
  60 +#define AT91_US_FRAME (0x1 << 6) // (DBGU) Framing Error Interrupt
  61 +#define AT91_US_PARE (0x1 << 7) // (DBGU) Parity Error Interrupt
  62 +#define AT91_US_TXEMPTY (0x1 << 9) // (DBGU) TXEMPTY Interrupt
  63 +#define AT91_US_TXBUFE (0x1 << 11) // (DBGU) TXBUFE Interrupt
  64 +#define AT91_US_RXBUFF (0x1 << 12) // (DBGU) RXBUFF Interrupt
  65 +#define AT91_US_COMM_TX (0x1 << 30) // (DBGU) COMM_TX Interrupt
  66 +#define AT91_US_COMM_RX (0x1 << 31) // (DBGU) COMM_RX Interrupt
  67 +
  68 +/* US registers */
  69 +#define AT91_US_CR (0)
  70 +#define AT91_US_MR (4 / sizeof(uint32_t))
  71 +#define AT91_US_IER (8 / sizeof(uint32_t))
  72 +#define AT91_US_IDR (0xC / sizeof(uint32_t))
  73 +#define AT91_US_IMR (0x10 / sizeof(uint32_t))
  74 +
  75 +/* matrix */
  76 +
  77 +// *****************************************************************************
  78 +// SOFTWARE API DEFINITION FOR AHB Matrix Interface
  79 +// *****************************************************************************
  80 +// *** Register offset in AT91S_MATRIX structure ***
  81 +#define MATRIX_MCFG0 ( 0) // Master Configuration Register 0
  82 +#define MATRIX_MCFG1 ( 4) // Master Configuration Register 1
  83 +#define MATRIX_MCFG2 ( 8) // Master Configuration Register 2
  84 +#define MATRIX_MCFG3 (12) // Master Configuration Register 3
  85 +#define MATRIX_MCFG4 (16) // Master Configuration Register 4
  86 +#define MATRIX_MCFG5 (20) // Master Configuration Register 5
  87 +#define MATRIX_MCFG6 (24) // Master Configuration Register 6
  88 +#define MATRIX_MCFG7 (28) // Master Configuration Register 7
  89 +#define MATRIX_MCFG8 (32) // Master Configuration Register 8
  90 +#define MATRIX_SCFG0 (64) // Slave Configuration Register 0
  91 +#define MATRIX_SCFG1 (68) // Slave Configuration Register 1
  92 +#define MATRIX_SCFG2 (72) // Slave Configuration Register 2
  93 +#define MATRIX_SCFG3 (76) // Slave Configuration Register 3
  94 +#define MATRIX_SCFG4 (80) // Slave Configuration Register 4
  95 +#define MATRIX_SCFG5 (84) // Slave Configuration Register 5
  96 +#define MATRIX_SCFG6 (88) // Slave Configuration Register 6
  97 +#define MATRIX_SCFG7 (92) // Slave Configuration Register 7
  98 +#define MATRIX_PRAS0 (128) // PRAS0
  99 +#define MATRIX_PRBS0 (132) // PRBS0
  100 +#define MATRIX_PRAS1 (136) // PRAS1
  101 +#define MATRIX_PRBS1 (140) // PRBS1
  102 +#define MATRIX_PRAS2 (144) // PRAS2
  103 +#define MATRIX_PRBS2 (148) // PRBS2
  104 +#define MATRIX_PRAS3 (152) // PRAS3
  105 +#define MATRIX_PRBS3 (156) // PRBS3
  106 +#define MATRIX_PRAS4 (160) // PRAS4
  107 +#define MATRIX_PRBS4 (164) // PRBS4
  108 +#define MATRIX_PRAS5 (168) // PRAS5
  109 +#define MATRIX_PRBS5 (172) // PRBS5
  110 +#define MATRIX_PRAS6 (176) // PRAS6
  111 +#define MATRIX_PRBS6 (180) // PRBS6
  112 +#define MATRIX_PRAS7 (184) // PRAS7
  113 +#define MATRIX_PRBS7 (188) // PRBS7
  114 +#define MATRIX_MRCR (256) // Master Remp Control Register
  115 +
  116 +#define AT91C_MATRIX_RCA926I (0x1 << 0) // (MATRIX) Remap Command Bit for ARM926EJ-S Instruction
  117 +#define AT91C_MATRIX_RCA926D (0x1 << 1) // (MATRIX) Remap Command Bit for ARM926EJ-S Data
  118 +#define AT91C_MATRIX_RCB2 (0x1 << 2) // (MATRIX) Remap Command Bit for PDC
  119 +#define AT91C_MATRIX_RCB3 (0x1 << 3) // (MATRIX) Remap Command Bit for LCD
  120 +#define AT91C_MATRIX_RCB4 (0x1 << 4) // (MATRIX) Remap Command Bit for 2DGC
  121 +#define AT91C_MATRIX_RCB5 (0x1 << 5) // (MATRIX) Remap Command Bit for ISI
  122 +#define AT91C_MATRIX_RCB6 (0x1 << 6) // (MATRIX) Remap Command Bit for DMA
  123 +#define AT91C_MATRIX_RCB7 (0x1 << 7) // (MATRIX) Remap Command Bit for EMAC
  124 +#define AT91C_MATRIX_RCB8 (0x1 << 8) // (MATRIX) Remap Command Bit for USB
  125 +
  126 +/*pitc */
  127 +#define AT91_PTIC_MR_PITEN (1 << 24)
  128 +#define AT91_PTIC_MR_PITIEN (1 << 25)
  129 +#define AT91_PITC_MR 0
  130 +#define AT91_PITC_SR (0x4 / sizeof(uint32_t))
  131 +#define AT91_PITC_PIVR (0x8 / sizeof(uint32_t))
  132 +#define AT91_PITC_PIIR (0xC / sizeof(uint32_t))
  133 +
  134 +/*AIC registers*/
  135 +#define AT91_AIC_SVR0 (0x80 / sizeof(uint32_t))
  136 +#define AT91_AIC_ISR (0x108 / sizeof(uint32_t))
  137 +#define AT91_AIC_IECR (0x120 / sizeof(uint32_t))
  138 +#define AT91_AIC_EOICR (0x130 / sizeof(uint32_t))
  139 +#define AT91_AIC_IVR (0x100 / sizeof(uint32_t))
  140 +#define AT91_AIC_IDCR (0x124 / sizeof(uint32_t))
  141 +
  142 +#define AT91_PERIPH_SYS_ID 1
  143 +
  144 +#endif//!_HW_AT91SAM9263_DEFS_H_
... ...