target/nios2: Use hw/registerfields.h for CR_TLBMISC fields

Use FIELD_EX32 and FIELD_DP32 instead of managing the
masking by hand.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220421151735.31996-30-richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2022-04-21 08:17:00 -07:00
parent 8036281527
commit 17c20fe3c8
4 changed files with 39 additions and 34 deletions

View File

@ -131,16 +131,25 @@ FIELD(CR_TLBACC, IG, 25, 7)
#define CR_TLBACC_G R_CR_TLBACC_G_MASK #define CR_TLBACC_G R_CR_TLBACC_G_MASK
#define CR_TLBMISC 10 #define CR_TLBMISC 10
#define CR_TLBMISC_WAY_SHIFT 20
#define CR_TLBMISC_WAY_MASK (0xF << CR_TLBMISC_WAY_SHIFT) FIELD(CR_TLBMISC, D, 0, 1)
#define CR_TLBMISC_RD (1 << 19) FIELD(CR_TLBMISC, PERM, 1, 1)
#define CR_TLBMISC_WE (1 << 18) FIELD(CR_TLBMISC, BAD, 2, 1)
#define CR_TLBMISC_PID_SHIFT 4 FIELD(CR_TLBMISC, DBL, 3, 1)
#define CR_TLBMISC_PID_MASK (0x3FFF << CR_TLBMISC_PID_SHIFT) FIELD(CR_TLBMISC, PID, 4, 14)
#define CR_TLBMISC_DBL (1 << 3) FIELD(CR_TLBMISC, WE, 18, 1)
#define CR_TLBMISC_BAD (1 << 2) FIELD(CR_TLBMISC, RD, 19, 1)
#define CR_TLBMISC_PERM (1 << 1) FIELD(CR_TLBMISC, WAY, 20, 4)
#define CR_TLBMISC_D (1 << 0) FIELD(CR_TLBMISC, EE, 24, 1)
#define CR_TLBMISC_EE R_CR_TLBMISC_EE_MASK
#define CR_TLBMISC_RD R_CR_TLBMISC_RD_MASK
#define CR_TLBMISC_WE R_CR_TLBMISC_WE_MASK
#define CR_TLBMISC_DBL R_CR_TLBMISC_DBL_MASK
#define CR_TLBMISC_BAD R_CR_TLBMISC_BAD_MASK
#define CR_TLBMISC_PERM R_CR_TLBMISC_PERM_MASK
#define CR_TLBMISC_D R_CR_TLBMISC_D_MASK
#define CR_ENCINJ 11 #define CR_ENCINJ 11
#define CR_BADADDR 12 #define CR_BADADDR 12
#define CR_CONFIG 13 #define CR_CONFIG 13

View File

@ -281,11 +281,8 @@ bool nios2_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
return false; return false;
} }
if (access_type == MMU_INST_FETCH) { env->ctrl[CR_TLBMISC] = FIELD_DP32(env->ctrl[CR_TLBMISC], CR_TLBMISC, D,
env->ctrl[CR_TLBMISC] &= ~CR_TLBMISC_D; access_type != MMU_INST_FETCH);
} else {
env->ctrl[CR_TLBMISC] |= CR_TLBMISC_D;
}
env->ctrl[CR_PTEADDR] = FIELD_DP32(env->ctrl[CR_PTEADDR], CR_PTEADDR, VPN, env->ctrl[CR_PTEADDR] = FIELD_DP32(env->ctrl[CR_PTEADDR], CR_PTEADDR, VPN,
address >> TARGET_PAGE_BITS); address >> TARGET_PAGE_BITS);
env->mmu.pteaddr_wr = env->ctrl[CR_PTEADDR]; env->mmu.pteaddr_wr = env->ctrl[CR_PTEADDR];

View File

