From: Shlomo Pongratz <shlomo.pongr...@huawei.com> This patch includes the code that binds together the codes of all the previous patches.
Signed-off-by: Shlomo Pongratz <shlomo.pongr...@huawei.com> --- hw/intc/Makefile.objs | 1 + hw/intc/arm_gicv3.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 hw/intc/arm_gicv3.c diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 0e6784f..b7b2288 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -18,6 +18,7 @@ common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpu_interface.o common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_dist.o common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_redist.o common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_spi_its.o +common-obj-$(CONFIG_ARM_GIC) += arm_gicv3.o common-obj-$(CONFIG_OPENPIC) += openpic.o obj-$(CONFIG_APIC) += apic.o apic_common.o diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c new file mode 100644 index 0000000..62c8299 --- /dev/null +++ b/hw/intc/arm_gicv3.c @@ -0,0 +1,134 @@ +/* + * ARM Generic/Distributed Interrupt Controller + * + * Copyright (c) 2006-2007 CodeSourcery. + * Copyright (c) 2015 Huawei. + * Written by Shlomo Pongratz + * Base on gic.c by Paul Brook + * + * This code is licensed under the GPL. + */ + +/* This file contains implementation code for the GIC-500 interrupt + * controller, which is an implementation of the GICv3 architecture. + * Curently it supports up to 64 cores. Enhancmet to 128 cores requires + * working with bitops. + */ + +#include "hw/sysbus.h" +#include "gicv3_internal.h" +#include "qom/cpu.h" +#include "arm_gicv3_cpu_interface.h" +#include "arm_gicv3_interrupts.h" +#include "arm_gicv3_dist.h" +#include "arm_gicv3_redist.h" +#include "arm_gicv3_spi_its.h" + +static const MemoryRegionOps gic_ops[] = { + { + .read_with_attrs = gic_dist_read, + .write_with_attrs = gic_dist_write, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, + .endianness = DEVICE_NATIVE_ENDIAN, + }, + { + .read_with_attrs = gic_redist_read, + .write_with_attrs = gic_redist_write, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, + .endianness = DEVICE_NATIVE_ENDIAN, + }, + { + .read = gic_its_read, + .write = gic_its_write, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, + .endianness = DEVICE_NATIVE_ENDIAN, + }, + { + .read = gic_spi_read, + .write = gic_spi_write, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, + .endianness = DEVICE_NATIVE_ENDIAN, + }, + { + .read = gic_its_cntrl_read, + .write = gic_its_cntrl_write, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, + .endianness = DEVICE_NATIVE_ENDIAN, + } +}; + +static void arm_gic_realize(DeviceState *dev, Error **errp) +{ + /* Device instance realize function for the GIC sysbus device */ + GICv3State *s = ARM_GICV3(dev); + ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s); + Error *local_err = NULL; + uint32_t power2; + + agc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + /* Cuurently no GICv2 backwards compatibility (e.g. no memory mapped regs) + * Uses system gicv3_no_gicv2_bc mode + */ + gicv3_sre = 1; + + /* Tell the common code we're a GICv3 */ + s->revision = REV_V3; + + gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops); + + /* Compute mask for decoding the core number in redistributer */ + if (is_power_of_2(NUM_CPU(s))) + power2 = NUM_CPU(s); + else + /* QEMU has only pow2floor !!! */ + power2 = pow2floor(2 * NUM_CPU(s)); + s->cpu_mask = (power2 - 1); + + DPRINTF(" -- NUM_CPUS(%d) - cpu mask(0%x) -- \n", NUM_CPU(s), s->cpu_mask); + + bitmap_zero(s->cpu_enabled, s->num_cpu); +} + +static void arm_gicv3_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + ARMGICv3Class *agc = ARM_GICV3_CLASS(klass); + + agc->parent_realize = dc->realize; + dc->realize = arm_gic_realize; +} + +static const TypeInfo arm_gicv3_info = { + .name = TYPE_ARM_GICV3, + .parent = TYPE_ARM_GICV3_COMMON, + .instance_size = sizeof(GICv3State), + .class_init = arm_gicv3_class_init, + .class_size = sizeof(ARMGICv3Class), +}; + +static void arm_gicv3_register_types(void) +{ + type_register_static(&arm_gicv3_info); +} + +type_init(arm_gicv3_register_types) -- 1.9.1