riscv_cpu_has_work() uses a handful of irq pending functions from cpu_helper.c. There is a very high possibility that KVM doesn't need the current implermentation of has_work(), but the common accel code needs an implementation of this callback (see cpu_exec_class_post_init) otherwise the KVM driver won't initialize.
Move the relevant irq helpers to cpu.c to allow KVM to keep using the current has_work implementation, allowing --disable-tcg to work. We'll circle it back to evaluate a proper KVM implementation for it in a later date. Signed-off-by: Daniel Henrique Barboza <[email protected]> --- target/riscv/cpu.c | 187 ++++++++++++++++++++++++++++++++++ target/riscv/cpu.h | 5 + target/riscv/tcg/cpu_helper.c | 187 ---------------------------------- 3 files changed, 192 insertions(+), 187 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 29af0f2be8..483ac2e0d0 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -738,6 +738,193 @@ static vaddr riscv_cpu_get_pc(CPUState *cs) } #ifndef CONFIG_USER_ONLY +/* + * Default priorities of local interrupts are defined in the + * RISC-V Advanced Interrupt Architecture specification. + * + * ---------------------------------------------------------------- + * Default | + * Priority | Major Interrupt Numbers + * ---------------------------------------------------------------- + * Highest | 47, 23, 46, 45, 22, 44, + * | 43, 21, 42, 41, 20, 40 + * | + * | 11 (0b), 3 (03), 7 (07) + * | 9 (09), 1 (01), 5 (05) + * | 12 (0c) + * | 10 (0a), 2 (02), 6 (06) + * | + * | 39, 19, 38, 37, 18, 36, + * Lowest | 35, 17, 34, 33, 16, 32 + * ---------------------------------------------------------------- + */ +static const uint8_t default_iprio[64] = { + /* Custom interrupts 48 to 63 */ + [63] = IPRIO_MMAXIPRIO, + [62] = IPRIO_MMAXIPRIO, + [61] = IPRIO_MMAXIPRIO, + [60] = IPRIO_MMAXIPRIO, + [59] = IPRIO_MMAXIPRIO, + [58] = IPRIO_MMAXIPRIO, + [57] = IPRIO_MMAXIPRIO, + [56] = IPRIO_MMAXIPRIO, + [55] = IPRIO_MMAXIPRIO, + [54] = IPRIO_MMAXIPRIO, + [53] = IPRIO_MMAXIPRIO, + [52] = IPRIO_MMAXIPRIO, + [51] = IPRIO_MMAXIPRIO, + [50] = IPRIO_MMAXIPRIO, + [49] = IPRIO_MMAXIPRIO, + [48] = IPRIO_MMAXIPRIO, + + /* Custom interrupts 24 to 31 */ + [31] = IPRIO_MMAXIPRIO, + [30] = IPRIO_MMAXIPRIO, + [29] = IPRIO_MMAXIPRIO, + [28] = IPRIO_MMAXIPRIO, + [27] = IPRIO_MMAXIPRIO, + [26] = IPRIO_MMAXIPRIO, + [25] = IPRIO_MMAXIPRIO, + [24] = IPRIO_MMAXIPRIO, + + [47] = IPRIO_DEFAULT_UPPER, + [23] = IPRIO_DEFAULT_UPPER + 1, + [46] = IPRIO_DEFAULT_UPPER + 2, + [45] = IPRIO_DEFAULT_UPPER + 3, + [22] = IPRIO_DEFAULT_UPPER + 4, + [44] = IPRIO_DEFAULT_UPPER + 5, + + [43] = IPRIO_DEFAULT_UPPER + 6, + [21] = IPRIO_DEFAULT_UPPER + 7, + [42] = IPRIO_DEFAULT_UPPER + 8, + [41] = IPRIO_DEFAULT_UPPER + 9, + [20] = IPRIO_DEFAULT_UPPER + 10, + [40] = IPRIO_DEFAULT_UPPER + 11, + + [11] = IPRIO_DEFAULT_M, + [3] = IPRIO_DEFAULT_M + 1, + [7] = IPRIO_DEFAULT_M + 2, + + [9] = IPRIO_DEFAULT_S, + [1] = IPRIO_DEFAULT_S + 1, + [5] = IPRIO_DEFAULT_S + 2, + + [12] = IPRIO_DEFAULT_SGEXT, + + [10] = IPRIO_DEFAULT_VS, + [2] = IPRIO_DEFAULT_VS + 1, + [6] = IPRIO_DEFAULT_VS + 2, + + [39] = IPRIO_DEFAULT_LOWER, + [19] = IPRIO_DEFAULT_LOWER + 1, + [38] = IPRIO_DEFAULT_LOWER + 2, + [37] = IPRIO_DEFAULT_LOWER + 3, + [18] = IPRIO_DEFAULT_LOWER + 4, + [36] = IPRIO_DEFAULT_LOWER + 5, + + [35] = IPRIO_DEFAULT_LOWER + 6, + [17] = IPRIO_DEFAULT_LOWER + 7, + [34] = IPRIO_DEFAULT_LOWER + 8, + [33] = IPRIO_DEFAULT_LOWER + 9, + [16] = IPRIO_DEFAULT_LOWER + 10, + [32] = IPRIO_DEFAULT_LOWER + 11, +}; + +uint8_t riscv_cpu_default_priority(int irq) +{ + if (irq < 0 || irq > 63) { + return IPRIO_MMAXIPRIO; + } + + return default_iprio[irq] ? default_iprio[irq] : IPRIO_MMAXIPRIO; +}; + +int riscv_cpu_pending_to_irq(CPURISCVState *env, + int extirq, unsigned int extirq_def_prio, + uint64_t pending, uint8_t *iprio) +{ + int irq, best_irq = RISCV_EXCP_NONE; + unsigned int prio, best_prio = UINT_MAX; + + if (!pending) { + return RISCV_EXCP_NONE; + } + + irq = ctz64(pending); + if (!((extirq == IRQ_M_EXT) ? riscv_cpu_cfg(env)->ext_smaia : + riscv_cpu_cfg(env)->ext_ssaia)) { + return irq; + } + + pending = pending >> irq; + while (pending) { + prio = iprio[irq]; + if (!prio) { + if (irq == extirq) { + prio = extirq_def_prio; + } else { + prio = (riscv_cpu_default_priority(irq) < extirq_def_prio) ? + 1 : IPRIO_MMAXIPRIO; + } + } + if ((pending & 0x1) && (prio <= best_prio)) { + best_irq = irq; + best_prio = prio; + } + irq++; + pending = pending >> 1; + } + + return best_irq; +} + +/* + * Doesn't report interrupts inserted using mvip from M-mode firmware or + * using hvip bits 13:63 from HS-mode. Those are returned in + * riscv_cpu_sirq_pending() and riscv_cpu_vsirq_pending(). + */ +uint64_t riscv_cpu_all_pending(CPURISCVState *env) +{ + uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN); + uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; + uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0; + + return (env->mip | vsgein | vstip) & env->mie; +} + +int riscv_cpu_mirq_pending(CPURISCVState *env) +{ + uint64_t irqs = riscv_cpu_all_pending(env) & ~env->mideleg & + ~(MIP_SGEIP | MIP_VSSIP | MIP_VSTIP | MIP_VSEIP); + + return riscv_cpu_pending_to_irq(env, IRQ_M_EXT, IPRIO_DEFAULT_M, + irqs, env->miprio); +} + +int riscv_cpu_sirq_pending(CPURISCVState *env) +{ + uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & ~env->hideleg; + uint64_t irqs_f = env->mvip & env->mvien & ~env->mideleg & env->sie; + + return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, + irqs | irqs_f, env->siprio); +} + +int riscv_cpu_vsirq_pending(CPURISCVState *env) +{ + uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & env->hideleg; + uint64_t irqs_f_vs = env->hvip & env->hvien & ~env->hideleg & env->vsie; + uint64_t vsbits; + + /* Bring VS-level bits to correct position */ + vsbits = irqs & VS_MODE_INTERRUPTS; + irqs &= ~VS_MODE_INTERRUPTS; + irqs |= vsbits >> 1; + + return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, + (irqs | irqs_f_vs), env->hviprio); +} + bool riscv_cpu_has_work(CPUState *cs) { RISCVCPU *cpu = RISCV_CPU(cs); diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 82430ecec6..396d9253e6 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -640,6 +640,11 @@ uint64_t riscv_cpu_all_pending(CPURISCVState *env); int riscv_cpu_mirq_pending(CPURISCVState *env); int riscv_cpu_sirq_pending(CPURISCVState *env); int riscv_cpu_vsirq_pending(CPURISCVState *env); +int riscv_cpu_pending_to_irq(CPURISCVState *env, + int extirq, unsigned int extirq_def_prio, + uint64_t pending, uint8_t *iprio); + + bool riscv_cpu_fp_enabled(CPURISCVState *env); uint8_t riscv_cpu_get_geilen(CPURISCVState *env); void riscv_cpu_set_geilen(CPURISCVState *env, uint8_t geilen); diff --git a/target/riscv/tcg/cpu_helper.c b/target/riscv/tcg/cpu_helper.c index 8c347aa1c0..b38f639dae 100644 --- a/target/riscv/tcg/cpu_helper.c +++ b/target/riscv/tcg/cpu_helper.c @@ -330,193 +330,6 @@ int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero) return 0; } -/* - * Default priorities of local interrupts are defined in the - * RISC-V Advanced Interrupt Architecture specification. - * - * ---------------------------------------------------------------- - * Default | - * Priority | Major Interrupt Numbers - * ---------------------------------------------------------------- - * Highest | 47, 23, 46, 45, 22, 44, - * | 43, 21, 42, 41, 20, 40 - * | - * | 11 (0b), 3 (03), 7 (07) - * | 9 (09), 1 (01), 5 (05) - * | 12 (0c) - * | 10 (0a), 2 (02), 6 (06) - * | - * | 39, 19, 38, 37, 18, 36, - * Lowest | 35, 17, 34, 33, 16, 32 - * ---------------------------------------------------------------- - */ -static const uint8_t default_iprio[64] = { - /* Custom interrupts 48 to 63 */ - [63] = IPRIO_MMAXIPRIO, - [62] = IPRIO_MMAXIPRIO, - [61] = IPRIO_MMAXIPRIO, - [60] = IPRIO_MMAXIPRIO, - [59] = IPRIO_MMAXIPRIO, - [58] = IPRIO_MMAXIPRIO, - [57] = IPRIO_MMAXIPRIO, - [56] = IPRIO_MMAXIPRIO, - [55] = IPRIO_MMAXIPRIO, - [54] = IPRIO_MMAXIPRIO, - [53] = IPRIO_MMAXIPRIO, - [52] = IPRIO_MMAXIPRIO, - [51] = IPRIO_MMAXIPRIO, - [50] = IPRIO_MMAXIPRIO, - [49] = IPRIO_MMAXIPRIO, - [48] = IPRIO_MMAXIPRIO, - - /* Custom interrupts 24 to 31 */ - [31] = IPRIO_MMAXIPRIO, - [30] = IPRIO_MMAXIPRIO, - [29] = IPRIO_MMAXIPRIO, - [28] = IPRIO_MMAXIPRIO, - [27] = IPRIO_MMAXIPRIO, - [26] = IPRIO_MMAXIPRIO, - [25] = IPRIO_MMAXIPRIO, - [24] = IPRIO_MMAXIPRIO, - - [47] = IPRIO_DEFAULT_UPPER, - [23] = IPRIO_DEFAULT_UPPER + 1, - [46] = IPRIO_DEFAULT_UPPER + 2, - [45] = IPRIO_DEFAULT_UPPER + 3, - [22] = IPRIO_DEFAULT_UPPER + 4, - [44] = IPRIO_DEFAULT_UPPER + 5, - - [43] = IPRIO_DEFAULT_UPPER + 6, - [21] = IPRIO_DEFAULT_UPPER + 7, - [42] = IPRIO_DEFAULT_UPPER + 8, - [41] = IPRIO_DEFAULT_UPPER + 9, - [20] = IPRIO_DEFAULT_UPPER + 10, - [40] = IPRIO_DEFAULT_UPPER + 11, - - [11] = IPRIO_DEFAULT_M, - [3] = IPRIO_DEFAULT_M + 1, - [7] = IPRIO_DEFAULT_M + 2, - - [9] = IPRIO_DEFAULT_S, - [1] = IPRIO_DEFAULT_S + 1, - [5] = IPRIO_DEFAULT_S + 2, - - [12] = IPRIO_DEFAULT_SGEXT, - - [10] = IPRIO_DEFAULT_VS, - [2] = IPRIO_DEFAULT_VS + 1, - [6] = IPRIO_DEFAULT_VS + 2, - - [39] = IPRIO_DEFAULT_LOWER, - [19] = IPRIO_DEFAULT_LOWER + 1, - [38] = IPRIO_DEFAULT_LOWER + 2, - [37] = IPRIO_DEFAULT_LOWER + 3, - [18] = IPRIO_DEFAULT_LOWER + 4, - [36] = IPRIO_DEFAULT_LOWER + 5, - - [35] = IPRIO_DEFAULT_LOWER + 6, - [17] = IPRIO_DEFAULT_LOWER + 7, - [34] = IPRIO_DEFAULT_LOWER + 8, - [33] = IPRIO_DEFAULT_LOWER + 9, - [16] = IPRIO_DEFAULT_LOWER + 10, - [32] = IPRIO_DEFAULT_LOWER + 11, -}; - -uint8_t riscv_cpu_default_priority(int irq) -{ - if (irq < 0 || irq > 63) { - return IPRIO_MMAXIPRIO; - } - - return default_iprio[irq] ? default_iprio[irq] : IPRIO_MMAXIPRIO; -}; - -static int riscv_cpu_pending_to_irq(CPURISCVState *env, - int extirq, unsigned int extirq_def_prio, - uint64_t pending, uint8_t *iprio) -{ - int irq, best_irq = RISCV_EXCP_NONE; - unsigned int prio, best_prio = UINT_MAX; - - if (!pending) { - return RISCV_EXCP_NONE; - } - - irq = ctz64(pending); - if (!((extirq == IRQ_M_EXT) ? riscv_cpu_cfg(env)->ext_smaia : - riscv_cpu_cfg(env)->ext_ssaia)) { - return irq; - } - - pending = pending >> irq; - while (pending) { - prio = iprio[irq]; - if (!prio) { - if (irq == extirq) { - prio = extirq_def_prio; - } else { - prio = (riscv_cpu_default_priority(irq) < extirq_def_prio) ? - 1 : IPRIO_MMAXIPRIO; - } - } - if ((pending & 0x1) && (prio <= best_prio)) { - best_irq = irq; - best_prio = prio; - } - irq++; - pending = pending >> 1; - } - - return best_irq; -} - -/* - * Doesn't report interrupts inserted using mvip from M-mode firmware or - * using hvip bits 13:63 from HS-mode. Those are returned in - * riscv_cpu_sirq_pending() and riscv_cpu_vsirq_pending(). - */ -uint64_t riscv_cpu_all_pending(CPURISCVState *env) -{ - uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN); - uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0; - uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0; - - return (env->mip | vsgein | vstip) & env->mie; -} - -int riscv_cpu_mirq_pending(CPURISCVState *env) -{ - uint64_t irqs = riscv_cpu_all_pending(env) & ~env->mideleg & - ~(MIP_SGEIP | MIP_VSSIP | MIP_VSTIP | MIP_VSEIP); - - return riscv_cpu_pending_to_irq(env, IRQ_M_EXT, IPRIO_DEFAULT_M, - irqs, env->miprio); -} - -int riscv_cpu_sirq_pending(CPURISCVState *env) -{ - uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & ~env->hideleg; - uint64_t irqs_f = env->mvip & env->mvien & ~env->mideleg & env->sie; - - return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, - irqs | irqs_f, env->siprio); -} - -int riscv_cpu_vsirq_pending(CPURISCVState *env) -{ - uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & env->hideleg; - uint64_t irqs_f_vs = env->hvip & env->hvien & ~env->hideleg & env->vsie; - uint64_t vsbits; - - /* Bring VS-level bits to correct position */ - vsbits = irqs & VS_MODE_INTERRUPTS; - irqs &= ~VS_MODE_INTERRUPTS; - irqs |= vsbits >> 1; - - return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S, - (irqs | irqs_f_vs), env->hviprio); -} - static int riscv_cpu_local_irq_pending(CPURISCVState *env) { uint64_t irqs, pending, mie, hsie, vsie, irqs_f, irqs_f_vs; -- 2.43.0
