aboutsummaryrefslogtreecommitdiff
path: root/target/loongarch/tcg/csr_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/loongarch/tcg/csr_helper.c')
-rw-r--r--target/loongarch/tcg/csr_helper.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/target/loongarch/tcg/csr_helper.c b/target/loongarch/tcg/csr_helper.c
index 2942d7f..5ebe15f 100644
--- a/target/loongarch/tcg/csr_helper.c
+++ b/target/loongarch/tcg/csr_helper.c
@@ -16,6 +16,7 @@
#include "accel/tcg/cpu-ldst.h"
#include "hw/irq.h"
#include "cpu-csr.h"
+#include "cpu-mmu.h"
target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val)
{
@@ -25,11 +26,16 @@ target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val)
* The real hardware only supports the min tlb_ps is 12
* tlb_ps=0 may cause undefined-behavior.
*/
- uint8_t tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
+ uint8_t tlb_ps = FIELD_EX64(val, CSR_STLBPS, PS);
if (!check_ps(env, tlb_ps)) {
qemu_log_mask(LOG_GUEST_ERROR,
"Attempted set ps %d\n", tlb_ps);
+ } else {
+ /* Only update PS field, reserved bit keeps zero */
+ val = FIELD_DP64(val, CSR_STLBPS, RESERVE, 0);
+ env->CSR_STLBPS = val;
}
+
return old_v;
}
@@ -68,6 +74,27 @@ target_ulong helper_csrrd_tval(CPULoongArchState *env)
return cpu_loongarch_get_constant_timer_ticks(cpu);
}
+target_ulong helper_csrrd_msgir(CPULoongArchState *env)
+{
+ int irq, new;
+
+ irq = find_first_bit((unsigned long *)env->CSR_MSGIS, 256);
+ if (irq < 256) {
+ clear_bit(irq, (unsigned long *)env->CSR_MSGIS);
+ new = find_first_bit((unsigned long *)env->CSR_MSGIS, 256);
+ if (new < 256) {
+ return irq;
+ }
+
+ env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 0);
+ } else {
+ /* bit 31 set 1 for no invalid irq */
+ irq = BIT(31);
+ }
+
+ return irq;
+}
+
target_ulong helper_csrwr_estat(CPULoongArchState *env, target_ulong val)
{
int64_t old_v = env->CSR_ESTAT;
@@ -131,8 +158,8 @@ target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val)
}
if (!check_ps(env, ptbase)) {
qemu_log_mask(LOG_GUEST_ERROR,
- "Attrmpted set ptbase 2^%d\n", ptbase);
+ "Attempted set ptbase 2^%d\n", ptbase);
}
- env->CSR_PWCL =val;
+ env->CSR_PWCL = val;
return old_v;
}