Commit fe7e8758d0abfb6953b5e4f5a1af17ea1598a2bb

Authored by Paul Brook
1 parent 0027b06d

ARM GIC qdev conversion

Signed-off-by: Paul Brook <paul@codesourcery.com>
hw/arm-misc.h
... ... @@ -34,11 +34,8 @@ struct arm_boot_info {
34 34 };
35 35 void arm_load_kernel(CPUState *env, struct arm_boot_info *info);
36 36  
37   -/* armv7m_nvic.c */
38   -
39 37 /* Multiplication factor to convert from system clock ticks to qemu timer
40 38 ticks. */
41 39 extern int system_clock_scale;
42   -qemu_irq *armv7m_nvic_init(CPUState *env);
43 40  
44 41 #endif /* !ARM_MISC_H */
... ...
hw/arm_gic.c
... ... @@ -32,6 +32,9 @@ static const uint8_t gic_id[] =
32 32 #define GIC_BASE_IRQ 0
33 33 #endif
34 34  
  35 +#define FROM_SYSBUSGIC(type, dev) \
  36 + DO_UPCAST(type, gic, FROM_SYSBUS(gic_state, dev))
  37 +
35 38 typedef struct gic_irq_state
36 39 {
37 40 /* ??? The documentation seems to imply the enable bits are global, even
... ... @@ -74,6 +77,7 @@ typedef struct gic_irq_state
74 77  
75 78 typedef struct gic_state
76 79 {
  80 + SysBusDevice busdev;
77 81 qemu_irq parent_irq[NCPU];
78 82 int enabled;
79 83 int cpu_enabled[NCPU];
... ... @@ -91,10 +95,7 @@ typedef struct gic_state
91 95 int running_priority[NCPU];
92 96 int current_pending[NCPU];
93 97  
94   - qemu_irq *in;
95   -#ifdef NVIC
96   - void *nvic;
97   -#endif
  98 + int iomemtype;
98 99 } gic_state;
99 100  
100 101 /* TODO: Many places that call this routine could be optimized. */
... ... @@ -363,7 +364,7 @@ static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
363 364 uint32_t addr;
364 365 addr = offset;
365 366 if (addr < 0x100 || addr > 0xd00)
366   - return nvic_readl(s->nvic, addr);
  367 + return nvic_readl(s, addr);
367 368 #endif
368 369 val = gic_dist_readw(opaque, offset);
369 370 val |= gic_dist_readw(opaque, offset + 2) << 16;
... ... @@ -523,7 +524,7 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
523 524 uint32_t addr;
524 525 addr = offset;
525 526 if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) {
526   - nvic_writel(s->nvic, addr, value);
  527 + nvic_writel(s, addr, value);
527 528 return;
528 529 }
529 530 #endif
... ... @@ -716,22 +717,16 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
716 717 return 0;
717 718 }
718 719  
719   -static gic_state *gic_init(uint32_t dist_base, qemu_irq *parent_irq)
  720 +static void gic_init(gic_state *s)
720 721 {
721   - gic_state *s;
722   - int iomemtype;
723 722 int i;
724 723  
725   - s = (gic_state *)qemu_mallocz(sizeof(gic_state));
726   - s->in = qemu_allocate_irqs(gic_set_irq, s, GIC_NIRQ);
  724 + qdev_init_irq_sink(&s->busdev.qdev, gic_set_irq, GIC_NIRQ - 32);
727 725 for (i = 0; i < NCPU; i++) {
728   - s->parent_irq[i] = parent_irq[i];
  726 + sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
729 727 }
730   - iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
731   - gic_dist_writefn, s);
732   - cpu_register_physical_memory(dist_base, 0x00001000,
733   - iomemtype);
  728 + s->iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
  729 + gic_dist_writefn, s);
734 730 gic_reset(s);
735 731 register_savevm("arm_gic", -1, 1, gic_save, gic_load, s);
736   - return s;
737 732 }
... ...
hw/armv7m.c
... ... @@ -7,7 +7,7 @@
7 7 * This code is licenced under the GPL.
8 8 */
9 9  
10   -#include "hw.h"
  10 +#include "sysbus.h"
