aboutsummaryrefslogtreecommitdiff
path: root/target/mips/tlb_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/mips/tlb_helper.c')
-rw-r--r--target/mips/tlb_helper.c254
1 files changed, 0 insertions, 254 deletions
diff --git a/target/mips/tlb_helper.c b/target/mips/tlb_helper.c
index afc019c80d..bfb08eaf50 100644
--- a/target/mips/tlb_helper.c
+++ b/target/mips/tlb_helper.c
@@ -25,16 +25,6 @@
#include "exec/log.h"
#include "hw/mips/cpudevs.h"
-enum {
- TLBRET_XI = -6,
- TLBRET_RI = -5,
- TLBRET_DIRTY = -4,
- TLBRET_INVALID = -3,
- TLBRET_NOMATCH = -2,
- TLBRET_BADADDR = -1,
- TLBRET_MATCH = 0
-};
-
#if !defined(CONFIG_USER_ONLY)
/* no MMU emulation */
@@ -166,236 +156,6 @@ void mmu_init(CPUMIPSState *env, const mips_def_t *def)
}
}
-static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx)
-{
- /*
- * Interpret access control mode and mmu_idx.
- * AdE? TLB?
- * AM K S U E K S U E
- * UK 0 0 1 1 0 0 - - 0
- * MK 1 0 1 1 0 1 - - !eu
- * MSK 2 0 0 1 0 1 1 - !eu
- * MUSK 3 0 0 0 0 1 1 1 !eu
- * MUSUK 4 0 0 0 0 0 1 1 0
- * USK 5 0 0 1 0 0 0 - 0
- * - 6 - - - - - - - -
- * UUSK 7 0 0 0 0 0 0 0 0
- */
- int32_t adetlb_mask;
-
- switch (mmu_idx) {
- case 3: /* ERL */
- /* If EU is set, always unmapped */
- if (eu) {
- return 0;
- }
- /* fall through */
- case MIPS_HFLAG_KM:
- /* Never AdE, TLB mapped if AM={1,2,3} */
- adetlb_mask = 0x70000000;
- goto check_tlb;
-
- case MIPS_HFLAG_SM:
- /* AdE if AM={0,1}, TLB mapped if AM={2,3,4} */
- adetlb_mask = 0xc0380000;
- goto check_ade;
-
- case MIPS_HFLAG_UM:
- /* AdE if AM={0,1,2,5}, TLB mapped if AM={3,4} */
- adetlb_mask = 0xe4180000;
- /* fall through */
- check_ade:
- /* does this AM cause AdE in current execution mode */
- if ((adetlb_mask << am) < 0) {
- return TLBRET_BADADDR;
- }
- adetlb_mask <<= 8;
- /* fall through */
- check_tlb:
- /* is this AM mapped in current execution mode */
- return ((adetlb_mask << am) < 0);
- default:
- assert(0);
- return TLBRET_BADADDR;
- };
-}
-
-static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical,
- int *prot, target_ulong real_address,
- MMUAccessType access_type, int mmu_idx,
- unsigned int am, bool eu,
- target_ulong segmask,
- hwaddr physical_base)
-{
- int mapped = is_seg_am_mapped(am, eu, mmu_idx);
-
- if (mapped < 0) {
- /* is_seg_am_mapped can report TLBRET_BADADDR */
- return mapped;
- } else if (mapped) {
- /* The segment is TLB mapped */
- return env->tlb->map_address(env, physical, prot, real_address,
- access_type);
- } else {
- /* The segment is unmapped */
- *physical = physical_base | (real_address & segmask);
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- return TLBRET_MATCH;
- }
-}
-
-static int get_segctl_physical_address(CPUMIPSState *env, hwaddr *physical,
- int *prot, target_ulong real_address,
- MMUAccessType access_type, int mmu_idx,
- uint16_t segctl, target_ulong segmask)
-{
- unsigned int am = (segctl & CP0SC_AM_MASK) >> CP0SC_AM;
- bool eu = (segctl >> CP0SC_EU) & 1;
- hwaddr pa = ((hwaddr)segctl & CP0SC_PA_MASK) << 20;
-
- return get_seg_physical_address(env, physical, prot, real_address,
- access_type, mmu_idx, am, eu, segmask,
- pa & ~(hwaddr)segmask);
-}
-
-static int get_physical_address(CPUMIPSState *env, hwaddr *physical,
- int *prot, target_ulong real_address,
- MMUAccessType access_type, int mmu_idx)
-{
- /* User mode can only access useg/xuseg */
-#if defined(TARGET_MIPS64)
- int user_mode = mmu_idx == MIPS_HFLAG_UM;
- int supervisor_mode = mmu_idx == MIPS_HFLAG_SM;
- int kernel_mode = !user_mode && !supervisor_mode;
- int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
- int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
- int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
-#endif
- int ret = TLBRET_MATCH;
- /* effective address (modified for KVM T&E kernel segments) */
- target_ulong address = real_address;
-
-#define USEG_LIMIT ((target_ulong)(int32_t)0x7FFFFFFFUL)
-#define KSEG0_BASE ((target_ulong)(int32_t)0x80000000UL)
-#define KSEG1_BASE ((target_ulong)(int32_t)0xA0000000UL)
-#define KSEG2_BASE ((target_ulong)(int32_t)0xC0000000UL)
-#define KSEG3_BASE ((target_ulong)(int32_t)0xE0000000UL)
-
-#define KVM_KSEG0_BASE ((target_ulong)(int32_t)0x40000000UL)
-#define KVM_KSEG2_BASE ((target_ulong)(int32_t)0x60000000UL)
-
- if (mips_um_ksegs_enabled()) {
- /* KVM T&E adds guest kernel segments in useg */
- if (real_address >= KVM_KSEG0_BASE) {
- if (real_address < KVM_KSEG2_BASE) {
- /* kseg0 */
- address += KSEG0_BASE - KVM_KSEG0_BASE;
- } else if (real_address <= USEG_LIMIT) {
- /* kseg2/3 */
- address += KSEG2_BASE - KVM_KSEG2_BASE;
- }
- }
- }
-
- if (address <= USEG_LIMIT) {
- /* useg */
- uint16_t segctl;
-
- if (address >= 0x40000000UL) {
- segctl = env->CP0_SegCtl2;
- } else {
- segctl = env->CP0_SegCtl2 >> 16;
- }
- ret = get_segctl_physical_address(env, physical, prot,
- real_address, access_type,
- mmu_idx, segctl, 0x3FFFFFFF);
-#if defined(TARGET_MIPS64)
- } else if (address < 0x4000000000000000ULL) {
- /* xuseg */
- if (UX && address <= (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot,
- real_address, access_type);
- } else {
- ret = TLBRET_BADADDR;
- }
- } else if (address < 0x8000000000000000ULL) {
- /* xsseg */
- if ((supervisor_mode || kernel_mode) &&
- SX && address <= (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot,
- real_address, access_type);
- } else {
- ret = TLBRET_BADADDR;
- }
- } else if (address < 0xC000000000000000ULL) {
- /* xkphys */
- if ((address & 0x07FFFFFFFFFFFFFFULL) <= env->PAMask) {
- /* KX/SX/UX bit to check for each xkphys EVA access mode */
- static const uint8_t am_ksux[8] = {
- [CP0SC_AM_UK] = (1u << CP0St_KX),
- [CP0SC_AM_MK] = (1u << CP0St_KX),
- [CP0SC_AM_MSK] = (1u << CP0St_SX),
- [CP0SC_AM_MUSK] = (1u << CP0St_UX),
- [CP0SC_AM_MUSUK] = (1u << CP0St_UX),
- [CP0SC_AM_USK] = (1u << CP0St_SX),
- [6] = (1u << CP0St_KX),
- [CP0SC_AM_UUSK] = (1u << CP0St_UX),
- };
- unsigned int am = CP0SC_AM_UK;
- unsigned int xr = (env->CP0_SegCtl2 & CP0SC2_XR_MASK) >> CP0SC2_XR;
-
- if (xr & (1 << ((address >> 59) & 0x7))) {
- am = (env->CP0_SegCtl1 & CP0SC1_XAM_MASK) >> CP0SC1_XAM;
- }
- /* Does CP0_Status.KX/SX/UX permit the access mode (am) */
- if (env->CP0_Status & am_ksux[am]) {
- ret = get_seg_physical_address(env, physical, prot,
- real_address, access_type,
- mmu_idx, am, false, env->PAMask,
- 0);
- } else {
- ret = TLBRET_BADADDR;
- }
- } else {
- ret = TLBRET_BADADDR;
- }
- } else if (address < 0xFFFFFFFF80000000ULL) {
- /* xkseg */
- if (kernel_mode && KX &&
- address <= (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
- ret = env->tlb->map_address(env, physical, prot,
- real_address, access_type);
- } else {
- ret = TLBRET_BADADDR;
- }
-#endif
- } else if (address < KSEG1_BASE) {
- /* kseg0 */
- ret = get_segctl_physical_address(env, physical, prot, real_address,
- access_type, mmu_idx,
- env->CP0_SegCtl1 >> 16, 0x1FFFFFFF);
- } else if (address < KSEG2_BASE) {
- /* kseg1 */
- ret = get_segctl_physical_address(env, physical, prot, real_address,
- access_type, mmu_idx,
- env->CP0_SegCtl1, 0x1FFFFFFF);
- } else if (address < KSEG3_BASE) {
- /* sseg (kseg2) */
- ret = get_segctl_physical_address(env, physical, prot, real_address,
- access_type, mmu_idx,
- env->CP0_SegCtl0 >> 16, 0x1FFFFFFF);
- } else {
- /*
- * kseg3
- * XXX: debug segment is not emulated
- */
- ret = get_segctl_physical_address(env, physical, prot, real_address,
- access_type, mmu_idx,
- env->CP0_SegCtl0, 0x1FFFFFFF);
- }
- return ret;
-}
-
void cpu_mips_tlb_flush(CPUMIPSState *env)
{
/* Flush qemu's TLB and discard all shadowed entries. */
@@ -482,20 +242,6 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
env->error_code = error_code;
}
-hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-{
- MIPSCPU *cpu = MIPS_CPU(cs);
- CPUMIPSState *env = &cpu->env;
- hwaddr phys_addr;
- int prot;
-
- if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
- cpu_mmu_index(env, false)) != 0) {
- return -1;
- }
- return phys_addr;
-}
-
#if !defined(TARGET_MIPS64)
/*