Am 8. Mai 2025 14:46:06 UTC schrieb Jiaxun Yang <[email protected]>:
>Implement interrupt controller on Bonito north bridge, as well
>as PCI INTx mapping as per Fuloong 2E's hardware connection.
>
>pci_bonito_set_irq is renamed to bonito_set_irq to reflect that
>it also sets other IRQs on chip.
>
>Signed-off-by: Jiaxun Yang <[email protected]>
>---
> hw/pci-host/bonito.c | 96 ++++++++++++++++++++++++++++++----------------------
> 1 file changed, 56 insertions(+), 40 deletions(-)
>
>diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
>index 
>7d6251a78d7e2e26803dd72968ca2ea7adcfe0e5..a599a1db4c068325b8c1aa8fb4a45f6b299b581b
> 100644
>--- a/hw/pci-host/bonito.c
>+++ b/hw/pci-host/bonito.c
>@@ -157,6 +157,22 @@ FIELD(BONGENCFG, PCIQUEUE,      12, 1)
> #define BONITO_INTEN            (0x38 >> 2)      /* 0x138 */
> #define BONITO_INTISR           (0x3c >> 2)      /* 0x13c */
> 
>+/* ICU Pins */
>+#define ICU_PIN_MBOXx(x)        (0 + (x))
>+#define ICU_PIN_DMARDY          4
>+#define ICU_PIN_DMAEMPTY        5
>+#define ICU_PIN_COPYRDY         6
>+#define ICU_PIN_COPYEMPTY       7
>+#define ICU_PIN_COPYERR         8
>+#define ICU_PIN_PCIIRQ          9
>+#define ICU_PIN_MASTERERR       10
>+#define ICU_PIN_SYSTEMERR       11
>+#define ICU_PIN_DRAMPERR        12
>+#define ICU_PIN_RETRYERR        13
>+#define ICU_PIN_INTTIMER        14
>+#define ICU_PIN_GPIOx(x)        (16 + (x))
>+#define ICU_PIN_GPINx(x)        (25 + (x))
>+
> /* PCI mail boxes */
> #define BONITO_PCIMAIL0_OFFSET    0x40
> #define BONITO_PCIMAIL1_OFFSET    0x44
>@@ -206,6 +222,7 @@ struct PCIBonitoState {
> 
>     BonitoState *pcihost;
>     uint32_t regs[BONITO_REGS];
>+    uint32_t icu_pin_state;
> 
>     struct bonldma {
>         uint32_t ldmactrl;
>@@ -242,6 +259,40 @@ struct BonitoState {
> #define TYPE_PCI_BONITO "Bonito"
> OBJECT_DECLARE_SIMPLE_TYPE(PCIBonitoState, PCI_BONITO)
> 
>+static void bonito_update_irq(PCIBonitoState *s)
>+{
>+    BonitoState *bs = s->pcihost;
>+    uint32_t inten = s->regs[BONITO_INTEN];
>+    uint32_t intisr = s->regs[BONITO_INTISR];
>+    uint32_t intpol = s->regs[BONITO_INTPOL];
>+    uint32_t intedge = s->regs[BONITO_INTEDGE];
>+    uint32_t pin_state = s->icu_pin_state;
>+    uint32_t level, edge;
>+
>+    pin_state = (pin_state & ~intpol) | (~pin_state & intpol);
>+
>+    level = pin_state & ~intedge;
>+    edge = (pin_state & ~intisr) & intedge;
>+
>+    intisr = (intisr & intedge) | level;
>+    intisr |= edge;
>+    intisr &= inten;
>+
>+    s->regs[BONITO_INTISR] = intisr;
>+
>+    qemu_set_irq(*bs->pic, !!intisr);
>+}
>+
>+static void bonito_set_irq(void *opaque, int irq, int level)
>+{
>+    BonitoState *bs = opaque;
>+    PCIBonitoState *s = bs->pci_dev;
>+
>+    s->icu_pin_state = deposit32(s->icu_pin_state, irq, 1, !!level);
>+
>+    bonito_update_irq(s);
>+}
>+
> static void bonito_writel(void *opaque, hwaddr addr,
>                           uint64_t val, unsigned size)
> {
>@@ -289,12 +340,12 @@ static void bonito_writel(void *opaque, hwaddr addr,
>         }
>         break;
>     case BONITO_INTENSET:
>-        s->regs[BONITO_INTENSET] = val;
>         s->regs[BONITO_INTEN] |= val;
>+        bonito_update_irq(s);
>         break;
>     case BONITO_INTENCLR:
>-        s->regs[BONITO_INTENCLR] = val;
>         s->regs[BONITO_INTEN] &= ~val;
>+        bonito_update_irq(s);
>         break;
>     case BONITO_INTEN:
>     case BONITO_INTISR:
>@@ -549,45 +600,10 @@ static const MemoryRegionOps bonito_spciconf_ops = {
>     .endianness = DEVICE_NATIVE_ENDIAN,
> };
> 
>-#define BONITO_IRQ_BASE 32
>-
>-static void pci_bonito_set_irq(void *opaque, int irq_num, int level)
>-{
>-    BonitoState *s = opaque;
>-    qemu_irq *pic = s->pic;
>-    PCIBonitoState *bonito_state = s->pci_dev;
>-    int internal_irq = irq_num - BONITO_IRQ_BASE;
>-
>-    if (bonito_state->regs[BONITO_INTEDGE] & (1 << internal_irq)) {
>-        qemu_irq_pulse(*pic);
>-    } else {   /* level triggered */
>-        if (bonito_state->regs[BONITO_INTPOL] & (1 << internal_irq)) {
>-            qemu_irq_raise(*pic);
>-        } else {
>-            qemu_irq_lower(*pic);
>-        }
>-    }
>-}
>-
>-/* map the original irq (0~3) to bonito irq (16~47, but 16~31 are unused) */
> static int pci_bonito_map_irq(PCIDevice *pci_dev, int irq_num)
> {
>-    int slot;
>-
>-    slot = PCI_SLOT(pci_dev->devfn);
>-
>-    switch (slot) {
>-    case 5:   /* FULOONG2E_VIA_SLOT, SouthBridge, IDE, USB, ACPI, AC97, MC97 
>*/
>-        return irq_num % 4 + BONITO_IRQ_BASE;
>-    case 6:   /* FULOONG2E_ATI_SLOT, VGA */
>-        return 4 + BONITO_IRQ_BASE;
>-    case 7:   /* FULOONG2E_RTL_SLOT, RTL8139 */
>-        return 5 + BONITO_IRQ_BASE;
>-    case 8 ... 12: /* PCI slot 1 to 4 */
>-        return (slot - 8 + irq_num) + 6 + BONITO_IRQ_BASE;
>-    default:  /* Unknown device, don't do any translation */
>-        return irq_num;
>-    }
>+    /* Fuloong 2E PCI INTX are connected to Bonito GPIN[3:0] */

Given this comment, doesn't this code belong into fuloong2e.c? See 
https://lore.kernel.org/qemu-devel/[email protected] .

>+    return ICU_PIN_GPINx(irq_num);

It would then make sense to export this define. I can rebase my series, or how 
about incorporating it here? Either way:

Reviewed-by: Bernhard Beschow <[email protected]>

> }
> 
> static void bonito_reset_hold(Object *obj, ResetType type)
>@@ -633,7 +649,7 @@ static void bonito_host_realize(DeviceState *dev, Error 
>**errp)
> 
>     memory_region_init(&bs->pci_mem, OBJECT(dev), "pci.mem", 
> BONITO_PCIHI_SIZE);
>     phb->bus = pci_register_root_bus(dev, "pci",
>-                                     pci_bonito_set_irq, pci_bonito_map_irq,
>+                                     bonito_set_irq, pci_bonito_map_irq,
>                                      dev, &bs->pci_mem, get_system_io(),
>                                      PCI_DEVFN(5, 0), 32, TYPE_PCI_BUS);
> 
>

Reply via email to