Commit e69954b9fc698996c8416a2fb26c6b50ad9f49a9

Authored by pbrook
1 parent 37dd208d

Add ARM RealView Emulation Baseboard.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2164 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -368,6 +368,7 @@ ifeq ($(TARGET_BASE_ARCH), arm)
368 368 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
369 369 VL_OBJS+= arm_boot.o pl011.o pl050.o pl080.o pl110.o pl190.o
370 370 VL_OBJS+= versatile_pci.o
  371 +VL_OBJS+= arm_gic.o realview.o arm_sysctl.o
371 372 endif
372 373 ifeq ($(TARGET_BASE_ARCH), sh4)
373 374 VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
... ...
hw/arm_gic.c 0 → 100644
  1 +/*
  2 + * ARM AMBA Generic/Distributed Interrupt Controller
  3 + *
  4 + * Copyright (c) 2006 CodeSourcery.
  5 + * Written by Paul Brook
  6 + *
  7 + * This code is licenced under the GPL.
  8 + */
  9 +
  10 +/* TODO: Some variants of this controller can handle multiple CPUs.
  11 + Currently only single CPU operation is implemented. */
  12 +
  13 +#include "vl.h"
  14 +#include "arm_pic.h"
  15 +
  16 +//#define DEBUG_GIC
  17 +
  18 +#ifdef DEBUG_GIC
  19 +#define DPRINTF(fmt, args...) \
  20 +do { printf("arm_gic: " fmt , (int)s->base, ##args); } while (0)
  21 +#else
  22 +#define DPRINTF(fmt, args...) do {} while(0)
  23 +#endif
  24 +
  25 +/* Distributed interrupt controller. */
  26 +
  27 +static const uint8_t gic_id[] =
  28 +{ 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
  29 +
  30 +#define GIC_NIRQ 96
  31 +
  32 +typedef struct gic_irq_state
  33 +{
  34 + unsigned enabled:1;
  35 + unsigned pending:1;
  36 + unsigned active:1;
  37 + unsigned level:1;
  38 + unsigned model:1; /* 0 = 1:N, 1 = N:N */
  39 + unsigned trigger:1; /* nonzero = edge triggered. */
  40 +} gic_irq_state;
  41 +
  42 +#define GIC_SET_ENABLED(irq) s->irq_state[irq].enabled = 1
  43 +#define GIC_CLEAR_ENABLED(irq) s->irq_state[irq].enabled = 0
  44 +#define GIC_TEST_ENABLED(irq) s->irq_state[irq].enabled
  45 +#define GIC_SET_PENDING(irq) s->irq_state[irq].pending = 1
  46 +#define GIC_CLEAR_PENDING(irq) s->irq_state[irq].pending = 0
  47 +#define GIC_TEST_PENDING(irq) s->irq_state[irq].pending
  48 +#define GIC_SET_ACTIVE(irq) s->irq_state[irq].active = 1
  49 +#define GIC_CLEAR_ACTIVE(irq) s->irq_state[irq].active = 0
  50 +#define GIC_TEST_ACTIVE(irq) s->irq_state[irq].active
  51 +#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
  52 +#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
  53 +#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
  54 +#define GIC_SET_LEVEL(irq) s->irq_state[irq].level = 1
  55 +#define GIC_CLEAR_LEVEL(irq) s->irq_state[irq].level = 0
  56 +#define GIC_TEST_LEVEL(irq) s->irq_state[irq].level
  57 +#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
  58 +#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
  59 +#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger
  60 +
  61 +typedef struct gic_state
  62 +{
  63 + arm_pic_handler handler;
  64 + uint32_t base;
  65 + void *parent;
  66 + int parent_irq;
  67 + int enabled;
  68 + int cpu_enabled;
  69 +
  70 + gic_irq_state irq_state[GIC_NIRQ];
  71 + int irq_target[GIC_NIRQ];
  72 + int priority[GIC_NIRQ];
  73 + int last_active[GIC_NIRQ];
  74 +
  75 + int priority_mask;
  76 + int running_irq;
  77 + int running_priority;
  78 + int current_pending;
  79 +} gic_state;
  80 +
  81 +/* TODO: Many places that call this routine could be optimized. */
  82 +/* Update interrupt status after enabled or pending bits have been changed. */
  83 +static void gic_update(gic_state *s)
  84 +{
  85 + int best_irq;
  86 + int best_prio;
  87 + int irq;
  88 +
  89 + s->current_pending = 1023;
  90 + if (!s->enabled || !s->cpu_enabled) {
  91 + pic_set_irq_new(s->parent, s->parent_irq, 0);
  92 + return;
  93 + }
  94 + best_prio = 0x100;
  95 + best_irq = 1023;
  96 + for (irq = 0; irq < 96; irq++) {
  97 + if (GIC_TEST_ENABLED(irq) && GIC_TEST_PENDING(irq)) {
  98 + if (s->priority[irq] < best_prio) {
  99 + best_prio = s->priority[irq];
  100 + best_irq = irq;
  101 + }
  102 + }
  103 + }
  104 + if (best_prio > s->priority_mask) {
  105 + pic_set_irq_new(s->parent, s->parent_irq, 0);
  106 + } else {
  107 + s->current_pending = best_irq;
  108 + if (best_prio < s->running_priority) {
  109 + DPRINTF("Raised pending IRQ %d\n", best_irq);
  110 + pic_set_irq_new(s->parent, s->parent_irq, 1);
  111 + }
  112 + }
  113 +}
  114 +
  115 +static void gic_set_irq(void *opaque, int irq, int level)
  116 +{
  117 + gic_state *s = (gic_state *)opaque;
  118 + /* The first external input line is internal interrupt 32. */
  119 + irq += 32;
  120 + if (level == GIC_TEST_LEVEL(irq))
  121 + return;
  122 +
  123 + if (level) {
  124 + GIC_SET_LEVEL(irq);
  125 + if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq)) {
  126 + DPRINTF("Set %d pending\n", irq);
  127 + GIC_SET_PENDING(irq);
  128 + }
  129 + } else {
  130 + GIC_CLEAR_LEVEL(irq);
  131 + }
  132 + gic_update(s);
  133 +}
  134 +
  135 +static void gic_set_running_irq(gic_state *s, int irq)
  136 +{
  137 + s->running_irq = irq;
  138 + s->running_priority = s->priority[irq];
  139 + gic_update(s);
  140 +}
  141 +
  142 +static uint32_t gic_acknowledge_irq(gic_state *s)
  143 +{
  144 + int new_irq;
  145 + new_irq = s->current_pending;
  146 + if (new_irq == 1023 || s->priority[new_irq] >= s->running_priority) {
  147 + DPRINTF("ACK no pending IRQ\n");
  148 + return 1023;
  149 + }
  150 + pic_set_irq_new(s->parent, s->parent_irq, 0);
  151 + s->last_active[new_irq] = s->running_irq;
  152 + /* For level triggered interrupts we clear the pending bit while
  153 + the interrupt is active. */
  154 + GIC_CLEAR_PENDING(new_irq);
  155 + gic_set_running_irq(s, new_irq);
  156 + DPRINTF("ACK %d\n", new_irq);
  157 + return new_irq;
  158 +}
  159 +
  160 +static void gic_complete_irq(gic_state * s, int irq)
  161 +{
  162 + int update = 0;
  163 + DPRINTF("EIO %d\n", irq);
  164 + if (s->running_irq == 1023)
  165 + return; /* No active IRQ. */
  166 + if (irq != 1023) {
  167 + /* Mark level triggered interrupts as pending if they are still
  168 + raised. */
  169 + if (!GIC_TEST_TRIGGER(irq) && GIC_TEST_ENABLED(irq)
  170 + && GIC_TEST_LEVEL(irq)) {
  171 + GIC_SET_PENDING(irq);
  172 + update = 1;
  173 + }
  174 + }
  175 + if (irq != s->running_irq) {
  176 + /* Complete an IRQ that is not currently running. */
  177 + int tmp = s->running_irq;
  178 + while (s->last_active[tmp] != 1023) {
  179 + if (s->last_active[tmp] == irq) {
  180 + s->last_active[tmp] = s->last_active[irq];
  181 + break;
  182 + }
  183 + tmp = s->last_active[tmp];
  184 + }
  185 + if (update) {
  186 + gic_update(s);
  187 + }
  188 + } else {
  189 + /* Complete the current running IRQ. */
  190 + gic_set_running_irq(s, s->last_active[s->running_irq]);
  191 + }
  192 +}
  193 +
  194 +static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
  195 +{
  196 + gic_state *s = (gic_state *)opaque;
  197 + uint32_t res;
  198 + int irq;
  199 + int i;
  200 +
  201 + offset -= s->base + 0x1000;
  202 + if (offset < 0x100) {
  203 + if (offset == 0)
  204 + return s->enabled;
  205 + if (offset == 4)
  206 + return (GIC_NIRQ / 32) - 1;
  207 + if (offset < 0x08)
  208 + return 0;
  209 + goto bad_reg;
  210 + } else if (offset < 0x200) {
  211 + /* Interrupt Set/Clear Enable. */
  212 + if (offset < 0x180)
  213 + irq = (offset - 0x100) * 8;
  214 + else
  215 + irq = (offset - 0x180) * 8;
  216 + if (irq >= GIC_NIRQ)
  217 + goto bad_reg;
  218 + res = 0;
  219 + for (i = 0; i < 8; i++) {
  220 + if (GIC_TEST_ENABLED(irq + i)) {
  221 + res |= (1 << i);
  222 + }
  223 + }
  224 + } else if (offset < 0x300) {
  225 + /* Interrupt Set/Clear Pending. */
  226 + if (offset < 0x280)
  227 + irq = (offset - 0x200) * 8;
  228 + else
  229 + irq = (offset - 0x280) * 8;
  230 + if (irq >= GIC_NIRQ)
  231 + goto bad_reg;
  232 + res = 0;
  233 + for (i = 0; i < 8; i++) {
  234 + if (GIC_TEST_PENDING(irq + i)) {
  235 + res |= (1 << i);
  236 + }
  237 + }
  238 + } else if (offset < 0x400) {
  239 + /* Interrupt Active. */
  240 + irq = (offset - 0x300) * 8;
  241 + if (irq >= GIC_NIRQ)
  242 + goto bad_reg;
  243 + res = 0;
  244 + for (i = 0; i < 8; i++) {
  245 + if (GIC_TEST_ACTIVE(irq + i)) {
  246 + res |= (1 << i);
  247 + }
  248 + }
  249 + } else if (offset < 0x800) {
  250 + /* Interrupt Priority. */
  251 + irq = offset - 0x400;
  252 + if (irq >= GIC_NIRQ)
  253 + goto bad_reg;
  254 + res = s->priority[irq];
  255 + } else if (offset < 0xc00) {
  256 + /* Interrupt CPU Target. */
  257 + irq = offset - 0x800;
  258 + if (irq >= GIC_NIRQ)
  259 + goto bad_reg;
  260 + res = s->irq_target[irq];
  261 + } else if (offset < 0xf00) {
  262 + /* Interrupt Configuration. */
  263 + irq = (offset - 0xc00) * 2;
  264 + if (irq >= GIC_NIRQ)
  265 + goto bad_reg;
  266 + res = 0;
  267 + for (i = 0; i < 4; i++) {
  268 + if (GIC_TEST_MODEL(irq + i))
  269 + res |= (1 << (i * 2));
  270 + if (GIC_TEST_TRIGGER(irq + i))
  271 + res |= (2 << (i * 2));
  272 + }
  273 + } else if (offset < 0xfe0) {
  274 + goto bad_reg;
  275 + } else /* offset >= 0xfe0 */ {
  276 + if (offset & 3) {
  277 + res = 0;
  278 + } else {
  279 + res = gic_id[(offset - 0xfe0) >> 2];
  280 + }
  281 + }
  282 + return res;
  283 +bad_reg:
  284 + cpu_abort (cpu_single_env, "gic_dist_readb: Bad offset %x\n", offset);
  285 + return 0;
  286 +}
  287 +
  288 +static uint32_t gic_dist_readw(void *opaque, target_phys_addr_t offset)
  289 +{
  290 + uint32_t val;
  291 + val = gic_dist_readb(opaque, offset);
  292 + val |= gic_dist_readb(opaque, offset + 1) << 8;
  293 + return val;
  294 +}
  295 +
  296 +static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
  297 +{
  298 + uint32_t val;
  299 + val = gic_dist_readw(opaque, offset);
  300 + val |= gic_dist_readw(opaque, offset + 2) << 16;
  301 + return val;
  302 +}
  303 +
  304 +static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
  305 + uint32_t value)
  306 +{
  307 + gic_state *s = (gic_state *)opaque;
  308 + int irq;
  309 + int i;
  310 +
  311 + offset -= s->base + 0x1000;
  312 + if (offset < 0x100) {
  313 + if (offset == 0) {
  314 + s->enabled = (value & 1);
  315 + DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
  316 + } else if (offset < 4) {
  317 + /* ignored. */
  318 + } else {
  319 + goto bad_reg;
  320 + }
  321 + } else if (offset < 0x180) {
  322 + /* Interrupt Set Enable. */
  323 + irq = (offset - 0x100) * 8;
  324 + if (irq >= GIC_NIRQ)
  325 + goto bad_reg;
  326 + for (i = 0; i < 8; i++) {
  327 + if (value & (1 << i)) {
  328 + if (!GIC_TEST_ENABLED(irq + i))
  329 + DPRINTF("Enabled IRQ %d\n", irq + i);
  330 + GIC_SET_ENABLED(irq + i);
  331 + /* If a raised level triggered IRQ enabled then mark
  332 + is as pending. */
  333 + if (GIC_TEST_LEVEL(irq + i) && !GIC_TEST_TRIGGER(irq + i))
  334 + GIC_SET_PENDING(irq + i);
  335 + }
  336 + }
  337 + } else if (offset < 0x200) {
  338 + /* Interrupt Clear Enable. */
  339 + irq = (offset - 0x180) * 8;
  340 + if (irq >= GIC_NIRQ)
  341 + goto bad_reg;
  342 + for (i = 0; i < 8; i++) {
  343 + if (value & (1 << i)) {
  344 + if (GIC_TEST_ENABLED(irq + i))
  345 + DPRINTF("Disabled IRQ %d\n", irq + i);
  346 + GIC_CLEAR_ENABLED(irq + i);
  347 + }
  348 + }
  349 + } else if (offset < 0x280) {
  350 + /* Interrupt Set Pending. */
  351 + irq = (offset - 0x200) * 8;
  352 + if (irq >= GIC_NIRQ)
  353 + goto bad_reg;
  354 + for (i = 0; i < 8; i++) {
  355 + if (value & (1 << i)) {
  356 + GIC_SET_PENDING(irq + i);
  357 + }
  358 + }
  359 + } else if (offset < 0x300) {
  360 + /* Interrupt Clear Pending. */
  361 + irq = (offset - 0x280) * 8;
  362 + if (irq >= GIC_NIRQ)
  363 + goto bad_reg;
  364 + for (i = 0; i < 8; i++) {
  365 + if (value & (1 << i)) {
  366 + GIC_CLEAR_PENDING(irq + i);
  367 + }
  368 + }
  369 + } else if (offset < 0x400) {
  370 + /* Interrupt Active. */
  371 + goto bad_reg;
  372 + } else if (offset < 0x800) {
  373 + /* Interrupt Priority. */
  374 + irq = offset - 0x400;
  375 + if (irq >= GIC_NIRQ)
  376 + goto bad_reg;
  377 + s->priority[irq] = value;
  378 + } else if (offset < 0xc00) {
  379 + /* Interrupt CPU Target. */
  380 + irq = offset - 0x800;
  381 + if (irq >= GIC_NIRQ)
  382 + goto bad_reg;
  383 + s->irq_target[irq] = value;
  384 + } else if (offset < 0xf00) {
  385 + /* Interrupt Configuration. */
  386 + irq = (offset - 0xc00) * 2;
  387 + if (irq >= GIC_NIRQ)
  388 + goto bad_reg;
  389 + for (i = 0; i < 4; i++) {
  390 + if (value & (1 << (i * 2))) {
  391 + GIC_SET_MODEL(irq + i);
  392 + } else {
  393 + GIC_CLEAR_MODEL(irq + i);
  394 + }
  395 + if (value & (2 << (i * 2))) {
  396 + GIC_SET_TRIGGER(irq + i);
  397 + } else {
  398 + GIC_CLEAR_TRIGGER(irq + i);
  399 + }
  400 + }
  401 + } else {
  402 + /* 0xf00 is only handled for word writes. */
  403 + goto bad_reg;
  404 + }
  405 + gic_update(s);
  406 + return;
  407 +bad_reg:
  408 + cpu_abort (cpu_single_env, "gic_dist_writeb: Bad offset %x\n", offset);
  409 +}
  410 +
  411 +static void gic_dist_writew(void *opaque, target_phys_addr_t offset,
  412 + uint32_t value)
  413 +{
  414 + gic_state *s = (gic_state *)opaque;
  415 + if (offset - s->base == 0xf00) {
  416 + GIC_SET_PENDING(value & 0x3ff);
  417 + gic_update(s);
  418 + return;
  419 + }
  420 + gic_dist_writeb(opaque, offset, value & 0xff);
  421 + gic_dist_writeb(opaque, offset + 1, value >> 8);
  422 +}
  423 +
  424 +static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
  425 + uint32_t value)
  426 +{
  427 + gic_dist_writew(opaque, offset, value & 0xffff);
  428 + gic_dist_writew(opaque, offset + 2, value >> 16);
  429 +}
  430 +
  431 +static CPUReadMemoryFunc *gic_dist_readfn[] = {
  432 + gic_dist_readb,
  433 + gic_dist_readw,
  434 + gic_dist_readl
  435 +};
  436 +
  437 +static CPUWriteMemoryFunc *gic_dist_writefn[] = {
  438 + gic_dist_writeb,
  439 + gic_dist_writew,
  440 + gic_dist_writel
  441 +};
  442 +
  443 +static uint32_t gic_cpu_read(void *opaque, target_phys_addr_t offset)
  444 +{
  445 + gic_state *s = (gic_state *)opaque;
  446 + offset -= s->base;
  447 + switch (offset) {
  448 + case 0x00: /* Control */
  449 + return s->cpu_enabled;
  450 + case 0x04: /* Priority mask */
  451 + return s->priority_mask;
  452 + case 0x08: /* Binary Point */
  453 + /* ??? Not implemented. */
  454 + return 0;
  455 + case 0x0c: /* Acknowledge */
  456 + return gic_acknowledge_irq(s);
  457 + case 0x14: /* Runing Priority */
  458 + return s->running_priority;
  459 + case 0x18: /* Highest Pending Interrupt */
  460 + return s->current_pending;
  461 + default:
  462 + cpu_abort (cpu_single_env, "gic_cpu_writeb: Bad offset %x\n", offset);
  463 + return 0;
  464 + }
  465 +}
  466 +
  467 +static void gic_cpu_write(void *opaque, target_phys_addr_t offset,
  468 + uint32_t value)
  469 +{
  470 + gic_state *s = (gic_state *)opaque;
  471 + offset -= s->base;
  472 + switch (offset) {
  473 + case 0x00: /* Control */
  474 + s->cpu_enabled = (value & 1);
  475 + DPRINTF("CPU %sabled\n", s->cpu_enabled ? "En" : "Dis");
  476 + break;
  477 + case 0x04: /* Priority mask */
  478 + s->priority_mask = (value & 0x3ff);
  479 + break;
  480 + case 0x08: /* Binary Point */
  481 + /* ??? Not implemented. */
  482 + break;
  483 + case 0x10: /* End Of Interrupt */
  484 + return gic_complete_irq(s, value & 0x3ff);
  485 + default:
  486 + cpu_abort (cpu_single_env, "gic_cpu_writeb: Bad offset %x\n", offset);
  487 + return;
  488 + }
  489 + gic_update(s);
  490 +}
  491 +
  492 +static CPUReadMemoryFunc *gic_cpu_readfn[] = {
  493 + gic_cpu_read,
  494 + gic_cpu_read,
  495 + gic_cpu_read
  496 +};
  497 +
  498 +static CPUWriteMemoryFunc *gic_cpu_writefn[] = {
  499 + gic_cpu_write,
  500 + gic_cpu_write,
  501 + gic_cpu_write
  502 +};
  503 +
  504 +static void gic_reset(gic_state *s)
  505 +{
  506 + int i;
  507 + memset(s->irq_state, 0, GIC_NIRQ * sizeof(gic_irq_state));
  508 + s->priority_mask = 0xf0;
  509 + s->current_pending = 1023;
  510 + s->running_irq = 1023;
  511 + s->running_priority = 0x100;
  512 + for (i = 0; i < 15; i++) {
  513 + GIC_SET_ENABLED(i);
  514 + GIC_SET_TRIGGER(i);
  515 + }
  516 + s->enabled = 0;
  517 + s->cpu_enabled = 0;
  518 +}
  519 +
  520 +void *arm_gic_init(uint32_t base, void *parent, int parent_irq)
  521 +{
  522 + gic_state *s;
  523 + int iomemtype;
  524 +
  525 + s = (gic_state *)qemu_mallocz(sizeof(gic_state));
  526 + if (!s)
  527 + return NULL;
  528 + s->handler = gic_set_irq;
  529 + s->parent = parent;
  530 + s->parent_irq = parent_irq;
  531 + if (base != 0xffffffff) {
  532 + iomemtype = cpu_register_io_memory(0, gic_cpu_readfn,
  533 + gic_cpu_writefn, s);
  534 + cpu_register_physical_memory(base, 0x00000fff, iomemtype);
  535 + iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
  536 + gic_dist_writefn, s);
  537 + cpu_register_physical_memory(base + 0x1000, 0x00000fff, iomemtype);
  538 + s->base = base;
  539 + } else {
  540 + s->base = 0;
  541 + }
  542 + gic_reset(s);
  543 + return s;
  544 +}
