DEF_HELPER_2(csrwr_asid, i64, env, tl)
DEF_HELPER_2(csrwr_tcfg, i64, env, tl)
DEF_HELPER_2(csrwr_ticlr, i64, env, tl)
+DEF_HELPER_2(csrwr_pwcl, i64, env, tl)
DEF_HELPER_2(iocsrrd_b, i64, env, tl)
DEF_HELPER_2(iocsrrd_h, i64, env, tl)
DEF_HELPER_2(iocsrrd_w, i64, env, tl)
*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "cpu.h"
#include "internals.h"
}
return old_v;
}
+
+target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val)
+{
+ int shift;
+ int64_t old_v = env->CSR_PWCL;
+
+ /*
+ * The real hardware only supports 64bit PTE width now, 128bit or others
+ * treated as illegal.
+ */
+ shift = FIELD_EX64(val, CSR_PWCL, PTEWIDTH);
+ if (shift) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Attempted set pte width with %d bit\n", 64 << shift);
+ val = FIELD_DP64(val, CSR_PWCL, PTEWIDTH, 0);
+ }
+
+ env->CSR_PWCL = val;
+ return old_v;
+}
{
CPUState *cs = env_cpu(env);
target_ulong badvaddr, index, phys, ret;
- int shift;
uint64_t dir_base, dir_width;
if (unlikely((level == 0) || (level > 4))) {
badvaddr = env->CSR_TLBRBADV;
base = base & TARGET_PHYS_MASK;
-
- /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
- shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
- shift = (shift + 1) * 3;
-
get_dir_base_width(env, &dir_base, &dir_width, level);
index = (badvaddr >> dir_base) & ((1 << dir_width) - 1);
- phys = base | index << shift;
+ phys = base | index << 3;
ret = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK;
return ret;
}
{
CPUState *cs = env_cpu(env);
target_ulong phys, tmp0, ptindex, ptoffset0, ptoffset1, ps, badv;
- int shift;
uint64_t ptbase = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE);
uint64_t ptwidth = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH);
uint64_t dir_base, dir_width;
tmp0 += MAKE_64BIT_MASK(ps, 1);
}
} else {
- /* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
- shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
- shift = (shift + 1) * 3;
badv = env->CSR_TLBRBADV;
ptindex = (badv >> ptbase) & ((1 << ptwidth) - 1);
ptindex = ptindex & ~0x1; /* clear bit 0 */
- ptoffset0 = ptindex << shift;
- ptoffset1 = (ptindex + 1) << shift;
-
+ ptoffset0 = ptindex << 3;
+ ptoffset1 = (ptindex + 1) << 3;
phys = base | (odd ? ptoffset1 : ptoffset0);
tmp0 = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK;
ps = ptbase;