Index: cpu-defs.h =================================================================== RCS file: /sources/qemu/qemu/cpu-defs.h,v retrieving revision 1.24 diff -u -d -d -p -r1.24 cpu-defs.h --- cpu-defs.h 19 Sep 2007 05:46:03 -0000 1.24 +++ cpu-defs.h 10 Oct 2007 03:29:03 -0000 @@ -112,15 +112,6 @@ typedef struct CPUTLBEntry { target_phys_addr_t addend; } CPUTLBEntry; -/* Alpha has 4 different running levels */ -#if defined(TARGET_ALPHA) -#define NB_MMU_MODES 4 -#elif defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */ -#define NB_MMU_MODES 3 -#else -#define NB_MMU_MODES 2 -#endif - #define CPU_COMMON \ struct TranslationBlock *current_tb; /* currently executing TB */ \ /* soft mmu support */ \ Index: cpu-exec.c =================================================================== RCS file: /sources/qemu/qemu/cpu-exec.c,v retrieving revision 1.119 diff -u -d -d -p -r1.119 cpu-exec.c --- cpu-exec.c 8 Oct 2007 13:16:13 -0000 1.119 +++ cpu-exec.c 10 Oct 2007 03:29:04 -0000 @@ -884,8 +884,7 @@ static inline int handle_cpu_signal(unsi } /* see if it is an MMU fault */ - ret = cpu_x86_handle_mmu_fault(env, address, is_write, - ((env->hflags & HF_CPL_MASK) == 3), 0); + ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) return 0; /* not an MMU fault */ if (ret == 0) @@ -934,7 +933,7 @@ static inline int handle_cpu_signal(unsi return 1; } /* see if it is an MMU fault */ - ret = cpu_arm_handle_mmu_fault(env, address, is_write, 1, 0); + ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) return 0; /* not an MMU fault */ if (ret == 0) @@ -970,7 +970,7 @@ static inline int handle_cpu_signal(unsi return 1; } /* see if it is an MMU fault */ - ret = cpu_sparc_handle_mmu_fault(env, address, is_write, 1, 0); + ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) return 0; /* not an MMU fault */ if (ret == 0) @@ -1007,7 +1008,7 @@ static inline int handle_cpu_signal(unsi } /* see if it is an MMU fault */ - ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0); + ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) return 0; /* not an MMU fault */ if (ret == 0) @@ -1056,7 +1057,7 @@ static inline int handle_cpu_signal(unsi return 1; } /* see if it is an MMU fault */ - ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 0); + ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) return 0; /* not an MMU fault */ if (ret == 0) @@ -1096,7 +1098,7 @@ static inline int handle_cpu_signal(unsi } /* see if it is an MMU fault */ - ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0); + ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) return 0; /* not an MMU fault */ if (ret == 0) @@ -1146,7 +1149,7 @@ static inline int handle_cpu_signal(unsi } /* see if it is an MMU fault */ - ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0); + ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) return 0; /* not an MMU fault */ if (ret == 0) @@ -1191,7 +1195,7 @@ static inline int handle_cpu_signal(unsi } /* see if it is an MMU fault */ - ret = cpu_alpha_handle_mmu_fault(env, address, is_write, 1, 0); + ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) return 0; /* not an MMU fault */ if (ret == 0) @@ -1235,7 +1239,7 @@ static inline int handle_cpu_signal(unsi } /* see if it is an MMU fault */ - ret = cpu_cris_handle_mmu_fault(env, address, is_write, 1, 0); + ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) return 0; /* not an MMU fault */ if (ret == 0) Index: exec-all.h =================================================================== RCS file: /sources/qemu/qemu/exec-all.h,v retrieving revision 1.67 diff -u -d -d -p -r1.67 exec-all.h --- exec-all.h 8 Oct 2007 13:16:14 -0000 1.67 +++ exec-all.h 10 Oct 2007 03:29:04 -0000 @@ -117,14 +122,14 @@ void tlb_flush_page(CPUState *env, targe void tlb_flush(CPUState *env, int flush_global); int tlb_set_page_exec(CPUState *env, target_ulong vaddr, target_phys_addr_t paddr, int prot, - int is_user, int is_softmmu); + int mmu_idx, int is_softmmu); static inline int tlb_set_page(CPUState *env, target_ulong vaddr, target_phys_addr_t paddr, int prot, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { if (prot & PAGE_READ) prot |= PAGE_EXEC; - return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); + return tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu); } #define CODE_GEN_MAX_SIZE 65536 @@ -562,10 +567,10 @@ extern int tb_invalidated_flag; #if !defined(CONFIG_USER_ONLY) -void tlb_fill(target_ulong addr, int is_write, int is_user, +void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr); -#define ACCESS_TYPE 3 +#define ACCESS_TYPE (NB_MMU_MODES + 1) #define MEMSUFFIX _code #define env cpu_single_env @@ -598,35 +603,15 @@ static inline target_ulong get_phys_addr is the offset relative to phys_ram_base */ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) { - int is_user, index, pd; + int mmu_idx, index, pd; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); -#if defined(TARGET_I386) - is_user = ((env->hflags & HF_CPL_MASK) == 3); -#elif defined (TARGET_PPC) - is_user = msr_pr; -#elif defined (TARGET_MIPS) - is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM); -#elif defined (TARGET_SPARC) - is_user = (env->psrs == 0); -#elif defined (TARGET_ARM) - is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR); -#elif defined (TARGET_SH4) - is_user = ((env->sr & SR_MD) == 0); -#elif defined (TARGET_ALPHA) - is_user = ((env->ps >> 3) & 3); -#elif defined (TARGET_M68K) - is_user = ((env->sr & SR_S) == 0); -#elif defined (TARGET_CRIS) - is_user = (0); -#else -#error unimplemented CPU -#endif - if (__builtin_expect(env->tlb_table[is_user][index].addr_code != + mmu_idx = cpu_mmu_index(env); + if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_code != (addr & TARGET_PAGE_MASK), 0)) { ldub_code(addr); } - pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK; + pd = env->tlb_table[mmu_idx][index].addr_code & ~TARGET_PAGE_MASK; if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { #ifdef TARGET_SPARC do_unassigned_access(addr, 0, 1, 0); @@ -634,7 +619,7 @@ static inline target_ulong get_phys_addr cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr); #endif } - return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base; + return addr + env->tlb_table[mmu_idx][index].addend - (unsigned long)phys_ram_base; } #endif Index: exec.c =================================================================== RCS file: /sources/qemu/qemu/exec.c,v retrieving revision 1.108 diff -u -d -d -p -r1.108 exec.c --- exec.c 8 Oct 2007 13:16:14 -0000 1.108 +++ exec.c 10 Oct 2007 03:29:04 -0000 @@ -1608,7 +1608,7 @@ static inline void tlb_set_dirty(CPUStat conflicting with the host address space). */ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, target_phys_addr_t paddr, int prot, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { PhysPageDesc *p; unsigned long pd; @@ -1626,8 +1626,8 @@ int tlb_set_page_exec(CPUState *env, tar pd = p->phys_offset; } #if defined(DEBUG_TLB) - printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n", - vaddr, (int)paddr, prot, is_user, is_softmmu, pd); + printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n", + vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd); #endif ret = 0; @@ -1664,7 +1664,7 @@ int tlb_set_page_exec(CPUState *env, tar index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); addend -= vaddr; - te = &env->tlb_table[is_user][index]; + te = &env->tlb_table[mmu_idx][index]; te->addend = addend; if (prot & PAGE_READ) { te->addr_read = address; @@ -1790,7 +1790,7 @@ void tlb_flush_page(CPUState *env, targe int tlb_set_page_exec(CPUState *env, target_ulong vaddr, target_phys_addr_t paddr, int prot, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { return 0; } Index: softmmu_exec.h =================================================================== RCS file: /sources/qemu/qemu/softmmu_exec.h,v retrieving revision 1.1 diff -u -d -d -p -r1.1 softmmu_exec.h --- softmmu_exec.h 30 Oct 2005 18:16:26 -0000 1.1 +++ softmmu_exec.h 10 Oct 2007 03:29:04 -0000 @@ -1,10 +1,16 @@ /* Common softmmu definitions and inline routines. */ -#define ldul_user ldl_user -#define ldul_kernel ldl_kernel +/* XXX: find something cleaner. + * Furthermore, this is false for 64 bits targets + */ +#define ldul_user ldl_user +#define ldul_kernel ldl_kernel +#define ldul_hypv ldl_hypv +#define ldul_executive ldl_executive +#define ldul_supervisor ldl_supervisor #define ACCESS_TYPE 0 -#define MEMSUFFIX _kernel +#define MEMSUFFIX MMU_MODE0_SUFFIX #define DATA_SIZE 1 #include "softmmu_header.h" @@ -20,7 +26,7 @@ #undef MEMSUFFIX #define ACCESS_TYPE 1 -#define MEMSUFFIX _user +#define MEMSUFFIX MMU_MODE1_SUFFIX #define DATA_SIZE 1 #include "softmmu_header.h" @@ -35,8 +41,50 @@ #undef ACCESS_TYPE #undef MEMSUFFIX -/* these access are slower, they must be as rare as possible */ +#if (NB_MMU_MODES >= 3) + #define ACCESS_TYPE 2 +#define MEMSUFFIX MMU_MODE2_SUFFIX +#define DATA_SIZE 1 +#include "softmmu_header.h" + +#define DATA_SIZE 2 +#include "softmmu_header.h" + +#define DATA_SIZE 4 +#include "softmmu_header.h" + +#define DATA_SIZE 8 +#include "softmmu_header.h" +#undef ACCESS_TYPE +#undef MEMSUFFIX + +#if (NB_MMU_MODES >= 4) + +#define ACCESS_TYPE 3 +#define MEMSUFFIX MMU_MODE3_SUFFIX +#define DATA_SIZE 1 +#include "softmmu_header.h" + +#define DATA_SIZE 2 +#include "softmmu_header.h" + +#define DATA_SIZE 4 +#include "softmmu_header.h" + +#define DATA_SIZE 8 +#include "softmmu_header.h" +#undef ACCESS_TYPE +#undef MEMSUFFIX + +#if (NB_MMU_MODES > 4) +#error "NB_MMU_MODES > 4 is not supported for now" +#endif /* (NB_MMU_MODES > 4) */ +#endif /* (NB_MMU_MODES == 4) */ +#endif /* (NB_MMU_MODES >= 3) */ + +/* these access are slower, they must be as rare as possible */ +#define ACCESS_TYPE (NB_MMU_MODES) #define MEMSUFFIX _data #define DATA_SIZE 1 #include "softmmu_header.h" Index: softmmu_header.h =================================================================== RCS file: /sources/qemu/qemu/softmmu_header.h,v retrieving revision 1.17 diff -u -d -d -p -r1.17 softmmu_header.h --- softmmu_header.h 8 Oct 2007 13:16:14 -0000 1.17 +++ softmmu_header.h 10 Oct 2007 03:29:04 -0000 @@ -39,66 +39,19 @@ #error unsupported data size #endif -#if ACCESS_TYPE == 0 - -#define CPU_MEM_INDEX 0 -#define MMUSUFFIX _mmu - -#elif ACCESS_TYPE == 1 +#if ACCESS_TYPE < (NB_MMU_MODES) -#define CPU_MEM_INDEX 1 +#define CPU_MMU_INDEX ACCESS_TYPE #define MMUSUFFIX _mmu -#elif ACCESS_TYPE == 2 +#elif ACCESS_TYPE == (NB_MMU_MODES) -#ifdef TARGET_I386 -#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) -#elif defined (TARGET_PPC) -#define CPU_MEM_INDEX (msr_pr) -#elif defined (TARGET_MIPS) -#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM) -#elif defined (TARGET_SPARC) -#define CPU_MEM_INDEX ((env->psrs) == 0) -#elif defined (TARGET_ARM) -#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) -#elif defined (TARGET_SH4) -#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0) -#elif defined (TARGET_ALPHA) -#define CPU_MEM_INDEX ((env->ps >> 3) & 3) -#elif defined (TARGET_M68K) -#define CPU_MEM_INDEX ((env->sr & SR_S) == 0) -#elif defined (TARGET_CRIS) -/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */ -#define CPU_MEM_INDEX (0) -#else -#error unsupported CPU -#endif +#define CPU_MMU_INDEX (cpu_mmu_index(env)) #define MMUSUFFIX _mmu -#elif ACCESS_TYPE == 3 +#elif ACCESS_TYPE == (NB_MMU_MODES + 1) -#ifdef TARGET_I386 -#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) -#elif defined (TARGET_PPC) -#define CPU_MEM_INDEX (msr_pr) -#elif defined (TARGET_MIPS) -#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM) -#elif defined (TARGET_SPARC) -#define CPU_MEM_INDEX ((env->psrs) == 0) -#elif defined (TARGET_ARM) -#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) -#elif defined (TARGET_SH4) -#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0) -#elif defined (TARGET_ALPHA) -#define CPU_MEM_INDEX ((env->ps >> 3) & 3) -#elif defined (TARGET_M68K) -#define CPU_MEM_INDEX ((env->sr & SR_S) == 0) -#elif defined (TARGET_CRIS) -/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */ -#define CPU_MEM_INDEX (0) -#else -#error unsupported CPU -#endif +#define CPU_MMU_INDEX (cpu_mmu_index(env)) #define MMUSUFFIX _cmmu #else @@ -111,15 +64,15 @@ #define RES_TYPE int #endif -#if ACCESS_TYPE == 3 +#if ACCESS_TYPE == (NB_MMU_MODES + 1) #define ADDR_READ addr_code #else #define ADDR_READ addr_read #endif DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, - int is_user); -void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user); + int mmu_idx); +void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int mmu_idx); #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \ (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU) @@ -161,8 +114,8 @@ static inline RES_TYPE glue(glue(ld, USU "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), - "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)), - "i" (CPU_MEM_INDEX), + "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)), + "i" (CPU_MMU_INDEX), "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) : "%eax", "%ecx", "%edx", "memory", "cc"); return res; @@ -208,8 +161,8 @@ static inline int glue(glue(lds, SUFFIX) "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), - "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)), - "i" (CPU_MEM_INDEX), + "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)), + "i" (CPU_MMU_INDEX), "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) : "%eax", "%ecx", "%edx", "memory", "cc"); return res; @@ -260,8 +213,8 @@ static inline void glue(glue(st, SUFFIX) "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), - "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)), - "i" (CPU_MEM_INDEX), + "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)), + "i" (CPU_MMU_INDEX), "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX)) : "%eax", "%ecx", "%edx", "memory", "cc"); } @@ -276,16 +229,16 @@ static inline RES_TYPE glue(glue(ld, USU RES_TYPE res; target_ulong addr; unsigned long physaddr; - int is_user; + int mmu_idx; addr = ptr; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); - is_user = CPU_MEM_INDEX; - if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ != + mmu_idx = CPU_MMU_INDEX; + if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ != (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { - res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user); + res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx); } else { - physaddr = addr + env->tlb_table[is_user][index].addend; + physaddr = addr + env->tlb_table[mmu_idx][index].addend; res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); } return res; @@ -297,23 +250,23 @@ static inline int glue(glue(lds, SUFFIX) int res, index; target_ulong addr; unsigned long physaddr; - int is_user; + int mmu_idx; addr = ptr; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); - is_user = CPU_MEM_INDEX; - if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ != + mmu_idx = CPU_MMU_INDEX; + if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ != (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { - res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user); + res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx); } else { - physaddr = addr + env->tlb_table[is_user][index].addend; + physaddr = addr + env->tlb_table[mmu_idx][index].addend; res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr); } return res; } #endif -#if ACCESS_TYPE != 3 +#if ACCESS_TYPE != (NB_MMU_MODES + 1) /* generic store macro */ @@ -322,25 +275,25 @@ static inline void glue(glue(st, SUFFIX) int index; target_ulong addr; unsigned long physaddr; - int is_user; + int mmu_idx; addr = ptr; index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); - is_user = CPU_MEM_INDEX; - if (__builtin_expect(env->tlb_table[is_user][index].addr_write != + mmu_idx = CPU_MMU_INDEX; + if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_write != (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { - glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user); + glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx); } else { - physaddr = addr + env->tlb_table[is_user][index].addend; + physaddr = addr + env->tlb_table[mmu_idx][index].addend; glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v); } } -#endif /* ACCESS_TYPE != 3 */ +#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */ #endif /* !asm */ -#if ACCESS_TYPE != 3 +#if ACCESS_TYPE != (NB_MMU_MODES + 1) #if DATA_SIZE == 8 static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr) @@ -386,7 +339,7 @@ static inline void glue(stfl, MEMSUFFIX) } #endif /* DATA_SIZE == 4 */ -#endif /* ACCESS_TYPE != 3 */ +#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */ #undef RES_TYPE #undef DATA_TYPE @@ -394,6 +347,6 @@ static inline void glue(stfl, MEMSUFFIX) #undef SUFFIX #undef USUFFIX #undef DATA_SIZE -#undef CPU_MEM_INDEX +#undef CPU_MMU_INDEX #undef MMUSUFFIX #undef ADDR_READ Index: softmmu_template.h =================================================================== RCS file: /sources/qemu/qemu/softmmu_template.h,v retrieving revision 1.18 diff -u -d -d -p -r1.18 softmmu_template.h --- softmmu_template.h 17 Sep 2007 08:09:45 -0000 1.18 +++ softmmu_template.h 10 Oct 2007 03:29:04 -0000 @@ -48,7 +48,7 @@ #endif static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, - int is_user, + int mmu_idx, void *retaddr); static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, target_ulong tlb_addr) @@ -76,7 +76,7 @@ static inline DATA_TYPE glue(io_read, SU /* handle all cases except unaligned access which span two pages */ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, - int is_user) + int mmu_idx) { DATA_TYPE res; int index; @@ -88,9 +88,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF /* XXX: could done more in memory macro in a non portable way */ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: - tlb_addr = env->tlb_table[is_user][index].ADDR_READ; + tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = addr + env->tlb_table[is_user][index].addend; + physaddr = addr + env->tlb_table[mmu_idx][index].addend; if (tlb_addr & ~TARGET_PAGE_MASK) { /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) @@ -101,16 +101,16 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF do_unaligned_access: retaddr = GETPC(); #ifdef ALIGNED_ONLY - do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr); + do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); #endif res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr, - is_user, retaddr); + mmu_idx, retaddr); } else { /* unaligned/aligned access in the same page */ #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { retaddr = GETPC(); - do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr); + do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); } #endif res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr); @@ -120,9 +120,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF retaddr = GETPC(); #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) - do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr); + do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); #endif - tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr); + tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); goto redo; } return res; @@ -130,7 +130,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUF /* handle all unaligned cases */ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, - int is_user, + int mmu_idx, void *retaddr) { DATA_TYPE res, res1, res2; @@ -140,9 +140,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFF index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: - tlb_addr = env->tlb_table[is_user][index].ADDR_READ; + tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = addr + env->tlb_table[is_user][index].addend; + physaddr = addr + env->tlb_table[mmu_idx][index].addend; if (tlb_addr & ~TARGET_PAGE_MASK) { /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) @@ -154,9 +154,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFF addr1 = addr & ~(DATA_SIZE - 1); addr2 = addr1 + DATA_SIZE; res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1, - is_user, retaddr); + mmu_idx, retaddr); res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2, - is_user, retaddr); + mmu_idx, retaddr); shift = (addr & (DATA_SIZE - 1)) * 8; #ifdef TARGET_WORDS_BIGENDIAN res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); @@ -170,7 +170,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFF } } else { /* the page is not in the TLB : fill it */ - tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr); + tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr); goto redo; } return res; @@ -180,7 +180,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFF static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE val, - int is_user, + int mmu_idx, void *retaddr); static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, @@ -211,7 +211,7 @@ static inline void glue(io_write, SUFFIX void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE val, - int is_user) + int mmu_idx) { target_phys_addr_t physaddr; target_ulong tlb_addr; @@ -220,9 +220,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX), index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: - tlb_addr = env->tlb_table[is_user][index].addr_write; + tlb_addr = env->tlb_table[mmu_idx][index].addr_write; if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = addr + env->tlb_table[is_user][index].addend; + physaddr = addr + env->tlb_table[mmu_idx][index].addend; if (tlb_addr & ~TARGET_PAGE_MASK) { /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) @@ -233,16 +233,16 @@ void REGPARM(2) glue(glue(__st, SUFFIX), do_unaligned_access: retaddr = GETPC(); #ifdef ALIGNED_ONLY - do_unaligned_access(addr, 1, is_user, retaddr); + do_unaligned_access(addr, 1, mmu_idx, retaddr); #endif glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val, - is_user, retaddr); + mmu_idx, retaddr); } else { /* aligned/unaligned access in the same page */ #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) { retaddr = GETPC(); - do_unaligned_access(addr, 1, is_user, retaddr); + do_unaligned_access(addr, 1, mmu_idx, retaddr); } #endif glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val); @@ -252,9 +252,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX), retaddr = GETPC(); #ifdef ALIGNED_ONLY if ((addr & (DATA_SIZE - 1)) != 0) - do_unaligned_access(addr, 1, is_user, retaddr); + do_unaligned_access(addr, 1, mmu_idx, retaddr); #endif - tlb_fill(addr, 1, is_user, retaddr); + tlb_fill(addr, 1, mmu_idx, retaddr); goto redo; } } @@ -262,7 +262,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), /* handles all unaligned cases */ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE val, - int is_user, + int mmu_idx, void *retaddr) { target_phys_addr_t physaddr; @@ -271,9 +271,9 @@ static void glue(glue(slow_st, SUFFIX), index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: - tlb_addr = env->tlb_table[is_user][index].addr_write; + tlb_addr = env->tlb_table[mmu_idx][index].addr_write; if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = addr + env->tlb_table[is_user][index].addend; + physaddr = addr + env->tlb_table[mmu_idx][index].addend; if (tlb_addr & ~TARGET_PAGE_MASK) { /* IO access */ if ((addr & (DATA_SIZE - 1)) != 0) @@ -285,10 +285,10 @@ static void glue(glue(slow_st, SUFFIX), for(i = 0;i < DATA_SIZE; i++) { #ifdef TARGET_WORDS_BIGENDIAN glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)), - is_user, retaddr); + mmu_idx, retaddr); #else glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8), - is_user, retaddr); + mmu_idx, retaddr); #endif } } else { @@ -297,7 +297,7 @@ static void glue(glue(slow_st, SUFFIX), } } else { /* the page is not in the TLB : fill it */ - tlb_fill(addr, 1, is_user, retaddr); + tlb_fill(addr, 1, mmu_idx, retaddr); goto redo; } } Index: hw/alpha_palcode.c =================================================================== RCS file: /sources/qemu/qemu/hw/alpha_palcode.c,v retrieving revision 1.3 diff -u -d -d -p -r1.3 alpha_palcode.c --- hw/alpha_palcode.c 17 Sep 2007 08:09:46 -0000 1.3 +++ hw/alpha_palcode.c 10 Oct 2007 03:29:05 -0000 @@ -811,12 +811,14 @@ static int get_page_bits (CPUState *env) static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp, uint64_t ptebase, int page_bits, uint64_t level, - int is_user, int rw) + int mmu_idx, int rw) { uint64_t pteaddr, pte, pfn; uint8_t gh; - int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar; + int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar, is_user; + /* XXX: TOFIX */ + is_user = mmu_idx != 0 ? 1 : 0; pteaddr = (ptebase << page_bits) + (8 * level); pte = ldq_raw(pteaddr); /* Decode all interresting PTE fields */ @@ -871,7 +873,7 @@ static int get_pte (uint64_t *pfnp, int static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot, uint64_t ptebase, int page_bits, - uint64_t vaddr, int is_user, int rw) + uint64_t vaddr, int mmu_idx, int rw) { uint64_t pfn, page_mask, lvl_mask, level1, level2, level3; int lvl_bits, ret; @@ -909,7 +911,7 @@ static int paddr_from_pte (uint64_t *pad break; } /* Level 3 PTE */ - ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, is_user, rw); + ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, mmu_idx, rw); if (ret & 0x1) { /* Translation not valid */ ret = 1; @@ -943,7 +945,7 @@ static int paddr_from_pte (uint64_t *pad static int virtual_to_physical (CPUState *env, uint64_t *physp, int *zbitsp, int *protp, - uint64_t virtual, int is_user, int rw) + uint64_t virtual, int mmu_idx, int rw) { uint64_t sva, ptebase; int seg, page_bits, ret; @@ -961,16 +963,16 @@ static int virtual_to_physical (CPUState case 0: /* seg1: 3 levels of PTE */ ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits, - virtual, is_user, rw); + virtual, mmu_idx, rw); break; case 1: /* seg1: 2 levels of PTE */ ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits, - virtual, is_user, rw); + virtual, mmu_idx, rw); break; case 2: /* kernel segment */ - if (is_user) { + if (mmu_idx != 0) { ret = 2; } else { *physp = virtual; @@ -979,7 +981,7 @@ static int virtual_to_physical (CPUState case 3: /* seg1: TB mapped */ ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits, - virtual, is_user, rw); + virtual, mmu_idx, rw); break; default: ret = 1; @@ -991,7 +993,7 @@ static int virtual_to_physical (CPUState /* XXX: code provision */ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { uint64_t physical, page_size, end; int prot, zbits, ret; @@ -1000,7 +1002,7 @@ int cpu_ppc_handle_mmu_fault (CPUState * ret = 2; } else { ret = virtual_to_physical(env, &physical, &zbits, &prot, - address, is_user, rw); + address, mmu_idx, rw); } switch (ret) { case 0: @@ -1009,7 +1011,7 @@ int cpu_ppc_handle_mmu_fault (CPUState * address &= ~(page_size - 1); for (end = physical + page_size; physical < end; physical += 0x1000) { ret = tlb_set_page(env, address, physical, prot, - is_user, is_softmmu); + mmu_idx, is_softmmu); address += 0x1000; } break; Index: target-alpha/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-alpha/cpu.h,v retrieving revision 1.8 diff -u -d -d -p -r1.8 cpu.h --- target-alpha/cpu.h 27 Sep 2007 16:44:31 -0000 1.8 +++ target-alpha/cpu.h 10 Oct 2007 03:29:07 -0000 @@ -256,6 +256,8 @@ struct pal_handler_t { void (*call_pal)(CPUAlphaState *env, uint32_t palcode); }; +#define NB_MMU_MODES 4 + struct CPUAlphaState { uint64_t ir[31]; float64 fir[31]; @@ -302,6 +304,17 @@ struct CPUAlphaState { #define cpu_gen_code cpu_alpha_gen_code #define cpu_signal_handler cpu_alpha_signal_handler +/* MMU modes definitions */ +#define MMU_MODE0_SUFFIX _kernel +#define MMU_MODE1_SUFFIX _executive +#define MMU_MODE2_SUFFIX _supervisor +#define MMU_MODE3_SUFFIX _user +#define MMU_USER_IDX 3 +static inline int cpu_mmu_index (CPUState *env) +{ + return (env->ps >> 3) & 3; +} + #include "cpu-all.h" enum { Index: target-alpha/exec.h =================================================================== RCS file: /sources/qemu/qemu/target-alpha/exec.h,v retrieving revision 1.3 diff -u -d -d -p -r1.3 exec.h --- target-alpha/exec.h 16 Sep 2007 21:08:01 -0000 1.3 +++ target-alpha/exec.h 10 Oct 2007 03:29:07 -0000 @@ -73,7 +73,7 @@ static inline void regs_to_env(void) } int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw, - int is_user, int is_softmmu); + int mmu_idx, int is_softmmu); int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp); int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp); Index: target-alpha/helper.c =================================================================== RCS file: /sources/qemu/qemu/target-alpha/helper.c,v retrieving revision 1.4 diff -u -d -d -p -r1.4 helper.c --- target-alpha/helper.c 17 Sep 2007 08:09:51 -0000 1.4 +++ target-alpha/helper.c 10 Oct 2007 03:29:07 -0000 @@ -28,7 +28,7 @@ #if defined(CONFIG_USER_ONLY) int cpu_alpha_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 = EXCP_ITB_MISS; @@ -57,7 +57,7 @@ target_phys_addr_t cpu_get_phys_page_deb } int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { uint32_t opc; Index: target-alpha/op_helper.c =================================================================== RCS file: /sources/qemu/qemu/target-alpha/op_helper.c,v retrieving revision 1.2 diff -u -d -d -p -r1.2 op_helper.c --- target-alpha/op_helper.c 16 Sep 2007 21:08:01 -0000 1.2 +++ target-alpha/op_helper.c 10 Oct 2007 03:29:07 -0000 @@ -1164,20 +1164,20 @@ void helper_mtpr (int iprn) void helper_ld_phys_to_virt (void) { uint64_t tlb_addr, physaddr; - int index, is_user; + int index, mmu_idx; void *retaddr; - is_user = (env->ps >> 3) & 3; + mmu_idx = cpu_mmu_index(env); index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: - tlb_addr = env->tlb_table[is_user][index].addr_read; + tlb_addr = env->tlb_table[mmu_idx][index].addr_read; if ((T0 & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = T0 + env->tlb_table[is_user][index].addend; + physaddr = T0 + env->tlb_table[mmu_idx][index].addend; } else { /* the page is not in the TLB : fill it */ retaddr = GETPC(); - tlb_fill(T0, 0, is_user, retaddr); + tlb_fill(T0, 0, mmu_idx, retaddr); goto redo; } T0 = physaddr; @@ -1186,20 +1186,20 @@ void helper_ld_phys_to_virt (void) void helper_st_phys_to_virt (void) { uint64_t tlb_addr, physaddr; - int index, is_user; + int index, mmu_idx; void *retaddr; - is_user = (env->ps >> 3) & 3; + mmu_idx = cpu_mmu_index(env); index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); redo: - tlb_addr = env->tlb_table[is_user][index].addr_write; + tlb_addr = env->tlb_table[mmu_idx][index].addr_write; if ((T0 & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { - physaddr = T0 + env->tlb_table[is_user][index].addend; + physaddr = T0 + env->tlb_table[mmu_idx][index].addend; } else { /* the page is not in the TLB : fill it */ retaddr = GETPC(); - tlb_fill(T0, 1, is_user, retaddr); + tlb_fill(T0, 1, mmu_idx, retaddr); goto redo; } T0 = physaddr; @@ -1223,7 +1223,7 @@ void helper_st_phys_to_virt (void) 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; CPUState *saved_env; @@ -1234,7 +1234,7 @@ void tlb_fill (target_ulong addr, int is generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, is_user, 1); + ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (!likely(ret == 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ Index: target-arm/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-arm/cpu.h,v retrieving revision 1.34 diff -u -d -d -p -r1.34 cpu.h --- target-arm/cpu.h 27 Sep 2007 16:44:31 -0000 1.34 +++ target-arm/cpu.h 10 Oct 2007 03:29:07 -0000 @@ -43,6 +43,8 @@ typedef void ARMWriteCPFunc(void *opaque typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info, int dstreg, int operand); +#define NB_MMU_MODES 2 + /* We currently assume float and double are IEEE single and double precision respectively. Doing runtime conversions is tricky because VFP registers may contain @@ -299,6 +301,15 @@ void cpu_arm_set_cp_io(CPUARMState *env, #define cpu_exec cpu_arm_exec #define cpu_gen_code cpu_arm_gen_code #define cpu_signal_handler cpu_arm_signal_handler + +/* 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->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0; +} #include "cpu-all.h" Index: target-arm/exec.h =================================================================== RCS file: /sources/qemu/qemu/target-arm/exec.h,v retrieving revision 1.13 diff -u -d -d -p -r1.13 exec.h --- target-arm/exec.h 16 Sep 2007 21:08:01 -0000 1.13 +++ target-arm/exec.h 10 Oct 2007 03:29:07 -0000 @@ -46,7 +46,7 @@ static inline void regs_to_env(void) } int cpu_arm_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) Index: target-arm/helper.c =================================================================== RCS file: /sources/qemu/qemu/target-arm/helper.c,v retrieving revision 1.21 diff -u -d -d -p -r1.21 helper.c --- target-arm/helper.c 16 Sep 2007 21:08:01 -0000 1.21 +++ target-arm/helper.c 10 Oct 2007 03:29:07 -0000 @@ -169,7 +169,7 @@ void do_interrupt (CPUState *env) } int cpu_arm_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 = EXCP_PREFETCH_ABORT; @@ -547,18 +547,19 @@ do_fault: } int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, - int access_type, int is_user, int is_softmmu) + int access_type, int mmu_idx, int is_softmmu) { uint32_t phys_addr; int prot; - int ret; + int ret, is_user; + is_user = mmu_idx; ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot); if (ret == 0) { /* Map a single [sub]page. */ phys_addr &= ~(uint32_t)0x3ff; address &= ~(uint32_t)0x3ff; - return tlb_set_page (env, address, phys_addr, prot, is_user, + return tlb_set_page (env, address, phys_addr, prot, mmu_idx, is_softmmu); } Index: target-arm/op_helper.c =================================================================== RCS file: /sources/qemu/qemu/target-arm/op_helper.c,v retrieving revision 1.6 diff -u -d -d -p -r1.6 op_helper.c --- target-arm/op_helper.c 16 Sep 2007 21:08:02 -0000 1.6 +++ target-arm/op_helper.c 10 Oct 2007 03:29:07 -0000 @@ -196,7 +196,7 @@ void do_vfp_get_fpscr(void) 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; CPUState *saved_env; @@ -207,7 +207,7 @@ void tlb_fill (target_ulong addr, int is generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_arm_handle_mmu_fault(env, addr, is_write, is_user, 1); + ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (__builtin_expect(ret, 0)) { if (retaddr) { /* now we have a real cpu fault */ Index: target-cris/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-cris/cpu.h,v retrieving revision 1.1 diff -u -d -d -p -r1.1 cpu.h --- target-cris/cpu.h 8 Oct 2007 13:04:02 -0000 1.1 +++ target-cris/cpu.h 10 Oct 2007 03:29:07 -0000 @@ -74,6 +74,8 @@ /* Internal flags for the implementation. */ #define F_DELAYSLOT 1 +#define NB_MMU_MODES 2 + typedef struct CPUCRISState { uint32_t debug1; uint32_t debug2; @@ -229,6 +231,16 @@ void register_cris_insns (CPUCRISState * #define cpu_gen_code cpu_cris_gen_code #define cpu_signal_handler cpu_cris_signal_handler +/* MMU modes definitions */ +#define MMU_MODE0_SUFFIX _kernel +#define MMU_MODE1_SUFFIX _user +#define MMU_USER_IDX 1 +/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */ +static inline int cpu_mmu_index (CPUState *env) +{ + return 0; +} + #include "cpu-all.h" /* Register aliases. */ Index: target-cris/exec.h =================================================================== RCS file: /sources/qemu/qemu/target-cris/exec.h,v retrieving revision 1.1 diff -u -d -d -p -r1.1 exec.h --- target-cris/exec.h 8 Oct 2007 13:04:02 -0000 1.1 +++ target-cris/exec.h 10 Oct 2007 03:29:07 -0000 @@ -45,8 +45,8 @@ static inline void regs_to_env(void) } int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu); -void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr); + int mmu_idx, int is_softmmu); +void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr); #if !defined(CONFIG_USER_ONLY) #include "softmmu_exec.h" Index: target-cris/helper.c =================================================================== RCS file: /sources/qemu/qemu/target-cris/helper.c,v retrieving revision 1.1 diff -u -d -d -p -r1.1 helper.c --- target-cris/helper.c 8 Oct 2007 13:04:02 -0000 1.1 +++ target-cris/helper.c 10 Oct 2007 03:29:07 -0000 @@ -35,7 +35,7 @@ void do_interrupt (CPUState *env) } int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { env->exception_index = 0xaa; env->debug1 = address; @@ -52,7 +52,7 @@ target_phys_addr_t cpu_get_phys_page_deb #else /* !CONFIG_USER_ONLY */ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { struct cris_mmu_result_t res; int prot, miss; @@ -61,7 +61,7 @@ int cpu_cris_handle_mmu_fault (CPUState address &= TARGET_PAGE_MASK; prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; // printf ("%s pc=%x %x w=%d smmu=%d\n", __func__, env->pc, address, rw, is_softmmu); - miss = cris_mmu_translate(&res, env, address, rw, is_user); + miss = cris_mmu_translate(&res, env, address, rw, mmu_idx); if (miss) { /* handle the miss. */ @@ -73,7 +73,7 @@ int cpu_cris_handle_mmu_fault (CPUState phy = res.phy; } // printf ("a=%x phy=%x\n", address, phy); - return tlb_set_page(env, address, phy, prot, is_user, is_softmmu); + return tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu); } Index: target-cris/mmu.c =================================================================== RCS file: /sources/qemu/qemu/target-cris/mmu.c,v retrieving revision 1.1 diff -u -d -d -p -r1.1 mmu.c --- target-cris/mmu.c 8 Oct 2007 13:11:58 -0000 1.1 +++ target-cris/mmu.c 10 Oct 2007 03:29:07 -0000 @@ -111,11 +111,12 @@ static int cris_mmu_translate_page(struc int cris_mmu_translate(struct cris_mmu_result_t *res, CPUState *env, uint32_t vaddr, - int rw, int is_user) + int rw, int mmu_idx) { uint32_t phy = vaddr; int seg; int miss = 0; + int is_user = mmu_idx; if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) { res->phy = vaddr; Index: target-cris/mmu.h =================================================================== RCS file: /sources/qemu/qemu/target-cris/mmu.h,v retrieving revision 1.1 diff -u -d -d -p -r1.1 mmu.h --- target-cris/mmu.h 8 Oct 2007 13:11:58 -0000 1.1 +++ target-cris/mmu.h 10 Oct 2007 03:29:07 -0000 @@ -17,4 +17,4 @@ struct cris_mmu_result_t int cris_mmu_translate(struct cris_mmu_result_t *res, CPUState *env, uint32_t vaddr, - int rw, int is_user); + int rw, int mmu_idx); Index: target-cris/op_helper.c =================================================================== RCS file: /sources/qemu/qemu/target-cris/op_helper.c,v retrieving revision 1.1 diff -u -d -d -p -r1.1 op_helper.c --- target-cris/op_helper.c 8 Oct 2007 13:04:02 -0000 1.1 +++ target-cris/op_helper.c 10 Oct 2007 03:29:07 -0000 @@ -41,7 +41,7 @@ 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; CPUState *saved_env; @@ -52,7 +52,7 @@ void tlb_fill (target_ulong addr, int is generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_cris_handle_mmu_fault(env, addr, is_write, is_user, 1); + ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (__builtin_expect(ret, 0)) { if (retaddr) { /* now we have a real cpu fault */ Index: target-i386/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-i386/cpu.h,v retrieving revision 1.50 diff -u -d -d -p -r1.50 cpu.h --- target-i386/cpu.h 27 Sep 2007 16:44:31 -0000 1.50 +++ target-i386/cpu.h 10 Oct 2007 03:29:07 -0000 @@ -432,6 +432,8 @@ typedef union { #define CPU_NB_REGS 8 #endif +#define NB_MMU_MODES 2 + typedef struct CPUX86State { #if TARGET_LONG_BITS > HOST_LONG_BITS /* temporaries if we cannot store them in host registers */ @@ -688,6 +690,15 @@ static inline int cpu_get_time_fast(void #define cpu_gen_code cpu_x86_gen_code #define cpu_signal_handler cpu_x86_signal_handler +/* 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->hflags & HF_CPL_MASK) == 3 ? 1 : 0; +} + #include "cpu-all.h" #include "svm.h" Index: target-i386/exec.h =================================================================== RCS file: /sources/qemu/qemu/target-i386/exec.h,v retrieving revision 1.37 diff -u -d -d -p -r1.37 exec.h --- target-i386/exec.h 23 Sep 2007 15:28:04 -0000 1.37 +++ target-i386/exec.h 10 Oct 2007 03:29:07 -0000 @@ -163,8 +163,8 @@ void cpu_x86_update_cr3(CPUX86State *env void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4); void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr); int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, - int is_write, int is_user, int is_softmmu); -void tlb_fill(target_ulong addr, int is_write, int is_user, + int is_write, int mmu_idx, int is_softmmu); +void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr); void __hidden cpu_lock(void); void __hidden cpu_unlock(void); Index: target-i386/helper.c =================================================================== RCS file: /sources/qemu/qemu/target-i386/helper.c,v retrieving revision 1.89 diff -u -d -d -p -r1.89 helper.c --- target-i386/helper.c 27 Sep 2007 01:52:00 -0000 1.89 +++ target-i386/helper.c 10 Oct 2007 03:29:08 -0000 @@ -3885,7 +3885,7 @@ void update_fp_status(void) 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; @@ -3897,7 +3897,7 @@ void tlb_fill(target_ulong addr, int is_ saved_env = env; env = cpu_single_env; - ret = cpu_x86_handle_mmu_fault(env, addr, is_write, is_user, 1); + ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (ret) { if (retaddr) { /* now we have a real cpu fault */ Index: target-i386/helper2.c =================================================================== RCS file: /sources/qemu/qemu/target-i386/helper2.c,v retrieving revision 1.52 diff -u -d -d -p -r1.52 helper2.c --- target-i386/helper2.c 23 Sep 2007 15:28:04 -0000 1.52 +++ target-i386/helper2.c 10 Oct 2007 03:29:08 -0000 @@ -571,7 +571,7 @@ void cpu_x86_flush_tlb(CPUX86State *env, #if defined(CONFIG_USER_ONLY) int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, - int is_write, int is_user, int is_softmmu) + int is_write, int mmu_idx, int is_softmmu) { /* user mode only emulation */ is_write &= 1; @@ -598,14 +598,15 @@ target_phys_addr_t cpu_get_phys_page_deb 2 = soft MMU activation required for this block */ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, - int is_write1, int is_user, int is_softmmu) + int is_write1, int mmu_idx, int is_softmmu) { uint64_t ptep, pte; uint32_t pdpe_addr, pde_addr, pte_addr; - int error_code, is_dirty, prot, page_size, ret, is_write; + int error_code, is_dirty, prot, page_size, ret, is_write, is_user; unsigned long paddr, page_offset; target_ulong vaddr, virt_addr; + is_user = mmu_idx; #if defined(DEBUG_MMU) printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n", addr, is_write1, is_user, env->eip); @@ -862,7 +863,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State paddr = (pte & TARGET_PAGE_MASK) + page_offset; vaddr = virt_addr + page_offset; - 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; do_fault_protect: error_code = PG_ERROR_P_MASK; Index: target-m68k/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-m68k/cpu.h,v retrieving revision 1.13 diff -u -d -d -p -r1.13 cpu.h --- target-m68k/cpu.h 17 Sep 2007 08:09:53 -0000 1.13 +++ target-m68k/cpu.h 10 Oct 2007 03:29:08 -0000 @@ -53,6 +53,8 @@ #define EXCP_RTE 0x100 #define EXCP_HALT_INSN 0x101 +#define NB_MMU_MODES 2 + typedef struct CPUM68KState { uint32_t dregs[8]; uint32_t aregs[8]; @@ -223,6 +225,15 @@ void register_m68k_insns (CPUM68KState * #define cpu_gen_code cpu_m68k_gen_code #define cpu_signal_handler cpu_m68k_signal_handler +/* 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->sr & SR_S) == 0 ? 1 : 0; +} + #include "cpu-all.h" #endif Index: target-m68k/exec.h =================================================================== RCS file: /sources/qemu/qemu/target-m68k/exec.h,v retrieving revision 1.4 diff -u -d -d -p -r1.4 exec.h --- target-m68k/exec.h 16 Sep 2007 21:08:03 -0000 1.4 +++ target-m68k/exec.h 10 Oct 2007 03:29:08 -0000 @@ -38,7 +38,7 @@ static inline void regs_to_env(void) } int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu); + int mmu_idx, int is_softmmu); #if !defined(CONFIG_USER_ONLY) #include "softmmu_exec.h" Index: target-m68k/helper.c =================================================================== RCS file: /sources/qemu/qemu/target-m68k/helper.c,v retrieving revision 1.7 diff -u -d -d -p -r1.7 helper.c --- target-m68k/helper.c 16 Sep 2007 21:08:03 -0000 1.7 +++ target-m68k/helper.c 10 Oct 2007 03:29:08 -0000 @@ -301,7 +301,7 @@ target_phys_addr_t cpu_get_phys_page_deb #if defined(CONFIG_USER_ONLY) int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { env->exception_index = EXCP_ACCESS; env->mmu.ar = address; @@ -311,13 +311,13 @@ int cpu_m68k_handle_mmu_fault (CPUState #else int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { int prot; address &= TARGET_PAGE_MASK; prot = PAGE_READ | PAGE_WRITE; - return tlb_set_page(env, address, address, prot, is_user, is_softmmu); + return tlb_set_page(env, address, address, prot, mmu_idx, is_softmmu); } /* Notify CPU of a pending interrupt. Prioritization and vectoring should Index: target-m68k/op_helper.c =================================================================== RCS file: /sources/qemu/qemu/target-m68k/op_helper.c,v retrieving revision 1.6 diff -u -d -d -p -r1.6 op_helper.c --- target-m68k/op_helper.c 16 Sep 2007 21:08:03 -0000 1.6 +++ target-m68k/op_helper.c 10 Oct 2007 03:29:08 -0000 @@ -49,7 +49,7 @@ extern int semihosting_enabled; 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; CPUState *saved_env; @@ -60,7 +60,7 @@ void tlb_fill (target_ulong addr, int is generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, is_user, 1); + ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (__builtin_expect(ret, 0)) { if (retaddr) { /* now we have a real cpu fault */ Index: target-mips/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-mips/cpu.h,v retrieving revision 1.47 diff -u -d -d -p -r1.47 cpu.h --- target-mips/cpu.h 27 Sep 2007 16:44:31 -0000 1.47 +++ target-mips/cpu.h 10 Oct 2007 03:29:08 -0000 @@ -107,6 +107,8 @@ struct CPUMIPSFPUContext { #define FP_UNIMPLEMENTED 32 }; +#define NB_MMU_MODES 2 + typedef struct CPUMIPSMVPContext CPUMIPSMVPContext; struct CPUMIPSMVPContext { int32_t CP0_MVPControl; @@ -482,6 +484,15 @@ int cpu_mips_register (CPUMIPSState *env #define cpu_exec cpu_mips_exec #define cpu_gen_code cpu_mips_gen_code #define cpu_signal_handler cpu_mips_signal_handler + +/* 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->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM ? 1 : 0; +} #include "cpu-all.h" Index: target-mips/exec.h =================================================================== RCS file: /sources/qemu/qemu/target-mips/exec.h,v retrieving revision 1.38 diff -u -d -d -p -r1.38 exec.h --- target-mips/exec.h 9 Oct 2007 03:39:58 -0000 1.38 +++ target-mips/exec.h 10 Oct 2007 03:29:08 -0000 @@ -105,7 +105,7 @@ void do_pmon (int function); void dump_sc (void); int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu); + int mmu_idx, int is_softmmu); void do_interrupt (CPUState *env); void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra); Index: target-mips/helper.c =================================================================== RCS file: /sources/qemu/qemu/target-mips/helper.c,v retrieving revision 1.53 diff -u -d -d -p -r1.53 helper.c --- target-mips/helper.c 30 Sep 2007 01:58:33 -0000 1.53 +++ target-mips/helper.c 10 Oct 2007 03:29:08 -0000 @@ -232,14 +232,15 @@ void cpu_mips_init_mmu (CPUState *env) #endif /* !defined(CONFIG_USER_ONLY) */ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { target_ulong physical; int prot; int exception = 0, error_code = 0; - int access_type; + int access_type, is_user; int ret = 0; + is_user = mmu_idx; if (logfile) { #if 0 cpu_dump_state(env, logfile, fprintf, 0); @@ -268,7 +269,7 @@ int cpu_mips_handle_mmu_fault (CPUState if (ret == TLBRET_MATCH) { ret = tlb_set_page(env, address & TARGET_PAGE_MASK, physical & TARGET_PAGE_MASK, prot, - is_user, is_softmmu); + mmu_idx, is_softmmu); } else if (ret < 0) { do_fault: switch (ret) { Index: target-mips/op_helper.c =================================================================== RCS file: /sources/qemu/qemu/target-mips/op_helper.c,v retrieving revision 1.65 diff -u -d -d -p -r1.65 op_helper.c --- target-mips/op_helper.c 9 Oct 2007 03:39:58 -0000 1.65 +++ target-mips/op_helper.c 10 Oct 2007 03:29:08 -0000 @@ -563,7 +563,7 @@ static void do_unaligned_access (target_ do_raise_exception ((is_write == 1) ? EXCP_AdES : EXCP_AdEL); } -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; CPUState *saved_env; @@ -574,7 +574,7 @@ void tlb_fill (target_ulong addr, int is generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_mips_handle_mmu_fault(env, addr, is_write, is_user, 1); + ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (ret) { if (retaddr) { /* now we have a real cpu fault */ Index: target-ppc/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-ppc/cpu.h,v retrieving revision 1.78 diff -u -d -d -p -r1.78 cpu.h --- target-ppc/cpu.h 8 Oct 2007 02:58:07 -0000 1.78 +++ target-ppc/cpu.h 10 Oct 2007 03:29:08 -0000 @@ -434,6 +432,12 @@ enum { POWERPC_FLAG_PMM = 0x00000400, }; +#if defined(TARGET_PPC64H) +#define NB_MMU_MODES 3 +#else +#define NB_MMU_MODES 2 +#endif + /*****************************************************************************/ /* The whole PowerPC CPU context */ struct CPUPPCState { @@ -697,6 +701,26 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, i #define cpu_exec cpu_ppc_exec #define cpu_gen_code cpu_ppc_gen_code #define cpu_signal_handler cpu_ppc_signal_handler + +/* MMU modes definitions */ +#if defined(TARGET_PPC64H) +#define MMU_MODE0_SUFFIX _user +#define MMU_MODE1_SUFFIX _kernel +#define MMU_MODE2_SUFFIX _hypv +#else +#define MMU_MODE0_SUFFIX _user +#define MMU_MODE1_SUFFIX _kernel +#endif +#define MMU_USER_IDX 0 +static inline int cpu_mmu_index (CPUState *env) +{ +#if defined(TARGET_PPC64H) + if (msr_pr == 0 && msr_hv == 1) + return 2; + else +#endif + return 1 - msr_pr; +} #include "cpu-all.h" Index: target-ppc/exec.h =================================================================== RCS file: /sources/qemu/qemu/target-ppc/exec.h,v retrieving revision 1.28 diff -u -d -d -p -r1.28 exec.h --- target-ppc/exec.h 7 Oct 2007 18:19:25 -0000 1.28 +++ target-ppc/exec.h 10 Oct 2007 03:29:08 -0000 @@ -112,7 +114,7 @@ static always_inline void regs_to_env (v } int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu); + int mmu_idx, int is_softmmu); static always_inline int cpu_halted (CPUState *env) { Index: target-ppc/helper.c =================================================================== RCS file: /sources/qemu/qemu/target-ppc/helper.c,v retrieving revision 1.75 diff -u -d -d -p -r1.75 helper.c --- target-ppc/helper.c 8 Oct 2007 02:58:07 -0000 1.75 +++ target-ppc/helper.c 10 Oct 2007 03:29:08 -0000 @@ -39,7 +40,7 @@ #if defined(CONFIG_USER_ONLY) int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { int exception, error_code; @@ -1349,7 +1543,7 @@ target_phys_addr_t cpu_get_phys_page_deb /* Perform address translation */ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { mmu_ctx_t ctx; int access_type; @@ -1370,7 +1564,7 @@ int cpu_ppc_handle_mmu_fault (CPUState * if (ret == 0) { ret = tlb_set_page(env, address & TARGET_PAGE_MASK, ctx.raddr & TARGET_PAGE_MASK, ctx.prot, - is_user, is_softmmu); + mmu_idx, is_softmmu); } else if (ret < 0) { #if defined (DEBUG_MMU) if (loglevel != 0) Index: target-ppc/op_helper.c =================================================================== RCS file: /sources/qemu/qemu/target-ppc/op_helper.c,v retrieving revision 1.49 diff -u -d -d -p -r1.49 op_helper.c --- target-ppc/op_helper.c 7 Oct 2007 17:13:43 -0000 1.49 +++ target-ppc/op_helper.c 10 Oct 2007 03:29:08 -0000 @@ -2307,7 +2315,7 @@ DO_SPE_OP1(fsctuf); 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; CPUState *saved_env; @@ -2318,7 +2326,7 @@ void tlb_fill (target_ulong addr, int is generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1); + ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (unlikely(ret != 0)) { if (likely(retaddr)) { /* now we have a real cpu fault */ Index: target-sh4/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-sh4/cpu.h,v retrieving revision 1.10 diff -u -d -d -p -r1.10 cpu.h --- target-sh4/cpu.h 16 Sep 2007 21:08:05 -0000 1.10 +++ target-sh4/cpu.h 10 Oct 2007 03:29:09 -0000 @@ -77,6 +77,8 @@ typedef struct tlb_t { #define UTLB_SIZE 64 #define ITLB_SIZE 4 +#define NB_MMU_MODES 2 + typedef struct CPUSH4State { uint32_t flags; /* general execution flags */ uint32_t gregs[24]; /* general registers */ @@ -134,6 +136,15 @@ int cpu_sh4_signal_handler(int host_sign #define cpu_gen_code cpu_sh4_gen_code #define cpu_signal_handler cpu_sh4_signal_handler +/* 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->sr & SR_MD) == 0 ? 1 : 0; +} + #include "cpu-all.h" /* Memory access type */ Index: target-sh4/exec.h =================================================================== RCS file: /sources/qemu/qemu/target-sh4/exec.h,v retrieving revision 1.5 diff -u -d -d -p -r1.5 exec.h --- target-sh4/exec.h 16 Sep 2007 21:08:05 -0000 1.5 +++ target-sh4/exec.h 10 Oct 2007 03:29:09 -0000 @@ -63,7 +63,7 @@ static inline void env_to_regs(void) } int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int is_user, int is_softmmu); + int mmu_idx, int is_softmmu); int find_itlb_entry(CPUState * env, target_ulong address, int use_asid, int update); Index: target-sh4/helper.c =================================================================== RCS file: /sources/qemu/qemu/target-sh4/helper.c,v retrieving revision 1.4 diff -u -d -d -p -r1.4 helper.c --- target-sh4/helper.c 16 Sep 2007 21:08:05 -0000 1.4 +++ target-sh4/helper.c 10 Oct 2007 03:29:09 -0000 @@ -36,7 +36,7 @@ void do_interrupt (CPUState *env) } int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { env->tea = address; switch (rw) { @@ -372,11 +372,12 @@ int get_physical_address(CPUState * env, } int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, - int is_user, int is_softmmu) + int mmu_idx, int is_softmmu) { target_ulong physical, page_offset, page_size; - int prot, ret, access_type; + int prot, ret, access_type, is_user; + is_user = mmu_idx; /* XXXXX */ #if 0 fprintf(stderr, "%s pc %08x ad %08x rw %d is_user %d smmu %d\n", @@ -426,7 +427,7 @@ int cpu_sh4_handle_mmu_fault(CPUState * address = (address & TARGET_PAGE_MASK) + page_offset; physical = (physical & TARGET_PAGE_MASK) + page_offset; - return tlb_set_page(env, address, physical, prot, is_user, is_softmmu); + return tlb_set_page(env, address, physical, prot, mmu_idx, is_softmmu); } target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) Index: target-sh4/op_helper.c =================================================================== RCS file: /sources/qemu/qemu/target-sh4/op_helper.c,v retrieving revision 1.4 diff -u -d -d -p -r1.4 op_helper.c --- target-sh4/op_helper.c 16 Sep 2007 21:08:05 -0000 1.4 +++ target-sh4/op_helper.c 10 Oct 2007 03:29:09 -0000 @@ -42,7 +42,7 @@ void do_raise_exception(void) #define SHIFT 3 #include "softmmu_template.h" -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; CPUState *saved_env; @@ -53,7 +53,7 @@ void tlb_fill(target_ulong addr, int is_ generated code */ saved_env = env; env = cpu_single_env; - ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, is_user, 1); + ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1); if (ret) { if (retaddr) { /* now we have a real cpu fault */ Index: target-sparc/cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v retrieving revision 1.52 diff -u -d -d -p -r1.52 cpu.h --- target-sparc/cpu.h 27 Sep 2007 16:44:32 -0000 1.52 +++ target-sparc/cpu.h 10 Oct 2007 03:29:09 -0000 @@ -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 */ @@ -315,6 +317,15 @@ void cpu_check_irqs(CPUSPARCState *env); #define cpu_exec cpu_sparc_exec #define cpu_gen_code cpu_sparc_gen_code #define cpu_signal_handler cpu_sparc_signal_handler + +/* 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" Index: target-sparc/exec.h =================================================================== RCS file: /sources/qemu/qemu/target-sparc/exec.h,v retrieving revision 1.21 diff -u -d -d -p -r1.21 exec.h --- target-sparc/exec.h 30 Sep 2007 19:38:11 -0000 1.21 +++ target-sparc/exec.h 10 Oct 2007 03:29:09 -0000 @@ -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) Index: target-sparc/helper.c =================================================================== RCS file: /sources/qemu/qemu/target-sparc/helper.c,v retrieving revision 1.27 diff -u -d -d -p -r1.27 helper.c --- target-sparc/helper.c 24 Sep 2007 19:44:09 -0000 1.27 +++ target-sparc/helper.c 10 Oct 2007 03:29:09 -0000 @@ -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; 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, /* 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 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 // 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(CPU 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; + 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, /* 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 Index: target-sparc/op_helper.c =================================================================== RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v retrieving revision 1.41 diff -u -d -d -p -r1.41 op_helper.c --- target-sparc/op_helper.c 1 Oct 2007 17:07:58 -0000 1.41 +++ target-sparc/op_helper.c 10 Oct 2007 03:29:10 -0000 @@ -1522,7 +1522,7 @@ static void do_unaligned_access(target_u 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_ 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 */ Index: target-sparc/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-sparc/translate.c,v retrieving revision 1.73 diff -u -d -d -p -r1.73 translate.c --- target-sparc/translate.c 3 Oct 2007 17:46:29 -0000 1.73 +++ target-sparc/translate.c 10 Oct 2007 03:29:10 -0000 @@ -3687,8 +3687,8 @@ target_phys_addr_t cpu_get_phys_page_deb #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) {