diff --git a/src/aic.c b/src/aic.c index f47d8c2a..4eb83fe7 100644 --- a/src/aic.c +++ b/src/aic.c @@ -10,6 +10,38 @@ u64 aic_base; #define MASK_REG(x) (4 * ((x) >> 5)) #define MASK_BIT(x) BIT((x)&GENMASK(4, 0)) +struct aic_regs { + uint64_t reg_size; + uint64_t event; + uint64_t tgt_cpu; + uint64_t sw_set; + uint64_t sw_clr; + uint64_t mask_set; + uint64_t mask_clr; +}; + +static const struct aic_regs aic1_regs = { + .reg_size = AIC_REG_SIZE, + .event = AIC_EVENT, + .tgt_cpu = AIC_TARGET_CPU, + .sw_set = AIC_SW_SET, + .sw_clr = AIC_SW_CLR, + .mask_set = AIC_MASK_SET, + .mask_clr = AIC_MASK_CLR, +}; + +static const struct aic_regs aic2_regs = { + .reg_size = AIC2_REG_SIZE, + .event = AIC2_EVENT, + .tgt_cpu = AIC2_TARGET_CPU, + .sw_set = AIC2_SW_SET, + .sw_clr = AIC2_SW_CLR, + .mask_set = AIC2_MASK_SET, + .mask_clr = AIC2_MASK_CLR, +}; + +static const struct aic_regs *regs; + void aic_init(void) { int path[8]; @@ -25,13 +57,26 @@ void aic_init(void) return; } - printf("AIC registers @ 0x%lx\n", aic_base); + if (adt_is_compatible(adt, node, "aic,1")) { + printf("AIC: Version 1 @ 0x%lx\n", aic_base); + regs = &aic1_regs; + } else if (adt_is_compatible(adt, node, "aic,2")) { + printf("AIC: Version 2 @ 0x%lx\n", aic_base); + regs = &aic2_regs; + } else { + printf("AIC: Error: Unsupported version @ 0x%lx\n", aic_base); + } } void aic_set_sw(int irq, bool active) { if (active) - write32(aic_base + AIC_SW_SET + MASK_REG(irq), MASK_BIT(irq)); + write32(aic_base + regs->sw_set + MASK_REG(irq), MASK_BIT(irq)); else - write32(aic_base + AIC_SW_CLR + MASK_REG(irq), MASK_BIT(irq)); + write32(aic_base + regs->sw_clr + MASK_REG(irq), MASK_BIT(irq)); +} + +uint32_t aic_ack(void) +{ + return read32(aic_base + regs->event); } diff --git a/src/aic.h b/src/aic.h index d5ba5a98..528eaf2e 100644 --- a/src/aic.h +++ b/src/aic.h @@ -9,5 +9,6 @@ extern u64 aic_base; void aic_init(void); void aic_set_sw(int irq, bool active); +uint32_t aic_ack(void); #endif diff --git a/src/aic_regs.h b/src/aic_regs.h index e2c6ffc6..236273fa 100644 --- a/src/aic_regs.h +++ b/src/aic_regs.h @@ -13,6 +13,15 @@ #define AIC_MASK_SET 0x4100 #define AIC_MASK_CLR 0x4180 +#define AIC2_INFO 0x0004 +#define AIC2_LATENCY 0x0204 +#define AIC2_EVENT 0xc000 +#define AIC2_TARGET_CPU 0x2000 +#define AIC2_SW_SET 0x6000 +#define AIC2_SW_CLR 0x6200 +#define AIC2_MASK_SET 0x6400 +#define AIC2_MASK_CLR 0x6800 + #define AIC_CPU_IPI_SET(cpu) (0x5008 + ((cpu) << 7)) #define AIC_CPU_IPI_CLR(cpu) (0x500c + ((cpu) << 7)) #define AIC_CPU_IPI_MASK_SET(cpu) (0x5024 + ((cpu) << 7)) diff --git a/src/exception.c b/src/exception.c index 15352925..adee2728 100644 --- a/src/exception.c +++ b/src/exception.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: MIT */ #include "exception.h" +#include "aic.h" #include "cpu_regs.h" #include "gxf.h" #include "iodev.h" @@ -283,26 +284,11 @@ void exc_sync(u64 *regs) void exc_irq(u64 *regs) { -#ifdef DEBUG_UART_IRQS - u32 ucon, utrstat, uerstat, ufstat; - ucon = read32(0x235200004); - utrstat = read32(0x235200010); - uerstat = read32(0x235200014); - ufstat = read32(0x235200018); -#endif + u32 reason = aic_ack(); - printf("Exception: IRQ (from %s)\n", get_exception_source(0)); + printf("Exception: IRQ (from %s) type: %d num: %d mpidr: %lx\n", get_exception_source(0), + reason >> 16, reason & 0xffff, mrs(MPIDR_EL1)); - u32 reason = read32(0x23b102004); - - printf(" type: %d num: %d mpidr: %lx\n", reason >> 16, reason & 0xffff, mrs(MPIDR_EL1)); - -#ifdef DEBUG_UART_IRQS - printf(" UCON: 0x%x\n", ucon); - printf(" UTRSTAT: 0x%x\n", utrstat); - printf(" UERSTAT: 0x%x\n", uerstat); - printf(" UFSTAT: 0x%x\n", ufstat); -#endif UNUSED(regs); // print_regs(regs); }