Re: [PATCH v5 05/41] Add GIC-400 to BCM2838 SoC

2024-02-23 Thread Peter Maydell
On Mon, 19 Feb 2024 at 01:20, Sergey Kambalin  wrote:
>
> Signed-off-by: Sergey Kambalin 
> ---
>  hw/arm/bcm2838.c | 167 ++-
>  hw/arm/trace-events  |   3 +
>  include/hw/arm/bcm2838.h |   2 +
>  include/hw/arm/bcm2838_peripherals.h |  37 ++
>  4 files changed, 207 insertions(+), 2 deletions(-)

Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH v5 05/41] Add GIC-400 to BCM2838 SoC

2024-02-18 Thread Sergey Kambalin
Signed-off-by: Sergey Kambalin 
---
 hw/arm/bcm2838.c | 167 ++-
 hw/arm/trace-events  |   3 +
 include/hw/arm/bcm2838.h |   2 +
 include/hw/arm/bcm2838_peripherals.h |  37 ++
 4 files changed, 207 insertions(+), 2 deletions(-)

diff --git a/hw/arm/bcm2838.c b/hw/arm/bcm2838.c
index 05281e247f..332e906a84 100644
--- a/hw/arm/bcm2838.c
+++ b/hw/arm/bcm2838.c
@@ -14,8 +14,36 @@
 #include "hw/arm/bcm2838.h"
 #include "trace.h"
 
+#define GIC400_MAINTENANCE_IRQ  9
+#define GIC400_TIMER_NS_EL2_IRQ 10
+#define GIC400_TIMER_VIRT_IRQ   11
+#define GIC400_LEGACY_FIQ   12
+#define GIC400_TIMER_S_EL1_IRQ  13
+#define GIC400_TIMER_NS_EL1_IRQ 14
+#define GIC400_LEGACY_IRQ   15
+
+/* Number of external interrupt lines to configure the GIC with */
+#define GIC_NUM_IRQS192
+
+#define PPI(cpu, irq) (GIC_NUM_IRQS + (cpu) * GIC_INTERNAL + GIC_NR_SGIS + irq)
+
+#define GIC_BASE_OFS0x
+#define GIC_DIST_OFS0x1000
+#define GIC_CPU_OFS 0x2000
+#define GIC_VIFACE_THIS_OFS 0x4000
+#define GIC_VIFACE_OTHER_OFS(cpu)  (0x5000 + (cpu) * 0x200)
+#define GIC_VCPU_OFS0x6000
+
 #define VIRTUAL_PMU_IRQ 7
 
+static void bcm2838_gic_set_irq(void *opaque, int irq, int level)
+{
+BCM2838State *s = (BCM2838State *)opaque;
+
+trace_bcm2838_gic_set_irq(irq, level);
+qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->gic), irq), level);
+}
+
 static void bcm2838_init(Object *obj)
 {
 BCM2838State *s = BCM2838(obj);
@@ -28,11 +56,12 @@ static void bcm2838_init(Object *obj)
   "vcram-size");
 object_property_add_alias(obj, "command-line", OBJECT(&s->peripherals),
   "command-line");
+
+object_initialize_child(obj, "gic", &s->gic, TYPE_ARM_GIC);
 }
 
 static void bcm2838_realize(DeviceState *dev, Error **errp)
 {
-int n;
 BCM2838State *s = BCM2838(dev);
 BCM283XBaseState *s_base = BCM283X_BASE(dev);
 BCM283XBaseClass *bc_base = BCM283X_BASE_GET_CLASS(dev);
@@ -40,6 +69,8 @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
 BCMSocPeripheralBaseState *ps_base =
 BCM_SOC_PERIPHERALS_BASE(&s->peripherals);
 
+DeviceState *gicdev = NULL;
+
 if (!bcm283x_common_realize(dev, ps_base, errp)) {
 return;
 }
@@ -52,11 +83,15 @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(&s_base->control), 0, bc_base->ctrl_base);
 
 /* Create cores */
-for (n = 0; n < bc_base->core_count; n++) {
+for (int n = 0; n < bc_base->core_count; n++) {
 
 object_property_set_int(OBJECT(&s_base->cpu[n].core), "mp-affinity",
 (bc_base->clusterid << 8) | n, &error_abort);
 
+/* set periphbase/CBAR value for CPU-local registers */
+object_property_set_int(OBJECT(&s_base->cpu[n].core), "reset-cbar",
+bc_base->peri_base, &error_abort);
+
 /* start powered off if not enabled */
 object_property_set_bool(OBJECT(&s_base->cpu[n].core),
  "start-powered-off",
@@ -66,6 +101,134 @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
 return;
 }
 }
+
+if (!object_property_set_uint(OBJECT(&s->gic), "revision", 2, errp)) {
+return;
+}
+
+if (!object_property_set_uint(OBJECT(&s->gic), "num-cpu", BCM283X_NCPUS,
+  errp)) {
+return;
+}
+
+if (!object_property_set_uint(OBJECT(&s->gic), "num-irq",
+  GIC_NUM_IRQS + GIC_INTERNAL, errp)) {
+return;
+}
+
+if (!object_property_set_bool(OBJECT(&s->gic),
+  "has-virtualization-extensions", true,
+  errp)) {
+return;
+}
+
+if (!sysbus_realize(SYS_BUS_DEVICE(&s->gic), errp)) {
+return;
+}
+
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 0,
+bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_DIST_OFS);
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 1,
+bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_CPU_OFS);
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 2,
+bc_base->ctrl_base + BCM2838_GIC_BASE + 
GIC_VIFACE_THIS_OFS);
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 3,
+bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_VCPU_OFS);
+
+for (int n = 0; n < BCM283X_NCPUS; n++) {
+sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 4 + n,
+bc_base->ctrl_base + BCM2838_GIC_BASE
++ GIC_VIFACE_OTHER_OFS(n));
+}
+
+gicdev = DEVICE(&s->gic);
+
+for (int n = 0; n < BCM283X_NCPUS; n++) {
+DeviceState *cpudev = DEVICE(&s_base->cpu[n]);
+
+/* Connect the GICv2 outputs to the CPU */
+