Revision fe7e8758 hw/arm_gic.c
b/hw/arm_gic.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 |
} |
Also available in: Unified diff