target/loongarch: Only support 64bit pte width

iFrom LoongArch Reference Manual pte width can be 64bit, 128bit
or more. Instead real hardware only supports 64bit pte width.
For 12bit pte, there is no detail definition for all 128bit
from manual.

Here only 64bit pte width is supported for simplicity, will add
this in later if real hw support it and there is definition for
all the bits from manual.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
This commit is contained in:
Bibo Mao 2024-12-31 18:07:18 +08:00
parent cc4ba2c2d2
commit 38adceb4c3
4 changed files with 26 additions and 15 deletions

View File

@ -104,6 +104,7 @@ DEF_HELPER_2(csrwr_estat, i64, env, tl)
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)

View File

@ -6,6 +6,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "cpu.h"
#include "internals.h"
@ -95,3 +96,23 @@ target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val)
}
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;
}

View File

@ -95,7 +95,7 @@ static const CSRInfo csr_info[] = {
CSR_OFF(PGDL),
CSR_OFF(PGDH),
CSR_OFF_FUNCS(PGD, CSRFL_READONLY, gen_helper_csrrd_pgd, NULL),
CSR_OFF(PWCL),
CSR_OFF_FUNCS(PWCL, 0, NULL, gen_helper_csrwr_pwcl),
CSR_OFF(PWCH),
CSR_OFF(STLBPS),
CSR_OFF(RVACFG),

View File

@ -512,7 +512,6 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
{
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))) {
@ -537,14 +536,9 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
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;
}
@ -554,7 +548,6 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
{
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;
@ -595,16 +588,12 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
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;