Wire all 160 SoC SPI interrupt lines through SplitIRQ splitters so that each interrupt is delivered to both the Cortex-A53 GICv3 and the Cortex-M7 NVIC simultaneously. As per i.MX8MP RM Table 7-2 the same interrupt lines are routed to both cores.
Signed-off-by: Gaurav Sharma <[email protected]> --- hw/arm/fsl-imx8mp.c | 59 +++++++++++++++++++++++++------------ include/hw/arm/fsl-imx8mp.h | 2 ++ 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c index e7dafa2403..17733c7270 100644 --- a/hw/arm/fsl-imx8mp.c +++ b/hw/arm/fsl-imx8mp.c @@ -200,6 +200,12 @@ static void fsl_imx8mp_init(Object *obj) FslImx8mpState *s = FSL_IMX8MP(obj); int i; + for (i = 0; i < FSL_IMX8MP_NUM_IRQS; i++) { + g_autofree char *name = g_strdup_printf("irq-splitter%d", i); + object_initialize_child(obj, name, &s->cpu_irq_splitter[i], + TYPE_SPLIT_IRQ); + } + object_initialize_child(obj, "cm7", &s->cm7, TYPE_ARMV7M); object_initialize_child(obj, "gic", &s->gic, gicv3_class_name()); @@ -286,6 +292,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) FslImx8mpState *s = FSL_IMX8MP(dev); DeviceState *gicdev = DEVICE(&s->gic); const char *cpu_type = ms->cpu_type ?: ARM_CPU_TYPE_NAME("cortex-a53"); + qemu_irq spi_irq[FSL_IMX8MP_NUM_IRQS]; int i; for (i = 0; i < FSL_IMX8MP_NUM_A53; i++) { @@ -407,6 +414,15 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) } } + for (i = 0; i < FSL_IMX8MP_NUM_IRQS; i++) { + DeviceState *splitter = DEVICE(&s->cpu_irq_splitter[i]); + qdev_prop_set_uint16(splitter, "num-lines", 2); + qdev_realize(splitter, NULL, &error_abort); + spi_irq[i] = qdev_get_gpio_in(splitter, 0); + qdev_connect_gpio_out(splitter, 0, + qdev_get_gpio_in(gicdev, i)); + } + /* CCM */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->ccm), errp)) { return; @@ -440,7 +456,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0, serial_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0, - qdev_get_gpio_in(gicdev, serial_table[i].irq)); + spi_irq[serial_table[i].irq]); } /* GPC */ @@ -482,6 +498,11 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) } arm_set_cpu_off(arm_cpu_mp_affinity(s->cm7.cpu)); + + for (i = 0; i < FSL_IMX8MP_NUM_IRQS; i++) { + qdev_connect_gpio_out(DEVICE(&s->cpu_irq_splitter[i]), 1, + qdev_get_gpio_in(DEVICE(&s->cm7), i)); + } } qdev_prop_set_uint32(DEVICE(&s->src), "cm7-vector-base", @@ -508,7 +529,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) } qdev_connect_gpio_out(DEVICE(&s->gpt5_gpt6_irq), 0, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_GPT5_GPT6_IRQ)); + spi_irq[FSL_IMX8MP_GPT5_GPT6_IRQ]); for (i = 0; i < FSL_IMX8MP_NUM_GPTS; i++) { hwaddr gpt_addrs[FSL_IMX8MP_NUM_GPTS] = { @@ -537,7 +558,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) }; sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0, - qdev_get_gpio_in(gicdev, gpt_irqs[i])); + spi_irq[gpt_irqs[i]]); } else { int irq = i - FSL_IMX8MP_NUM_GPTS + 2; @@ -572,7 +593,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) } sysbus_connect_irq(SYS_BUS_DEVICE(&s->mu[0].a), 0, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_MU1_A_IRQ)); + spi_irq[FSL_IMX8MP_MU1_A_IRQ]); /* I2Cs */ for (i = 0; i < FSL_IMX8MP_NUM_I2CS; i++) { @@ -594,7 +615,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, i2c_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0, - qdev_get_gpio_in(gicdev, i2c_table[i].irq)); + spi_irq[i2c_table[i].irq]); } /* GPIOs */ @@ -641,9 +662,9 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, gpio_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0, - qdev_get_gpio_in(gicdev, gpio_table[i].irq_low)); + spi_irq[gpio_table[i].irq_low]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1, - qdev_get_gpio_in(gicdev, gpio_table[i].irq_high)); + spi_irq[gpio_table[i].irq_high]); } /* USDHCs */ @@ -663,7 +684,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0, usdhc_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0, - qdev_get_gpio_in(gicdev, usdhc_table[i].irq)); + spi_irq[usdhc_table[i].irq]); } /* USBs */ @@ -684,7 +705,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) } sysbus_mmio_map(SYS_BUS_DEVICE(&s->usb[i]), 0, usb_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->usb[i].sysbus_xhci), 0, - qdev_get_gpio_in(gicdev, usb_table[i].irq)); + spi_irq[usb_table[i].irq]); } /* ECSPIs */ @@ -704,7 +725,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0, - qdev_get_gpio_in(gicdev, spi_table[i].irq)); + spi_irq[spi_table[i].irq]); } /* ENET1 */ @@ -718,9 +739,9 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->enet), 0, fsl_imx8mp_memmap[FSL_IMX8MP_ENET1].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->enet), 0, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_ENET1_MAC_IRQ)); + spi_irq[FSL_IMX8MP_ENET1_MAC_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->enet), 1, - qdev_get_gpio_in(gicdev, FSL_IMX6_ENET1_MAC_1588_IRQ)); + spi_irq[FSL_IMX6_ENET1_MAC_1588_IRQ]); /* SNVS */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->snvs), errp)) { @@ -748,7 +769,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0, wdog_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->wdt[i]), 0, - qdev_get_gpio_in(gicdev, wdog_table[i].irq)); + spi_irq[wdog_table[i].irq]); } /* PCIe */ @@ -759,15 +780,15 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) fsl_imx8mp_memmap[FSL_IMX8MP_PCIE1].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTA_IRQ)); + spi_irq[FSL_IMX8MP_PCI_INTA_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTB_IRQ)); + spi_irq[FSL_IMX8MP_PCI_INTB_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTC_IRQ)); + spi_irq[FSL_IMX8MP_PCI_INTC_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_INTD_IRQ)); + spi_irq[FSL_IMX8MP_PCI_INTD_IRQ]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4, - qdev_get_gpio_in(gicdev, FSL_IMX8MP_PCI_MSI_IRQ)); + spi_irq[FSL_IMX8MP_PCI_MSI_IRQ]); if (!sysbus_realize(SYS_BUS_DEVICE(&s->pcie_phy), errp)) { return; @@ -800,7 +821,7 @@ static void fsl_imx8mp_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->flexcan[i]), 0, flexcan_table[i].addr); sysbus_connect_irq(SYS_BUS_DEVICE(&s->flexcan[i]), 0, - qdev_get_gpio_in(gicdev, flexcan_table[i].irq)); + spi_irq[flexcan_table[i].irq]); } /* On-Chip RAM */ diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h index e8d84f82b5..1685938a0b 100644 --- a/include/hw/arm/fsl-imx8mp.h +++ b/include/hw/arm/fsl-imx8mp.h @@ -25,6 +25,7 @@ #include "hw/net/flexcan.h" #include "hw/net/imx_fec.h" #include "hw/core/or-irq.h" +#include "hw/core/split-irq.h" #include "hw/pci-host/designware.h" #include "hw/pci-host/fsl_imx8m_phy.h" #include "hw/sd/sdhci.h" @@ -93,6 +94,7 @@ struct FslImx8mpState { FslImx8mPciePhyState pcie_phy; FlexcanState flexcan[FSL_IMX8MP_NUM_CANS]; OrIRQState gpt5_gpt6_irq; + SplitIRQ cpu_irq_splitter[FSL_IMX8MP_NUM_IRQS]; MemoryRegion ocram; MemoryRegion itcm; MemoryRegion dtcm; -- 2.34.1
