diff options
Diffstat (limited to 'target-sparc')
-rw-r--r-- | target-sparc/cpu.h | 11 | ||||
-rw-r--r-- | target-sparc/exec.h | 2 | ||||
-rw-r--r-- | target-sparc/helper.c | 25 | ||||
-rw-r--r-- | target-sparc/op_helper.c | 4 | ||||
-rw-r--r-- | target-sparc/translate.c | 2 |
5 files changed, 29 insertions, 15 deletions
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index fac18a7775..30e1d827da 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -166,6 +166,8 @@ typedef struct sparc_def_t sparc_def_t; +#define NB_MMU_MODES 2 + typedef struct CPUSPARCState { target_ulong gregs[8]; /* general registers */ target_ulong *regwptr; /* pointer to current register window */ @@ -317,6 +319,15 @@ void cpu_check_irqs(CPUSPARCState *env); #define cpu_signal_handler cpu_sparc_signal_handler #define cpu_list sparc_cpu_list +/* MMU modes definitions */ +#define MMU_MODE0_SUFFIX _kernel +#define MMU_MODE1_SUFFIX _user +#define MMU_USER_IDX 1 +static inline int cpu_mmu_index (CPUState *env) +{ + return env->psrs == 0 ? 1 : 0; +} + #include "cpu-all.h" #endif diff --git a/target-sparc/exec.h b/target-sparc/exec.h index 063e2ee644..81c4741be3 100644 --- a/target-sparc/exec.h +++ b/target-sparc/exec.h @@ -115,7 +115,7 @@ static inline void regs_to_env(void) } int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu); + int mmu_idx, int is_softmmu); static inline int cpu_halted(CPUState *env) { if (!env->halted) diff --git a/target-sparc/helper.c b/target-sparc/helper.c index af8bc96948..ebe642f8cb 100644 --- a/target-sparc/helper.c +++ b/target-sparc/helper.c @@ -49,7 +49,7 @@ void cpu_unlock(void) #if defined(CONFIG_USER_ONLY) int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { if (rw & 2) env->exception_index = TT_TFAULT; @@ -100,15 +100,16 @@ static const int perm_table[2][8] = { int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot, int *access_index, target_ulong address, int rw, - int is_user) + int mmu_idx) { int access_perms = 0; target_phys_addr_t pde_ptr; uint32_t pde; target_ulong virt_addr; - int error_code = 0, is_dirty; + int error_code = 0, is_dirty, is_user; unsigned long page_offset; + is_user = mmu_idx == MMU_USER_IDX; virt_addr = address & TARGET_PAGE_MASK; if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */ @@ -216,13 +217,13 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot /* Perform address translation */ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { target_phys_addr_t paddr; target_ulong vaddr; int error_code = 0, prot, ret = 0, access_index; - error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user); + error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx); if (error_code == 0) { vaddr = address & TARGET_PAGE_MASK; paddr &= TARGET_PAGE_MASK; @@ -230,7 +231,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr " TARGET_FMT_lx "\n", address, paddr, vaddr); #endif - ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); + ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu); return ret; } @@ -246,7 +247,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, // switching to normal mode. vaddr = address & TARGET_PAGE_MASK; prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; - ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); + ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu); return ret; } else { if (rw & 2) @@ -484,8 +485,10 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot, int *access_index, target_ulong address, int rw, - int is_user) + int mmu_idx) { + int is_user = mmu_idx == MMU_USER_IDX; + if (rw == 2) return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user); else @@ -494,20 +497,20 @@ int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot, /* Perform address translation */ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { target_ulong virt_addr, vaddr; target_phys_addr_t paddr; int error_code = 0, prot, ret = 0, access_index; - error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user); + error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx); if (error_code == 0) { virt_addr = address & TARGET_PAGE_MASK; vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1)); #ifdef DEBUG_MMU printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr); #endif - ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); + ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu); return ret; } // XXX diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index a4839a0558..6d08e1c651 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -1522,7 +1522,7 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user, NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ /* XXX: fix it to restore all registers */ -void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) +void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) { TranslationBlock *tb; int ret; @@ -1534,7 +1534,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) saved_env = env; env = cpu_single_env; - ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1); + ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (ret) { if (retaddr) { /* now we have a real cpu fault */ diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 27c22ede59..3027bb8afc 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -3689,7 +3689,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) #else extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot, int *access_index, target_ulong address, int rw, - int is_user); + int mmu_idx); target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) { |