... ...
hw/arm_sysctl.c 0 → 100644
  1 +/*
  2 + * Status and system control registers for ARM RealView/Versatile boards.
  3 + *
  4 + * Copyright (c) 2006 CodeSourcery.
  5 + * Written by Paul Brook
  6 + *
  7 + * This code is licenced under the GPL.
  8 + */
  9 +
  10 +#include "vl.h"
  11 +#include "arm_pic.h"
  12 +
  13 +#define LOCK_VALUE 0xa05f
  14 +
  15 +typedef struct {
  16 + uint32_t base;
  17 + uint32_t sys_id;
  18 + uint32_t leds;
  19 + uint16_t lockval;
  20 + uint32_t cfgdata1;
  21 + uint32_t cfgdata2;
  22 + uint32_t flags;
  23 + uint32_t nvflags;
  24 + uint32_t resetlevel;
  25 +} arm_sysctl_state;
  26 +
  27 +static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
  28 +{
  29 + arm_sysctl_state *s = (arm_sysctl_state *)opaque;
  30 +
  31 + offset -= s->base;
  32 + switch (offset) {
  33 + case 0x00: /* ID */
  34 + return s->sys_id;
  35 + case 0x04: /* SW */
  36 + /* General purpose hardware switches.
  37 + We don't have a useful way of exposing these to the user. */
  38 + return 0;
  39 + case 0x08: /* LED */
  40 + return s->leds;
  41 + case 0x20: /* LOCK */
  42 + return s->lockval;
  43 + case 0x0c: /* OSC0 */
  44 + case 0x10: /* OSC1 */
  45 + case 0x14: /* OSC2 */
  46 + case 0x18: /* OSC3 */
  47 + case 0x1c: /* OSC4 */
  48 + case 0x24: /* 100HZ */
  49 + /* ??? Implement these. */
  50 + return 0;
  51 + case 0x28: /* CFGDATA1 */
  52 + return s->cfgdata1;
  53 + case 0x2c: /* CFGDATA2 */
  54 + return s->cfgdata2;
  55 + case 0x30: /* FLAGS */
  56 + return s->flags;
  57 + case 0x38: /* NVFLAGS */
  58 + return s->nvflags;
  59 + case 0x40: /* RESETCTL */
  60 + return s->resetlevel;
  61 + case 0x44: /* PCICTL */
  62 + return 1;
  63 + case 0x48: /* MCI */
  64 + return 0;
  65 + case 0x4c: /* FLASH */
  66 + return 0;
  67 + case 0x50: /* CLCD */
  68 + return 0x1000;
  69 + case 0x54: /* CLCDSER */
  70 + return 0;
  71 + case 0x58: /* BOOTCS */
  72 + return 0;
  73 + case 0x5c: /* 24MHz */
  74 + /* ??? not implemented. */
  75 + return 0;
  76 + case 0x60: /* MISC */
  77 + return 0;
  78 + case 0x84: /* PROCID0 */
  79 + /* ??? Don't know what the proper value for the core tile ID is. */
  80 + return 0x02000000;
  81 + case 0x88: /* PROCID1 */
  82 + return 0xff000000;
  83 + case 0x64: /* DMAPSR0 */
  84 + case 0x68: /* DMAPSR1 */
  85 + case 0x6c: /* DMAPSR2 */
  86 + case 0x70: /* IOSEL */
  87 + case 0x74: /* PLDCTL */
  88 + case 0x80: /* BUSID */
  89 + case 0x8c: /* OSCRESET0 */
  90 + case 0x90: /* OSCRESET1 */
  91 + case 0x94: /* OSCRESET2 */
  92 + case 0x98: /* OSCRESET3 */
  93 + case 0x9c: /* OSCRESET4 */
  94 + case 0xc0: /* SYS_TEST_OSC0 */
  95 + case 0xc4: /* SYS_TEST_OSC1 */
  96 + case 0xc8: /* SYS_TEST_OSC2 */
  97 + case 0xcc: /* SYS_TEST_OSC3 */
  98 + case 0xd0: /* SYS_TEST_OSC4 */
  99 + return 0;
  100 + default:
  101 + printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset);
  102 + return 0;
  103 + }
  104 +}
  105 +
  106 +static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
  107 + uint32_t val)
  108 +{
  109 + arm_sysctl_state *s = (arm_sysctl_state *)opaque;
  110 + offset -= s->base;
  111 +
  112 + switch (offset) {
  113 + case 0x08: /* LED */
  114 + s->leds = val;
  115 + case 0x0c: /* OSC0 */
  116 + case 0x10: /* OSC1 */
  117 + case 0x14: /* OSC2 */
  118 + case 0x18: /* OSC3 */
  119 + case 0x1c: /* OSC4 */
  120 + /* ??? */
  121 + break;
  122 + case 0x20: /* LOCK */
  123 + if (val == LOCK_VALUE)
  124 + s->lockval = val;
  125 + else
  126 + s->lockval = val & 0x7fff;
  127 + break;
  128 + case 0x28: /* CFGDATA1 */
  129 + /* ??? Need to implement this. */
  130 + s->cfgdata1 = val;
  131 + break;
  132 + case 0x2c: /* CFGDATA2 */
  133 + /* ??? Need to implement this. */
  134 + s->cfgdata2 = val;
  135 + break;
  136 + case 0x30: /* FLAGSSET */
  137 + s->flags |= val;
  138 + break;
  139 + case 0x34: /* FLAGSCLR */
  140 + s->flags &= ~val;
  141 + break;
  142 + case 0x38: /* NVFLAGSSET */
  143 + s->nvflags |= val;
  144 + break;
  145 + case 0x3c: /* NVFLAGSCLR */
  146 + s->nvflags &= ~val;
  147 + break;
  148 + case 0x40: /* RESETCTL */
  149 + if (s->lockval == LOCK_VALUE) {
  150 + s->resetlevel = val;
  151 + if (val & 0x100)
  152 + cpu_abort(cpu_single_env, "Board reset\n");
  153 + }
  154 + break;
  155 + case 0x44: /* PCICTL */
  156 + /* nothing to do. */
  157 + break;
  158 + case 0x4c: /* FLASH */
  159 + case 0x50: /* CLCD */
  160 + case 0x54: /* CLCDSER */
  161 + case 0x64: /* DMAPSR0 */
  162 + case 0x68: /* DMAPSR1 */
  163 + case 0x6c: /* DMAPSR2 */
  164 + case 0x70: /* IOSEL */
  165 + case 0x74: /* PLDCTL */
  166 + case 0x80: /* BUSID */
  167 + case 0x84: /* PROCID0 */
  168 + case 0x88: /* PROCID1 */
  169 + case 0x8c: /* OSCRESET0 */
  170 + case 0x90: /* OSCRESET1 */
  171 + case 0x94: /* OSCRESET2 */
  172 + case 0x98: /* OSCRESET3 */
  173 + case 0x9c: /* OSCRESET4 */
  174 + break;
  175 + default:
  176 + printf ("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset);
  177 + return;
  178 + }
  179 +}
  180 +
  181 +static CPUReadMemoryFunc *arm_sysctl_readfn[] = {
  182 + arm_sysctl_read,
  183 + arm_sysctl_read,
  184 + arm_sysctl_read
  185 +};
  186 +
  187 +static CPUWriteMemoryFunc *arm_sysctl_writefn[] = {
  188 + arm_sysctl_write,
  189 + arm_sysctl_write,
  190 + arm_sysctl_write
  191 +};
  192 +
  193 +void arm_sysctl_init(uint32_t base, uint32_t sys_id)
  194 +{
  195 + arm_sysctl_state *s;
  196 + int iomemtype;
  197 +
  198 + s = (arm_sysctl_state *)qemu_mallocz(sizeof(arm_sysctl_state));
  199 + if (!s)
  200 + return;
  201 + s->base = base;
  202 + s->sys_id = sys_id;
  203 + iomemtype = cpu_register_io_memory(0, arm_sysctl_readfn,
  204 + arm_sysctl_writefn, s);
  205 + cpu_register_physical_memory(base, 0x00000fff, iomemtype);
  206 + /* ??? Save/restore. */
  207 +}
  208 +
... ...
hw/pl080.c
1 1 /*
2   - * Arm PrimeCell PL080 DMA controller
  2 + * Arm PrimeCell PL080/PL081 DMA controller
3 3 *
4 4 * Copyright (c) 2006 CodeSourcery.
5 5 * Written by Paul Brook
... ... @@ -9,7 +9,7 @@
9 9  
10 10 #include "vl.h"
11 11  
12   -#define PL080_NUM_CHANNELS 8
  12 +#define PL080_MAX_CHANNELS 8
13 13 #define PL080_CONF_E 0x1
14 14 #define PL080_CONF_M1 0x2
15 15 #define PL080_CONF_M2 0x4
... ... @@ -45,7 +45,8 @@ typedef struct {
45 45 uint32_t sync;
46 46 uint32_t req_single;
47 47 uint32_t req_burst;
48   - pl080_channel chan[PL080_NUM_CHANNELS];
  48 + pl080_channel chan[PL080_MAX_CHANNELS];
  49 + int nchannels;
49 50 /* Flag to avoid recursive DMA invocations. */
50 51 int running;
51 52 void *pic;
... ... @@ -55,6 +56,9 @@ typedef struct {
55 56 static const unsigned char pl080_id[] =
56 57 { 0x80, 0x10, 0x04, 0x0a, 0x0d, 0xf0, 0x05, 0xb1 };
57 58  
  59 +static const unsigned char pl081_id[] =
  60 +{ 0x81, 0x10, 0x04, 0x0a, 0x0d, 0xf0, 0x05, 0xb1 };
  61 +
58 62 static void pl080_update(pl080_state *s)
59 63 {
60 64 if ((s->tc_int & s->tc_mask)
... ... @@ -80,7 +84,7 @@ static void pl080_run(pl080_state *s)
80 84 uint32_t req;
81 85  
82 86 s->tc_mask = 0;
83   - for (c = 0; c < PL080_NUM_CHANNELS; c++) {
  87 + for (c = 0; c < s->nchannels; c++) {
84 88 if (s->chan[c].conf & PL080_CCONF_ITC)
85 89 s->tc_mask |= 1 << c;
86 90 if (s->chan[c].conf & PL080_CCONF_IE)
... ... @@ -99,7 +103,7 @@ cpu_abort(cpu_single_env, &quot;DMA active\n&quot;);
99 103 }
100 104 s->running = 1;
101 105 while (s->running) {
102   - for (c = 0; c < PL080_NUM_CHANNELS; c++) {
  106 + for (c = 0; c < s->nchannels; c++) {
103 107 ch = &s->chan[c];
104 108 again:
105 109 /* Test if thiws channel has any pending DMA requests. */
... ... @@ -185,10 +189,16 @@ static uint32_t pl080_read(void *opaque, target_phys_addr_t offset)
185 189  
186 190 offset -= s->base;
187 191 if (offset >= 0xfe0 && offset < 0x1000) {
188   - return pl080_id[(offset - 0xfe0) >> 2];
  192 + if (s->nchannels == 8) {
  193 + return pl080_id[(offset - 0xfe0) >> 2];
  194 + } else {
  195 + return pl081_id[(offset - 0xfe0) >> 2];
  196 + }
189 197 }
190 198 if (offset >= 0x100 && offset < 0x200) {
191 199 i = (offset & 0xe0) >> 5;
  200 + if (i >= s->nchannels)
  201 + goto bad_offset;
192 202 switch (offset >> 2) {
193 203 case 0: /* SrcAddr */
194 204 return s->chan[i].src;
... ... @@ -217,7 +227,7 @@ static uint32_t pl080_read(void *opaque, target_phys_addr_t offset)
217 227 return s->err_int;
218 228 case 7: /* EnbldChns */
219 229 mask = 0;
220   - for (i = 0; i < PL080_NUM_CHANNELS; i++) {
  230 + for (i = 0; i < s->nchannels; i++) {
221 231 if (s->chan[i].conf & PL080_CCONF_E)
222 232 mask |= 1 << i;
223 233 }
... ... @@ -248,6 +258,8 @@ static void pl080_write(void *opaque, target_phys_addr_t offset,
248 258 offset -= s->base;
249 259 if (offset >= 0x100 && offset < 0x200) {
250 260 i = (offset & 0xe0) >> 5;
  261 + if (i >= s->nchannels)
  262 + goto bad_offset;
251 263 switch (offset >> 2) {
252 264 case 0: /* SrcAddr */
253 265 s->chan[i].src = value;
... ... @@ -293,6 +305,7 @@ static void pl080_write(void *opaque, target_phys_addr_t offset,
293 305 s->sync = value;
294 306 break;
295 307 default:
  308 + bad_offset:
296 309 cpu_abort(cpu_single_env, "pl080_write: Bad offset %x\n", offset);
297 310 }
298 311 pl080_update(s);
... ... @@ -310,7 +323,9 @@ static CPUWriteMemoryFunc *pl080_writefn[] = {
310 323 pl080_write
311 324 };
312 325  
313   -void *pl080_init(uint32_t base, void *pic, int irq)
  326 +/* The PL080 and PL081 are the same except for the number of channels
  327 + they implement (8 and 2 respectively). */
  328 +void *pl080_init(uint32_t base, void *pic, int irq, int nchannels)
314 329 {
315 330 int iomemtype;
316 331 pl080_state *s;
... ... @@ -322,6 +337,7 @@ void *pl080_init(uint32_t base, void *pic, int irq)
322 337 s->base = base;
323 338 s->pic = pic;
324 339 s->irq = irq;
  340 + s->nchannels = nchannels;
325 341 /* ??? Save/restore. */
326 342 return s;
327 343 }
... ...
hw/realview.c 0 → 100644
  1 +/*
  2 + * ARM RealView Baseboard System emulation.
  3 + *
  4 + * Copyright (c) 2006 CodeSourcery.
  5 + * Written by Paul Brook
  6 + *
  7 + * This code is licenced under the GPL.
  8 + */
  9 +
  10 +#include "vl.h"
  11 +#include "arm_pic.h"
  12 +
  13 +/* Board init. */
  14 +
  15 +static void realview_init(int ram_size, int vga_ram_size, int boot_device,
  16 + DisplayState *ds, const char **fd_filename, int snapshot,
  17 + const char *kernel_filename, const char *kernel_cmdline,
  18 + const char *initrd_filename)
  19 +{
  20 + CPUState *env;
  21 + void *pic;
  22 + void *scsi_hba;
  23 + PCIBus *pci_bus;
  24 + NICInfo *nd;
  25 + int n;
  26 + int done_smc = 0;
  27 +
  28 + env = cpu_init();
  29 + cpu_arm_set_model(env, ARM_CPUID_ARM926);
  30 + //cpu_arm_set_model(env, ARM_CPUID_ARM11MPCORE);
  31 + /* ??? RAM shoud repeat to fill physical memory space. */
  32 + /* SDRAM at address zero. */
  33 + cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
  34 +
  35 + arm_sysctl_init(0x10000000, 0xc1400400);
  36 + pic = arm_pic_init_cpu(env);
  37 + /* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3
  38 + is nIRQ (there are inconsistencies). However Linux 2.6.17 expects
  39 + GIC1 to be nIRQ and ignores all the others, so do that for now. */
  40 + pic = arm_gic_init(0x10040000, pic, ARM_PIC_CPU_IRQ);
  41 + pl050_init(0x10006000, pic, 20, 0);
  42 + pl050_init(0x10007000, pic, 21, 1);
  43 +
  44 + pl011_init(0x10009000, pic, 12, serial_hds[0]);
  45 + pl011_init(0x1000a000, pic, 13, serial_hds[1]);
  46 + pl011_init(0x1000b000, pic, 14, serial_hds[2]);
  47 + pl011_init(0x1000c000, pic, 15, serial_hds[3]);
  48 +
  49 + /* DMA controller is optional, apparently. */
  50 + pl080_init(0x10030000, pic, 24, 2);
  51 +
  52 + sp804_init(0x10011000, pic, 4);
  53 + sp804_init(0x10012000, pic, 5);
  54 +
  55 + pl110_init(ds, 0x10020000, pic, 23, 1);
  56 +
  57 + pci_bus = pci_vpb_init(pic, 48, 1);
  58 + if (usb_enabled) {
  59 + usb_ohci_init(pci_bus, 3, -1);
  60 + }
  61 + scsi_hba = lsi_scsi_init(pci_bus, -1);
  62 + for (n = 0; n < MAX_DISKS; n++) {
  63 + if (bs_table[n]) {
  64 + lsi_scsi_attach(scsi_hba, bs_table[n], n);
  65 + }
  66 + }
  67 + for(n = 0; n < nb_nics; n++) {
  68 + nd = &nd_table[n];
  69 + if (!nd->model)
  70 + nd->model = done_smc ? "rtl8139" : "smc91c111";
  71 + if (strcmp(nd->model, "smc91c111") == 0) {
  72 + smc91c111_init(nd, 0x4e000000, pic, 28);
  73 + } else {
  74 + pci_nic_init(pci_bus, nd);
  75 + }
  76 + }
  77 +
  78 + /* Memory map for RealView Emulation Baseboard: */
  79 + /* 0x10000000 System registers. */
  80 + /* 0x10001000 System controller. */
  81 + /* 0x10002000 Two-Wire Serial Bus. */
  82 + /* 0x10003000 Reserved. */
  83 + /* 0x10004000 AACI. */
  84 + /* 0x10005000 MCI. */
  85 + /* 0x10006000 KMI0. */
  86 + /* 0x10007000 KMI1. */
  87 + /* 0x10008000 Character LCD. */
  88 + /* 0x10009000 UART0. */
  89 + /* 0x1000a000 UART1. */
  90 + /* 0x1000b000 UART2. */
  91 + /* 0x1000c000 UART3. */
  92 + /* 0x1000d000 SSPI. */
  93 + /* 0x1000e000 SCI. */
  94 + /* 0x1000f000 Reserved. */
  95 + /* 0x10010000 Watchdog. */
  96 + /* 0x10011000 Timer 0+1. */
  97 + /* 0x10012000 Timer 2+3. */
  98 + /* 0x10013000 GPIO 0. */
  99 + /* 0x10014000 GPIO 1. */
  100 + /* 0x10015000 GPIO 2. */
  101 + /* 0x10016000 Reserved. */
  102 + /* 0x10017000 RTC. */
  103 + /* 0x10018000 DMC. */
  104 + /* 0x10019000 PCI controller config. */
  105 + /* 0x10020000 CLCD. */
  106 + /* 0x10030000 DMA Controller. */
  107 + /* 0x10040000 GIC1 (FIQ1). */
  108 + /* 0x10050000 GIC2 (IRQ1). */
  109 + /* 0x10060000 GIC3 (FIQ2). */
  110 + /* 0x10070000 GIC4 (IRQ2). */
  111 + /* 0x10080000 SMC. */
  112 + /* 0x40000000 NOR flash. */
  113 + /* 0x44000000 DoC flash. */
  114 + /* 0x48000000 SRAM. */
  115 + /* 0x4c000000 Configuration flash. */
  116 + /* 0x4e000000 Ethernet. */
  117 + /* 0x4f000000 USB. */
  118 + /* 0x50000000 PISMO. */
  119 + /* 0x54000000 PISMO. */
  120 + /* 0x58000000 PISMO. */
  121 + /* 0x5c000000 PISMO. */
  122 + /* 0x60000000 PCI. */
  123 + /* 0x61000000 PCI Self Config. */
  124 + /* 0x62000000 PCI Config. */
  125 + /* 0x63000000 PCI IO. */
  126 + /* 0x64000000 PCI mem 0. */
  127 + /* 0x68000000 PCI mem 1. */
  128 + /* 0x6c000000 PCI mem 2. */
  129 +
  130 + arm_load_kernel(ram_size, kernel_filename, kernel_cmdline,
  131 + initrd_filename, 0x33b);
  132 +}
  133 +
  134 +QEMUMachine realview_machine = {
  135 + "realview",
  136 + "ARM RealView Emulation Baseboard (ARM926EJ-S)",
  137 + realview_init
  138 +};
... ...
hw/versatile_pci.c
... ... @@ -77,31 +77,49 @@ static CPUReadMemoryFunc *pci_vpb_config_read[] = {
77 77 &pci_vpb_config_readl,
78 78 };
79 79  
  80 +static int pci_vpb_irq;
  81 +
80 82 static void pci_vpb_set_irq(PCIDevice *d, void *pic, int irq_num, int level)
81 83 {
82   - pic_set_irq_new(pic, 27 + irq_num, level);
  84 + pic_set_irq_new(pic, pci_vpb_irq + irq_num, level);
83 85 }
84 86  
85   -PCIBus *pci_vpb_init(void *pic)
  87 +PCIBus *pci_vpb_init(void *pic, int irq, int realview)
86 88 {
87 89 PCIBus *s;
88 90 PCIDevice *d;
89 91 int mem_config;
90   -
  92 + uint32_t base;
  93 + const char * name;
  94 +
  95 + pci_vpb_irq = irq;
  96 + if (realview) {
  97 + base = 0x60000000;
  98 + name = "RealView EB PCI Controller";
  99 + } else {
  100 + base = 0x40000000;
  101 + name = "Versatile/PB PCI Controller";
  102 + }
91 103 s = pci_register_bus(pci_vpb_set_irq, pic, 11 << 3);
92 104 /* ??? Register memory space. */
93 105  
94 106 mem_config = cpu_register_io_memory(0, pci_vpb_config_read,
95 107 pci_vpb_config_write, s);
96 108 /* Selfconfig area. */
97   - cpu_register_physical_memory(0x41000000, 0x10000, mem_config);
  109 + cpu_register_physical_memory(base + 0x01000000, 0x10000, mem_config);
98 110 /* Normal config area. */
99   - cpu_register_physical_memory(0x42000000, 0x10000, mem_config);
  111 + cpu_register_physical_memory(base + 0x02000000, 0x10000, mem_config);
  112 +
  113 + d = pci_register_device(s, name, sizeof(PCIDevice), -1, NULL, NULL);
  114 +
  115 + if (realview) {
  116 + /* IO memory area. */
  117 + isa_mmio_init(base + 0x03000000, 0x00100000);
  118 + }
100 119  
101   - d = pci_register_device(s, "Versatile/PB PCI Controller",
102   - sizeof(PCIDevice), -1, NULL, NULL);
103 120 d->config[0x00] = 0xee; // vendor_id
104 121 d->config[0x01] = 0x10;
  122 + /* Both boards have the same device ID. Oh well. */
105 123 d->config[0x02] = 0x00; // device_id
106 124 d->config[0x03] = 0x03;
107 125 d->config[0x04] = 0x00;
... ...
hw/versatilepb.c
... ... @@ -10,8 +10,6 @@
10 10 #include "vl.h"
11 11 #include "arm_pic.h"
12 12  
13   -#define LOCK_VALUE 0xa05f
14   -
15 13 /* Primary interrupt controller. */
16 14  
17 15 typedef struct vpb_sic_state
... ... @@ -75,7 +73,7 @@ static uint32_t vpb_sic_read(void *opaque, target_phys_addr_t offset)
75 73 case 8: /* PICENABLE */
76 74 return s->pic_enable;
77 75 default:
78   - printf ("vpb_sic_read: Bad register offset 0x%x\n", offset);
  76 + printf ("vpb_sic_read: Bad register offset 0x%x\n", (int)offset);
79 77 return 0;
80 78 }
81 79 }
... ... @@ -110,7 +108,7 @@ static void vpb_sic_write(void *opaque, target_phys_addr_t offset,
110 108 vpb_sic_update_pic(s);
111 109 break;
112 110 default:
113   - printf ("vpb_sic_write: Bad register offset 0x%x\n", offset);
  111 + printf ("vpb_sic_write: Bad register offset 0x%x\n", (int)offset);
114 112 return;
115 113 }
116 114 vpb_sic_update(s);
... ... @@ -147,188 +145,6 @@ static vpb_sic_state *vpb_sic_init(uint32_t base, void *parent, int irq)
147 145 return s;
148 146 }
149 147  
150   -/* System controller. */
151   -
152   -typedef struct {
153   - uint32_t base;
154   - uint32_t leds;
155   - uint16_t lockval;
156   - uint32_t cfgdata1;
157   - uint32_t cfgdata2;
158   - uint32_t flags;
159   - uint32_t nvflags;
160   - uint32_t resetlevel;
161   -} vpb_sys_state;
162   -
163   -static uint32_t vpb_sys_read(void *opaque, target_phys_addr_t offset)
164   -{
165   - vpb_sys_state *s = (vpb_sys_state *)opaque;
166   -
167   - offset -= s->base;
168   - switch (offset) {
169   - case 0x00: /* ID */
170   - return 0x41007004;
171   - case 0x04: /* SW */
172   - /* General purpose hardware switches.
173   - We don't have a useful way of exposing these to the user. */
174   - return 0;
175   - case 0x08: /* LED */
176   - return s->leds;
177   - case 0x20: /* LOCK */
178   - return s->lockval;
179   - case 0x0c: /* OSC0 */
180   - case 0x10: /* OSC1 */
181   - case 0x14: /* OSC2 */
182   - case 0x18: /* OSC3 */
183   - case 0x1c: /* OSC4 */
184   - case 0x24: /* 100HZ */
185   - /* ??? Implement these. */
186   - return 0;
187   - case 0x28: /* CFGDATA1 */
188   - return s->cfgdata1;
189   - case 0x2c: /* CFGDATA2 */
190   - return s->cfgdata2;
191   - case 0x30: /* FLAGS */
192   - return s->flags;
193   - case 0x38: /* NVFLAGS */
194   - return s->nvflags;
195   - case 0x40: /* RESETCTL */
196   - return s->resetlevel;
197   - case 0x44: /* PCICTL */
198   - return 1;
199   - case 0x48: /* MCI */
200   - return 0;
201   - case 0x4c: /* FLASH */
202   - return 0;
203   - case 0x50: /* CLCD */
204   - return 0x1000;
205   - case 0x54: /* CLCDSER */
206   - return 0;
207   - case 0x58: /* BOOTCS */
208   - return 0;
209   - case 0x5c: /* 24MHz */
210   - /* ??? not implemented. */
211   - return 0;
212   - case 0x60: /* MISC */
213   - return 0;
214   - case 0x64: /* DMAPSR0 */
215   - case 0x68: /* DMAPSR1 */
216   - case 0x6c: /* DMAPSR2 */
217   - case 0x8c: /* OSCRESET0 */
218   - case 0x90: /* OSCRESET1 */
219   - case 0x94: /* OSCRESET2 */
220   - case 0x98: /* OSCRESET3 */
221   - case 0x9c: /* OSCRESET4 */
222   - case 0xc0: /* SYS_TEST_OSC0 */
223   - case 0xc4: /* SYS_TEST_OSC1 */
224   - case 0xc8: /* SYS_TEST_OSC2 */
225   - case 0xcc: /* SYS_TEST_OSC3 */
226   - case 0xd0: /* SYS_TEST_OSC4 */
227   - return 0;
228   - default:
229   - printf ("vpb_sys_read: Bad register offset 0x%x\n", offset);
230   - return 0;
231   - }
232   -}
233   -
234   -static void vpb_sys_write(void *opaque, target_phys_addr_t offset,
235   - uint32_t val)
236   -{
237   - vpb_sys_state *s = (vpb_sys_state *)opaque;
238   - offset -= s->base;
239   -
240   - switch (offset) {
241   - case 0x08: /* LED */
242   - s->leds = val;
243   - case 0x0c: /* OSC0 */
244   - case 0x10: /* OSC1 */
245   - case 0x14: /* OSC2 */
246   - case 0x18: /* OSC3 */
247   - case 0x1c: /* OSC4 */
248   - /* ??? */
249   - break;
250   - case 0x20: /* LOCK */
251   - if (val == LOCK_VALUE)
252   - s->lockval = val;
253   - else
254   - s->lockval = val & 0x7fff;
255   - break;
256   - case 0x28: /* CFGDATA1 */
257   - /* ??? Need to implement this. */
258   - s->cfgdata1 = val;
259   - break;
260   - case 0x2c: /* CFGDATA2 */
261   - /* ??? Need to implement this. */
262   - s->cfgdata2 = val;
263   - break;
264   - case 0x30: /* FLAGSSET */
265   - s->flags |= val;
266   - break;
267   - case 0x34: /* FLAGSCLR */
268   - s->flags &= ~val;
269   - break;
270   - case 0x38: /* NVFLAGSSET */
271   - s->nvflags |= val;
272   - break;
273   - case 0x3c: /* NVFLAGSCLR */
274   - s->nvflags &= ~val;
275   - break;
276   - case 0x40: /* RESETCTL */
277   - if (s->lockval == LOCK_VALUE) {
278   - s->resetlevel = val;
279   - if (val & 0x100)
280   - cpu_abort(cpu_single_env, "Board reset\n");
281   - }
282   - break;
283   - case 0x44: /* PCICTL */
284   - /* nothing to do. */
285   - break;
286   - case 0x4c: /* FLASH */
287   - case 0x50: /* CLCD */
288   - case 0x54: /* CLCDSER */
289   - case 0x64: /* DMAPSR0 */
290   - case 0x68: /* DMAPSR1 */
291   - case 0x6c: /* DMAPSR2 */
292   - case 0x8c: /* OSCRESET0 */
293   - case 0x90: /* OSCRESET1 */
294   - case 0x94: /* OSCRESET2 */
295   - case 0x98: /* OSCRESET3 */
296   - case 0x9c: /* OSCRESET4 */
297   - break;
298   - default:
299   - printf ("vpb_sys_write: Bad register offset 0x%x\n", offset);
300   - return;
301   - }
302   -}
303   -
304   -static CPUReadMemoryFunc *vpb_sys_readfn[] = {
305   - vpb_sys_read,
306   - vpb_sys_read,
307   - vpb_sys_read
308   -};
309   -
310   -static CPUWriteMemoryFunc *vpb_sys_writefn[] = {
311   - vpb_sys_write,
312   - vpb_sys_write,
313   - vpb_sys_write
314   -};
315   -
316   -static vpb_sys_state *vpb_sys_init(uint32_t base)
317   -{
318   - vpb_sys_state *s;
319   - int iomemtype;
320   -
321   - s = (vpb_sys_state *)qemu_mallocz(sizeof(vpb_sys_state));
322   - if (!s)
323   - return NULL;
324   - s->base = base;
325   - iomemtype = cpu_register_io_memory(0, vpb_sys_readfn,
326   - vpb_sys_writefn, s);
327   - cpu_register_physical_memory(base, 0x00000fff, iomemtype);
328   - /* ??? Save/restore. */
329   - return s;
330   -}
331   -
332 148 /* Board init. */
333 149  
334 150 /* The AB and PB boards both use the same core, just with different
... ... @@ -355,14 +171,14 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
355 171 /* SDRAM at address zero. */
356 172 cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
357 173  
358   - vpb_sys_init(0x10000000);
  174 + arm_sysctl_init(0x10000000, 0x41007004);
359 175 pic = arm_pic_init_cpu(env);
360 176 pic = pl190_init(0x10140000, pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
361 177 sic = vpb_sic_init(0x10003000, pic, 31);
362 178 pl050_init(0x10006000, sic, 3, 0);
363 179 pl050_init(0x10007000, sic, 4, 1);
364 180  
365   - pci_bus = pci_vpb_init(sic);
  181 + pci_bus = pci_vpb_init(sic, 27, 0);
366 182 /* The Versatile PCI bridge does not provide access to PCI IO space,
367 183 so many of the qemu PCI devices are not useable. */
368 184 for(n = 0; n < nb_nics; n++) {
... ... @@ -390,7 +206,7 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
390 206 pl011_init(0x101f3000, pic, 14, serial_hds[2]);
391 207 pl011_init(0x10009000, sic, 6, serial_hds[3]);
392 208  
393   - pl080_init(0x10130000, pic, 17);
  209 + pl080_init(0x10130000, pic, 17, 8);
394 210 sp804_init(0x101e2000, pic, 4);
395 211 sp804_init(0x101e3000, pic, 5);
396 212  
... ...
... ... @@ -6150,6 +6150,7 @@ void register_machines(void)
6150 6150 qemu_register_machine(&integratorcp1026_machine);
6151 6151 qemu_register_machine(&versatilepb_machine);
6152 6152 qemu_register_machine(&versatileab_machine);
  6153 + qemu_register_machine(&realview_machine);
6153 6154 #elif defined(TARGET_SH4)
6154 6155 qemu_register_machine(&shix_machine);
6155 6156 #else
... ...
... ... @@ -778,7 +778,7 @@ PCIBus *pci_pmac_init(void *pic);
778 778 PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
779 779 void *pic);
780 780  
781   -PCIBus *pci_vpb_init(void *pic);
  781 +PCIBus *pci_vpb_init(void *pic, int irq, int realview);
782 782  
783 783 /* piix_pci.c */
784 784 PCIBus *i440fx_init(void);
... ... @@ -1222,6 +1222,9 @@ extern QEMUMachine integratorcp1026_machine;
1222 1222 extern QEMUMachine versatilepb_machine;
1223 1223 extern QEMUMachine versatileab_machine;
1224 1224  
  1225 +/* realview.c */
  1226 +extern QEMUMachine realview_machine;
  1227 +
1225 1228 /* ps2.c */
1226 1229 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg);
1227 1230 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg);
... ... @@ -1244,7 +1247,7 @@ void pl011_init(uint32_t base, void *pic, int irq, CharDriverState *chr);
1244 1247 void pl050_init(uint32_t base, void *pic, int irq, int is_mouse);
1245 1248  
1246 1249 /* pl080.c */
1247   -void *pl080_init(uint32_t base, void *pic, int irq);
  1250 +void *pl080_init(uint32_t base, void *pic, int irq, int nchannels);
1248 1251  
1249 1252 /* pl190.c */
1250 1253 void *pl190_init(uint32_t base, void *parent, int irq, int fiq);
... ... @@ -1253,6 +1256,12 @@ void *pl190_init(uint32_t base, void *parent, int irq, int fiq);
1253 1256 void sp804_init(uint32_t base, void *pic, int irq);
1254 1257 void icp_pit_init(uint32_t base, void *pic, int irq);
1255 1258  
  1259 +/* arm_sysctl.c */
  1260 +void arm_sysctl_init(uint32_t base, uint32_t sys_id);
  1261 +
  1262 +/* arm_gic.c */
  1263 +void *arm_gic_init(uint32_t base, void *parent, int parent_irq);
  1264 +
1256 1265 /* arm_boot.c */
1257 1266  
1258 1267 void arm_load_kernel(int ram_size, const char *kernel_filename,
... ...