Skip to content

Commit 38adceb

Browse files
committed
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 <[email protected]> Reviewed-by: Bibo Mao <[email protected]>
1 parent cc4ba2c commit 38adceb

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

target/loongarch/helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ DEF_HELPER_2(csrwr_estat, i64, env, tl)
104104
DEF_HELPER_2(csrwr_asid, i64, env, tl)
105105
DEF_HELPER_2(csrwr_tcfg, i64, env, tl)
106106
DEF_HELPER_2(csrwr_ticlr, i64, env, tl)
107+
DEF_HELPER_2(csrwr_pwcl, i64, env, tl)
107108
DEF_HELPER_2(iocsrrd_b, i64, env, tl)
108109
DEF_HELPER_2(iocsrrd_h, i64, env, tl)
109110
DEF_HELPER_2(iocsrrd_w, i64, env, tl)

target/loongarch/tcg/csr_helper.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include "qemu/osdep.h"
9+
#include "qemu/log.h"
910
#include "qemu/main-loop.h"
1011
#include "cpu.h"
1112
#include "internals.h"
@@ -95,3 +96,23 @@ target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val)
9596
}
9697
return old_v;
9798
}
99+
100+
target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val)
101+
{
102+
int shift;
103+
int64_t old_v = env->CSR_PWCL;
104+
105+
/*
106+
* The real hardware only supports 64bit PTE width now, 128bit or others
107+
* treated as illegal.
108+
*/
109+
shift = FIELD_EX64(val, CSR_PWCL, PTEWIDTH);
110+
if (shift) {
111+
qemu_log_mask(LOG_GUEST_ERROR,
112+
"Attempted set pte width with %d bit\n", 64 << shift);
113+
val = FIELD_DP64(val, CSR_PWCL, PTEWIDTH, 0);
114+
}
115+
116+
env->CSR_PWCL = val;
117+
return old_v;
118+
}

target/loongarch/tcg/insn_trans/trans_privileged.c.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static const CSRInfo csr_info[] = {
9595
CSR_OFF(PGDL),
9696
CSR_OFF(PGDH),
9797
CSR_OFF_FUNCS(PGD, CSRFL_READONLY, gen_helper_csrrd_pgd, NULL),
98-
CSR_OFF(PWCL),
98+
CSR_OFF_FUNCS(PWCL, 0, NULL, gen_helper_csrwr_pwcl),
9999
CSR_OFF(PWCH),
100100
CSR_OFF(STLBPS),
101101
CSR_OFF(RVACFG),

target/loongarch/tcg/tlb_helper.c

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,6 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
512512
{
513513
CPUState *cs = env_cpu(env);
514514
target_ulong badvaddr, index, phys, ret;
515-
int shift;
516515
uint64_t dir_base, dir_width;
517516

518517
if (unlikely((level == 0) || (level > 4))) {
@@ -537,14 +536,9 @@ target_ulong helper_lddir(CPULoongArchState *env, target_ulong base,
537536

538537
badvaddr = env->CSR_TLBRBADV;
539538
base = base & TARGET_PHYS_MASK;
540-
541-
/* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
542-
shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
543-
shift = (shift + 1) * 3;
544-
545539
get_dir_base_width(env, &dir_base, &dir_width, level);
546540
index = (badvaddr >> dir_base) & ((1 << dir_width) - 1);
547-
phys = base | index << shift;
541+
phys = base | index << 3;
548542
ret = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK;
549543
return ret;
550544
}
@@ -554,7 +548,6 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
554548
{
555549
CPUState *cs = env_cpu(env);
556550
target_ulong phys, tmp0, ptindex, ptoffset0, ptoffset1, ps, badv;
557-
int shift;
558551
uint64_t ptbase = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE);
559552
uint64_t ptwidth = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH);
560553
uint64_t dir_base, dir_width;
@@ -595,16 +588,12 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
595588
tmp0 += MAKE_64BIT_MASK(ps, 1);
596589
}
597590
} else {
598-
/* 0:64bit, 1:128bit, 2:192bit, 3:256bit */
599-
shift = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTEWIDTH);
600-
shift = (shift + 1) * 3;
601591
badv = env->CSR_TLBRBADV;
602592

603593
ptindex = (badv >> ptbase) & ((1 << ptwidth) - 1);
604594
ptindex = ptindex & ~0x1; /* clear bit 0 */
605-
ptoffset0 = ptindex << shift;
606-
ptoffset1 = (ptindex + 1) << shift;
607-
595+
ptoffset0 = ptindex << 3;
596+
ptoffset1 = (ptindex + 1) << 3;
608597
phys = base | (odd ? ptoffset1 : ptoffset0);
609598
tmp0 = ldq_phys(cs->as, phys) & TARGET_PHYS_MASK;
610599
ps = ptbase;

0 commit comments

Comments
 (0)