IRQ_LOCAL_GUEST_MAX depends on TARGET_LONG_BITS and is used in hw/intc/riscv_imsic.c. The macro is replaced by a field in RISCVCPUDef initialized in riscv_cpu_class_base_init().
Reviewed-by: Pierrick Bouvier <[email protected]> Signed-off-by: Anton Johansson <[email protected]> --- target/riscv/cpu.h | 1 + target/riscv/cpu_bits.h | 2 -- hw/intc/riscv_imsic.c | 4 +++- target/riscv/cpu.c | 14 ++++++++++++-- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 946665d9ed..3573581f0c 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -563,6 +563,7 @@ typedef struct RISCVCPUDef { int32_t vext_spec; RISCVCPUConfig cfg; bool bare; + uint8_t irq_local_guest_max; const RISCVCSR *custom_csrs; } RISCVCPUDef; diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index b62dd82fe7..13e052bce2 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -809,8 +809,6 @@ typedef enum RISCVException { #define IRQ_S_GEXT 12 #define IRQ_PMU_OVF 13 #define IRQ_LOCAL_MAX 64 -/* -1 is due to bit zero of hgeip and hgeie being ROZ. */ -#define IRQ_LOCAL_GUEST_MAX (TARGET_LONG_BITS - 1) /* RNMI causes */ #define RNMI_MAX 16 diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c index 9274a1e842..3d32198468 100644 --- a/hw/intc/riscv_imsic.c +++ b/hw/intc/riscv_imsic.c @@ -453,13 +453,15 @@ DeviceState *riscv_imsic_create(hwaddr addr, uint32_t hartid, bool mmode, { DeviceState *dev = qdev_new(TYPE_RISCV_IMSIC); CPUState *cpu = cpu_by_arch_id(hartid); + RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(RISCV_CPU(cpu)); uint32_t i; assert(!(addr & (IMSIC_MMIO_PAGE_SZ - 1))); if (mmode) { assert(num_pages == 1); } else { - assert(num_pages >= 1 && num_pages <= (IRQ_LOCAL_GUEST_MAX + 1)); + assert(num_pages >= 1 && + num_pages <= (mcc->def->irq_local_guest_max + 1)); } assert(IMSIC_MIN_ID <= num_ids); assert(num_ids <= IMSIC_MAX_ID); diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 7a8b8d736e..dd58e63ecd 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1019,6 +1019,7 @@ void riscv_add_satp_mode_properties(Object *obj) static void riscv_cpu_set_irq(void *opaque, int irq, int level) { + RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(opaque); RISCVCPU *cpu = RISCV_CPU(opaque); CPURISCVState *env = &cpu->env; @@ -1053,7 +1054,7 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level) default: g_assert_not_reached(); } - } else if (irq < (IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX)) { + } else if (irq < (IRQ_LOCAL_MAX + mcc->def->irq_local_guest_max)) { /* Require H-extension for handling guest local interrupts */ if (!riscv_has_ext(env, RVH)) { g_assert_not_reached(); @@ -1100,7 +1101,7 @@ static void riscv_cpu_init(Object *obj) #ifndef CONFIG_USER_ONLY qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq, - IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX); + IRQ_LOCAL_MAX + mcc->def->irq_local_guest_max); qdev_init_gpio_in_named(DEVICE(cpu), riscv_cpu_set_nmi, "riscv.cpu.rnmi", RNMI_MAX); #endif /* CONFIG_USER_ONLY */ @@ -2791,6 +2792,15 @@ static void riscv_cpu_class_base_init(ObjectClass *c, const void *data) mcc->def = g_new0(RISCVCPUDef, 1); } + /* + * RISCVCPUDef::irq_local_guest_max is initialized to + * `target_long_bits()-1` due to bit zero of hgeip and hgeie + * being ROZ. + * + * This value does not vary between CPU types. + */ + mcc->def->irq_local_guest_max = target_long_bits() - 1; + if (data) { const RISCVCPUDef *def = data; mcc->def->bare |= def->bare; -- 2.51.0
