target/loongarch: Add function sptw_prepare_tlb before adding tlb entry

With software page table walker, tlb entry comes from CSR registers.
however with hardware page table walker, tlb entry comes from page
table entry information directly, TLB CSR registers are not necessary.

Here add function sptw_prepare_context(), get tlb entry information
from TLB CSR registers.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Song Gao <gaosong@loongson.cn>
This commit is contained in:
Bibo Mao 2025-09-30 09:43:56 +08:00
parent 7b7c6fae9b
commit 261612da4e
2 changed files with 22 additions and 2 deletions

View file

@ -25,6 +25,7 @@ typedef struct MMUContext {
hwaddr physical;
int ps; /* page size shift */
int prot;
uint64_t pte_buddy[2];
} MMUContext;
static inline bool cpu_has_ptw(CPULoongArchState *env)

View file

@ -159,10 +159,10 @@ static void invalidate_tlb(CPULoongArchState *env, int index)
invalidate_tlb_entry(env, index);
}
static void fill_tlb_entry(CPULoongArchState *env, LoongArchTLB *tlb)
/* Prepare tlb entry information in software PTW mode */
static void sptw_prepare_context(CPULoongArchState *env, MMUContext *context)
{
uint64_t lo0, lo1, csr_vppn;
uint16_t csr_asid;
uint8_t csr_ps;
if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
@ -185,6 +185,25 @@ static void fill_tlb_entry(CPULoongArchState *env, LoongArchTLB *tlb)
lo1 = env->CSR_TLBELO1;
}
context->ps = csr_ps;
context->addr = csr_vppn << R_TLB_MISC_VPPN_SHIFT;
context->pte_buddy[0] = lo0;
context->pte_buddy[1] = lo1;
}
static void fill_tlb_entry(CPULoongArchState *env, LoongArchTLB *tlb)
{
uint64_t lo0, lo1, csr_vppn;
uint16_t csr_asid;
uint8_t csr_ps;
MMUContext context;
sptw_prepare_context(env, &context);
csr_vppn = context.addr >> R_TLB_MISC_VPPN_SHIFT;
csr_ps = context.ps;
lo0 = context.pte_buddy[0];
lo1 = context.pte_buddy[1];
/* 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);