@ -33,7 +33,7 @@ unsigned int mmu_translate(CPUNios2State *env,
target_ulong vaddr, int rw, int mmu_idx) target_ulong vaddr, int rw, int mmu_idx)
{ {
Nios2CPU *cpu = env_archcpu(env); Nios2CPU *cpu = env_archcpu(env);
int pid = (env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK) >> 4; int pid = FIELD_EX32(env->mmu.tlbmisc_wr, CR_TLBMISC, PID);
int vpn = vaddr >> 12; int vpn = vaddr >> 12;
int way, n_ways = cpu->tlb_num_ways; int way, n_ways = cpu->tlb_num_ways;
@ -96,9 +96,9 @@ void helper_mmu_write_tlbacc(CPUNios2State *env, uint32_t v)
/* if tlbmisc.WE == 1 then trigger a TLB write on writes to TLBACC */ /* if tlbmisc.WE == 1 then trigger a TLB write on writes to TLBACC */
if (env->ctrl[CR_TLBMISC] & CR_TLBMISC_WE) { if (env->ctrl[CR_TLBMISC] & CR_TLBMISC_WE) {
int way = (env->ctrl[CR_TLBMISC] >> CR_TLBMISC_WAY_SHIFT); int way = FIELD_EX32(env->ctrl[CR_TLBMISC], CR_TLBMISC, WAY);
int vpn = FIELD_EX32(env->mmu.pteaddr_wr, CR_PTEADDR, VPN); int vpn = FIELD_EX32(env->mmu.pteaddr_wr, CR_PTEADDR, VPN);
int pid = (env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK) >> 4; int pid = FIELD_EX32(env->mmu.tlbmisc_wr, CR_TLBMISC, PID);
int g = FIELD_EX32(v, CR_TLBACC, G); int g = FIELD_EX32(v, CR_TLBACC, G);
int valid = FIELD_EX32(vpn, CR_TLBACC, PFN) < 0xC0000; int valid = FIELD_EX32(vpn, CR_TLBACC, PFN) < 0xC0000;
Nios2TLBEntry *entry = Nios2TLBEntry *entry =
@ -117,10 +117,9 @@ void helper_mmu_write_tlbacc(CPUNios2State *env, uint32_t v)
entry->data = newData; entry->data = newData;
} }
/* Auto-increment tlbmisc.WAY */ /* Auto-increment tlbmisc.WAY */
env->ctrl[CR_TLBMISC] = env->ctrl[CR_TLBMISC] = FIELD_DP32(env->ctrl[CR_TLBMISC],
(env->ctrl[CR_TLBMISC] & ~CR_TLBMISC_WAY_MASK) | CR_TLBMISC, WAY,
(((way + 1) & (cpu->tlb_num_ways - 1)) << (way + 1) & (cpu->tlb_num_ways - 1));
CR_TLBMISC_WAY_SHIFT);
} }
/* Writes to TLBACC don't change the read-back value */ /* Writes to TLBACC don't change the read-back value */
@ -130,24 +129,25 @@ void helper_mmu_write_tlbacc(CPUNios2State *env, uint32_t v)
void helper_mmu_write_tlbmisc(CPUNios2State *env, uint32_t v) void helper_mmu_write_tlbmisc(CPUNios2State *env, uint32_t v)
{ {
Nios2CPU *cpu = env_archcpu(env); Nios2CPU *cpu = env_archcpu(env);
uint32_t new_pid = FIELD_EX32(v, CR_TLBMISC, PID);
uint32_t old_pid = FIELD_EX32(env->mmu.tlbmisc_wr, CR_TLBMISC, PID);
uint32_t way = FIELD_EX32(v, CR_TLBMISC, WAY);
trace_nios2_mmu_write_tlbmisc(v >> CR_TLBMISC_WAY_SHIFT, trace_nios2_mmu_write_tlbmisc(way,
(v & CR_TLBMISC_RD) ? 'R' : '.', (v & CR_TLBMISC_RD) ? 'R' : '.',
(v & CR_TLBMISC_WE) ? 'W' : '.', (v & CR_TLBMISC_WE) ? 'W' : '.',
(v & CR_TLBMISC_DBL) ? '2' : '.', (v & CR_TLBMISC_DBL) ? '2' : '.',
(v & CR_TLBMISC_BAD) ? 'B' : '.', (v & CR_TLBMISC_BAD) ? 'B' : '.',
(v & CR_TLBMISC_PERM) ? 'P' : '.', (v & CR_TLBMISC_PERM) ? 'P' : '.',
(v & CR_TLBMISC_D) ? 'D' : '.', (v & CR_TLBMISC_D) ? 'D' : '.',
(v & CR_TLBMISC_PID_MASK) >> 4); new_pid);
if ((v & CR_TLBMISC_PID_MASK) != if (new_pid != old_pid) {
(env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK)) { mmu_flush_pid(env, old_pid);
mmu_flush_pid(env, (env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK) >>
CR_TLBMISC_PID_SHIFT);
} }
/* if tlbmisc.RD == 1 then trigger a TLB read on writes to TLBMISC */ /* if tlbmisc.RD == 1 then trigger a TLB read on writes to TLBMISC */
if (v & CR_TLBMISC_RD) { if (v & CR_TLBMISC_RD) {
int way = (v >> CR_TLBMISC_WAY_SHIFT);
int vpn = FIELD_EX32(env->mmu.pteaddr_wr, CR_PTEADDR, VPN); int vpn = FIELD_EX32(env->mmu.pteaddr_wr, CR_PTEADDR, VPN);
Nios2TLBEntry *entry = Nios2TLBEntry *entry =
&env->mmu.tlb[(way * cpu->tlb_num_ways) + &env->mmu.tlb[(way * cpu->tlb_num_ways) +
@ -156,10 +156,9 @@ void helper_mmu_write_tlbmisc(CPUNios2State *env, uint32_t v)
env->ctrl[CR_TLBACC] &= R_CR_TLBACC_IG_MASK; env->ctrl[CR_TLBACC] &= R_CR_TLBACC_IG_MASK;
env->ctrl[CR_TLBACC] |= entry->data; env->ctrl[CR_TLBACC] |= entry->data;
env->ctrl[CR_TLBACC] |= (entry->tag & (1 << 11)) ? CR_TLBACC_G : 0; env->ctrl[CR_TLBACC] |= (entry->tag & (1 << 11)) ? CR_TLBACC_G : 0;
env->ctrl[CR_TLBMISC] = env->ctrl[CR_TLBMISC] = FIELD_DP32(v, CR_TLBMISC, PID,
(v & ~CR_TLBMISC_PID_MASK) | entry->tag &
((entry->tag & ((1 << cpu->pid_num_bits) - 1)) << ((1 << cpu->pid_num_bits) - 1));
CR_TLBMISC_PID_SHIFT);
env->ctrl[CR_PTEADDR] = FIELD_DP32(env->ctrl[CR_PTEADDR], env->ctrl[CR_PTEADDR] = FIELD_DP32(env->ctrl[CR_PTEADDR],
CR_PTEADDR, VPN, CR_PTEADDR, VPN,
entry->tag >> TARGET_PAGE_BITS); entry->tag >> TARGET_PAGE_BITS);

View File

@ -925,7 +925,7 @@ void nios2_cpu_dump_state(CPUState *cs, FILE *f, int flags)
} }
qemu_fprintf(f, " mmu write: VPN=%05X PID %02X TLBACC %08X\n", qemu_fprintf(f, " mmu write: VPN=%05X PID %02X TLBACC %08X\n",
env->mmu.pteaddr_wr & R_CR_PTEADDR_VPN_MASK, env->mmu.pteaddr_wr & R_CR_PTEADDR_VPN_MASK,
(env->mmu.tlbmisc_wr & CR_TLBMISC_PID_MASK) >> 4, FIELD_EX32(env->mmu.tlbmisc_wr, CR_TLBMISC, PID),
env->mmu.tlbacc_wr); env->mmu.tlbacc_wr);
#endif #endif
qemu_fprintf(f, "\n\n"); qemu_fprintf(f, "\n\n");