11 11 #include "arm-misc.h"
12 12 #include "sysemu.h"
13 13  
... ... @@ -140,11 +140,15 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
140 140 const char *kernel_filename, const char *cpu_model)
141 141 {
142 142 CPUState *env;
143   - qemu_irq *pic;
  143 + DeviceState *nvic;
  144 + /* FIXME: make this local state. */
  145 + static qemu_irq pic[64];
  146 + qemu_irq *cpu_pic;
144 147 uint32_t pc;
145 148 int image_size;
146 149 uint64_t entry;
147 150 uint64_t lowaddr;
  151 + int i;
148 152  
149 153 flash_size *= 1024;
150 154 sram_size *= 1024;
... ... @@ -176,7 +180,14 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
176 180 qemu_ram_alloc(sram_size) | IO_MEM_RAM);
177 181 armv7m_bitband_init();
178 182  
179   - pic = armv7m_nvic_init(env);
  183 + nvic = qdev_create(NULL, "armv7m_nvic");
  184 + qdev_set_prop_ptr(nvic, "cpu", env);
  185 + qdev_init(nvic);
  186 + cpu_pic = arm_pic_init_cpu(env);
  187 + sysbus_connect_irq(sysbus_from_qdev(nvic), 0, cpu_pic[ARM_PIC_CPU_IRQ]);
  188 + for (i = 0; i < 64; i++) {
  189 + pic[i] = qdev_get_irq_sink(nvic, i);
  190 + }
180 191  
181 192 image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL);
182 193 if (image_size < 0) {
... ...
hw/armv7m_nvic.c
... ... @@ -10,7 +10,7 @@
10 10 * NVIC. Much of that is also implemented here.
11 11 */
12 12  
13   -#include "hw.h"
  13 +#include "sysbus.h"
14 14 #include "qemu-timer.h"
15 15 #include "arm-misc.h"
16 16  
... ... @@ -33,13 +33,13 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
33 33 #include "arm_gic.c"
34 34  
35 35 typedef struct {
  36 + gic_state gic;
36 37 struct {
37 38 uint32_t control;
38 39 uint32_t reload;
39 40 int64_t tick;
40 41 QEMUTimer *timer;
41 42 } systick;
42   - gic_state *gic;
43 43 } nvic_state;
44 44  
45 45 /* qemu timers run at 1GHz. We want something closer to 1MHz. */
... ... @@ -91,7 +91,7 @@ void armv7m_nvic_set_pending(void *opaque, int irq)
91 91 nvic_state *s = (nvic_state *)opaque;
92 92 if (irq >= 16)
93 93 irq += 16;
94   - gic_set_pending_private(s->gic, 0, irq);
  94 + gic_set_pending_private(&s->gic, 0, irq);
95 95 }
96 96  
97 97 /* Make pending IRQ active. */
... ... @@ -100,7 +100,7 @@ int armv7m_nvic_acknowledge_irq(void *opaque)
100 100 nvic_state *s = (nvic_state *)opaque;
101 101 uint32_t irq;
102 102  
103   - irq = gic_acknowledge_irq(s->gic, 0);
  103 + irq = gic_acknowledge_irq(&s->gic, 0);
104 104 if (irq == 1023)
105 105 hw_error("Interrupt but no vector\n");
106 106 if (irq >= 32)
... ... @@ -113,7 +113,7 @@ void armv7m_nvic_complete_irq(void *opaque, int irq)
113 113 nvic_state *s = (nvic_state *)opaque;
114 114 if (irq >= 16)
115 115 irq += 16;
116   - gic_complete_irq(s->gic, 0, irq);
  116 + gic_complete_irq(&s->gic, 0, irq);
117 117 }
118 118  
119 119 static uint32_t nvic_readl(void *opaque, uint32_t offset)
... ... @@ -153,35 +153,35 @@ static uint32_t nvic_readl(void *opaque, uint32_t offset)
153 153 return cpu_single_env->cp15.c0_cpuid;
154 154 case 0xd04: /* Interrypt Control State. */
155 155 /* VECTACTIVE */
156   - val = s->gic->running_irq[0];
  156 + val = s->gic.running_irq[0];
