@samitouri / QOSamiQemu / commits / e49b1e25fa

target/riscv: move some irq helpers to cpu.c

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 <daniel.barboza@oss.qualcomm.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260703180538.3346781-14-daniel.barboza@oss.qualcomm.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Daniel Henrique Barboza committed Jul 3, 2026 at 15:05 UTC e49b1e25fabd937c172c5acbe00e30b0e2e9ed4b
3 files changed +192 -187
target/riscv/cpu.c
+187
@@ -745,6 +745,193 @@ static vaddr riscv_cpu_get_pc(CPUState *cs)
745 }
746
747 #ifndef CONFIG_USER_ONLY
748 +/*
749 + * Default priorities of local interrupts are defined in the
750 + * RISC-V Advanced Interrupt Architecture specification.
751 + *
752 + * ----------------------------------------------------------------
753 + * Default |
754 + * Priority | Major Interrupt Numbers
755 + * ----------------------------------------------------------------
756 + * Highest | 47, 23, 46, 45, 22, 44,
757 + * | 43, 21, 42, 41, 20, 40
758 + * |
759 + * | 11 (0b), 3 (03), 7 (07)
760 + * | 9 (09), 1 (01), 5 (05)
761 + * | 12 (0c)
762 + * | 10 (0a), 2 (02), 6 (06)
763 + * |
764 + * | 39, 19, 38, 37, 18, 36,
765 + * Lowest | 35, 17, 34, 33, 16, 32
766 + * ----------------------------------------------------------------
767 + */
768 +static const uint8_t default_iprio[64] = {
769 + /* Custom interrupts 48 to 63 */
770 + [63] = IPRIO_MMAXIPRIO,
771 + [62] = IPRIO_MMAXIPRIO,
772 + [61] = IPRIO_MMAXIPRIO,
773 + [60] = IPRIO_MMAXIPRIO,
774 + [59] = IPRIO_MMAXIPRIO,
775 + [58] = IPRIO_MMAXIPRIO,
776 + [57] = IPRIO_MMAXIPRIO,
777 + [56] = IPRIO_MMAXIPRIO,
778 + [55] = IPRIO_MMAXIPRIO,
779 + [54] = IPRIO_MMAXIPRIO,
780 + [53] = IPRIO_MMAXIPRIO,
781 + [52] = IPRIO_MMAXIPRIO,
782 + [51] = IPRIO_MMAXIPRIO,
783 + [50] = IPRIO_MMAXIPRIO,
784 + [49] = IPRIO_MMAXIPRIO,
785 + [48] = IPRIO_MMAXIPRIO,
786 +
787 + /* Custom interrupts 24 to 31 */
788 + [31] = IPRIO_MMAXIPRIO,
789 + [30] = IPRIO_MMAXIPRIO,
790 + [29] = IPRIO_MMAXIPRIO,
791 + [28] = IPRIO_MMAXIPRIO,
792 + [27] = IPRIO_MMAXIPRIO,
793 + [26] = IPRIO_MMAXIPRIO,
794 + [25] = IPRIO_MMAXIPRIO,
795 + [24] = IPRIO_MMAXIPRIO,
796 +
797 + [47] = IPRIO_DEFAULT_UPPER,
798 + [23] = IPRIO_DEFAULT_UPPER + 1,
799 + [46] = IPRIO_DEFAULT_UPPER + 2,
800 + [45] = IPRIO_DEFAULT_UPPER + 3,
801 + [22] = IPRIO_DEFAULT_UPPER + 4,
802 + [44] = IPRIO_DEFAULT_UPPER + 5,
803 +
804 + [43] = IPRIO_DEFAULT_UPPER + 6,
805 + [21] = IPRIO_DEFAULT_UPPER + 7,
806 + [42] = IPRIO_DEFAULT_UPPER + 8,
807 + [41] = IPRIO_DEFAULT_UPPER + 9,
808 + [20] = IPRIO_DEFAULT_UPPER + 10,
809 + [40] = IPRIO_DEFAULT_UPPER + 11,
810 +
811 + [11] = IPRIO_DEFAULT_M,
812 + [3] = IPRIO_DEFAULT_M + 1,
813 + [7] = IPRIO_DEFAULT_M + 2,
814 +
815 + [9] = IPRIO_DEFAULT_S,
816 + [1] = IPRIO_DEFAULT_S + 1,
817 + [5] = IPRIO_DEFAULT_S + 2,
818 +
819 + [12] = IPRIO_DEFAULT_SGEXT,
820 +
821 + [10] = IPRIO_DEFAULT_VS,
822 + [2] = IPRIO_DEFAULT_VS + 1,
823 + [6] = IPRIO_DEFAULT_VS + 2,
824 +
825 + [39] = IPRIO_DEFAULT_LOWER,
826 + [19] = IPRIO_DEFAULT_LOWER + 1,
827 + [38] = IPRIO_DEFAULT_LOWER + 2,
828 + [37] = IPRIO_DEFAULT_LOWER + 3,
829 + [18] = IPRIO_DEFAULT_LOWER + 4,
830 + [36] = IPRIO_DEFAULT_LOWER + 5,
831 +
832 + [35] = IPRIO_DEFAULT_LOWER + 6,
833 + [17] = IPRIO_DEFAULT_LOWER + 7,
834 + [34] = IPRIO_DEFAULT_LOWER + 8,
835 + [33] = IPRIO_DEFAULT_LOWER + 9,
836 + [16] = IPRIO_DEFAULT_LOWER + 10,
837 + [32] = IPRIO_DEFAULT_LOWER + 11,
838 +};
839 +
840 +uint8_t riscv_cpu_default_priority(int irq)
841 +{
842 + if (irq < 0 || irq > 63) {
843 + return IPRIO_MMAXIPRIO;
844 + }
845 +
846 + return default_iprio[irq] ? default_iprio[irq] : IPRIO_MMAXIPRIO;
847 +};
848 +
849 +int riscv_cpu_pending_to_irq(CPURISCVState *env,
850 + int extirq, unsigned int extirq_def_prio,
851 + uint64_t pending, uint8_t *iprio)
852 +{
853 + int irq, best_irq = RISCV_EXCP_NONE;
854 + unsigned int prio, best_prio = UINT_MAX;
855 +
856 + if (!pending) {
857 + return RISCV_EXCP_NONE;
858 + }
859 +
860 + irq = ctz64(pending);
861 + if (!((extirq == IRQ_M_EXT) ? riscv_cpu_cfg(env)->ext_smaia :
862 + riscv_cpu_cfg(env)->ext_ssaia)) {
863 + return irq;
864 + }
865 +
866 + pending = pending >> irq;
867 + while (pending) {
868 + prio = iprio[irq];
869 + if (!prio) {
870 + if (irq == extirq) {
871 + prio = extirq_def_prio;
872 + } else {
873 + prio = (riscv_cpu_default_priority(irq) < extirq_def_prio) ?
874 + 1 : IPRIO_MMAXIPRIO;
875 + }
876 + }
877 + if ((pending & 0x1) && (prio <= best_prio)) {
878 + best_irq = irq;
879 + best_prio = prio;
880 + }
881 + irq++;
882 + pending = pending >> 1;
883 + }
884 +
885 + return best_irq;
886 +}
887 +
888 +/*
889 + * Doesn't report interrupts inserted using mvip from M-mode firmware or
890 + * using hvip bits 13:63 from HS-mode. Those are returned in
891 + * riscv_cpu_sirq_pending() and riscv_cpu_vsirq_pending().
892 + */
893 +uint64_t riscv_cpu_all_pending(CPURISCVState *env)
894 +{
895 + uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
896 + uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
897 + uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
898 +
899 + return (env->mip | vsgein | vstip) & env->mie;
900 +}
901 +
902 +int riscv_cpu_mirq_pending(CPURISCVState *env)
903 +{
904 + uint64_t irqs = riscv_cpu_all_pending(env) & ~env->mideleg &
905 + ~(MIP_SGEIP | MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
906 +
907 + return riscv_cpu_pending_to_irq(env, IRQ_M_EXT, IPRIO_DEFAULT_M,
908 + irqs, env->miprio);
909 +}
910 +
911 +int riscv_cpu_sirq_pending(CPURISCVState *env)
912 +{
913 + uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & ~env->hideleg;
914 + uint64_t irqs_f = env->mvip & env->mvien & ~env->mideleg & env->sie;
915 +
916 + return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S,
917 + irqs | irqs_f, env->siprio);
918 +}
919 +
920 +int riscv_cpu_vsirq_pending(CPURISCVState *env)
921 +{
922 + uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & env->hideleg;
923 + uint64_t irqs_f_vs = env->hvip & env->hvien & ~env->hideleg & env->vsie;
924 + uint64_t vsbits;
925 +
926 + /* Bring VS-level bits to correct position */
927 + vsbits = irqs & VS_MODE_INTERRUPTS;
928 + irqs &= ~VS_MODE_INTERRUPTS;
929 + irqs |= vsbits >> 1;
930 +
931 + return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S,
932 + (irqs | irqs_f_vs), env->hviprio);
933 +}
934 +
935 bool riscv_cpu_has_work(CPUState *cs)
936 {
937 RISCVCPU *cpu = RISCV_CPU(cs);
target/riscv/cpu.h
+5
@@ -640,6 +640,11 @@ uint64_t riscv_cpu_all_pending(CPURISCVState *env);
640 int riscv_cpu_mirq_pending(CPURISCVState *env);
641 int riscv_cpu_sirq_pending(CPURISCVState *env);
642 int riscv_cpu_vsirq_pending(CPURISCVState *env);
643 +int riscv_cpu_pending_to_irq(CPURISCVState *env,
644 + int extirq, unsigned int extirq_def_prio,
645 + uint64_t pending, uint8_t *iprio);
646 +
647 +
648 bool riscv_cpu_fp_enabled(CPURISCVState *env);
649 uint8_t riscv_cpu_get_geilen(CPURISCVState *env);
650 void riscv_cpu_set_geilen(CPURISCVState *env, uint8_t geilen);
target/riscv/tcg/cpu_helper.c
-187
@@ -330,193 +330,6 @@ int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero)
330 return 0;
331 }
332
333 -/*
334 - * Default priorities of local interrupts are defined in the
335 - * RISC-V Advanced Interrupt Architecture specification.
336 - *
337 - * ----------------------------------------------------------------
338 - * Default |
339 - * Priority | Major Interrupt Numbers
340 - * ----------------------------------------------------------------
341 - * Highest | 47, 23, 46, 45, 22, 44,
342 - * | 43, 21, 42, 41, 20, 40
343 - * |
344 - * | 11 (0b), 3 (03), 7 (07)
345 - * | 9 (09), 1 (01), 5 (05)
346 - * | 12 (0c)
347 - * | 10 (0a), 2 (02), 6 (06)
348 - * |
349 - * | 39, 19, 38, 37, 18, 36,
350 - * Lowest | 35, 17, 34, 33, 16, 32
351 - * ----------------------------------------------------------------
352 - */
353 -static const uint8_t default_iprio[64] = {
354 - /* Custom interrupts 48 to 63 */
355 - [63] = IPRIO_MMAXIPRIO,
356 - [62] = IPRIO_MMAXIPRIO,
357 - [61] = IPRIO_MMAXIPRIO,
358 - [60] = IPRIO_MMAXIPRIO,
359 - [59] = IPRIO_MMAXIPRIO,
360 - [58] = IPRIO_MMAXIPRIO,
361 - [57] = IPRIO_MMAXIPRIO,
362 - [56] = IPRIO_MMAXIPRIO,
363 - [55] = IPRIO_MMAXIPRIO,
364 - [54] = IPRIO_MMAXIPRIO,
365 - [53] = IPRIO_MMAXIPRIO,
366 - [52] = IPRIO_MMAXIPRIO,
367 - [51] = IPRIO_MMAXIPRIO,
368 - [50] = IPRIO_MMAXIPRIO,
369 - [49] = IPRIO_MMAXIPRIO,
370 - [48] = IPRIO_MMAXIPRIO,
371 -
372 - /* Custom interrupts 24 to 31 */
373 - [31] = IPRIO_MMAXIPRIO,
374 - [30] = IPRIO_MMAXIPRIO,
375 - [29] = IPRIO_MMAXIPRIO,
376 - [28] = IPRIO_MMAXIPRIO,
377 - [27] = IPRIO_MMAXIPRIO,
378 - [26] = IPRIO_MMAXIPRIO,
379 - [25] = IPRIO_MMAXIPRIO,
380 - [24] = IPRIO_MMAXIPRIO,
381 -
382 - [47] = IPRIO_DEFAULT_UPPER,
383 - [23] = IPRIO_DEFAULT_UPPER + 1,
384 - [46] = IPRIO_DEFAULT_UPPER + 2,
385 - [45] = IPRIO_DEFAULT_UPPER + 3,
386 - [22] = IPRIO_DEFAULT_UPPER + 4,
387 - [44] = IPRIO_DEFAULT_UPPER + 5,
388 -
389 - [43] = IPRIO_DEFAULT_UPPER + 6,
390 - [21] = IPRIO_DEFAULT_UPPER + 7,
391 - [42] = IPRIO_DEFAULT_UPPER + 8,
392 - [41] = IPRIO_DEFAULT_UPPER + 9,
393 - [20] = IPRIO_DEFAULT_UPPER + 10,
394 - [40] = IPRIO_DEFAULT_UPPER + 11,
395 -
396 - [11] = IPRIO_DEFAULT_M,
397 - [3] = IPRIO_DEFAULT_M + 1,
398 - [7] = IPRIO_DEFAULT_M + 2,
399 -
400 - [9] = IPRIO_DEFAULT_S,
401 - [1] = IPRIO_DEFAULT_S + 1,
402 - [5] = IPRIO_DEFAULT_S + 2,
403 -
404 - [12] = IPRIO_DEFAULT_SGEXT,
405 -
406 - [10] = IPRIO_DEFAULT_VS,
407 - [2] = IPRIO_DEFAULT_VS + 1,
408 - [6] = IPRIO_DEFAULT_VS + 2,
409 -
410 - [39] = IPRIO_DEFAULT_LOWER,
411 - [19] = IPRIO_DEFAULT_LOWER + 1,
412 - [38] = IPRIO_DEFAULT_LOWER + 2,
413 - [37] = IPRIO_DEFAULT_LOWER + 3,
414 - [18] = IPRIO_DEFAULT_LOWER + 4,
415 - [36] = IPRIO_DEFAULT_LOWER + 5,
416 -
417 - [35] = IPRIO_DEFAULT_LOWER + 6,
418 - [17] = IPRIO_DEFAULT_LOWER + 7,
419 - [34] = IPRIO_DEFAULT_LOWER + 8,
420 - [33] = IPRIO_DEFAULT_LOWER + 9,
421 - [16] = IPRIO_DEFAULT_LOWER + 10,
422 - [32] = IPRIO_DEFAULT_LOWER + 11,
423 -};
424 -
425 -uint8_t riscv_cpu_default_priority(int irq)
426 -{
427 - if (irq < 0 || irq > 63) {
428 - return IPRIO_MMAXIPRIO;
429 - }
430 -
431 - return default_iprio[irq] ? default_iprio[irq] : IPRIO_MMAXIPRIO;
432 -};
433 -
434 -static int riscv_cpu_pending_to_irq(CPURISCVState *env,
435 - int extirq, unsigned int extirq_def_prio,
436 - uint64_t pending, uint8_t *iprio)
437 -{
438 - int irq, best_irq = RISCV_EXCP_NONE;
439 - unsigned int prio, best_prio = UINT_MAX;
440 -
441 - if (!pending) {
442 - return RISCV_EXCP_NONE;
443 - }
444 -
445 - irq = ctz64(pending);
446 - if (!((extirq == IRQ_M_EXT) ? riscv_cpu_cfg(env)->ext_smaia :
447 - riscv_cpu_cfg(env)->ext_ssaia)) {
448 - return irq;
449 - }
450 -
451 - pending = pending >> irq;
452 - while (pending) {
453 - prio = iprio[irq];
454 - if (!prio) {
455 - if (irq == extirq) {
456 - prio = extirq_def_prio;
457 - } else {
458 - prio = (riscv_cpu_default_priority(irq) < extirq_def_prio) ?
459 - 1 : IPRIO_MMAXIPRIO;
460 - }
461 - }
462 - if ((pending & 0x1) && (prio <= best_prio)) {
463 - best_irq = irq;
464 - best_prio = prio;
465 - }
466 - irq++;
467 - pending = pending >> 1;
468 - }
469 -
470 - return best_irq;
471 -}
472 -
473 -/*
474 - * Doesn't report interrupts inserted using mvip from M-mode firmware or
475 - * using hvip bits 13:63 from HS-mode. Those are returned in
476 - * riscv_cpu_sirq_pending() and riscv_cpu_vsirq_pending().
477 - */
478 -uint64_t riscv_cpu_all_pending(CPURISCVState *env)
479 -{
480 - uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
481 - uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
482 - uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
483 -
484 - return (env->mip | vsgein | vstip) & env->mie;
485 -}
486 -
487 -int riscv_cpu_mirq_pending(CPURISCVState *env)
488 -{
489 - uint64_t irqs = riscv_cpu_all_pending(env) & ~env->mideleg &
490 - ~(MIP_SGEIP | MIP_VSSIP | MIP_VSTIP | MIP_VSEIP);
491 -
492 - return riscv_cpu_pending_to_irq(env, IRQ_M_EXT, IPRIO_DEFAULT_M,
493 - irqs, env->miprio);
494 -}
495 -
496 -int riscv_cpu_sirq_pending(CPURISCVState *env)
497 -{
498 - uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & ~env->hideleg;
499 - uint64_t irqs_f = env->mvip & env->mvien & ~env->mideleg & env->sie;
500 -
501 - return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S,
502 - irqs | irqs_f, env->siprio);
503 -}
504 -
505 -int riscv_cpu_vsirq_pending(CPURISCVState *env)
506 -{
507 - uint64_t irqs = riscv_cpu_all_pending(env) & env->mideleg & env->hideleg;
508 - uint64_t irqs_f_vs = env->hvip & env->hvien & ~env->hideleg & env->vsie;
509 - uint64_t vsbits;
510 -
511 - /* Bring VS-level bits to correct position */
512 - vsbits = irqs & VS_MODE_INTERRUPTS;
513 - irqs &= ~VS_MODE_INTERRUPTS;
514 - irqs |= vsbits >> 1;
515 -
516 - return riscv_cpu_pending_to_irq(env, IRQ_S_EXT, IPRIO_DEFAULT_S,
517 - (irqs | irqs_f_vs), env->hviprio);
518 -}
519 -
333 static int riscv_cpu_local_irq_pending(CPURISCVState *env)
334 {
335 uint64_t irqs, pending, mie, hsie, vsie, irqs_f, irqs_f_vs;