Commit 1d47d78e9fe018c44e8c55e9f4948eba0761585b
1 parent
f13b3ca3
add emulation of at91sam9263 cpu, plus sdram, plus nor flash connected to this cpu
Showing
3 changed files
with
841 additions
and
1 deletions
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_ | ... | ... |