From 4b4ae3ab90a45f04d3beeefd5a152142f21f6716 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Mon, 23 Aug 2021 17:01:33 +0900 Subject: [PATCH] aic: Add trivial AIC scaffolding, move regs to aic_regs.h Signed-off-by: Hector Martin --- Makefile | 1 + src/aic.c | 37 +++++++++++++++++++++++++++++++++++++ src/aic.h | 13 +++++++++++++ src/aic_regs.h | 36 ++++++++++++++++++++++++++++++++++++ src/hv_aic.c | 30 +++--------------------------- src/main.c | 2 ++ 6 files changed, 92 insertions(+), 27 deletions(-) create mode 100644 src/aic.c create mode 100644 src/aic.h create mode 100644 src/aic_regs.h diff --git a/Makefile b/Makefile index b544970d..92146373 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,7 @@ LIBFDT_OBJECTS := $(patsubst %,libfdt/%, \ OBJECTS := \ adt.o \ + aic.o \ bootlogo_128.o bootlogo_256.o \ chickens.o \ dart.o \ diff --git a/src/aic.c b/src/aic.c new file mode 100644 index 00000000..f47d8c2a --- /dev/null +++ b/src/aic.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: MIT */ + +#include "aic.h" +#include "adt.h" +#include "aic_regs.h" +#include "utils.h" + +u64 aic_base; + +#define MASK_REG(x) (4 * ((x) >> 5)) +#define MASK_BIT(x) BIT((x)&GENMASK(4, 0)) + +void aic_init(void) +{ + int path[8]; + int node = adt_path_offset_trace(adt, "/arm-io/aic", path); + + if (node < 0) { + printf("AIC node not found!\n"); + return; + } + + if (adt_get_reg(adt, path, "reg", 0, &aic_base, NULL)) { + printf("Failed to get AIC reg property!\n"); + return; + } + + printf("AIC registers @ 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)); + else + write32(aic_base + AIC_SW_CLR + MASK_REG(irq), MASK_BIT(irq)); +} diff --git a/src/aic.h b/src/aic.h new file mode 100644 index 00000000..d5ba5a98 --- /dev/null +++ b/src/aic.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef AIC_H +#define AIC_H + +#include "types.h" + +extern u64 aic_base; + +void aic_init(void); +void aic_set_sw(int irq, bool active); + +#endif diff --git a/src/aic_regs.h b/src/aic_regs.h new file mode 100644 index 00000000..e2c6ffc6 --- /dev/null +++ b/src/aic_regs.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: MIT */ + +#define AIC_INFO 0x0004 +#define AIC_WHOAMI 0x2000 +#define AIC_EVENT 0x2004 +#define AIC_IPI_SEND 0x2008 +#define AIC_IPI_ACK 0x200c +#define AIC_IPI_MASK_SET 0x2024 +#define AIC_IPI_MASK_CLR 0x2028 +#define AIC_TARGET_CPU 0x3000 +#define AIC_SW_SET 0x4000 +#define AIC_SW_CLR 0x4080 +#define AIC_MASK_SET 0x4100 +#define AIC_MASK_CLR 0x4180 + +#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)) +#define AIC_CPU_IPI_MASK_CLR(cpu) (0x5028 + ((cpu) << 7)) + +#define AIC_INFO_NR_HW GENMASK(15, 0) + +#define AIC_EVENT_TYPE GENMASK(31, 16) +#define AIC_EVENT_NUM GENMASK(15, 0) + +#define AIC_EVENT_TYPE_HW 1 +#define AIC_EVENT_TYPE_IPI 4 +#define AIC_EVENT_IPI_OTHER 1 +#define AIC_EVENT_IPI_SELF 2 + +#define AIC_IPI_SEND_CPU(cpu) BIT(cpu) + +#define AIC_IPI_OTHER BIT(0) +#define AIC_IPI_SELF BIT(31) + +#define AIC_MAX_HW_NUM (28 * 32) diff --git a/src/hv_aic.c b/src/hv_aic.c index 4ed3762c..7d0a676b 100644 --- a/src/hv_aic.c +++ b/src/hv_aic.c @@ -1,24 +1,11 @@ /* SPDX-License-Identifier: MIT */ #include "adt.h" +#include "aic_regs.h" #include "hv.h" #include "uartproxy.h" #include "utils.h" -#define AIC_INFO 0x0004 -#define AIC_INFO_NR_HW GENMASK(15, 0) - -#define AIC_EVENT 0x2004 -#define AIC_EVENT_TYPE GENMASK(31, 16) -#define AIC_EVENT_NUM GENMASK(15, 0) - -#define AIC_EVENT_TYPE_HW 1 -#define AIC_EVENT_TYPE_IPI 4 -#define AIC_EVENT_IPI_OTHER 1 -#define AIC_EVENT_IPI_SELF 2 - -#define AIC_MAX_HW_NUM (28 * 32) - #define IRQTRACE_IRQ BIT(0) static u64 aic_base; @@ -88,19 +75,8 @@ bool hv_trace_irq(u32 type, u32 num, u32 count, u32 flags) } if (!aic_base) { - static const char path[] = "/arm-io/aic"; - int adt_path[8]; - - int node = adt_path_offset_trace(adt, path, adt_path); - if (node < 0) { - printf("HV: Error getting %s node\n", path); - return false; - } - - if (adt_get_reg(adt, adt_path, "reg", 0, &aic_base, NULL) < 0) { - printf("HV: Error getting AIC base address.\n"); - return false; - } + printf("HV: AIC not initialized\n"); + return false; } static bool hooked = false; diff --git a/src/main.c b/src/main.c index fea85113..6b710c59 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include "../config.h" #include "adt.h" +#include "aic.h" #include "exception.h" #include "fb.h" #include "heapblock.h" @@ -85,6 +86,7 @@ void m1n1_main(void) #endif print_info(); + aic_init(); wdt_disable(); pmgr_init();