Add gstat, gtlbc and gintc definitions and corresponding helpers.
Signed-off-by: SignKirigami <[email protected]>
Signed-off-by: Hengyu Yu <[email protected]>
---
target/loongarch/tcg/csr_helper.c | 53 +++++++++++++++++++
target/loongarch/tcg/helper.h | 3 ++
.../tcg/insn_trans/trans_privileged.c.inc | 3 ++
3 files changed, 59 insertions(+)
diff --git a/target/loongarch/tcg/csr_helper.c
b/target/loongarch/tcg/csr_helper.c
index 7ef0032f5d..f113097046 100644
--- a/target/loongarch/tcg/csr_helper.c
+++ b/target/loongarch/tcg/csr_helper.c
@@ -217,3 +217,56 @@ target_ulong helper_csrwr_pwch(CPULoongArchState *env,
sys->CSR_PWCH = val;
return old_v;
}
+
+target_ulong helper_csrwr_gstat(CPULoongArchState *env,
+ target_ulong val, uint32_t vm_level)
+{
+ CPUSysState *sys = get_sys(env, VM_LEVEL0);
+ int64_t old_v = sys->CSR_GSTAT;
+ uint8_t old_gid = FIELD_EX64(sys->CSR_GSTAT, CSR_GSTAT, GID);
+
+ sys->CSR_GSTAT = FIELD_DP64(sys->CSR_GSTAT, CSR_GSTAT, PVM,
+ FIELD_EX64(val, CSR_GSTAT, PVM));
+ sys->CSR_GSTAT = FIELD_DP64(sys->CSR_GSTAT, CSR_GSTAT, GID,
+ FIELD_EX64(val, CSR_GSTAT, GID));
+
+ if (old_gid != FIELD_EX64(sys->CSR_GSTAT, CSR_GSTAT, GID)) {
+ tlb_flush(env_cpu(env));
+ }
+
+ return old_v;
+}
+
+target_ulong helper_csrwr_gtlbc(CPULoongArchState *env,
+ target_ulong val, uint32_t vm_level)
+{
+ CPUSysState *sys = get_sys(env, VM_LEVEL0);
+ int64_t old_v = sys->CSR_GTLBC;
+ uint8_t old_use_tgid = FIELD_EX64(old_v, CSR_GTLBC, USETGID);
+ uint8_t old_tgid = FIELD_EX64(old_v, CSR_GTLBC, TGID);
+
+ sys->CSR_GTLBC = val;
+ if (old_use_tgid != FIELD_EX64(sys->CSR_GTLBC, CSR_GTLBC, USETGID) ||
+ old_tgid != FIELD_EX64(sys->CSR_GTLBC, CSR_GTLBC, TGID)) {
+ tlb_flush(env_cpu(env));
+ }
+
+ return old_v;
+}
+
+target_ulong helper_csrwr_gintc(CPULoongArchState *env,
+ target_ulong val, uint32_t vm_level)
+{
+ CPUSysState *host = get_sys(env, VM_LEVEL0);
+ CPUSysState *guest = get_sys(env, VM_LEVEL1);
+ int64_t old_v = host->CSR_GINTC;
+ uint8_t hwis = FIELD_EX64(val, CSR_GINTC, HWIS);
+ /* TODO: hwip and hwic support */
+
+ host->CSR_GINTC = val & 0xffff00;
+ guest->CSR_ESTAT = deposit64(guest->CSR_ESTAT, 2, 8,
+ hwis);
+
+ return old_v;
+}
+
diff --git a/target/loongarch/tcg/helper.h b/target/loongarch/tcg/helper.h
index bce5f46dc2..84eaee208c 100644
--- a/target/loongarch/tcg/helper.h
+++ b/target/loongarch/tcg/helper.h
@@ -104,6 +104,9 @@ DEF_HELPER_3(csrwr_tcfg, i64, env, tl, i32)
DEF_HELPER_3(csrwr_ticlr, i64, env, tl, i32)
DEF_HELPER_3(csrwr_pwcl, i64, env, tl, i32)
DEF_HELPER_3(csrwr_pwch, i64, env, tl, i32)
+DEF_HELPER_3(csrwr_gstat, i64, env, tl, i32)
+DEF_HELPER_3(csrwr_gtlbc, i64, env, tl, i32)
+DEF_HELPER_3(csrwr_gintc, i64, env, tl, i32)
DEF_HELPER_2(iocsrrd_b, i64, env, tl)
DEF_HELPER_2(iocsrrd_h, i64, env, tl)
DEF_HELPER_2(iocsrrd_w, i64, env, tl)
diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
index 139dbd6e2a..37b7ef13dc 100644
--- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
@@ -88,6 +88,9 @@ void loongarch_csr_translate_init(void)
SET_CSR_FUNC(TVAL, gen_helper_csrrd_tval, NULL);
SET_CSR_FUNC(TICLR, NULL, gen_helper_csrwr_ticlr);
SET_CSR_FUNC(MSGIR, gen_helper_csrrd_msgir, NULL);
+ SET_CSR_FUNC(GSTAT, NULL, gen_helper_csrwr_gstat);
+ SET_CSR_FUNC(GTLBC, NULL, gen_helper_csrwr_gtlbc);
+ SET_CSR_FUNC(GINTC, NULL, gen_helper_csrwr_gintc);
}
#undef SET_CSR_FUNC
--
2.55.0