@samitouri / QOSamiQemu / commits / ce969fa50b

target/loongarch: Use sys_state in cpu.c when accessing CSR registers

When accessing CSR register in file cpu.c, use sys_state rather than env. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Philippe Mathieu-Daudé <philmd@mailo.com> Tested-by: Song Gao <gaosong@loongson.cn> Message-ID: <20260605082552.175336-3-maobibo@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn>

Bibo Mao committed Jun 5, 2026 at 16:25 UTC ce969fa50bf6edd7888a8b4cd383f13355ba9f1e
2 files changed +63 -56
target/loongarch/cpu.c
+60 -54
@@ -62,6 +62,7 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
62 LoongArchCPU *cpu = opaque;
63 CPULoongArchState *env = &cpu->env;
64 CPUState *cs = CPU(cpu);
65 + CPUSysState *sys = env_sys(env);
66
67 if (irq < 0 || irq >= N_IRQS) {
68 return;
@@ -70,8 +71,8 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
71 if (kvm_enabled()) {
72 kvm_loongarch_set_interrupt(cpu, irq, level);
73 } else if (tcg_enabled()) {
73 - env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
74 - if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
74 + sys->CSR_ESTAT = deposit64(sys->CSR_ESTAT, irq, 1, level != 0);
75 + if (FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS)) {
76 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
77 } else {
78 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
@@ -84,9 +85,10 @@ bool cpu_loongarch_hw_interrupts_pending(CPULoongArchState *env)
85 {
86 uint32_t pending;
87 uint32_t status;
88 + CPUSysState *sys = env_sys(env);
89
88 - pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS);
89 - status = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE);
90 + pending = FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS);
91 + status = FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, LIE);
92
93 return (pending & status) != 0;
94 }
@@ -112,11 +114,12 @@ static void loongarch_la464_init_csr(DeviceState *dev)
114 static bool initialized;
115 LoongArchCPU *cpu = LOONGARCH_CPU(dev);
116 CPULoongArchState *env = &cpu->env;
117 + CPUSysState *sys = env_sys(env);
118 int i, num;
119
120 if (!initialized) {
121 initialized = true;
119 - num = FIELD_EX64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM);
122 + num = FIELD_EX64(sys->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM);
123 for (i = num; i < 16; i++) {
124 set_csr_flag(LOONGARCH_CSR_SAVE(i), CSRFL_UNUSED);
125 }
@@ -275,6 +278,7 @@ static void loongarch_la464_initfn(Object *obj)
278 {
279 LoongArchCPU *cpu = LOONGARCH_CPU(obj);
280 CPULoongArchState *env = &cpu->env;
281 + CPUSysState *sys;
282 uint32_t data = 0, field;
283 int i;
284
@@ -382,18 +386,19 @@ static void loongarch_la464_initfn(Object *obj)
386 data = FIELD_DP32(data, CPUCFG20, L3IU_SIZE, 6);
387 env->cpucfg[20] = data;
388
385 - env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
389 + sys = env_sys(env);
390 + sys->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
391
387 - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8);
388 - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f);
389 - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7);
392 + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8);
393 + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f);
394 + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7);
395
391 - env->CSR_PRCFG2 = 0x3ffff000;
396 + sys->CSR_PRCFG2 = 0x3ffff000;
397
393 - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2);
394 - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63);
395 - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7);
396 - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8);
398 + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2);
399 + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63);
400 + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7);
401 + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8);
402
403 cpu->msgint = ON_OFF_AUTO_OFF;
404 cpu->ptw = ON_OFF_AUTO_OFF;
@@ -595,6 +600,7 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
600 CPUState *cs = CPU(obj);
601 LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(obj);
602 CPULoongArchState *env = cpu_env(cs);
603 + CPUSysState *sys = env_sys(env);
604
605 if (lacc->parent_phases.hold) {
606 lacc->parent_phases.hold(obj, type);
@@ -618,55 +624,55 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
624
625 int n;
626 /* Set csr registers value after reset, see the manual 6.4. */
621 - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0);
622 - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0);
623 - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1);
624 - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0);
625 - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATF, 0);
626 - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 0);
627 -
628 - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, FPE, 0);
629 - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, SXE, 0);
630 - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, ASXE, 0);
631 - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, BTE, 0);
632 -
633 - env->CSR_MISC = 0;
634 -
635 - env->CSR_ECFG = FIELD_DP64(env->CSR_ECFG, CSR_ECFG, VS, 0);
636 - env->CSR_ECFG = FIELD_DP64(env->CSR_ECFG, CSR_ECFG, LIE, 0);
637 -
638 - env->CSR_ESTAT = env->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2));
639 - env->CSR_RVACFG = FIELD_DP64(env->CSR_RVACFG, CSR_RVACFG, RBITS, 0);
640 - env->CSR_CPUID = cs->cpu_index;
641 - env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0);
642 - env->CSR_LLBCTL = FIELD_DP64(env->CSR_LLBCTL, CSR_LLBCTL, KLO, 0);
643 - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0);
644 - env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
645 - env->CSR_TID = cs->cpu_index;
627 + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, 0);
628 + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, 0);
629 + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 1);
630 + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 0);
631 + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DATF, 0);
632 + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DATM, 0);
633 +
634 + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, FPE, 0);
635 + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, SXE, 0);
636 + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, ASXE, 0);
637 + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, BTE, 0);
638 +
639 + sys->CSR_MISC = 0;
640 +
641 + sys->CSR_ECFG = FIELD_DP64(sys->CSR_ECFG, CSR_ECFG, VS, 0);
642 + sys->CSR_ECFG = FIELD_DP64(sys->CSR_ECFG, CSR_ECFG, LIE, 0);
643 +
644 + sys->CSR_ESTAT = sys->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2));
645 + sys->CSR_RVACFG = FIELD_DP64(sys->CSR_RVACFG, CSR_RVACFG, RBITS, 0);
646 + sys->CSR_CPUID = cs->cpu_index;
647 + sys->CSR_TCFG = FIELD_DP64(sys->CSR_TCFG, CSR_TCFG, EN, 0);
648 + sys->CSR_LLBCTL = FIELD_DP64(sys->CSR_LLBCTL, CSR_LLBCTL, KLO, 0);
649 + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0);
650 + sys->CSR_MERRCTL = FIELD_DP64(sys->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
651 + sys->CSR_TID = cs->cpu_index;
652 /*
653 * Workaround for edk2-stable202408, CSR PGD register is set only if
654 * its value is equal to zero for boot cpu, it causes reboot issue.
655 *
656 * Here clear CSR registers relative with TLB.
657 */
652 - env->CSR_PGDH = 0;
653 - env->CSR_PGDL = 0;
654 - env->CSR_PWCH = 0;
655 - env->CSR_EENTRY = 0;
656 - env->CSR_TLBRENTRY = 0;
657 - env->CSR_MERRENTRY = 0;
658 + sys->CSR_PGDH = 0;
659 + sys->CSR_PGDL = 0;
660 + sys->CSR_PWCH = 0;
661 + sys->CSR_EENTRY = 0;
662 + sys->CSR_TLBRENTRY = 0;
663 + sys->CSR_MERRENTRY = 0;
664 /* set CSR_PWCL.PTBASE and CSR_STLBPS.PS bits from CSR_PRCFG2 */
659 - if (env->CSR_PRCFG2 == 0) {
660 - env->CSR_PRCFG2 = 0x3fffff000;
665 + if (sys->CSR_PRCFG2 == 0) {
666 + sys->CSR_PRCFG2 = 0x3fffff000;
667 }
662 - tlb_ps = ctz32(env->CSR_PRCFG2);
663 - env->CSR_STLBPS = FIELD_DP64(env->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps);
664 - env->CSR_PWCL = FIELD_DP64(env->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps);
668 + tlb_ps = ctz32(sys->CSR_PRCFG2);
669 + sys->CSR_STLBPS = FIELD_DP64(sys->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps);
670 + sys->CSR_PWCL = FIELD_DP64(sys->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps);
671 for (n = 0; n < 4; n++) {
666 - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0);
667 - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0);
668 - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV2, 0);
669 - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV3, 0);
672 + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV0, 0);
673 + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV1, 0);
674 + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV2, 0);
675 + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV3, 0);
676 }
677
678 #ifndef CONFIG_USER_ONLY
target/loongarch/cpu.h
+3 -2
@@ -503,8 +503,9 @@ static inline bool is_va32(CPULoongArchState *env)
503 {
504 /* VA32 if !LA64 or VA32L[1-3] */
505 bool va32 = !is_la64(env);
506 - uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV);
507 - if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) {
506 + CPUSysState *sys = env_sys(env);
507 + uint64_t plv = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV);
508 + if (plv >= 1 && (FIELD_EX64(sys->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) {
509 va32 = true;
510 }
511 return va32;