diff options
Diffstat (limited to 'hw/arm/xlnx-versal.c')
| -rw-r--r-- | hw/arm/xlnx-versal.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index 3d960ed263..6474440118 100644 --- a/hw/arm/xlnx-versal.c +++ b/hw/arm/xlnx-versal.c @@ -52,14 +52,26 @@ /* * IRQ descriptor to catch the following cases: + * - An IRQ can either connect to the GICs, to the PPU1 intc, or the the EAM * - Multiple devices can connect to the same IRQ. They are OR'ed together. */ FIELD(VERSAL_IRQ, IRQ, 0, 16) +FIELD(VERSAL_IRQ, TARGET, 16, 2) FIELD(VERSAL_IRQ, ORED, 18, 1) FIELD(VERSAL_IRQ, OR_IDX, 19, 4) /* input index on the IRQ OR gate */ +typedef enum VersalIrqTarget { + IRQ_TARGET_GIC, + IRQ_TARGET_PPU1, + IRQ_TARGET_EAM, +} VersalIrqTarget; + +#define PPU1_IRQ(irq) ((IRQ_TARGET_PPU1 << R_VERSAL_IRQ_TARGET_SHIFT) | (irq)) +#define EAM_IRQ(irq) ((IRQ_TARGET_EAM << R_VERSAL_IRQ_TARGET_SHIFT) | (irq)) #define OR_IRQ(irq, or_idx) \ (R_VERSAL_IRQ_ORED_MASK | ((or_idx) << R_VERSAL_IRQ_OR_IDX_SHIFT) | (irq)) +#define PPU1_OR_IRQ(irq, or_idx) \ + ((IRQ_TARGET_PPU1 << R_VERSAL_IRQ_TARGET_SHIFT) | OR_IRQ(irq, or_idx)) typedef struct VersalSimplePeriphMap { uint64_t addr; @@ -414,6 +426,13 @@ static qemu_irq versal_get_gic_irq(Versal *s, int irq_idx) static qemu_irq versal_get_irq_or_gate_in(Versal *s, int irq_idx, qemu_irq target_irq) { + static const char *TARGET_STR[] = { + [IRQ_TARGET_GIC] = "gic", + [IRQ_TARGET_PPU1] = "ppu1", + [IRQ_TARGET_EAM] = "eam", + }; + + VersalIrqTarget target; Object *container = versal_get_child(s, "irq-or-gates"); DeviceState *dev; g_autofree char *name; @@ -421,8 +440,9 @@ static qemu_irq versal_get_irq_or_gate_in(Versal *s, int irq_idx, idx = FIELD_EX32(irq_idx, VERSAL_IRQ, IRQ); or_idx = FIELD_EX32(irq_idx, VERSAL_IRQ, OR_IDX); + target = FIELD_EX32(irq_idx, VERSAL_IRQ, TARGET); - name = g_strdup_printf("irq[%d]", idx); + name = g_strdup_printf("%s-irq[%d]", TARGET_STR[target], idx); dev = DEVICE(object_resolve_path_at(container, name)); if (dev == NULL) { @@ -438,12 +458,29 @@ static qemu_irq versal_get_irq_or_gate_in(Versal *s, int irq_idx, static qemu_irq versal_get_irq(Versal *s, int irq_idx) { + VersalIrqTarget target; qemu_irq irq; bool ored; + target = FIELD_EX32(irq_idx, VERSAL_IRQ, TARGET); ored = FIELD_EX32(irq_idx, VERSAL_IRQ, ORED); - irq = versal_get_gic_irq(s, irq_idx); + switch (target) { + case IRQ_TARGET_EAM: + /* EAM not implemented */ + return NULL; + + case IRQ_TARGET_PPU1: + /* PPU1 CPU not implemented */ + return NULL; + + case IRQ_TARGET_GIC: + irq = versal_get_gic_irq(s, irq_idx); + break; + + default: + g_assert_not_reached(); + } if (ored) { irq = versal_get_irq_or_gate_in(s, irq_idx, irq); |