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


Reply via email to