157 157 if (val == 1023) {
158 158 val = 0;
159 159 } else if (val >= 32) {
160 160 val -= 16;
161 161 }
162 162 /* RETTOBASE */
163   - if (s->gic->running_irq[0] == 1023
164   - || s->gic->last_active[s->gic->running_irq[0]][0] == 1023) {
  163 + if (s->gic.running_irq[0] == 1023
  164 + || s->gic.last_active[s->gic.running_irq[0]][0] == 1023) {
165 165 val |= (1 << 11);
166 166 }
167 167 /* VECTPENDING */
168   - if (s->gic->current_pending[0] != 1023)
169   - val |= (s->gic->current_pending[0] << 12);
  168 + if (s->gic.current_pending[0] != 1023)
  169 + val |= (s->gic.current_pending[0] << 12);
170 170 /* ISRPENDING */
171 171 for (irq = 32; irq < GIC_NIRQ; irq++) {
172   - if (s->gic->irq_state[irq].pending) {
  172 + if (s->gic.irq_state[irq].pending) {
173 173 val |= (1 << 22);
174 174 break;
175 175 }
176 176 }
177 177 /* PENDSTSET */
178   - if (s->gic->irq_state[ARMV7M_EXCP_SYSTICK].pending)
  178 + if (s->gic.irq_state[ARMV7M_EXCP_SYSTICK].pending)
179 179 val |= (1 << 26);
180 180 /* PENDSVSET */
181   - if (s->gic->irq_state[ARMV7M_EXCP_PENDSV].pending)
  181 + if (s->gic.irq_state[ARMV7M_EXCP_PENDSV].pending)
182 182 val |= (1 << 28);
183 183 /* NMIPENDSET */
184   - if (s->gic->irq_state[ARMV7M_EXCP_NMI].pending)
  184 + if (s->gic.irq_state[ARMV7M_EXCP_NMI].pending)
185 185 val |= (1 << 31);
186 186 return val;
187 187 case 0xd08: /* Vector Table Offset. */
... ... @@ -197,27 +197,27 @@ static uint32_t nvic_readl(void *opaque, uint32_t offset)
197 197 case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */
198 198 irq = offset - 0xd14;
199 199 val = 0;
200   - val = s->gic->priority1[irq++][0];
201   - val = s->gic->priority1[irq++][0] << 8;
202   - val = s->gic->priority1[irq++][0] << 16;
203   - val = s->gic->priority1[irq][0] << 24;
  200 + val = s->gic.priority1[irq++][0];
  201 + val = s->gic.priority1[irq++][0] << 8;
  202 + val = s->gic.priority1[irq++][0] << 16;
  203 + val = s->gic.priority1[irq][0] << 24;
204 204 return val;
205 205 case 0xd24: /* System Handler Status. */
206 206 val = 0;
207   - if (s->gic->irq_state[ARMV7M_EXCP_MEM].active) val |= (1 << 0);
208   - if (s->gic->irq_state[ARMV7M_EXCP_BUS].active) val |= (1 << 1);
209   - if (s->gic->irq_state[ARMV7M_EXCP_USAGE].active) val |= (1 << 3);
210   - if (s->gic->irq_state[ARMV7M_EXCP_SVC].active) val |= (1 << 7);
211   - if (s->gic->irq_state[ARMV7M_EXCP_DEBUG].active) val |= (1 << 8);
212   - if (s->gic->irq_state[ARMV7M_EXCP_PENDSV].active) val |= (1 << 10);
213   - if (s->gic->irq_state[ARMV7M_EXCP_SYSTICK].active) val |= (1 << 11);
214   - if (s->gic->irq_state[ARMV7M_EXCP_USAGE].pending) val |= (1 << 12);
215   - if (s->gic->irq_state[ARMV7M_EXCP_MEM].pending) val |= (1 << 13);
216   - if (s->gic->irq_state[ARMV7M_EXCP_BUS].pending) val |= (1 << 14);
217   - if (s->gic->irq_state[ARMV7M_EXCP_SVC].pending) val |= (1 << 15);
218   - if (s->gic->irq_state[ARMV7M_EXCP_MEM].enabled) val |= (1 << 16);
219   - if (s->gic->irq_state[ARMV7M_EXCP_BUS].enabled) val |= (1 << 17);
220   - if (s->gic->irq_state[ARMV7M_EXCP_USAGE].enabled) val |= (1 << 18);
  207 + if (s->gic.irq_state[ARMV7M_EXCP_MEM].active) val |= (1 << 0);
  208 + if (s->gic.irq_state[ARMV7M_EXCP_BUS].active) val |= (1 << 1);
  209 + if (s->gic.irq_state[ARMV7M_EXCP_USAGE].active) val |= (1 << 3);
  210 + if (s->gic.irq_state[ARMV7M_EXCP_SVC].active) val |= (1 << 7);
  211 + if (s->gic.irq_state[ARMV7M_EXCP_DEBUG].active) val |= (1 << 8);
  212 + if (s->gic.irq_state[ARMV7M_EXCP_PENDSV].active) val |= (1 << 10);
  213 + if (s->gic.irq_state[ARMV7M_EXCP_SYSTICK].active) val |= (1 << 11);
  214 + if (s->gic.irq_state[ARMV7M_EXCP_USAGE].pending) val |= (1 << 12);
  215 + if (s->gic.irq_state[ARMV7M_EXCP_MEM].pending) val |= (1 << 13);
  216 + if (s->gic.irq_state[ARMV7M_EXCP_BUS].pending) val |= (1 << 14);
  217 + if (s->gic.irq_state[ARMV7M_EXCP_SVC].pending) val |= (1 << 15);
  218 + if (s->gic.irq_state[ARMV7M_EXCP_MEM].enabled) val |= (1 << 16);
  219 + if (s->gic.irq_state[ARMV7M_EXCP_BUS].enabled) val |= (1 << 17);
  220 + if (s->gic.irq_state[ARMV7M_EXCP_USAGE].enabled) val |= (1 << 18);
221 221 return val;
222 222 case 0xd28: /* Configurable Fault Status. */
223 223 /* TODO: Implement Fault Status. */
... ... @@ -307,14 +307,14 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value)
307 307 if (value & (1 << 28)) {
308 308 armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV);
309 309 } else if (value & (1 << 27)) {
310   - s->gic->irq_state[ARMV7M_EXCP_PENDSV].pending = 0;
311   - gic_update(s->gic);
  310 + s->gic.irq_state[ARMV7M_EXCP_PENDSV].pending = 0;
  311 + gic_update(&s->gic);
312 312 }
313 313 if (value & (1 << 26)) {
314 314 armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK);
315 315 } else if (value & (1 << 25)) {
316   - s->gic->irq_state[ARMV7M_EXCP_SYSTICK].pending = 0;
317   - gic_update(s->gic);
  316 + s->gic.irq_state[ARMV7M_EXCP_SYSTICK].pending = 0;
  317 + gic_update(&s->gic);
318 318 }
319 319 break;
320 320 case 0xd08: /* Vector Table Offset. */
... ... @@ -338,19 +338,19 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value)
338 338 {
339 339 int irq;
340 340 irq = offset - 0xd14;
341   - s->gic->priority1[irq++][0] = value & 0xff;
342   - s->gic->priority1[irq++][0] = (value >> 8) & 0xff;
343   - s->gic->priority1[irq++][0] = (value >> 16) & 0xff;
344   - s->gic->priority1[irq][0] = (value >> 24) & 0xff;
345   - gic_update(s->gic);
  341 + s->gic.priority1[irq++][0] = value & 0xff;
  342 + s->gic.priority1[irq++][0] = (value >> 8) & 0xff;
  343 + s->gic.priority1[irq++][0] = (value >> 16) & 0xff;
  344 + s->gic.priority1[irq][0] = (value >> 24) & 0xff;
  345 + gic_update(&s->gic);
346 346 }
347 347 break;
348 348 case 0xd24: /* System Handler Control. */
349 349 /* TODO: Real hardware allows you to set/clear the active bits
350 350 under some circumstances. We don't implement this. */
351   - s->gic->irq_state[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
352   - s->gic->irq_state[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
353   - s->gic->irq_state[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
  351 + s->gic.irq_state[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
  352 + s->gic.irq_state[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
  353 + s->gic.irq_state[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
354 354 break;
355 355 case 0xd28: /* Configurable Fault Status. */
356 356 case 0xd2c: /* Hard Fault Status. */
... ... @@ -390,19 +390,24 @@ static int nvic_load(QEMUFile *f, void *opaque, int version_id)
390 390 return 0;
391 391 }
392 392  
393   -qemu_irq *armv7m_nvic_init(CPUState *env)
  393 +static void armv7m_nvic_init(SysBusDevice *dev)
394 394 {
395   - nvic_state *s;
396   - qemu_irq *parent;
  395 + nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
  396 + CPUState *env;
397 397  
398   - parent = arm_pic_init_cpu(env);
399   - s = (nvic_state *)qemu_mallocz(sizeof(nvic_state));
400   - s->gic = gic_init(0xe000e000, &parent[ARM_PIC_CPU_IRQ]);
401   - s->gic->nvic = s;
  398 + env = qdev_get_prop_ptr(&dev->qdev, "cpu");
  399 + gic_init(&s->gic);
  400 + cpu_register_physical_memory(0xe000e000, 0x1000, s->gic.iomemtype);
402 401 s->systick.timer = qemu_new_timer(vm_clock, systick_timer_tick, s);
403 402 if (env->v7m.nvic)
404 403 hw_error("CPU can only have one NVIC\n");
405 404 env->v7m.nvic = s;
406 405 register_savevm("armv7m_nvic", -1, 1, nvic_save, nvic_load, s);
407   - return s->gic->in;
408 406 }
  407 +
  408 +static void armv7m_nvic_register_devices(void)
  409 +{
  410 + sysbus_register_dev("armv7m_nvic", sizeof(nvic_state), armv7m_nvic_init);
  411 +}
  412 +
  413 +device_init(armv7m_nvic_register_devices)
... ...
hw/mpcore.c
... ... @@ -7,9 +7,8 @@
7 7 * This code is licenced under the GPL.
8 8 */
9 9  
10   -#include "hw.h"
  10 +#include "sysbus.h"
11 11 #include "qemu-timer.h"
12   -#include "primecell.h"
13 12  
14 13 #define MPCORE_PRIV_BASE 0x10100000
15 14 #define NCPU 4
... ... @@ -41,8 +40,9 @@ typedef struct {
41 40 } mpcore_timer_state;
42 41  
43 42 typedef struct mpcore_priv_state {
44   - gic_state *gic;
  43 + gic_state gic;
45 44 uint32_t scu_control;
  45 + int iomemtype;
46 46 mpcore_timer_state timer[8];
47 47 } mpcore_priv_state;
48 48  
... ... @@ -51,7 +51,7 @@ typedef struct mpcore_priv_state {
51 51 static inline void mpcore_timer_update_irq(mpcore_timer_state *s)
52 52 {
53 53 if (s->status & ~s->old_status) {
54   - gic_set_pending_private(s->mpcore->gic, s->id >> 1, 29 + (s->id & 1));
  54 + gic_set_pending_private(&s->mpcore->gic, s->id >> 1, 29 + (s->id & 1));
55 55 }
56 56 s->old_status = s->status;
57 57 }
... ... @@ -181,7 +181,7 @@ static uint32_t mpcore_priv_read(void *opaque, target_phys_addr_t offset)
181 181 } else {
182 182 id = (offset - 0x200) >> 8;
183 183 }
184   - return gic_cpu_read(s->gic, id, offset & 0xff);
  184 + return gic_cpu_read(&s->gic, id, offset & 0xff);
185 185 } else if (offset < 0xb00) {
186 186 /* Timers. */
187 187 if (offset < 0x700) {
... ... @@ -224,7 +224,7 @@ static void mpcore_priv_write(void *opaque, target_phys_addr_t offset,
224 224 } else {
225 225 id = (offset - 0x200) >> 8;
226 226 }
227   - gic_cpu_write(s->gic, id, offset & 0xff, value);
  227 + gic_cpu_write(&s->gic, id, offset & 0xff, value);
228 228 } else if (offset < 0xb00) {
229 229 /* Timers. */
230 230 if (offset < 0x700) {
... ... @@ -255,32 +255,34 @@ static CPUWriteMemoryFunc *mpcore_priv_writefn[] = {
255 255 mpcore_priv_write
256 256 };
257 257  
  258 +static void mpcore_priv_map(SysBusDevice *dev, target_phys_addr_t base)
  259 +{
  260 + mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
  261 + cpu_register_physical_memory(base, 0x1000, s->iomemtype);
  262 + cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype);
  263 +}
258 264  
259   -static qemu_irq *mpcore_priv_init(uint32_t base, qemu_irq *pic_irq)
  265 +static void mpcore_priv_init(SysBusDevice *dev)
260 266 {
261   - mpcore_priv_state *s;
262   - int iomemtype;
  267 + mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
263 268 int i;
264 269  
265   - s = (mpcore_priv_state *)qemu_mallocz(sizeof(mpcore_priv_state));
266   - s->gic = gic_init(base + 0x1000, pic_irq);
267   - if (!s->gic)
268   - return NULL;
269   - iomemtype = cpu_register_io_memory(0, mpcore_priv_readfn,
270   - mpcore_priv_writefn, s);
271   - cpu_register_physical_memory(base, 0x00001000, iomemtype);
  270 + gic_init(&s->gic);
  271 + s->iomemtype = cpu_register_io_memory(0, mpcore_priv_readfn,
  272 + mpcore_priv_writefn, s);
  273 + sysbus_init_mmio_cb(dev, 0x2000, mpcore_priv_map);
272 274 for (i = 0; i < 8; i++) {
273 275 mpcore_timer_init(s, &s->timer[i], i);
274 276 }
275   - return s->gic->in;
276 277 }
277 278  
278 279 /* Dummy PIC to route IRQ lines. The baseboard has 4 independent IRQ
279 280 controllers. The output of these, plus some of the raw input lines
280 281 are fed into a single SMP-aware interrupt controller on the CPU. */
281 282 typedef struct {
282   - qemu_irq *cpuic;
283   - qemu_irq *rvic[4];
  283 + SysBusDevice busdev;
  284 + qemu_irq cpuic[32];
  285 + qemu_irq rvic[4][64];
284 286 } mpcore_rirq_state;
285 287  
286 288 /* Map baseboard IRQs onto CPU IRQ lines. */
... ... @@ -307,17 +309,36 @@ static void mpcore_rirq_set_irq(void *opaque, int irq, int level)
307 309 }
308 310 }
309 311  
310   -qemu_irq *mpcore_irq_init(qemu_irq *cpu_irq)
  312 +static void realview_mpcore_init(SysBusDevice *dev)
311 313 {
312   - mpcore_rirq_state *s;
  314 + mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev);
  315 + DeviceState *gic;
  316 + DeviceState *priv;
313 317 int n;
  318 + int i;
314 319  
  320 + priv = sysbus_create_simple("arm11mpcore_priv", MPCORE_PRIV_BASE, NULL);
  321 + sysbus_pass_irq(dev, sysbus_from_qdev(priv));
  322 + for (i = 0; i < 32; i++) {
  323 + s->cpuic[i] = qdev_get_irq_sink(priv, i);
  324 + }
315 325 /* ??? IRQ routing is hardcoded to "normal" mode. */
316   - s = qemu_mallocz(sizeof(mpcore_rirq_state));
317   - s->cpuic = mpcore_priv_init(MPCORE_PRIV_BASE, cpu_irq);
318 326 for (n = 0; n < 4; n++) {
319   - s->rvic[n] = realview_gic_init(0x10040000 + n * 0x10000,
320   - s->cpuic[10 + n]);
  327 + gic = sysbus_create_simple("realview_gic", 0x10040000 + n * 0x10000,
  328 + s->cpuic[10 + n]);
  329 + for (i = 0; i < 64; i++) {
  330 + s->rvic[n][i] = qdev_get_irq_sink(gic, i);
  331 + }
321 332 }
322   - return qemu_allocate_irqs(mpcore_rirq_set_irq, s, 64);
  333 + qdev_init_irq_sink(&dev->qdev, mpcore_rirq_set_irq, 64);
323 334 }
  335 +
  336 +static void mpcore_register_devices(void)
  337 +{
  338 + sysbus_register_dev("realview_mpcore", sizeof(mpcore_rirq_state),
  339 + realview_mpcore_init);
  340 + sysbus_register_dev("arm11mpcore_priv", sizeof(mpcore_priv_state),
  341 + mpcore_priv_init);
  342 +}
  343 +
  344 +device_init(mpcore_register_devices)
... ...
hw/primecell.h
... ... @@ -17,12 +17,6 @@ qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out);
17 17 /* pl080.c */
18 18 void *pl080_init(uint32_t base, qemu_irq irq, int nchannels);
19 19  
20   -/* realview_gic.c */
21   -qemu_irq *realview_gic_init(uint32_t base, qemu_irq parent_irq);
22   -
23   -/* mpcore.c */
24   -extern qemu_irq *mpcore_irq_init(qemu_irq *cpu_irq);
25   -
26 20 /* arm_sysctl.c */
27 21 void arm_sysctl_init(uint32_t base, uint32_t sys_id);
28 22  
... ...
hw/realview.c
... ... @@ -31,8 +31,9 @@ static void realview_init(ram_addr_t ram_size,
31 31 {
32 32 CPUState *env;
33 33 ram_addr_t ram_offset;
34   - qemu_irq *pic;
35 34 DeviceState *dev;
  35 + qemu_irq *irqp;
  36 + qemu_irq pic[64];
36 37 PCIBus *pci_bus;
37 38 NICInfo *nd;
38 39 int n;
... ... @@ -55,8 +56,8 @@ static void realview_init(ram_addr_t ram_size,
55 56 fprintf(stderr, "Unable to find CPU definition\n");
56 57 exit(1);
57 58 }
58   - pic = arm_pic_init_cpu(env);
59   - cpu_irq[n] = pic[ARM_PIC_CPU_IRQ];
  59 + irqp = arm_pic_init_cpu(env);
  60 + cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
60 61 if (n > 0) {
61 62 /* Set entry point for secondary CPUs. This assumes we're using
62 63 the init code from arm_boot.c. Real hardware resets all CPUs
... ... @@ -76,9 +77,14 @@ static void realview_init(ram_addr_t ram_size,
76 77 /* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3
77 78 is nIRQ (there are inconsistencies). However Linux 2.6.17 expects
78 79 GIC1 to be nIRQ and ignores all the others, so do that for now. */
79   - pic = realview_gic_init(0x10040000, cpu_irq[0]);
  80 + dev = sysbus_create_simple("realview_gic", 0x10040000, cpu_irq[0]);
80 81 } else {
81   - pic = mpcore_irq_init(cpu_irq);
  82 + dev = sysbus_create_varargs("realview_mpcore", -1,
  83 + cpu_irq[0], cpu_irq[1], cpu_irq[2],
  84 + cpu_irq[3], NULL);
  85 + }
  86 + for (n = 0; n < 64; n++) {
  87 + pic[n] = qdev_get_irq_sink(dev, n);
82 88 }
83 89  
84 90 sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);
... ...
hw/realview_gic.c
... ... @@ -7,8 +7,7 @@
7 7 * This code is licenced under the GPL.
8 8 */
9 9  
10   -#include "hw.h"
11   -#include "primecell.h"
  10 +#include "sysbus.h"
12 11  
13 12 #define GIC_NIRQ 96
14 13 #define NCPU 1
... ... @@ -22,6 +21,11 @@ gic_get_current_cpu(void)
22 21  
23 22 #include "arm_gic.c"
24 23  
  24 +typedef struct {
  25 + gic_state gic;
  26 + int iomemtype;
  27 +} RealViewGICState;
  28 +
25 29 static uint32_t realview_gic_cpu_read(void *opaque, target_phys_addr_t offset)
26 30 {
27 31 gic_state *s = (gic_state *)opaque;
... ... @@ -47,16 +51,27 @@ static CPUWriteMemoryFunc *realview_gic_cpu_writefn[] = {
47 51 realview_gic_cpu_write
48 52 };
49 53  
50   -qemu_irq *realview_gic_init(uint32_t base, qemu_irq parent_irq)
  54 +static void realview_gic_map(SysBusDevice *dev, target_phys_addr_t base)
51 55 {
52   - gic_state *s;
53   - int iomemtype;
  56 + RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev);
  57 + cpu_register_physical_memory(base, 0x1000, s->iomemtype);
  58 + cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype);
  59 +}
  60 +
  61 +static void realview_gic_init(SysBusDevice *dev)
  62 +{
  63 + RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev);
54 64  
55   - s = gic_init(base + 0x1000, &parent_irq);
56   - if (!s)
57   - return NULL;
58   - iomemtype = cpu_register_io_memory(0, realview_gic_cpu_readfn,
59   - realview_gic_cpu_writefn, s);
60   - cpu_register_physical_memory(base, 0x00001000, iomemtype);
61   - return s->in;
  65 + gic_init(&s->gic);
  66 + s->iomemtype = cpu_register_io_memory(0, realview_gic_cpu_readfn,
  67 + realview_gic_cpu_writefn, s);
  68 + sysbus_init_mmio_cb(dev, 0x2000, realview_gic_map);
62 69 }
  70 +
  71 +static void realview_gic_register_devices(void)
  72 +{
  73 + sysbus_register_dev("realview_gic", sizeof(RealViewGICState),
  74 + realview_gic_init);
  75 +}
  76 +
  77 +device_init(realview_gic_register_devices)
... ...