Revision 53111180
b/hw/arm_gic.c | ||
---|---|---|
659 | 659 |
memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000); |
660 | 660 |
} |
661 | 661 |
|
662 |
static int arm_gic_init(SysBusDevice *dev)
|
|
662 |
static void arm_gic_realize(DeviceState *dev, Error **errp)
|
|
663 | 663 |
{ |
664 |
/* Device instance init function for the GIC sysbus device */
|
|
664 |
/* Device instance realize function for the GIC sysbus device */
|
|
665 | 665 |
int i; |
666 |
GICState *s = FROM_SYSBUS(GICState, dev); |
|
666 |
GICState *s = ARM_GIC(dev); |
|
667 |
SysBusDevice *sbd = SYS_BUS_DEVICE(dev); |
|
667 | 668 |
ARMGICClass *agc = ARM_GIC_GET_CLASS(s); |
668 | 669 |
|
669 |
agc->parent_init(dev); |
|
670 |
agc->parent_realize(dev, errp); |
|
671 |
if (error_is_set(errp)) { |
|
672 |
return; |
|
673 |
} |
|
670 | 674 |
|
671 | 675 |
gic_init_irqs_and_distributor(s, s->num_irq); |
672 | 676 |
|
... | ... | |
686 | 690 |
"gic_cpu", 0x100); |
687 | 691 |
} |
688 | 692 |
/* Distributor */ |
689 |
sysbus_init_mmio(dev, &s->iomem);
|
|
693 |
sysbus_init_mmio(sbd, &s->iomem);
|
|
690 | 694 |
/* cpu interfaces (one for "current cpu" plus one per cpu) */ |
691 | 695 |
for (i = 0; i <= NUM_CPU(s); i++) { |
692 |
sysbus_init_mmio(dev, &s->cpuiomem[i]);
|
|
696 |
sysbus_init_mmio(sbd, &s->cpuiomem[i]);
|
|
693 | 697 |
} |
694 |
return 0; |
|
695 | 698 |
} |
696 | 699 |
|
697 | 700 |
static void arm_gic_class_init(ObjectClass *klass, void *data) |
698 | 701 |
{ |
699 | 702 |
DeviceClass *dc = DEVICE_CLASS(klass); |
700 |
SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); |
|
701 | 703 |
ARMGICClass *agc = ARM_GIC_CLASS(klass); |
702 |
agc->parent_init = sbc->init; |
|
703 |
sbc->init = arm_gic_init; |
|
704 |
|
|
704 | 705 |
dc->no_user = 1; |
706 |
agc->parent_realize = dc->realize; |
|
707 |
dc->realize = arm_gic_realize; |
|
705 | 708 |
} |
706 | 709 |
|
707 | 710 |
static const TypeInfo arm_gic_info = { |
b/hw/arm_gic_common.c | ||
---|---|---|
104 | 104 |
return 0; |
105 | 105 |
} |
106 | 106 |
|
107 |
static int arm_gic_common_init(SysBusDevice *dev)
|
|
107 |
static void arm_gic_common_realize(DeviceState *dev, Error **errp)
|
|
108 | 108 |
{ |
109 |
GICState *s = FROM_SYSBUS(GICState, dev);
|
|
109 |
GICState *s = ARM_GIC_COMMON(dev);
|
|
110 | 110 |
int num_irq = s->num_irq; |
111 | 111 |
|
112 | 112 |
if (s->num_cpu > NCPU) { |
113 |
hw_error("requested %u CPUs exceeds GIC maximum %d\n", |
|
114 |
s->num_cpu, NCPU); |
|
113 |
error_setg(errp, "requested %u CPUs exceeds GIC maximum %d", |
|
114 |
s->num_cpu, NCPU); |
|
115 |
return; |
|
115 | 116 |
} |
116 | 117 |
s->num_irq += GIC_BASE_IRQ; |
117 | 118 |
if (s->num_irq > GIC_MAXIRQ) { |
118 |
hw_error("requested %u interrupt lines exceeds GIC maximum %d\n", |
|
119 |
num_irq, GIC_MAXIRQ); |
|
119 |
error_setg(errp, |
|
120 |
"requested %u interrupt lines exceeds GIC maximum %d", |
|
121 |
num_irq, GIC_MAXIRQ); |
|
122 |
return; |
|
120 | 123 |
} |
121 | 124 |
/* ITLinesNumber is represented as (N / 32) - 1 (see |
122 | 125 |
* gic_dist_readb) so this is an implementation imposed |
123 | 126 |
* restriction, not an architectural one: |
124 | 127 |
*/ |
125 | 128 |
if (s->num_irq < 32 || (s->num_irq % 32)) { |
126 |
hw_error("%d interrupt lines unsupported: not divisible by 32\n", |
|
127 |
num_irq); |
|
129 |
error_setg(errp, |
|
130 |
"%d interrupt lines unsupported: not divisible by 32", |
|
131 |
num_irq); |
|
132 |
return; |
|
128 | 133 |
} |
129 | 134 |
|
130 | 135 |
register_savevm(NULL, "arm_gic", -1, 3, gic_save, gic_load, s); |
131 |
return 0; |
|
132 | 136 |
} |
133 | 137 |
|
134 | 138 |
static void arm_gic_common_reset(DeviceState *dev) |
... | ... | |
173 | 177 |
|
174 | 178 |
static void arm_gic_common_class_init(ObjectClass *klass, void *data) |
175 | 179 |
{ |
176 |
SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass); |
|
177 | 180 |
DeviceClass *dc = DEVICE_CLASS(klass); |
181 |
|
|
178 | 182 |
dc->reset = arm_gic_common_reset; |
183 |
dc->realize = arm_gic_common_realize; |
|
179 | 184 |
dc->props = arm_gic_common_properties; |
180 | 185 |
dc->no_user = 1; |
181 |
sc->init = arm_gic_common_init; |
|
182 | 186 |
} |
183 | 187 |
|
184 | 188 |
static const TypeInfo arm_gic_common_type = { |
b/hw/arm_gic_internal.h | ||
---|---|---|
132 | 132 |
|
133 | 133 |
typedef struct ARMGICClass { |
134 | 134 |
ARMGICCommonClass parent_class; |
135 |
int (*parent_init)(SysBusDevice *dev);
|
|
135 |
DeviceRealize parent_realize;
|
|
136 | 136 |
} ARMGICClass; |
137 | 137 |
|
138 | 138 |
#endif /* !QEMU_ARM_GIC_INTERNAL_H */ |
b/hw/armv7m_nvic.c | ||
---|---|---|
41 | 41 |
/*< private >*/ |
42 | 42 |
ARMGICClass parent_class; |
43 | 43 |
/*< public >*/ |
44 |
int (*parent_init)(SysBusDevice *dev);
|
|
44 |
DeviceRealize parent_realize;
|
|
45 | 45 |
void (*parent_reset)(DeviceState *dev); |
46 | 46 |
} NVICClass; |
47 | 47 |
|
... | ... | |
465 | 465 |
systick_reset(s); |
466 | 466 |
} |
467 | 467 |
|
468 |
static int armv7m_nvic_init(SysBusDevice *dev)
|
|
468 |
static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
|
|
469 | 469 |
{ |
470 | 470 |
nvic_state *s = NVIC(dev); |
471 | 471 |
NVICClass *nc = NVIC_GET_CLASS(s); |
... | ... | |
475 | 475 |
/* Tell the common code we're an NVIC */ |
476 | 476 |
s->gic.revision = 0xffffffff; |
477 | 477 |
s->num_irq = s->gic.num_irq; |
478 |
nc->parent_init(dev); |
|
478 |
nc->parent_realize(dev, errp); |
|
479 |
if (error_is_set(errp)) { |
|
480 |
return; |
|
481 |
} |
|
479 | 482 |
gic_init_irqs_and_distributor(&s->gic, s->num_irq); |
480 | 483 |
/* The NVIC and system controller register area looks like this: |
481 | 484 |
* 0..0xff : system control registers, including systick |
... | ... | |
503 | 506 |
*/ |
504 | 507 |
memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container); |
505 | 508 |
s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s); |
506 |
return 0; |
|
507 | 509 |
} |
508 | 510 |
|
509 | 511 |
static void armv7m_nvic_instance_init(Object *obj) |
... | ... | |
526 | 528 |
{ |
527 | 529 |
NVICClass *nc = NVIC_CLASS(klass); |
528 | 530 |
DeviceClass *dc = DEVICE_CLASS(klass); |
529 |
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); |
|
530 | 531 |
|
531 | 532 |
nc->parent_reset = dc->reset; |
532 |
nc->parent_init = sdc->init; |
|
533 |
sdc->init = armv7m_nvic_init; |
|
533 |
nc->parent_realize = dc->realize; |
|
534 | 534 |
dc->vmsd = &vmstate_nvic; |
535 | 535 |
dc->reset = armv7m_nvic_reset; |
536 |
dc->realize = armv7m_nvic_realize; |
|
536 | 537 |
} |
537 | 538 |
|
538 | 539 |
static const TypeInfo armv7m_nvic_info = { |
Also available in: Unified diff