aboutsummaryrefslogtreecommitdiff
path: root/target/loongarch/tcg
diff options
context:
space:
mode:
Diffstat (limited to 'target/loongarch/tcg')
-rw-r--r--target/loongarch/tcg/csr_helper.c1
-rw-r--r--target/loongarch/tcg/insn_trans/trans_atomic.c.inc36
-rw-r--r--target/loongarch/tcg/insn_trans/trans_extra.c.inc8
-rw-r--r--target/loongarch/tcg/insn_trans/trans_farith.c.inc8
-rw-r--r--target/loongarch/tcg/insn_trans/trans_fcnv.c.inc4
-rw-r--r--target/loongarch/tcg/insn_trans/trans_fmemory.c.inc16
-rw-r--r--target/loongarch/tcg/insn_trans/trans_privileged.c.inc4
-rw-r--r--target/loongarch/tcg/insn_trans/trans_shift.c.inc4
-rw-r--r--target/loongarch/tcg/insn_trans/trans_vec.c.inc6
-rw-r--r--target/loongarch/tcg/tcg_loongarch.h7
-rw-r--r--target/loongarch/tcg/tlb_helper.c144
11 files changed, 88 insertions, 150 deletions
diff --git a/target/loongarch/tcg/csr_helper.c b/target/loongarch/tcg/csr_helper.c
index 28b1bb8..0d99e2c 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)
{
diff --git a/target/loongarch/tcg/insn_trans/trans_atomic.c.inc b/target/loongarch/tcg/insn_trans/trans_atomic.c.inc
index 3d70d75..77eeedb 100644
--- a/target/loongarch/tcg/insn_trans/trans_atomic.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_atomic.c.inc
@@ -74,38 +74,38 @@ TRANS(sc_w, ALL, gen_sc, MO_TESL)
TRANS(ll_d, 64, gen_ll, MO_TEUQ)
TRANS(sc_d, 64, gen_sc, MO_TEUQ)
TRANS(amswap_w, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
-TRANS(amswap_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
+TRANS64(amswap_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
TRANS(amadd_w, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
-TRANS(amadd_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
+TRANS64(amadd_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
TRANS(amand_w, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
-TRANS(amand_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
+TRANS64(amand_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
TRANS(amor_w, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
-TRANS(amor_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
+TRANS64(amor_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
TRANS(amxor_w, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
-TRANS(amxor_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
+TRANS64(amxor_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
TRANS(ammax_w, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
-TRANS(ammax_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
+TRANS64(ammax_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
TRANS(ammin_w, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
-TRANS(ammin_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
+TRANS64(ammin_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
TRANS(ammax_wu, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
-TRANS(ammax_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
+TRANS64(ammax_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
TRANS(ammin_wu, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
-TRANS(ammin_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
+TRANS64(ammin_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
TRANS(amswap_db_w, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
-TRANS(amswap_db_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
+TRANS64(amswap_db_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
TRANS(amadd_db_w, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
-TRANS(amadd_db_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
+TRANS64(amadd_db_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
TRANS(amand_db_w, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
-TRANS(amand_db_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
+TRANS64(amand_db_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
TRANS(amor_db_w, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
-TRANS(amor_db_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
+TRANS64(amor_db_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
TRANS(amxor_db_w, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
-TRANS(amxor_db_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
+TRANS64(amxor_db_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
TRANS(ammax_db_w, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
-TRANS(ammax_db_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
+TRANS64(ammax_db_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
TRANS(ammin_db_w, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
-TRANS(ammin_db_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
+TRANS64(ammin_db_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
TRANS(ammax_db_wu, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
-TRANS(ammax_db_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
+TRANS64(ammax_db_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
TRANS(ammin_db_wu, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
-TRANS(ammin_db_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
+TRANS64(ammin_db_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
diff --git a/target/loongarch/tcg/insn_trans/trans_extra.c.inc b/target/loongarch/tcg/insn_trans/trans_extra.c.inc
index eda3d6e..298a80c 100644
--- a/target/loongarch/tcg/insn_trans/trans_extra.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_extra.c.inc
@@ -69,6 +69,10 @@ static bool trans_rdtimeh_w(DisasContext *ctx, arg_rdtimeh_w *a)
static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a)
{
+ if (!avail_64(ctx)) {
+ return false;
+ }
+
return gen_rdtime(ctx, a, 0, 0);
}
@@ -100,8 +104,8 @@ static bool gen_crc(DisasContext *ctx, arg_rrr *a,
TRANS(crc_w_b_w, CRC, gen_crc, gen_helper_crc32, tcg_constant_tl(1))
TRANS(crc_w_h_w, CRC, gen_crc, gen_helper_crc32, tcg_constant_tl(2))
TRANS(crc_w_w_w, CRC, gen_crc, gen_helper_crc32, tcg_constant_tl(4))
-TRANS(crc_w_d_w, CRC, gen_crc, gen_helper_crc32, tcg_constant_tl(8))
+TRANS64(crc_w_d_w, CRC, gen_crc, gen_helper_crc32, tcg_constant_tl(8))
TRANS(crcc_w_b_w, CRC, gen_crc, gen_helper_crc32c, tcg_constant_tl(1))
TRANS(crcc_w_h_w, CRC, gen_crc, gen_helper_crc32c, tcg_constant_tl(2))
TRANS(crcc_w_w_w, CRC, gen_crc, gen_helper_crc32c, tcg_constant_tl(4))
-TRANS(crcc_w_d_w, CRC, gen_crc, gen_helper_crc32c, tcg_constant_tl(8))
+TRANS64(crcc_w_d_w, CRC, gen_crc, gen_helper_crc32c, tcg_constant_tl(8))
diff --git a/target/loongarch/tcg/insn_trans/trans_farith.c.inc b/target/loongarch/tcg/insn_trans/trans_farith.c.inc
index f4a0dea..ff6cf34 100644
--- a/target/loongarch/tcg/insn_trans/trans_farith.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_farith.c.inc
@@ -183,16 +183,16 @@ TRANS(fmaxa_s, FP_SP, gen_fff, gen_helper_fmaxa_s)
TRANS(fmaxa_d, FP_DP, gen_fff, gen_helper_fmaxa_d)
TRANS(fmina_s, FP_SP, gen_fff, gen_helper_fmina_s)
TRANS(fmina_d, FP_DP, gen_fff, gen_helper_fmina_d)
-TRANS(fscaleb_s, FP_SP, gen_fff, gen_helper_fscaleb_s)
-TRANS(fscaleb_d, FP_DP, gen_fff, gen_helper_fscaleb_d)
+TRANS64(fscaleb_s, FP_SP, gen_fff, gen_helper_fscaleb_s)
+TRANS64(fscaleb_d, FP_DP, gen_fff, gen_helper_fscaleb_d)
TRANS(fsqrt_s, FP_SP, gen_ff, gen_helper_fsqrt_s)
TRANS(fsqrt_d, FP_DP, gen_ff, gen_helper_fsqrt_d)
TRANS(frecip_s, FP_SP, gen_ff, gen_helper_frecip_s)
TRANS(frecip_d, FP_DP, gen_ff, gen_helper_frecip_d)
TRANS(frsqrt_s, FP_SP, gen_ff, gen_helper_frsqrt_s)
TRANS(frsqrt_d, FP_DP, gen_ff, gen_helper_frsqrt_d)
-TRANS(flogb_s, FP_SP, gen_ff, gen_helper_flogb_s)
-TRANS(flogb_d, FP_DP, gen_ff, gen_helper_flogb_d)
+TRANS64(flogb_s, FP_SP, gen_ff, gen_helper_flogb_s)
+TRANS64(flogb_d, FP_DP, gen_ff, gen_helper_flogb_d)
TRANS(fclass_s, FP_SP, gen_ff, gen_helper_fclass_s)
TRANS(fclass_d, FP_DP, gen_ff, gen_helper_fclass_d)
TRANS(fmadd_s, FP_SP, gen_muladd, gen_helper_fmuladd_s, 0)
diff --git a/target/loongarch/tcg/insn_trans/trans_fcnv.c.inc b/target/loongarch/tcg/insn_trans/trans_fcnv.c.inc
index 833c059..ca1d76a 100644
--- a/target/loongarch/tcg/insn_trans/trans_fcnv.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_fcnv.c.inc
@@ -29,5 +29,5 @@ TRANS(ffint_s_w, FP_SP, gen_ff, gen_helper_ffint_s_w)
TRANS(ffint_s_l, FP_SP, gen_ff, gen_helper_ffint_s_l)
TRANS(ffint_d_w, FP_DP, gen_ff, gen_helper_ffint_d_w)
TRANS(ffint_d_l, FP_DP, gen_ff, gen_helper_ffint_d_l)
-TRANS(frint_s, FP_SP, gen_ff, gen_helper_frint_s)
-TRANS(frint_d, FP_DP, gen_ff, gen_helper_frint_d)
+TRANS64(frint_s, FP_SP, gen_ff, gen_helper_frint_s)
+TRANS64(frint_d, FP_DP, gen_ff, gen_helper_frint_d)
diff --git a/target/loongarch/tcg/insn_trans/trans_fmemory.c.inc b/target/loongarch/tcg/insn_trans/trans_fmemory.c.inc
index 13452bc..79da471 100644
--- a/target/loongarch/tcg/insn_trans/trans_fmemory.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_fmemory.c.inc
@@ -148,11 +148,11 @@ TRANS(fldx_s, FP_SP, gen_floadx, MO_TEUL)
TRANS(fldx_d, FP_DP, gen_floadx, MO_TEUQ)
TRANS(fstx_s, FP_SP, gen_fstorex, MO_TEUL)
TRANS(fstx_d, FP_DP, gen_fstorex, MO_TEUQ)
-TRANS(fldgt_s, FP_SP, gen_fload_gt, MO_TEUL)
-TRANS(fldgt_d, FP_DP, gen_fload_gt, MO_TEUQ)
-TRANS(fldle_s, FP_SP, gen_fload_le, MO_TEUL)
-TRANS(fldle_d, FP_DP, gen_fload_le, MO_TEUQ)
-TRANS(fstgt_s, FP_SP, gen_fstore_gt, MO_TEUL)
-TRANS(fstgt_d, FP_DP, gen_fstore_gt, MO_TEUQ)
-TRANS(fstle_s, FP_SP, gen_fstore_le, MO_TEUL)
-TRANS(fstle_d, FP_DP, gen_fstore_le, MO_TEUQ)
+TRANS64(fldgt_s, FP_SP, gen_fload_gt, MO_TEUL)
+TRANS64(fldgt_d, FP_DP, gen_fload_gt, MO_TEUQ)
+TRANS64(fldle_s, FP_SP, gen_fload_le, MO_TEUL)
+TRANS64(fldle_d, FP_DP, gen_fload_le, MO_TEUQ)
+TRANS64(fstgt_s, FP_SP, gen_fstore_gt, MO_TEUL)
+TRANS64(fstgt_d, FP_DP, gen_fstore_gt, MO_TEUQ)
+TRANS64(fstle_s, FP_SP, gen_fstore_le, MO_TEUL)
+TRANS64(fstle_d, FP_DP, gen_fstore_le, MO_TEUQ)
diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
index ecbfe23..34cfab8 100644
--- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
@@ -233,11 +233,11 @@ static bool gen_iocsrwr(DisasContext *ctx, arg_rr *a,
TRANS(iocsrrd_b, IOCSR, gen_iocsrrd, gen_helper_iocsrrd_b)
TRANS(iocsrrd_h, IOCSR, gen_iocsrrd, gen_helper_iocsrrd_h)
TRANS(iocsrrd_w, IOCSR, gen_iocsrrd, gen_helper_iocsrrd_w)
-TRANS(iocsrrd_d, IOCSR, gen_iocsrrd, gen_helper_iocsrrd_d)
+TRANS64(iocsrrd_d, IOCSR, gen_iocsrrd, gen_helper_iocsrrd_d)
TRANS(iocsrwr_b, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_b)
TRANS(iocsrwr_h, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_h)
TRANS(iocsrwr_w, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_w)
-TRANS(iocsrwr_d, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_d)
+TRANS64(iocsrwr_d, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_d)
static void check_mmu_idx(DisasContext *ctx)
{
diff --git a/target/loongarch/tcg/insn_trans/trans_shift.c.inc b/target/loongarch/tcg/insn_trans/trans_shift.c.inc
index 3773077..136c4c8 100644
--- a/target/loongarch/tcg/insn_trans/trans_shift.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_shift.c.inc
@@ -78,7 +78,7 @@ TRANS(sra_w, ALL, gen_rrr, EXT_SIGN, EXT_NONE, EXT_SIGN, gen_sra_w)
TRANS(sll_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sll_d)
TRANS(srl_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_srl_d)
TRANS(sra_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sra_d)
-TRANS(rotr_w, 64, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_rotr_w)
+TRANS(rotr_w, ALL, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_rotr_w)
TRANS(rotr_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rotr_d)
TRANS(slli_w, ALL, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_shli_tl)
TRANS(slli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shli_tl)
@@ -86,5 +86,5 @@ TRANS(srli_w, ALL, gen_rri_c, EXT_ZERO, EXT_SIGN, tcg_gen_shri_tl)
TRANS(srli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shri_tl)
TRANS(srai_w, ALL, gen_rri_c, EXT_NONE, EXT_NONE, gen_sari_w)
TRANS(srai_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_sari_tl)
-TRANS(rotri_w, 64, gen_rri_v, EXT_NONE, EXT_NONE, gen_rotr_w)
+TRANS(rotri_w, ALL, gen_rri_v, EXT_NONE, EXT_NONE, gen_rotr_w)
TRANS(rotri_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_rotri_tl)
diff --git a/target/loongarch/tcg/insn_trans/trans_vec.c.inc b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
index 7873002..38bccf2 100644
--- a/target/loongarch/tcg/insn_trans/trans_vec.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_vec.c.inc
@@ -3585,7 +3585,9 @@ static bool gen_vldi(DisasContext *ctx, arg_vldi *a, uint32_t oprsz)
int sel, vece;
uint64_t value;
- if (!check_valid_vldi_mode(a)) {
+ sel = (a->imm >> 12) & 0x1;
+
+ if (sel && !check_valid_vldi_mode(a)) {
generate_exception(ctx, EXCCODE_INE);
return true;
}
@@ -3594,8 +3596,6 @@ static bool gen_vldi(DisasContext *ctx, arg_vldi *a, uint32_t oprsz)
return true;
}
- sel = (a->imm >> 12) & 0x1;
-
if (sel) {
value = vldi_get_value(ctx, a->imm);
vece = MO_64;
diff --git a/target/loongarch/tcg/tcg_loongarch.h b/target/loongarch/tcg/tcg_loongarch.h
index fd4e116..4770289 100644
--- a/target/loongarch/tcg/tcg_loongarch.h
+++ b/target/loongarch/tcg/tcg_loongarch.h
@@ -7,6 +7,7 @@
#ifndef TARGET_LOONGARCH_TCG_LOONGARCH_H
#define TARGET_LOONGARCH_TCG_LOONGARCH_H
#include "cpu.h"
+#include "cpu-mmu.h"
void loongarch_csr_translate_init(void);
@@ -14,8 +15,8 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
-int loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- MMUAccessType access_type, int mmu_idx);
+TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env,
+ MMUContext *context,
+ MMUAccessType access_type, int mmu_idx);
#endif /* TARGET_LOONGARCH_TCG_LOONGARCH_H */
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 8872593..9365860 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -10,6 +10,7 @@
#include "qemu/guest-random.h"
#include "cpu.h"
+#include "cpu-mmu.h"
#include "internals.h"
#include "exec/helper-proto.h"
#include "exec/cputlb.h"
@@ -28,8 +29,8 @@ bool check_ps(CPULoongArchState *env, uint8_t tlb_ps)
return BIT_ULL(tlb_ps) & (env->CSR_PRCFG2);
}
-static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
- MMUAccessType access_type, int tlb_error)
+static void raise_mmu_exception(CPULoongArchState *env, vaddr address,
+ MMUAccessType access_type, TLBRet tlb_error)
{
CPUState *cs = env_cpu(env);
@@ -110,23 +111,20 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
if (!tlb_e) {
return;
}
- if (index >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
pagesize = MAKE_64BIT_MASK(tlb_ps, 1);
mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
+ addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & ~mask;
+ addr = sextract64(addr, 0, TARGET_VIRT_ADDR_SPACE_BITS);
if (tlb_v0) {
- addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & ~mask; /* even */
tlb_flush_range_by_mmuidx(env_cpu(env), addr, pagesize,
mmu_idx, TARGET_LONG_BITS);
}
if (tlb_v1) {
- addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & pagesize; /* odd */
- tlb_flush_range_by_mmuidx(env_cpu(env), addr, pagesize,
+ tlb_flush_range_by_mmuidx(env_cpu(env), addr + pagesize, pagesize,
mmu_idx, TARGET_LONG_BITS);
}
}
@@ -173,11 +171,8 @@ static void fill_tlb_entry(CPULoongArchState *env, int index)
lo1 = env->CSR_TLBELO1;
}
- /* Only MTLB has the ps fields */
- if (index >= LOONGARCH_STLB) {
- tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps);
- }
-
+ /* Store page size in field PS */
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps);
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, VPPN, csr_vppn);
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 1);
csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
@@ -203,7 +198,7 @@ static uint32_t get_random_tlb(uint32_t low, uint32_t high)
* field in tlb entry contains bit[47:13], so need adjust.
* virt_vpn = vaddr[47:13]
*/
-static bool loongarch_tlb_search(CPULoongArchState *env, target_ulong vaddr,
+static bool loongarch_tlb_search(CPULoongArchState *env, vaddr vaddr,
int *index)
{
LoongArchTLB *tlb;
@@ -283,12 +278,7 @@ void helper_tlbrd(CPULoongArchState *env)
index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX);
tlb = &env->tlb[index];
-
- if (index >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
if (!tlb_e) {
@@ -476,11 +466,8 @@ void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info,
if (!tlb_e) {
continue;
}
- if (i >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
@@ -509,11 +496,8 @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
if (!tlb_e) {
continue;
}
- if (i >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
@@ -533,13 +517,15 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
CPULoongArchState *env = cpu_env(cs);
hwaddr physical;
int prot;
- int ret;
+ MMUContext context;
+ TLBRet ret;
/* Data access */
- ret = get_physical_address(env, &physical, &prot, address,
- access_type, mmu_idx, 0);
-
+ context.addr = address;
+ ret = get_physical_address(env, &context, access_type, mmu_idx, 0);
if (ret == TLBRET_MATCH) {
+ physical = context.physical;
+ prot = context.prot;
tlb_set_page(cs, address & TARGET_PAGE_MASK,
physical & TARGET_PAGE_MASK, prot,
mmu_idx, TARGET_PAGE_SIZE);
@@ -664,85 +650,31 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, PS, ps);
}
-static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- int access_type, int index, int mmu_idx)
+static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env,
+ MMUContext *context,
+ MMUAccessType access_type, int index,
+ int mmu_idx)
{
LoongArchTLB *tlb = &env->tlb[index];
- uint64_t plv = mmu_idx;
- uint64_t tlb_entry, tlb_ppn;
- uint8_t tlb_ps, n, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv;
-
- if (index >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
- n = (address >> tlb_ps) & 0x1;/* Odd or even */
-
- tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
- tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V);
- tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D);
- tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV);
- if (is_la64(env)) {
- tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN);
- tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX);
- tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR);
- tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV);
- } else {
- tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN);
- tlb_nx = 0;
- tlb_nr = 0;
- tlb_rplv = 0;
- }
-
- /* Remove sw bit between bit12 -- bit PS*/
- tlb_ppn = tlb_ppn & ~(((0x1UL << (tlb_ps - 12)) - 1));
-
- /* Check access rights */
- if (!tlb_v) {
- return TLBRET_INVALID;
- }
+ uint8_t tlb_ps, n;
- if (access_type == MMU_INST_FETCH && tlb_nx) {
- return TLBRET_XI;
- }
-
- if (access_type == MMU_DATA_LOAD && tlb_nr) {
- return TLBRET_RI;
- }
-
- if (((tlb_rplv == 0) && (plv > tlb_plv)) ||
- ((tlb_rplv == 1) && (plv != tlb_plv))) {
- return TLBRET_PE;
- }
-
- if ((access_type == MMU_DATA_STORE) && !tlb_d) {
- return TLBRET_DIRTY;
- }
-
- *physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
- (address & MAKE_64BIT_MASK(0, tlb_ps));
- *prot = PAGE_READ;
- if (tlb_d) {
- *prot |= PAGE_WRITE;
- }
- if (!tlb_nx) {
- *prot |= PAGE_EXEC;
- }
- return TLBRET_MATCH;
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
+ n = (context->addr >> tlb_ps) & 0x1;/* Odd or even */
+ context->pte = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
+ context->ps = tlb_ps;
+ return loongarch_check_pte(env, context, access_type, mmu_idx);
}
-int loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- MMUAccessType access_type, int mmu_idx)
+TLBRet loongarch_get_addr_from_tlb(CPULoongArchState *env,
+ MMUContext *context,
+ MMUAccessType access_type, int mmu_idx)
{
int index, match;
- match = loongarch_tlb_search(env, address, &index);
+ match = loongarch_tlb_search(env, context->addr, &index);
if (match) {
- return loongarch_map_tlb_entry(env, physical, prot,
- address, access_type, index, mmu_idx);
+ return loongarch_map_tlb_entry(env, context, access_type, index,
+ mmu_idx);
}
return TLBRET_NOMATCH;