mirror of https://github.com/proxmox/mirror_qemu
target-arm queue:
* Support multiple redistributor regions for TCG GICv3 * Send RTC_CHANGE QMP event from pl031 -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmGSrLQZHHBldGVyLm1h eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3n9ID/9E4onDjL5f0UkRqISs72Kv q80tMer6qZHeyiJCKyomYBuHPRa4hGxZ28E2Zn/Y0qNSr/U2yjnkQiybIa2q4Th+ 8zLC+AsdXtJxk0vaDMr6uuWlXmbHKodA4OLAxbrom8e0q7H9SyzsvqaGWuLIoarl xXQuPumrBjjWR2jzUjSONupayKMKTHnRlqG8sl9Mw60W8BiNirar/lZP7s9tJI9/ IIh1MvpMIYEPZnRHokI2JNA2HBHFFGEM9Pu2I84ApzNFk2zpTS8U0Uoa+ITb7E5A pn3Yd6tizNWRBQXbkE43/TSbNe4PIm43ZhO9mQiyDqZ7/+9T1fl3wGR39KI0oZNG 47vTjR9MihG8BPuGvTIHyVzAFUL/cff6w+P0YQSBB9H/k39TKUVcujM2Z0TfeoUs rofzKnGSZ0eTR/tiNJUWzh8heF45gM4ZscOaoyX7mLznUPCq0CQQ0oJC26UMWeHn ngECVPbmQSsR4qiUdnVLAqQSiy6SUk+bd+QWKU+8Gh+UVqcJiGwSSLEhWqRrV7yX pOAgDBOcCu9hgMQN0zbdZnm2Cg/tOZLMR1tm+vLy4Mm450quWjGGcOgryejBqy2V TIONc4aWvxzPVyFy0AV9DP8iA7EG8pDuKjLg/5msUyA7a+HUsf1VWq3RC1CU2Aq6 RfGl5xxZwA5ppKeq0dp4Ow== =XJbZ -----END PGP SIGNATURE----- Merge tag 'pull-target-arm-20211115-1' of https://git.linaro.org/people/pmaydell/qemu-arm into staging target-arm queue: * Support multiple redistributor regions for TCG GICv3 * Send RTC_CHANGE QMP event from pl031 # gpg: Signature made Mon 15 Nov 2021 07:53:40 PM CET # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [full] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full] * tag 'pull-target-arm-20211115-1' of https://git.linaro.org/people/pmaydell/qemu-arm: hw/rtc/pl031: Send RTC_CHANGE QMP event hw/intc/arm_gicv3: Support multiple redistributor regions hw/intc/arm_gicv3: Set GICR_TYPER.Last correctly when nb_redist_regions > 1 hw/intc/arm_gicv3: Move checking of redist-region-count to arm_gicv3_common_realize Signed-off-by: Richard Henderson <richard.henderson@linaro.org>master
commit
3e595538b8
|
@ -387,17 +387,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->nb_redist_regions != 1) {
|
gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
|
||||||
error_setg(errp, "VGICv3 redist region number(%d) not equal to 1",
|
|
||||||
s->nb_redist_regions);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops, &local_err);
|
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gicv3_init_cpuif(s);
|
gicv3_init_cpuif(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,21 +250,11 @@ static const VMStateDescription vmstate_gicv3 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
||||||
const MemoryRegionOps *ops, Error **errp)
|
const MemoryRegionOps *ops)
|
||||||
{
|
{
|
||||||
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
|
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
|
||||||
int rdist_capacity = 0;
|
|
||||||
int i;
|
int i;
|
||||||
|
int cpuidx;
|
||||||
for (i = 0; i < s->nb_redist_regions; i++) {
|
|
||||||
rdist_capacity += s->redist_region_count[i];
|
|
||||||
}
|
|
||||||
if (rdist_capacity < s->num_cpu) {
|
|
||||||
error_setg(errp, "Capacity of the redist regions(%d) "
|
|
||||||
"is less than number of vcpus(%d)",
|
|
||||||
rdist_capacity, s->num_cpu);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
|
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
|
||||||
* GPIO array layout is thus:
|
* GPIO array layout is thus:
|
||||||
|
@ -293,14 +283,20 @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
||||||
"gicv3_dist", 0x10000);
|
"gicv3_dist", 0x10000);
|
||||||
sysbus_init_mmio(sbd, &s->iomem_dist);
|
sysbus_init_mmio(sbd, &s->iomem_dist);
|
||||||
|
|
||||||
s->iomem_redist = g_new0(MemoryRegion, s->nb_redist_regions);
|
s->redist_regions = g_new0(GICv3RedistRegion, s->nb_redist_regions);
|
||||||
|
cpuidx = 0;
|
||||||
for (i = 0; i < s->nb_redist_regions; i++) {
|
for (i = 0; i < s->nb_redist_regions; i++) {
|
||||||
char *name = g_strdup_printf("gicv3_redist_region[%d]", i);
|
char *name = g_strdup_printf("gicv3_redist_region[%d]", i);
|
||||||
|
GICv3RedistRegion *region = &s->redist_regions[i];
|
||||||
|
|
||||||
memory_region_init_io(&s->iomem_redist[i], OBJECT(s),
|
region->gic = s;
|
||||||
ops ? &ops[1] : NULL, s, name,
|
region->cpuidx = cpuidx;
|
||||||
|
cpuidx += s->redist_region_count[i];
|
||||||
|
|
||||||
|
memory_region_init_io(®ion->iomem, OBJECT(s),
|
||||||
|
ops ? &ops[1] : NULL, region, name,
|
||||||
s->redist_region_count[i] * GICV3_REDIST_SIZE);
|
s->redist_region_count[i] * GICV3_REDIST_SIZE);
|
||||||
sysbus_init_mmio(sbd, &s->iomem_redist[i]);
|
sysbus_init_mmio(sbd, ®ion->iomem);
|
||||||
g_free(name);
|
g_free(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,7 +304,7 @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
||||||
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
GICv3State *s = ARM_GICV3_COMMON(dev);
|
GICv3State *s = ARM_GICV3_COMMON(dev);
|
||||||
int i;
|
int i, rdist_capacity, cpuidx;
|
||||||
|
|
||||||
/* revision property is actually reserved and currently used only in order
|
/* revision property is actually reserved and currently used only in order
|
||||||
* to keep the interface compatible with GICv2 code, avoiding extra
|
* to keep the interface compatible with GICv2 code, avoiding extra
|
||||||
|
@ -350,12 +346,22 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rdist_capacity = 0;
|
||||||
|
for (i = 0; i < s->nb_redist_regions; i++) {
|
||||||
|
rdist_capacity += s->redist_region_count[i];
|
||||||
|
}
|
||||||
|
if (rdist_capacity < s->num_cpu) {
|
||||||
|
error_setg(errp, "Capacity of the redist regions(%d) "
|
||||||
|
"is less than number of vcpus(%d)",
|
||||||
|
rdist_capacity, s->num_cpu);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
s->cpu = g_new0(GICv3CPUState, s->num_cpu);
|
s->cpu = g_new0(GICv3CPUState, s->num_cpu);
|
||||||
|
|
||||||
for (i = 0; i < s->num_cpu; i++) {
|
for (i = 0; i < s->num_cpu; i++) {
|
||||||
CPUState *cpu = qemu_get_cpu(i);
|
CPUState *cpu = qemu_get_cpu(i);
|
||||||
uint64_t cpu_affid;
|
uint64_t cpu_affid;
|
||||||
int last;
|
|
||||||
|
|
||||||
s->cpu[i].cpu = cpu;
|
s->cpu[i].cpu = cpu;
|
||||||
s->cpu[i].gic = s;
|
s->cpu[i].gic = s;
|
||||||
|
@ -375,7 +381,6 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||||
* PLPIS == 0 (physical LPIs not supported)
|
* PLPIS == 0 (physical LPIs not supported)
|
||||||
*/
|
*/
|
||||||
cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL);
|
cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL);
|
||||||
last = (i == s->num_cpu - 1);
|
|
||||||
|
|
||||||
/* The CPU mp-affinity property is in MPIDR register format; squash
|
/* The CPU mp-affinity property is in MPIDR register format; squash
|
||||||
* the affinity bytes into 32 bits as the GICR_TYPER has them.
|
* the affinity bytes into 32 bits as the GICR_TYPER has them.
|
||||||
|
@ -384,13 +389,22 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
|
||||||
(cpu_affid & 0xFFFFFF);
|
(cpu_affid & 0xFFFFFF);
|
||||||
s->cpu[i].gicr_typer = (cpu_affid << 32) |
|
s->cpu[i].gicr_typer = (cpu_affid << 32) |
|
||||||
(1 << 24) |
|
(1 << 24) |
|
||||||
(i << 8) |
|
(i << 8);
|
||||||
(last << 4);
|
|
||||||
|
|
||||||
if (s->lpi_enable) {
|
if (s->lpi_enable) {
|
||||||
s->cpu[i].gicr_typer |= GICR_TYPER_PLPIS;
|
s->cpu[i].gicr_typer |= GICR_TYPER_PLPIS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now go through and set GICR_TYPER.Last for the final
|
||||||
|
* redistributor in each region.
|
||||||
|
*/
|
||||||
|
cpuidx = 0;
|
||||||
|
for (i = 0; i < s->nb_redist_regions; i++) {
|
||||||
|
cpuidx += s->redist_region_count[i];
|
||||||
|
s->cpu[cpuidx - 1].gicr_typer |= GICR_TYPER_LAST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arm_gicv3_finalize(Object *obj)
|
static void arm_gicv3_finalize(Object *obj)
|
||||||
|
|
|
@ -787,11 +787,7 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL, &local_err);
|
gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL);
|
||||||
if (local_err) {
|
|
||||||
error_propagate(errp, local_err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < s->num_cpu; i++) {
|
for (i = 0; i < s->num_cpu; i++) {
|
||||||
ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
|
ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
|
||||||
|
@ -829,7 +825,7 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
|
||||||
KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd, 0);
|
KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd, 0);
|
||||||
|
|
||||||
if (!multiple_redist_region_allowed) {
|
if (!multiple_redist_region_allowed) {
|
||||||
kvm_arm_register_device(&s->iomem_redist[0], -1,
|
kvm_arm_register_device(&s->redist_regions[0].iomem, -1,
|
||||||
KVM_DEV_ARM_VGIC_GRP_ADDR,
|
KVM_DEV_ARM_VGIC_GRP_ADDR,
|
||||||
KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd, 0);
|
KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd, 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -842,7 +838,7 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
|
||||||
uint64_t addr_ormask =
|
uint64_t addr_ormask =
|
||||||
i | ((uint64_t)s->redist_region_count[i] << 52);
|
i | ((uint64_t)s->redist_region_count[i] << 52);
|
||||||
|
|
||||||
kvm_arm_register_device(&s->iomem_redist[i], -1,
|
kvm_arm_register_device(&s->redist_regions[i].iomem, -1,
|
||||||
KVM_DEV_ARM_VGIC_GRP_ADDR,
|
KVM_DEV_ARM_VGIC_GRP_ADDR,
|
||||||
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION,
|
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION,
|
||||||
s->dev_fd, addr_ormask);
|
s->dev_fd, addr_ormask);
|
||||||
|
|
|
@ -425,22 +425,24 @@ static MemTxResult gicr_writell(GICv3CPUState *cs, hwaddr offset,
|
||||||
MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
|
MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
|
||||||
unsigned size, MemTxAttrs attrs)
|
unsigned size, MemTxAttrs attrs)
|
||||||
{
|
{
|
||||||
GICv3State *s = opaque;
|
GICv3RedistRegion *region = opaque;
|
||||||
|
GICv3State *s = region->gic;
|
||||||
GICv3CPUState *cs;
|
GICv3CPUState *cs;
|
||||||
MemTxResult r;
|
MemTxResult r;
|
||||||
int cpuidx;
|
int cpuidx;
|
||||||
|
|
||||||
assert((offset & (size - 1)) == 0);
|
assert((offset & (size - 1)) == 0);
|
||||||
|
|
||||||
/* This region covers all the redistributor pages; there are
|
/*
|
||||||
* (for GICv3) two 64K pages per CPU. At the moment they are
|
* There are (for GICv3) two 64K redistributor pages per CPU.
|
||||||
* all contiguous (ie in this one region), though we might later
|
* In some cases the redistributor pages for all CPUs are not
|
||||||
* want to allow splitting of redistributor pages into several
|
* contiguous (eg on the virt board they are split into two
|
||||||
* blocks so we can support more CPUs.
|
* parts if there are too many CPUs to all fit in the same place
|
||||||
|
* in the memory map); if so then the GIC has multiple MemoryRegions
|
||||||
|
* for the redistributors.
|
||||||
*/
|
*/
|
||||||
cpuidx = offset / 0x20000;
|
cpuidx = region->cpuidx + offset / GICV3_REDIST_SIZE;
|
||||||
offset %= 0x20000;
|
offset %= GICV3_REDIST_SIZE;
|
||||||
assert(cpuidx < s->num_cpu);
|
|
||||||
|
|
||||||
cs = &s->cpu[cpuidx];
|
cs = &s->cpu[cpuidx];
|
||||||
|
|
||||||
|
@ -482,22 +484,24 @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
|
||||||
MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
|
MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
|
||||||
unsigned size, MemTxAttrs attrs)
|
unsigned size, MemTxAttrs attrs)
|
||||||
{
|
{
|
||||||
GICv3State *s = opaque;
|
GICv3RedistRegion *region = opaque;
|
||||||
|
GICv3State *s = region->gic;
|
||||||
GICv3CPUState *cs;
|
GICv3CPUState *cs;
|
||||||
MemTxResult r;
|
MemTxResult r;
|
||||||
int cpuidx;
|
int cpuidx;
|
||||||
|
|
||||||
assert((offset & (size - 1)) == 0);
|
assert((offset & (size - 1)) == 0);
|
||||||
|
|
||||||
/* This region covers all the redistributor pages; there are
|
/*
|
||||||
* (for GICv3) two 64K pages per CPU. At the moment they are
|
* There are (for GICv3) two 64K redistributor pages per CPU.
|
||||||
* all contiguous (ie in this one region), though we might later
|
* In some cases the redistributor pages for all CPUs are not
|
||||||
* want to allow splitting of redistributor pages into several
|
* contiguous (eg on the virt board they are split into two
|
||||||
* blocks so we can support more CPUs.
|
* parts if there are too many CPUs to all fit in the same place
|
||||||
|
* in the memory map); if so then the GIC has multiple MemoryRegions
|
||||||
|
* for the redistributors.
|
||||||
*/
|
*/
|
||||||
cpuidx = offset / 0x20000;
|
cpuidx = region->cpuidx + offset / GICV3_REDIST_SIZE;
|
||||||
offset %= 0x20000;
|
offset %= GICV3_REDIST_SIZE;
|
||||||
assert(cpuidx < s->num_cpu);
|
|
||||||
|
|
||||||
cs = &s->cpu[cpuidx];
|
cs = &s->cpu[cpuidx];
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
softmmu_ss.add(when: 'CONFIG_DS1338', if_true: files('ds1338.c'))
|
softmmu_ss.add(when: 'CONFIG_DS1338', if_true: files('ds1338.c'))
|
||||||
softmmu_ss.add(when: 'CONFIG_M41T80', if_true: files('m41t80.c'))
|
softmmu_ss.add(when: 'CONFIG_M41T80', if_true: files('m41t80.c'))
|
||||||
softmmu_ss.add(when: 'CONFIG_M48T59', if_true: files('m48t59.c'))
|
softmmu_ss.add(when: 'CONFIG_M48T59', if_true: files('m48t59.c'))
|
||||||
softmmu_ss.add(when: 'CONFIG_PL031', if_true: files('pl031.c'))
|
specific_ss.add(when: 'CONFIG_PL031', if_true: files('pl031.c'))
|
||||||
softmmu_ss.add(when: 'CONFIG_TWL92230', if_true: files('twl92230.c'))
|
softmmu_ss.add(when: 'CONFIG_TWL92230', if_true: files('twl92230.c'))
|
||||||
softmmu_ss.add(when: ['CONFIG_ISA_BUS', 'CONFIG_M48T59'], if_true: files('m48t59-isa.c'))
|
softmmu_ss.add(when: ['CONFIG_ISA_BUS', 'CONFIG_M48T59'], if_true: files('m48t59-isa.c'))
|
||||||
softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-rtc.c'))
|
softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-rtc.c'))
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#include "qapi/qapi-events-misc-target.h"
|
||||||
|
|
||||||
#define RTC_DR 0x00 /* Data read register */
|
#define RTC_DR 0x00 /* Data read register */
|
||||||
#define RTC_MR 0x04 /* Match register */
|
#define RTC_MR 0x04 /* Match register */
|
||||||
|
@ -136,10 +137,17 @@ static void pl031_write(void * opaque, hwaddr offset,
|
||||||
trace_pl031_write(offset, value);
|
trace_pl031_write(offset, value);
|
||||||
|
|
||||||
switch (offset) {
|
switch (offset) {
|
||||||
case RTC_LR:
|
case RTC_LR: {
|
||||||
|
struct tm tm;
|
||||||
|
|
||||||
s->tick_offset += value - pl031_get_count(s);
|
s->tick_offset += value - pl031_get_count(s);
|
||||||
|
|
||||||
|
qemu_get_timedate(&tm, s->tick_offset);
|
||||||
|
qapi_event_send_rtc_change(qemu_timedate_diff(&tm));
|
||||||
|
|
||||||
pl031_set_alarm(s);
|
pl031_set_alarm(s);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case RTC_MR:
|
case RTC_MR:
|
||||||
s->mr = value;
|
s->mr = value;
|
||||||
pl031_set_alarm(s);
|
pl031_set_alarm(s);
|
||||||
|
|
|
@ -215,13 +215,23 @@ struct GICv3CPUState {
|
||||||
bool seenbetter;
|
bool seenbetter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The redistributor pages might be split into more than one region
|
||||||
|
* on some machine types if there are many CPUs.
|
||||||
|
*/
|
||||||
|
typedef struct GICv3RedistRegion {
|
||||||
|
GICv3State *gic;
|
||||||
|
MemoryRegion iomem;
|
||||||
|
uint32_t cpuidx; /* index of first CPU this region covers */
|
||||||
|
} GICv3RedistRegion;
|
||||||
|
|
||||||
struct GICv3State {
|
struct GICv3State {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
SysBusDevice parent_obj;
|
SysBusDevice parent_obj;
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
|
|
||||||
MemoryRegion iomem_dist; /* Distributor */
|
MemoryRegion iomem_dist; /* Distributor */
|
||||||
MemoryRegion *iomem_redist; /* Redistributor Regions */
|
GICv3RedistRegion *redist_regions; /* Redistributor Regions */
|
||||||
uint32_t *redist_region_count; /* redistributor count within each region */
|
uint32_t *redist_region_count; /* redistributor count within each region */
|
||||||
uint32_t nb_redist_regions; /* number of redist regions */
|
uint32_t nb_redist_regions; /* number of redist regions */
|
||||||
|
|
||||||
|
@ -306,6 +316,6 @@ struct ARMGICv3CommonClass {
|
||||||
};
|
};
|
||||||
|
|
||||||
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
|
||||||
const MemoryRegionOps *ops, Error **errp);
|
const MemoryRegionOps *ops);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue