Commit 6ebbf390003270afece028facef4d9834df81a8c

Authored by j_mayer
1 parent d0f48074

Replace is_user variable with mmu_idx in softmmu core,

allowing support of more than 2 mmu access modes.
Add backward compatibility is_user variable in targets code when needed.
Implement per target cpu_mmu_index function, avoiding duplicated code
  and #ifdef TARGET_xxx in softmmu core functions.
Implement per target mmu modes definitions. As an example, add PowerPC
  hypervisor mode definition and Alpha executive and kernel modes definitions.
Optimize PowerPC case, precomputing mmu_idx when MSR register changes
  and using the same definition in code translation code.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3384 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-defs.h
@@ -112,15 +112,6 @@ typedef struct CPUTLBEntry { @@ -112,15 +112,6 @@ typedef struct CPUTLBEntry {
112 target_phys_addr_t addend; 112 target_phys_addr_t addend;
113 } CPUTLBEntry; 113 } CPUTLBEntry;
114 114
115 -/* Alpha has 4 different running levels */  
116 -#if defined(TARGET_ALPHA)  
117 -#define NB_MMU_MODES 4  
118 -#elif defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */  
119 -#define NB_MMU_MODES 3  
120 -#else  
121 -#define NB_MMU_MODES 2  
122 -#endif  
123 -  
124 #define CPU_COMMON \ 115 #define CPU_COMMON \
125 struct TranslationBlock *current_tb; /* currently executing TB */ \ 116 struct TranslationBlock *current_tb; /* currently executing TB */ \
126 /* soft mmu support */ \ 117 /* soft mmu support */ \
cpu-exec.c
@@ -884,8 +884,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -884,8 +884,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
884 } 884 }
885 885
886 /* see if it is an MMU fault */ 886 /* see if it is an MMU fault */
887 - ret = cpu_x86_handle_mmu_fault(env, address, is_write,  
888 - ((env->hflags & HF_CPL_MASK) == 3), 0); 887 + ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
889 if (ret < 0) 888 if (ret < 0)
890 return 0; /* not an MMU fault */ 889 return 0; /* not an MMU fault */
891 if (ret == 0) 890 if (ret == 0)
@@ -934,7 +933,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -934,7 +933,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
934 return 1; 933 return 1;
935 } 934 }
936 /* see if it is an MMU fault */ 935 /* see if it is an MMU fault */
937 - ret = cpu_arm_handle_mmu_fault(env, address, is_write, 1, 0); 936 + ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
938 if (ret < 0) 937 if (ret < 0)
939 return 0; /* not an MMU fault */ 938 return 0; /* not an MMU fault */
940 if (ret == 0) 939 if (ret == 0)
@@ -970,7 +969,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -970,7 +969,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
970 return 1; 969 return 1;
971 } 970 }
972 /* see if it is an MMU fault */ 971 /* see if it is an MMU fault */
973 - ret = cpu_sparc_handle_mmu_fault(env, address, is_write, 1, 0); 972 + ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
974 if (ret < 0) 973 if (ret < 0)
975 return 0; /* not an MMU fault */ 974 return 0; /* not an MMU fault */
976 if (ret == 0) 975 if (ret == 0)
@@ -1007,7 +1006,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -1007,7 +1006,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1007 } 1006 }
1008 1007
1009 /* see if it is an MMU fault */ 1008 /* see if it is an MMU fault */
1010 - ret = cpu_ppc_handle_mmu_fault(env, address, is_write, msr_pr, 0); 1009 + ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1011 if (ret < 0) 1010 if (ret < 0)
1012 return 0; /* not an MMU fault */ 1011 return 0; /* not an MMU fault */
1013 if (ret == 0) 1012 if (ret == 0)
@@ -1056,7 +1055,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -1056,7 +1055,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1056 return 1; 1055 return 1;
1057 } 1056 }
1058 /* see if it is an MMU fault */ 1057 /* see if it is an MMU fault */
1059 - ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 0); 1058 + ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1060 if (ret < 0) 1059 if (ret < 0)
1061 return 0; /* not an MMU fault */ 1060 return 0; /* not an MMU fault */
1062 if (ret == 0) 1061 if (ret == 0)
@@ -1096,7 +1095,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -1096,7 +1095,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1096 } 1095 }
1097 1096
1098 /* see if it is an MMU fault */ 1097 /* see if it is an MMU fault */
1099 - ret = cpu_mips_handle_mmu_fault(env, address, is_write, 1, 0); 1098 + ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1100 if (ret < 0) 1099 if (ret < 0)
1101 return 0; /* not an MMU fault */ 1100 return 0; /* not an MMU fault */
1102 if (ret == 0) 1101 if (ret == 0)
@@ -1146,7 +1145,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -1146,7 +1145,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1146 } 1145 }
1147 1146
1148 /* see if it is an MMU fault */ 1147 /* see if it is an MMU fault */
1149 - ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0); 1148 + ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1150 if (ret < 0) 1149 if (ret < 0)
1151 return 0; /* not an MMU fault */ 1150 return 0; /* not an MMU fault */
1152 if (ret == 0) 1151 if (ret == 0)
@@ -1191,7 +1190,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -1191,7 +1190,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1191 } 1190 }
1192 1191
1193 /* see if it is an MMU fault */ 1192 /* see if it is an MMU fault */
1194 - ret = cpu_alpha_handle_mmu_fault(env, address, is_write, 1, 0); 1193 + ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1195 if (ret < 0) 1194 if (ret < 0)
1196 return 0; /* not an MMU fault */ 1195 return 0; /* not an MMU fault */
1197 if (ret == 0) 1196 if (ret == 0)
@@ -1235,7 +1234,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, @@ -1235,7 +1234,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1235 } 1234 }
1236 1235
1237 /* see if it is an MMU fault */ 1236 /* see if it is an MMU fault */
1238 - ret = cpu_cris_handle_mmu_fault(env, address, is_write, 1, 0); 1237 + ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1239 if (ret < 0) 1238 if (ret < 0)
1240 return 0; /* not an MMU fault */ 1239 return 0; /* not an MMU fault */
1241 if (ret == 0) 1240 if (ret == 0)
exec-all.h
@@ -117,14 +117,14 @@ void tlb_flush_page(CPUState *env, target_ulong addr); @@ -117,14 +117,14 @@ void tlb_flush_page(CPUState *env, target_ulong addr);
117 void tlb_flush(CPUState *env, int flush_global); 117 void tlb_flush(CPUState *env, int flush_global);
118 int tlb_set_page_exec(CPUState *env, target_ulong vaddr, 118 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
119 target_phys_addr_t paddr, int prot, 119 target_phys_addr_t paddr, int prot,
120 - int is_user, int is_softmmu); 120 + int mmu_idx, int is_softmmu);
121 static inline int tlb_set_page(CPUState *env, target_ulong vaddr, 121 static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
122 target_phys_addr_t paddr, int prot, 122 target_phys_addr_t paddr, int prot,
123 - int is_user, int is_softmmu) 123 + int mmu_idx, int is_softmmu)
124 { 124 {
125 if (prot & PAGE_READ) 125 if (prot & PAGE_READ)
126 prot |= PAGE_EXEC; 126 prot |= PAGE_EXEC;
127 - return tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); 127 + return tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
128 } 128 }
129 129
130 #define CODE_GEN_MAX_SIZE 65536 130 #define CODE_GEN_MAX_SIZE 65536
@@ -562,10 +562,10 @@ extern int tb_invalidated_flag; @@ -562,10 +562,10 @@ extern int tb_invalidated_flag;
562 562
563 #if !defined(CONFIG_USER_ONLY) 563 #if !defined(CONFIG_USER_ONLY)
564 564
565 -void tlb_fill(target_ulong addr, int is_write, int is_user, 565 +void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
566 void *retaddr); 566 void *retaddr);
567 567
568 -#define ACCESS_TYPE 3 568 +#define ACCESS_TYPE (NB_MMU_MODES + 1)
569 #define MEMSUFFIX _code 569 #define MEMSUFFIX _code
570 #define env cpu_single_env 570 #define env cpu_single_env
571 571
@@ -598,35 +598,15 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) @@ -598,35 +598,15 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
598 is the offset relative to phys_ram_base */ 598 is the offset relative to phys_ram_base */
599 static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) 599 static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
600 { 600 {
601 - int is_user, index, pd; 601 + int mmu_idx, index, pd;
602 602
603 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 603 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
604 -#if defined(TARGET_I386)  
605 - is_user = ((env->hflags & HF_CPL_MASK) == 3);  
606 -#elif defined (TARGET_PPC)  
607 - is_user = msr_pr;  
608 -#elif defined (TARGET_MIPS)  
609 - is_user = ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);  
610 -#elif defined (TARGET_SPARC)  
611 - is_user = (env->psrs == 0);  
612 -#elif defined (TARGET_ARM)  
613 - is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);  
614 -#elif defined (TARGET_SH4)  
615 - is_user = ((env->sr & SR_MD) == 0);  
616 -#elif defined (TARGET_ALPHA)  
617 - is_user = ((env->ps >> 3) & 3);  
618 -#elif defined (TARGET_M68K)  
619 - is_user = ((env->sr & SR_S) == 0);  
620 -#elif defined (TARGET_CRIS)  
621 - is_user = (0);  
622 -#else  
623 -#error unimplemented CPU  
624 -#endif  
625 - if (__builtin_expect(env->tlb_table[is_user][index].addr_code != 604 + mmu_idx = cpu_mmu_index(env);
  605 + if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_code !=
626 (addr & TARGET_PAGE_MASK), 0)) { 606 (addr & TARGET_PAGE_MASK), 0)) {
627 ldub_code(addr); 607 ldub_code(addr);
628 } 608 }
629 - pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK; 609 + pd = env->tlb_table[mmu_idx][index].addr_code & ~TARGET_PAGE_MASK;
630 if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { 610 if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
631 #ifdef TARGET_SPARC 611 #ifdef TARGET_SPARC
632 do_unassigned_access(addr, 0, 1, 0); 612 do_unassigned_access(addr, 0, 1, 0);
@@ -634,7 +614,7 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) @@ -634,7 +614,7 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
634 cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr); 614 cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
635 #endif 615 #endif
636 } 616 }
637 - return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base; 617 + return addr + env->tlb_table[mmu_idx][index].addend - (unsigned long)phys_ram_base;
638 } 618 }
639 #endif 619 #endif
640 620
@@ -1608,7 +1608,7 @@ static inline void tlb_set_dirty(CPUState *env, @@ -1608,7 +1608,7 @@ static inline void tlb_set_dirty(CPUState *env,
1608 conflicting with the host address space). */ 1608 conflicting with the host address space). */
1609 int tlb_set_page_exec(CPUState *env, target_ulong vaddr, 1609 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1610 target_phys_addr_t paddr, int prot, 1610 target_phys_addr_t paddr, int prot,
1611 - int is_user, int is_softmmu) 1611 + int mmu_idx, int is_softmmu)
1612 { 1612 {
1613 PhysPageDesc *p; 1613 PhysPageDesc *p;
1614 unsigned long pd; 1614 unsigned long pd;
@@ -1626,8 +1626,8 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, @@ -1626,8 +1626,8 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1626 pd = p->phys_offset; 1626 pd = p->phys_offset;
1627 } 1627 }
1628 #if defined(DEBUG_TLB) 1628 #if defined(DEBUG_TLB)
1629 - printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x u=%d smmu=%d pd=0x%08lx\n",  
1630 - vaddr, (int)paddr, prot, is_user, is_softmmu, pd); 1629 + printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x%08x prot=%x idx=%d smmu=%d pd=0x%08lx\n",
  1630 + vaddr, (int)paddr, prot, mmu_idx, is_softmmu, pd);
1631 #endif 1631 #endif
1632 1632
1633 ret = 0; 1633 ret = 0;
@@ -1664,7 +1664,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, @@ -1664,7 +1664,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1664 1664
1665 index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 1665 index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1666 addend -= vaddr; 1666 addend -= vaddr;
1667 - te = &env->tlb_table[is_user][index]; 1667 + te = &env->tlb_table[mmu_idx][index];
1668 te->addend = addend; 1668 te->addend = addend;
1669 if (prot & PAGE_READ) { 1669 if (prot & PAGE_READ) {
1670 te->addr_read = address; 1670 te->addr_read = address;
@@ -1790,7 +1790,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr) @@ -1790,7 +1790,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
1790 1790
1791 int tlb_set_page_exec(CPUState *env, target_ulong vaddr, 1791 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1792 target_phys_addr_t paddr, int prot, 1792 target_phys_addr_t paddr, int prot,
1793 - int is_user, int is_softmmu) 1793 + int mmu_idx, int is_softmmu)
1794 { 1794 {
1795 return 0; 1795 return 0;
1796 } 1796 }
hw/alpha_palcode.c
@@ -811,12 +811,14 @@ static int get_page_bits (CPUState *env) @@ -811,12 +811,14 @@ static int get_page_bits (CPUState *env)
811 811
812 static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp, 812 static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
813 uint64_t ptebase, int page_bits, uint64_t level, 813 uint64_t ptebase, int page_bits, uint64_t level,
814 - int is_user, int rw) 814 + int mmu_idx, int rw)
815 { 815 {
816 uint64_t pteaddr, pte, pfn; 816 uint64_t pteaddr, pte, pfn;
817 uint8_t gh; 817 uint8_t gh;
818 - int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar; 818 + int ure, uwe, kre, kwe, foE, foR, foW, v, ret, ar, is_user;
819 819
  820 + /* XXX: TOFIX */
  821 + is_user = mmu_idx == MMU_USER_IDX;
820 pteaddr = (ptebase << page_bits) + (8 * level); 822 pteaddr = (ptebase << page_bits) + (8 * level);
821 pte = ldq_raw(pteaddr); 823 pte = ldq_raw(pteaddr);
822 /* Decode all interresting PTE fields */ 824 /* Decode all interresting PTE fields */
@@ -871,7 +873,7 @@ static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp, @@ -871,7 +873,7 @@ static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
871 873
872 static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot, 874 static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
873 uint64_t ptebase, int page_bits, 875 uint64_t ptebase, int page_bits,
874 - uint64_t vaddr, int is_user, int rw) 876 + uint64_t vaddr, int mmu_idx, int rw)
875 { 877 {
876 uint64_t pfn, page_mask, lvl_mask, level1, level2, level3; 878 uint64_t pfn, page_mask, lvl_mask, level1, level2, level3;
877 int lvl_bits, ret; 879 int lvl_bits, ret;
@@ -909,7 +911,7 @@ static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot, @@ -909,7 +911,7 @@ static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
909 break; 911 break;
910 } 912 }
911 /* Level 3 PTE */ 913 /* Level 3 PTE */
912 - ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, is_user, rw); 914 + ret = get_pte(&pfn, zbitsp, prot, pfn, page_bits, level3, mmu_idx, rw);
913 if (ret & 0x1) { 915 if (ret & 0x1) {
914 /* Translation not valid */ 916 /* Translation not valid */
915 ret = 1; 917 ret = 1;
@@ -943,7 +945,7 @@ static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot, @@ -943,7 +945,7 @@ static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
943 945
944 static int virtual_to_physical (CPUState *env, uint64_t *physp, 946 static int virtual_to_physical (CPUState *env, uint64_t *physp,
945 int *zbitsp, int *protp, 947 int *zbitsp, int *protp,
946 - uint64_t virtual, int is_user, int rw) 948 + uint64_t virtual, int mmu_idx, int rw)
947 { 949 {
948 uint64_t sva, ptebase; 950 uint64_t sva, ptebase;
949 int seg, page_bits, ret; 951 int seg, page_bits, ret;
@@ -961,16 +963,16 @@ static int virtual_to_physical (CPUState *env, uint64_t *physp, @@ -961,16 +963,16 @@ static int virtual_to_physical (CPUState *env, uint64_t *physp,
961 case 0: 963 case 0:
962 /* seg1: 3 levels of PTE */ 964 /* seg1: 3 levels of PTE */
963 ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits, 965 ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
964 - virtual, is_user, rw); 966 + virtual, mmu_idx, rw);
965 break; 967 break;
966 case 1: 968 case 1:
967 /* seg1: 2 levels of PTE */ 969 /* seg1: 2 levels of PTE */
968 ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits, 970 ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
969 - virtual, is_user, rw); 971 + virtual, mmu_idx, rw);
970 break; 972 break;
971 case 2: 973 case 2:
972 /* kernel segment */ 974 /* kernel segment */
973 - if (is_user) { 975 + if (mmu_idx != 0) {
974 ret = 2; 976 ret = 2;
975 } else { 977 } else {
976 *physp = virtual; 978 *physp = virtual;
@@ -979,7 +981,7 @@ static int virtual_to_physical (CPUState *env, uint64_t *physp, @@ -979,7 +981,7 @@ static int virtual_to_physical (CPUState *env, uint64_t *physp,
979 case 3: 981 case 3:
980 /* seg1: TB mapped */ 982 /* seg1: TB mapped */
981 ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits, 983 ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
982 - virtual, is_user, rw); 984 + virtual, mmu_idx, rw);
983 break; 985 break;
984 default: 986 default:
985 ret = 1; 987 ret = 1;
@@ -991,7 +993,7 @@ static int virtual_to_physical (CPUState *env, uint64_t *physp, @@ -991,7 +993,7 @@ static int virtual_to_physical (CPUState *env, uint64_t *physp,
991 993
992 /* XXX: code provision */ 994 /* XXX: code provision */
993 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, 995 int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
994 - int is_user, int is_softmmu) 996 + int mmu_idx, int is_softmmu)
995 { 997 {
996 uint64_t physical, page_size, end; 998 uint64_t physical, page_size, end;
997 int prot, zbits, ret; 999 int prot, zbits, ret;
@@ -1000,7 +1002,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -1000,7 +1002,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
1000 ret = 2; 1002 ret = 2;
1001 } else { 1003 } else {
1002 ret = virtual_to_physical(env, &physical, &zbits, &prot, 1004 ret = virtual_to_physical(env, &physical, &zbits, &prot,
1003 - address, is_user, rw); 1005 + address, mmu_idx, rw);
1004 } 1006 }
1005 switch (ret) { 1007 switch (ret) {
1006 case 0: 1008 case 0:
@@ -1009,7 +1011,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -1009,7 +1011,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
1009 address &= ~(page_size - 1); 1011 address &= ~(page_size - 1);
1010 for (end = physical + page_size; physical < end; physical += 0x1000) { 1012 for (end = physical + page_size; physical < end; physical += 0x1000) {
1011 ret = tlb_set_page(env, address, physical, prot, 1013 ret = tlb_set_page(env, address, physical, prot,
1012 - is_user, is_softmmu); 1014 + mmu_idx, is_softmmu);
1013 address += 0x1000; 1015 address += 0x1000;
1014 } 1016 }
1015 break; 1017 break;
softmmu_exec.h
1 /* Common softmmu definitions and inline routines. */ 1 /* Common softmmu definitions and inline routines. */
2 2
3 -#define ldul_user ldl_user  
4 -#define ldul_kernel ldl_kernel 3 +/* XXX: find something cleaner.
  4 + * Furthermore, this is false for 64 bits targets
  5 + */
  6 +#define ldul_user ldl_user
  7 +#define ldul_kernel ldl_kernel
  8 +#define ldul_hypv ldl_hypv
  9 +#define ldul_executive ldl_executive
  10 +#define ldul_supervisor ldl_supervisor
5 11
6 #define ACCESS_TYPE 0 12 #define ACCESS_TYPE 0
7 -#define MEMSUFFIX _kernel 13 +#define MEMSUFFIX MMU_MODE0_SUFFIX
8 #define DATA_SIZE 1 14 #define DATA_SIZE 1
9 #include "softmmu_header.h" 15 #include "softmmu_header.h"
10 16
@@ -20,7 +26,7 @@ @@ -20,7 +26,7 @@
20 #undef MEMSUFFIX 26 #undef MEMSUFFIX
21 27
22 #define ACCESS_TYPE 1 28 #define ACCESS_TYPE 1
23 -#define MEMSUFFIX _user 29 +#define MEMSUFFIX MMU_MODE1_SUFFIX
24 #define DATA_SIZE 1 30 #define DATA_SIZE 1
25 #include "softmmu_header.h" 31 #include "softmmu_header.h"
26 32
@@ -35,8 +41,50 @@ @@ -35,8 +41,50 @@
35 #undef ACCESS_TYPE 41 #undef ACCESS_TYPE
36 #undef MEMSUFFIX 42 #undef MEMSUFFIX
37 43
38 -/* these access are slower, they must be as rare as possible */ 44 +#if (NB_MMU_MODES >= 3)
  45 +
39 #define ACCESS_TYPE 2 46 #define ACCESS_TYPE 2
  47 +#define MEMSUFFIX MMU_MODE2_SUFFIX
  48 +#define DATA_SIZE 1
  49 +#include "softmmu_header.h"
  50 +
  51 +#define DATA_SIZE 2
  52 +#include "softmmu_header.h"
  53 +
  54 +#define DATA_SIZE 4
  55 +#include "softmmu_header.h"
  56 +
  57 +#define DATA_SIZE 8
  58 +#include "softmmu_header.h"
  59 +#undef ACCESS_TYPE
  60 +#undef MEMSUFFIX
  61 +
  62 +#if (NB_MMU_MODES >= 4)
  63 +
  64 +#define ACCESS_TYPE 3
  65 +#define MEMSUFFIX MMU_MODE3_SUFFIX
  66 +#define DATA_SIZE 1
  67 +#include "softmmu_header.h"
  68 +
  69 +#define DATA_SIZE 2
  70 +#include "softmmu_header.h"
  71 +
  72 +#define DATA_SIZE 4
  73 +#include "softmmu_header.h"
  74 +
  75 +#define DATA_SIZE 8
  76 +#include "softmmu_header.h"
  77 +#undef ACCESS_TYPE
  78 +#undef MEMSUFFIX
  79 +
  80 +#if (NB_MMU_MODES > 4)
  81 +#error "NB_MMU_MODES > 4 is not supported for now"
  82 +#endif /* (NB_MMU_MODES > 4) */
  83 +#endif /* (NB_MMU_MODES == 4) */
  84 +#endif /* (NB_MMU_MODES >= 3) */
  85 +
  86 +/* these access are slower, they must be as rare as possible */
  87 +#define ACCESS_TYPE (NB_MMU_MODES)
40 #define MEMSUFFIX _data 88 #define MEMSUFFIX _data
41 #define DATA_SIZE 1 89 #define DATA_SIZE 1
42 #include "softmmu_header.h" 90 #include "softmmu_header.h"
softmmu_header.h
@@ -39,66 +39,19 @@ @@ -39,66 +39,19 @@
39 #error unsupported data size 39 #error unsupported data size
40 #endif 40 #endif
41 41
42 -#if ACCESS_TYPE == 0 42 +#if ACCESS_TYPE < (NB_MMU_MODES)
43 43
44 -#define CPU_MEM_INDEX 0 44 +#define CPU_MMU_INDEX ACCESS_TYPE
45 #define MMUSUFFIX _mmu 45 #define MMUSUFFIX _mmu
46 46
47 -#elif ACCESS_TYPE == 1 47 +#elif ACCESS_TYPE == (NB_MMU_MODES)
48 48
49 -#define CPU_MEM_INDEX 1 49 +#define CPU_MMU_INDEX (cpu_mmu_index(env))
50 #define MMUSUFFIX _mmu 50 #define MMUSUFFIX _mmu
51 51
52 -#elif ACCESS_TYPE == 2  
53 -  
54 -#ifdef TARGET_I386  
55 -#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)  
56 -#elif defined (TARGET_PPC)  
57 -#define CPU_MEM_INDEX (msr_pr)  
58 -#elif defined (TARGET_MIPS)  
59 -#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)  
60 -#elif defined (TARGET_SPARC)  
61 -#define CPU_MEM_INDEX ((env->psrs) == 0)  
62 -#elif defined (TARGET_ARM)  
63 -#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)  
64 -#elif defined (TARGET_SH4)  
65 -#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)  
66 -#elif defined (TARGET_ALPHA)  
67 -#define CPU_MEM_INDEX ((env->ps >> 3) & 3)  
68 -#elif defined (TARGET_M68K)  
69 -#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)  
70 -#elif defined (TARGET_CRIS)  
71 -/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */  
72 -#define CPU_MEM_INDEX (0)  
73 -#else  
74 -#error unsupported CPU  
75 -#endif  
76 -#define MMUSUFFIX _mmu 52 +#elif ACCESS_TYPE == (NB_MMU_MODES + 1)
77 53
78 -#elif ACCESS_TYPE == 3  
79 -  
80 -#ifdef TARGET_I386  
81 -#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)  
82 -#elif defined (TARGET_PPC)  
83 -#define CPU_MEM_INDEX (msr_pr)  
84 -#elif defined (TARGET_MIPS)  
85 -#define CPU_MEM_INDEX ((env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM)  
86 -#elif defined (TARGET_SPARC)  
87 -#define CPU_MEM_INDEX ((env->psrs) == 0)  
88 -#elif defined (TARGET_ARM)  
89 -#define CPU_MEM_INDEX ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR)  
90 -#elif defined (TARGET_SH4)  
91 -#define CPU_MEM_INDEX ((env->sr & SR_MD) == 0)  
92 -#elif defined (TARGET_ALPHA)  
93 -#define CPU_MEM_INDEX ((env->ps >> 3) & 3)  
94 -#elif defined (TARGET_M68K)  
95 -#define CPU_MEM_INDEX ((env->sr & SR_S) == 0)  
96 -#elif defined (TARGET_CRIS)  
97 -/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */  
98 -#define CPU_MEM_INDEX (0)  
99 -#else  
100 -#error unsupported CPU  
101 -#endif 54 +#define CPU_MMU_INDEX (cpu_mmu_index(env))
102 #define MMUSUFFIX _cmmu 55 #define MMUSUFFIX _cmmu
103 56
104 #else 57 #else
@@ -111,18 +64,18 @@ @@ -111,18 +64,18 @@
111 #define RES_TYPE int 64 #define RES_TYPE int
112 #endif 65 #endif
113 66
114 -#if ACCESS_TYPE == 3 67 +#if ACCESS_TYPE == (NB_MMU_MODES + 1)
115 #define ADDR_READ addr_code 68 #define ADDR_READ addr_code
116 #else 69 #else
117 #define ADDR_READ addr_read 70 #define ADDR_READ addr_read
118 #endif 71 #endif
119 72
120 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 73 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
121 - int is_user);  
122 -void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int is_user); 74 + int mmu_idx);
  75 +void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, DATA_TYPE v, int mmu_idx);
123 76
124 #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \ 77 #if (DATA_SIZE <= 4) && (TARGET_LONG_BITS == 32) && defined(__i386__) && \
125 - (ACCESS_TYPE <= 1) && defined(ASM_SOFTMMU) 78 + (ACCESS_TYPE < NB_MMU_MODES) && defined(ASM_SOFTMMU)
126 79
127 #define CPU_TLB_ENTRY_BITS 4 80 #define CPU_TLB_ENTRY_BITS 4
128 81
@@ -161,8 +114,8 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) @@ -161,8 +114,8 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
161 "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), 114 "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
162 "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), 115 "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
163 "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), 116 "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
164 - "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),  
165 - "i" (CPU_MEM_INDEX), 117 + "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
  118 + "i" (CPU_MMU_INDEX),
166 "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) 119 "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
167 : "%eax", "%ecx", "%edx", "memory", "cc"); 120 : "%eax", "%ecx", "%edx", "memory", "cc");
168 return res; 121 return res;
@@ -208,8 +161,8 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr) @@ -208,8 +161,8 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
208 "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), 161 "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
209 "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), 162 "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
210 "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), 163 "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
211 - "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_read)),  
212 - "i" (CPU_MEM_INDEX), 164 + "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_read)),
  165 + "i" (CPU_MMU_INDEX),
213 "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX)) 166 "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
214 : "%eax", "%ecx", "%edx", "memory", "cc"); 167 : "%eax", "%ecx", "%edx", "memory", "cc");
215 return res; 168 return res;
@@ -260,8 +213,8 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE @@ -260,8 +213,8 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
260 "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), 213 "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
261 "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), 214 "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
262 "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), 215 "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)),
263 - "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MEM_INDEX][0].addr_write)),  
264 - "i" (CPU_MEM_INDEX), 216 + "m" (*(uint32_t *)offsetof(CPUState, tlb_table[CPU_MMU_INDEX][0].addr_write)),
  217 + "i" (CPU_MMU_INDEX),
265 "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX)) 218 "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
266 : "%eax", "%ecx", "%edx", "memory", "cc"); 219 : "%eax", "%ecx", "%edx", "memory", "cc");
267 } 220 }
@@ -276,16 +229,16 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) @@ -276,16 +229,16 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
276 RES_TYPE res; 229 RES_TYPE res;
277 target_ulong addr; 230 target_ulong addr;
278 unsigned long physaddr; 231 unsigned long physaddr;
279 - int is_user; 232 + int mmu_idx;
280 233
281 addr = ptr; 234 addr = ptr;
282 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 235 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
283 - is_user = CPU_MEM_INDEX;  
284 - if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ != 236 + mmu_idx = CPU_MMU_INDEX;
  237 + if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
285 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { 238 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
286 - res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user); 239 + res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
287 } else { 240 } else {
288 - physaddr = addr + env->tlb_table[is_user][index].addend; 241 + physaddr = addr + env->tlb_table[mmu_idx][index].addend;
289 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); 242 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
290 } 243 }
291 return res; 244 return res;
@@ -297,23 +250,23 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr) @@ -297,23 +250,23 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
297 int res, index; 250 int res, index;
298 target_ulong addr; 251 target_ulong addr;
299 unsigned long physaddr; 252 unsigned long physaddr;
300 - int is_user; 253 + int mmu_idx;
301 254
302 addr = ptr; 255 addr = ptr;
303 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 256 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
304 - is_user = CPU_MEM_INDEX;  
305 - if (__builtin_expect(env->tlb_table[is_user][index].ADDR_READ != 257 + mmu_idx = CPU_MMU_INDEX;
  258 + if (__builtin_expect(env->tlb_table[mmu_idx][index].ADDR_READ !=
306 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { 259 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
307 - res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user); 260 + res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
308 } else { 261 } else {
309 - physaddr = addr + env->tlb_table[is_user][index].addend; 262 + physaddr = addr + env->tlb_table[mmu_idx][index].addend;
310 res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr); 263 res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
311 } 264 }
312 return res; 265 return res;
313 } 266 }
314 #endif 267 #endif
315 268
316 -#if ACCESS_TYPE != 3 269 +#if ACCESS_TYPE != (NB_MMU_MODES + 1)
317 270
318 /* generic store macro */ 271 /* generic store macro */
319 272
@@ -322,25 +275,25 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE @@ -322,25 +275,25 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
322 int index; 275 int index;
323 target_ulong addr; 276 target_ulong addr;
324 unsigned long physaddr; 277 unsigned long physaddr;
325 - int is_user; 278 + int mmu_idx;
326 279
327 addr = ptr; 280 addr = ptr;
328 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 281 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
329 - is_user = CPU_MEM_INDEX;  
330 - if (__builtin_expect(env->tlb_table[is_user][index].addr_write != 282 + mmu_idx = CPU_MMU_INDEX;
  283 + if (__builtin_expect(env->tlb_table[mmu_idx][index].addr_write !=
331 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { 284 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) {
332 - glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user); 285 + glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
333 } else { 286 } else {
334 - physaddr = addr + env->tlb_table[is_user][index].addend; 287 + physaddr = addr + env->tlb_table[mmu_idx][index].addend;
335 glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v); 288 glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
336 } 289 }
337 } 290 }
338 291
339 -#endif /* ACCESS_TYPE != 3 */ 292 +#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
340 293
341 #endif /* !asm */ 294 #endif /* !asm */
342 295
343 -#if ACCESS_TYPE != 3 296 +#if ACCESS_TYPE != (NB_MMU_MODES + 1)
344 297
345 #if DATA_SIZE == 8 298 #if DATA_SIZE == 8
346 static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr) 299 static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
@@ -386,7 +339,7 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v) @@ -386,7 +339,7 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
386 } 339 }
387 #endif /* DATA_SIZE == 4 */ 340 #endif /* DATA_SIZE == 4 */
388 341
389 -#endif /* ACCESS_TYPE != 3 */ 342 +#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
390 343
391 #undef RES_TYPE 344 #undef RES_TYPE
392 #undef DATA_TYPE 345 #undef DATA_TYPE
@@ -394,6 +347,6 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v) @@ -394,6 +347,6 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
394 #undef SUFFIX 347 #undef SUFFIX
395 #undef USUFFIX 348 #undef USUFFIX
396 #undef DATA_SIZE 349 #undef DATA_SIZE
397 -#undef CPU_MEM_INDEX 350 +#undef CPU_MMU_INDEX
398 #undef MMUSUFFIX 351 #undef MMUSUFFIX
399 #undef ADDR_READ 352 #undef ADDR_READ
softmmu_template.h
@@ -48,7 +48,7 @@ @@ -48,7 +48,7 @@
48 #endif 48 #endif
49 49
50 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 50 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
51 - int is_user, 51 + int mmu_idx,
52 void *retaddr); 52 void *retaddr);
53 static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, 53 static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
54 target_ulong tlb_addr) 54 target_ulong tlb_addr)
@@ -76,7 +76,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, @@ -76,7 +76,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
76 76
77 /* handle all cases except unaligned access which span two pages */ 77 /* handle all cases except unaligned access which span two pages */
78 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 78 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
79 - int is_user) 79 + int mmu_idx)
80 { 80 {
81 DATA_TYPE res; 81 DATA_TYPE res;
82 int index; 82 int index;
@@ -88,9 +88,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -88,9 +88,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
88 /* XXX: could done more in memory macro in a non portable way */ 88 /* XXX: could done more in memory macro in a non portable way */
89 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 89 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
90 redo: 90 redo:
91 - tlb_addr = env->tlb_table[is_user][index].ADDR_READ; 91 + tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
92 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 92 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
93 - physaddr = addr + env->tlb_table[is_user][index].addend; 93 + physaddr = addr + env->tlb_table[mmu_idx][index].addend;
94 if (tlb_addr & ~TARGET_PAGE_MASK) { 94 if (tlb_addr & ~TARGET_PAGE_MASK) {
95 /* IO access */ 95 /* IO access */
96 if ((addr & (DATA_SIZE - 1)) != 0) 96 if ((addr & (DATA_SIZE - 1)) != 0)
@@ -101,16 +101,16 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -101,16 +101,16 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
101 do_unaligned_access: 101 do_unaligned_access:
102 retaddr = GETPC(); 102 retaddr = GETPC();
103 #ifdef ALIGNED_ONLY 103 #ifdef ALIGNED_ONLY
104 - do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr); 104 + do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
105 #endif 105 #endif
106 res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr, 106 res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
107 - is_user, retaddr); 107 + mmu_idx, retaddr);
108 } else { 108 } else {
109 /* unaligned/aligned access in the same page */ 109 /* unaligned/aligned access in the same page */
110 #ifdef ALIGNED_ONLY 110 #ifdef ALIGNED_ONLY
111 if ((addr & (DATA_SIZE - 1)) != 0) { 111 if ((addr & (DATA_SIZE - 1)) != 0) {
112 retaddr = GETPC(); 112 retaddr = GETPC();
113 - do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr); 113 + do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
114 } 114 }
115 #endif 115 #endif
116 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr); 116 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)physaddr);
@@ -120,9 +120,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -120,9 +120,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
120 retaddr = GETPC(); 120 retaddr = GETPC();
121 #ifdef ALIGNED_ONLY 121 #ifdef ALIGNED_ONLY
122 if ((addr & (DATA_SIZE - 1)) != 0) 122 if ((addr & (DATA_SIZE - 1)) != 0)
123 - do_unaligned_access(addr, READ_ACCESS_TYPE, is_user, retaddr); 123 + do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
124 #endif 124 #endif
125 - tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr); 125 + tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
126 goto redo; 126 goto redo;
127 } 127 }
128 return res; 128 return res;
@@ -130,7 +130,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -130,7 +130,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
130 130
131 /* handle all unaligned cases */ 131 /* handle all unaligned cases */
132 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, 132 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
133 - int is_user, 133 + int mmu_idx,
134 void *retaddr) 134 void *retaddr)
135 { 135 {
136 DATA_TYPE res, res1, res2; 136 DATA_TYPE res, res1, res2;
@@ -140,9 +140,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -140,9 +140,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
140 140
141 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 141 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
142 redo: 142 redo:
143 - tlb_addr = env->tlb_table[is_user][index].ADDR_READ; 143 + tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
144 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 144 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
145 - physaddr = addr + env->tlb_table[is_user][index].addend; 145 + physaddr = addr + env->tlb_table[mmu_idx][index].addend;
146 if (tlb_addr & ~TARGET_PAGE_MASK) { 146 if (tlb_addr & ~TARGET_PAGE_MASK) {
147 /* IO access */ 147 /* IO access */
148 if ((addr & (DATA_SIZE - 1)) != 0) 148 if ((addr & (DATA_SIZE - 1)) != 0)
@@ -154,9 +154,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -154,9 +154,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
154 addr1 = addr & ~(DATA_SIZE - 1); 154 addr1 = addr & ~(DATA_SIZE - 1);
155 addr2 = addr1 + DATA_SIZE; 155 addr2 = addr1 + DATA_SIZE;
156 res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1, 156 res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
157 - is_user, retaddr); 157 + mmu_idx, retaddr);
158 res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2, 158 res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
159 - is_user, retaddr); 159 + mmu_idx, retaddr);
160 shift = (addr & (DATA_SIZE - 1)) * 8; 160 shift = (addr & (DATA_SIZE - 1)) * 8;
161 #ifdef TARGET_WORDS_BIGENDIAN 161 #ifdef TARGET_WORDS_BIGENDIAN
162 res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); 162 res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
@@ -170,7 +170,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -170,7 +170,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
170 } 170 }
171 } else { 171 } else {
172 /* the page is not in the TLB : fill it */ 172 /* the page is not in the TLB : fill it */
173 - tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr); 173 + tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
174 goto redo; 174 goto redo;
175 } 175 }
176 return res; 176 return res;
@@ -180,7 +180,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -180,7 +180,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
180 180
181 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, 181 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
182 DATA_TYPE val, 182 DATA_TYPE val,
183 - int is_user, 183 + int mmu_idx,
184 void *retaddr); 184 void *retaddr);
185 185
186 static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, 186 static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
@@ -211,7 +211,7 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, @@ -211,7 +211,7 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
211 211
212 void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, 212 void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
213 DATA_TYPE val, 213 DATA_TYPE val,
214 - int is_user) 214 + int mmu_idx)
215 { 215 {
216 target_phys_addr_t physaddr; 216 target_phys_addr_t physaddr;
217 target_ulong tlb_addr; 217 target_ulong tlb_addr;
@@ -220,9 +220,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -220,9 +220,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
220 220
221 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 221 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
222 redo: 222 redo:
223 - tlb_addr = env->tlb_table[is_user][index].addr_write; 223 + tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
224 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 224 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
225 - physaddr = addr + env->tlb_table[is_user][index].addend; 225 + physaddr = addr + env->tlb_table[mmu_idx][index].addend;
226 if (tlb_addr & ~TARGET_PAGE_MASK) { 226 if (tlb_addr & ~TARGET_PAGE_MASK) {
227 /* IO access */ 227 /* IO access */
228 if ((addr & (DATA_SIZE - 1)) != 0) 228 if ((addr & (DATA_SIZE - 1)) != 0)
@@ -233,16 +233,16 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -233,16 +233,16 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
233 do_unaligned_access: 233 do_unaligned_access:
234 retaddr = GETPC(); 234 retaddr = GETPC();
235 #ifdef ALIGNED_ONLY 235 #ifdef ALIGNED_ONLY
236 - do_unaligned_access(addr, 1, is_user, retaddr); 236 + do_unaligned_access(addr, 1, mmu_idx, retaddr);
237 #endif 237 #endif
238 glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val, 238 glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
239 - is_user, retaddr); 239 + mmu_idx, retaddr);
240 } else { 240 } else {
241 /* aligned/unaligned access in the same page */ 241 /* aligned/unaligned access in the same page */
242 #ifdef ALIGNED_ONLY 242 #ifdef ALIGNED_ONLY
243 if ((addr & (DATA_SIZE - 1)) != 0) { 243 if ((addr & (DATA_SIZE - 1)) != 0) {
244 retaddr = GETPC(); 244 retaddr = GETPC();
245 - do_unaligned_access(addr, 1, is_user, retaddr); 245 + do_unaligned_access(addr, 1, mmu_idx, retaddr);
246 } 246 }
247 #endif 247 #endif
248 glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val); 248 glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)physaddr, val);
@@ -252,9 +252,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -252,9 +252,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
252 retaddr = GETPC(); 252 retaddr = GETPC();
253 #ifdef ALIGNED_ONLY 253 #ifdef ALIGNED_ONLY
254 if ((addr & (DATA_SIZE - 1)) != 0) 254 if ((addr & (DATA_SIZE - 1)) != 0)
255 - do_unaligned_access(addr, 1, is_user, retaddr); 255 + do_unaligned_access(addr, 1, mmu_idx, retaddr);
256 #endif 256 #endif
257 - tlb_fill(addr, 1, is_user, retaddr); 257 + tlb_fill(addr, 1, mmu_idx, retaddr);
258 goto redo; 258 goto redo;
259 } 259 }
260 } 260 }
@@ -262,7 +262,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -262,7 +262,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
262 /* handles all unaligned cases */ 262 /* handles all unaligned cases */
263 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, 263 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
264 DATA_TYPE val, 264 DATA_TYPE val,
265 - int is_user, 265 + int mmu_idx,
266 void *retaddr) 266 void *retaddr)
267 { 267 {
268 target_phys_addr_t physaddr; 268 target_phys_addr_t physaddr;
@@ -271,9 +271,9 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -271,9 +271,9 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
271 271
272 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 272 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
273 redo: 273 redo:
274 - tlb_addr = env->tlb_table[is_user][index].addr_write; 274 + tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
275 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 275 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
276 - physaddr = addr + env->tlb_table[is_user][index].addend; 276 + physaddr = addr + env->tlb_table[mmu_idx][index].addend;
277 if (tlb_addr & ~TARGET_PAGE_MASK) { 277 if (tlb_addr & ~TARGET_PAGE_MASK) {
278 /* IO access */ 278 /* IO access */
279 if ((addr & (DATA_SIZE - 1)) != 0) 279 if ((addr & (DATA_SIZE - 1)) != 0)
@@ -285,10 +285,10 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -285,10 +285,10 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
285 for(i = 0;i < DATA_SIZE; i++) { 285 for(i = 0;i < DATA_SIZE; i++) {
286 #ifdef TARGET_WORDS_BIGENDIAN 286 #ifdef TARGET_WORDS_BIGENDIAN
287 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)), 287 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
288 - is_user, retaddr); 288 + mmu_idx, retaddr);
289 #else 289 #else
290 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8), 290 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
291 - is_user, retaddr); 291 + mmu_idx, retaddr);
292 #endif 292 #endif
293 } 293 }
294 } else { 294 } else {
@@ -297,7 +297,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr, @@ -297,7 +297,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
297 } 297 }
298 } else { 298 } else {
299 /* the page is not in the TLB : fill it */ 299 /* the page is not in the TLB : fill it */
300 - tlb_fill(addr, 1, is_user, retaddr); 300 + tlb_fill(addr, 1, mmu_idx, retaddr);
301 goto redo; 301 goto redo;
302 } 302 }
303 } 303 }
target-alpha/cpu.h
@@ -256,6 +256,8 @@ struct pal_handler_t { @@ -256,6 +256,8 @@ struct pal_handler_t {
256 void (*call_pal)(CPUAlphaState *env, uint32_t palcode); 256 void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
257 }; 257 };
258 258
  259 +#define NB_MMU_MODES 4
  260 +
259 struct CPUAlphaState { 261 struct CPUAlphaState {
260 uint64_t ir[31]; 262 uint64_t ir[31];
261 float64 fir[31]; 263 float64 fir[31];
@@ -302,6 +304,17 @@ struct CPUAlphaState { @@ -302,6 +304,17 @@ struct CPUAlphaState {
302 #define cpu_gen_code cpu_alpha_gen_code 304 #define cpu_gen_code cpu_alpha_gen_code
303 #define cpu_signal_handler cpu_alpha_signal_handler 305 #define cpu_signal_handler cpu_alpha_signal_handler
304 306
  307 +/* MMU modes definitions */
  308 +#define MMU_MODE0_SUFFIX _kernel
  309 +#define MMU_MODE1_SUFFIX _executive
  310 +#define MMU_MODE2_SUFFIX _supervisor
  311 +#define MMU_MODE3_SUFFIX _user
  312 +#define MMU_USER_IDX 3
  313 +static inline int cpu_mmu_index (CPUState *env)
  314 +{
  315 + return (env->ps >> 3) & 3;
  316 +}
  317 +
305 #include "cpu-all.h" 318 #include "cpu-all.h"
306 319
307 enum { 320 enum {
target-alpha/exec.h
@@ -73,7 +73,7 @@ static inline void regs_to_env(void) @@ -73,7 +73,7 @@ static inline void regs_to_env(void)
73 } 73 }
74 74
75 int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw, 75 int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
76 - int is_user, int is_softmmu); 76 + int mmu_idx, int is_softmmu);
77 int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp); 77 int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
78 int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp); 78 int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
79 79
target-alpha/helper.c
@@ -28,7 +28,7 @@ @@ -28,7 +28,7 @@
28 #if defined(CONFIG_USER_ONLY) 28 #if defined(CONFIG_USER_ONLY)
29 29
30 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 30 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
31 - int is_user, int is_softmmu) 31 + int mmu_idx, int is_softmmu)
32 { 32 {
33 if (rw == 2) 33 if (rw == 2)
34 env->exception_index = EXCP_ITB_MISS; 34 env->exception_index = EXCP_ITB_MISS;
@@ -57,7 +57,7 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) @@ -57,7 +57,7 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
57 } 57 }
58 58
59 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 59 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
60 - int is_user, int is_softmmu) 60 + int mmu_idx, int is_softmmu)
61 { 61 {
62 uint32_t opc; 62 uint32_t opc;
63 63
target-alpha/op_helper.c
@@ -1164,20 +1164,20 @@ void helper_mtpr (int iprn) @@ -1164,20 +1164,20 @@ void helper_mtpr (int iprn)
1164 void helper_ld_phys_to_virt (void) 1164 void helper_ld_phys_to_virt (void)
1165 { 1165 {
1166 uint64_t tlb_addr, physaddr; 1166 uint64_t tlb_addr, physaddr;
1167 - int index, is_user; 1167 + int index, mmu_idx;
1168 void *retaddr; 1168 void *retaddr;
1169 1169
1170 - is_user = (env->ps >> 3) & 3; 1170 + mmu_idx = cpu_mmu_index(env);
1171 index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 1171 index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1172 redo: 1172 redo:
1173 - tlb_addr = env->tlb_table[is_user][index].addr_read; 1173 + tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
1174 if ((T0 & TARGET_PAGE_MASK) == 1174 if ((T0 & TARGET_PAGE_MASK) ==
1175 (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 1175 (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1176 - physaddr = T0 + env->tlb_table[is_user][index].addend; 1176 + physaddr = T0 + env->tlb_table[mmu_idx][index].addend;
1177 } else { 1177 } else {
1178 /* the page is not in the TLB : fill it */ 1178 /* the page is not in the TLB : fill it */
1179 retaddr = GETPC(); 1179 retaddr = GETPC();
1180 - tlb_fill(T0, 0, is_user, retaddr); 1180 + tlb_fill(T0, 0, mmu_idx, retaddr);
1181 goto redo; 1181 goto redo;
1182 } 1182 }
1183 T0 = physaddr; 1183 T0 = physaddr;
@@ -1186,20 +1186,20 @@ void helper_ld_phys_to_virt (void) @@ -1186,20 +1186,20 @@ void helper_ld_phys_to_virt (void)
1186 void helper_st_phys_to_virt (void) 1186 void helper_st_phys_to_virt (void)
1187 { 1187 {
1188 uint64_t tlb_addr, physaddr; 1188 uint64_t tlb_addr, physaddr;
1189 - int index, is_user; 1189 + int index, mmu_idx;
1190 void *retaddr; 1190 void *retaddr;
1191 1191
1192 - is_user = (env->ps >> 3) & 3; 1192 + mmu_idx = cpu_mmu_index(env);
1193 index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 1193 index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1194 redo: 1194 redo:
1195 - tlb_addr = env->tlb_table[is_user][index].addr_write; 1195 + tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
1196 if ((T0 & TARGET_PAGE_MASK) == 1196 if ((T0 & TARGET_PAGE_MASK) ==
1197 (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { 1197 (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1198 - physaddr = T0 + env->tlb_table[is_user][index].addend; 1198 + physaddr = T0 + env->tlb_table[mmu_idx][index].addend;
1199 } else { 1199 } else {
1200 /* the page is not in the TLB : fill it */ 1200 /* the page is not in the TLB : fill it */
1201 retaddr = GETPC(); 1201 retaddr = GETPC();
1202 - tlb_fill(T0, 1, is_user, retaddr); 1202 + tlb_fill(T0, 1, mmu_idx, retaddr);
1203 goto redo; 1203 goto redo;
1204 } 1204 }
1205 T0 = physaddr; 1205 T0 = physaddr;
@@ -1223,7 +1223,7 @@ void helper_st_phys_to_virt (void) @@ -1223,7 +1223,7 @@ void helper_st_phys_to_virt (void)
1223 NULL, it means that the function was called in C code (i.e. not 1223 NULL, it means that the function was called in C code (i.e. not
1224 from generated code or from helper.c) */ 1224 from generated code or from helper.c) */
1225 /* XXX: fix it to restore all registers */ 1225 /* XXX: fix it to restore all registers */
1226 -void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) 1226 +void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
1227 { 1227 {
1228 TranslationBlock *tb; 1228 TranslationBlock *tb;
1229 CPUState *saved_env; 1229 CPUState *saved_env;
@@ -1234,7 +1234,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) @@ -1234,7 +1234,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
1234 generated code */ 1234 generated code */
1235 saved_env = env; 1235 saved_env = env;
1236 env = cpu_single_env; 1236 env = cpu_single_env;
1237 - ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, is_user, 1); 1237 + ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
1238 if (!likely(ret == 0)) { 1238 if (!likely(ret == 0)) {
1239 if (likely(retaddr)) { 1239 if (likely(retaddr)) {
1240 /* now we have a real cpu fault */ 1240 /* now we have a real cpu fault */
target-arm/cpu.h
@@ -43,6 +43,8 @@ typedef void ARMWriteCPFunc(void *opaque, int cp_info, @@ -43,6 +43,8 @@ typedef void ARMWriteCPFunc(void *opaque, int cp_info,
43 typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info, 43 typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info,
44 int dstreg, int operand); 44 int dstreg, int operand);
45 45
  46 +#define NB_MMU_MODES 2
  47 +
46 /* We currently assume float and double are IEEE single and double 48 /* We currently assume float and double are IEEE single and double
47 precision respectively. 49 precision respectively.
48 Doing runtime conversions is tricky because VFP registers may contain 50 Doing runtime conversions is tricky because VFP registers may contain
@@ -301,6 +303,15 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, @@ -301,6 +303,15 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
301 #define cpu_signal_handler cpu_arm_signal_handler 303 #define cpu_signal_handler cpu_arm_signal_handler
302 #define cpu_list arm_cpu_list 304 #define cpu_list arm_cpu_list
303 305
  306 +/* MMU modes definitions */
  307 +#define MMU_MODE0_SUFFIX _kernel
  308 +#define MMU_MODE1_SUFFIX _user
  309 +#define MMU_USER_IDX 1
  310 +static inline int cpu_mmu_index (CPUState *env)
  311 +{
  312 + return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
  313 +}
  314 +
304 #include "cpu-all.h" 315 #include "cpu-all.h"
305 316
306 #endif 317 #endif
target-arm/exec.h
@@ -46,7 +46,7 @@ static inline void regs_to_env(void) @@ -46,7 +46,7 @@ static inline void regs_to_env(void)
46 } 46 }
47 47
48 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 48 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
49 - int is_user, int is_softmmu); 49 + int mmu_idx, int is_softmmu);
50 50
51 static inline int cpu_halted(CPUState *env) { 51 static inline int cpu_halted(CPUState *env) {
52 if (!env->halted) 52 if (!env->halted)
target-arm/helper.c
@@ -169,7 +169,7 @@ void do_interrupt (CPUState *env) @@ -169,7 +169,7 @@ void do_interrupt (CPUState *env)
169 } 169 }
170 170
171 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 171 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
172 - int is_user, int is_softmmu) 172 + int mmu_idx, int is_softmmu)
173 { 173 {
174 if (rw == 2) { 174 if (rw == 2) {
175 env->exception_index = EXCP_PREFETCH_ABORT; 175 env->exception_index = EXCP_PREFETCH_ABORT;
@@ -547,18 +547,19 @@ do_fault: @@ -547,18 +547,19 @@ do_fault:
547 } 547 }
548 548
549 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, 549 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
550 - int access_type, int is_user, int is_softmmu) 550 + int access_type, int mmu_idx, int is_softmmu)
551 { 551 {
552 uint32_t phys_addr; 552 uint32_t phys_addr;
553 int prot; 553 int prot;
554 - int ret; 554 + int ret, is_user;
555 555
  556 + is_user = mmu_idx == MMU_USER_IDX;
556 ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot); 557 ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);
557 if (ret == 0) { 558 if (ret == 0) {
558 /* Map a single [sub]page. */ 559 /* Map a single [sub]page. */
559 phys_addr &= ~(uint32_t)0x3ff; 560 phys_addr &= ~(uint32_t)0x3ff;
560 address &= ~(uint32_t)0x3ff; 561 address &= ~(uint32_t)0x3ff;
561 - return tlb_set_page (env, address, phys_addr, prot, is_user, 562 + return tlb_set_page (env, address, phys_addr, prot, mmu_idx,
562 is_softmmu); 563 is_softmmu);
563 } 564 }
564 565
target-arm/op_helper.c
@@ -196,7 +196,7 @@ void do_vfp_get_fpscr(void) @@ -196,7 +196,7 @@ void do_vfp_get_fpscr(void)
196 NULL, it means that the function was called in C code (i.e. not 196 NULL, it means that the function was called in C code (i.e. not
197 from generated code or from helper.c) */ 197 from generated code or from helper.c) */
198 /* XXX: fix it to restore all registers */ 198 /* XXX: fix it to restore all registers */
199 -void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) 199 +void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
200 { 200 {
201 TranslationBlock *tb; 201 TranslationBlock *tb;
202 CPUState *saved_env; 202 CPUState *saved_env;
@@ -207,7 +207,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) @@ -207,7 +207,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
207 generated code */ 207 generated code */
208 saved_env = env; 208 saved_env = env;
209 env = cpu_single_env; 209 env = cpu_single_env;
210 - ret = cpu_arm_handle_mmu_fault(env, addr, is_write, is_user, 1); 210 + ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
211 if (__builtin_expect(ret, 0)) { 211 if (__builtin_expect(ret, 0)) {
212 if (retaddr) { 212 if (retaddr) {
213 /* now we have a real cpu fault */ 213 /* now we have a real cpu fault */
target-cris/cpu.h
@@ -74,6 +74,8 @@ @@ -74,6 +74,8 @@
74 /* Internal flags for the implementation. */ 74 /* Internal flags for the implementation. */
75 #define F_DELAYSLOT 1 75 #define F_DELAYSLOT 1
76 76
  77 +#define NB_MMU_MODES 2
  78 +
77 typedef struct CPUCRISState { 79 typedef struct CPUCRISState {
78 uint32_t debug1; 80 uint32_t debug1;
79 uint32_t debug2; 81 uint32_t debug2;
@@ -229,6 +231,16 @@ void register_cris_insns (CPUCRISState *env); @@ -229,6 +231,16 @@ void register_cris_insns (CPUCRISState *env);
229 #define cpu_gen_code cpu_cris_gen_code 231 #define cpu_gen_code cpu_cris_gen_code
230 #define cpu_signal_handler cpu_cris_signal_handler 232 #define cpu_signal_handler cpu_cris_signal_handler
231 233
  234 +/* MMU modes definitions */
  235 +#define MMU_MODE0_SUFFIX _kernel
  236 +#define MMU_MODE1_SUFFIX _user
  237 +#define MMU_USER_IDX 1
  238 +/* CRIS FIXME: I guess we want to validate supervisor mode acceses here. */
  239 +static inline int cpu_mmu_index (CPUState *env)
  240 +{
  241 + return 0;
  242 +}
  243 +
232 #include "cpu-all.h" 244 #include "cpu-all.h"
233 245
234 /* Register aliases. */ 246 /* Register aliases. */
target-cris/exec.h
@@ -45,8 +45,8 @@ static inline void regs_to_env(void) @@ -45,8 +45,8 @@ static inline void regs_to_env(void)
45 } 45 }
46 46
47 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 47 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
48 - int is_user, int is_softmmu);  
49 -void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr); 48 + int mmu_idx, int is_softmmu);
  49 +void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr);
50 50
51 #if !defined(CONFIG_USER_ONLY) 51 #if !defined(CONFIG_USER_ONLY)
52 #include "softmmu_exec.h" 52 #include "softmmu_exec.h"
target-cris/helper.c
@@ -35,7 +35,7 @@ void do_interrupt (CPUState *env) @@ -35,7 +35,7 @@ void do_interrupt (CPUState *env)
35 } 35 }
36 36
37 int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw, 37 int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
38 - int is_user, int is_softmmu) 38 + int mmu_idx, int is_softmmu)
39 { 39 {
40 env->exception_index = 0xaa; 40 env->exception_index = 0xaa;
41 env->debug1 = address; 41 env->debug1 = address;
@@ -52,7 +52,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) @@ -52,7 +52,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
52 #else /* !CONFIG_USER_ONLY */ 52 #else /* !CONFIG_USER_ONLY */
53 53
54 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 54 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
55 - int is_user, int is_softmmu) 55 + int mmu_idx, int is_softmmu)
56 { 56 {
57 struct cris_mmu_result_t res; 57 struct cris_mmu_result_t res;
58 int prot, miss; 58 int prot, miss;
@@ -61,7 +61,7 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -61,7 +61,7 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
61 address &= TARGET_PAGE_MASK; 61 address &= TARGET_PAGE_MASK;
62 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 62 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
63 // printf ("%s pc=%x %x w=%d smmu=%d\n", __func__, env->pc, address, rw, is_softmmu); 63 // printf ("%s pc=%x %x w=%d smmu=%d\n", __func__, env->pc, address, rw, is_softmmu);
64 - miss = cris_mmu_translate(&res, env, address, rw, is_user); 64 + miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
65 if (miss) 65 if (miss)
66 { 66 {
67 /* handle the miss. */ 67 /* handle the miss. */
@@ -73,7 +73,7 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -73,7 +73,7 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
73 phy = res.phy; 73 phy = res.phy;
74 } 74 }
75 // printf ("a=%x phy=%x\n", address, phy); 75 // printf ("a=%x phy=%x\n", address, phy);
76 - return tlb_set_page(env, address, phy, prot, is_user, is_softmmu); 76 + return tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
77 } 77 }
78 78
79 79
target-cris/mmu.c
@@ -111,11 +111,12 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res, @@ -111,11 +111,12 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
111 111
112 int cris_mmu_translate(struct cris_mmu_result_t *res, 112 int cris_mmu_translate(struct cris_mmu_result_t *res,
113 CPUState *env, uint32_t vaddr, 113 CPUState *env, uint32_t vaddr,
114 - int rw, int is_user) 114 + int rw, int mmu_idx)
115 { 115 {
116 uint32_t phy = vaddr; 116 uint32_t phy = vaddr;
117 int seg; 117 int seg;
118 int miss = 0; 118 int miss = 0;
  119 + int is_user = mmu_idx == MMU_USER_IDX;
119 120
120 if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) { 121 if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
121 res->phy = vaddr; 122 res->phy = vaddr;
target-cris/mmu.h
@@ -17,4 +17,4 @@ struct cris_mmu_result_t @@ -17,4 +17,4 @@ struct cris_mmu_result_t
17 17
18 int cris_mmu_translate(struct cris_mmu_result_t *res, 18 int cris_mmu_translate(struct cris_mmu_result_t *res,
19 CPUState *env, uint32_t vaddr, 19 CPUState *env, uint32_t vaddr,
20 - int rw, int is_user); 20 + int rw, int mmu_idx);
target-cris/op_helper.c
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 NULL, it means that the function was called in C code (i.e. not 41 NULL, it means that the function was called in C code (i.e. not
42 from generated code or from helper.c) */ 42 from generated code or from helper.c) */
43 /* XXX: fix it to restore all registers */ 43 /* XXX: fix it to restore all registers */
44 -void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) 44 +void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
45 { 45 {
46 TranslationBlock *tb; 46 TranslationBlock *tb;
47 CPUState *saved_env; 47 CPUState *saved_env;
@@ -52,7 +52,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) @@ -52,7 +52,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
52 generated code */ 52 generated code */
53 saved_env = env; 53 saved_env = env;
54 env = cpu_single_env; 54 env = cpu_single_env;
55 - ret = cpu_cris_handle_mmu_fault(env, addr, is_write, is_user, 1); 55 + ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
56 if (__builtin_expect(ret, 0)) { 56 if (__builtin_expect(ret, 0)) {
57 if (retaddr) { 57 if (retaddr) {
58 /* now we have a real cpu fault */ 58 /* now we have a real cpu fault */
target-i386/cpu.h
@@ -432,6 +432,8 @@ typedef union { @@ -432,6 +432,8 @@ typedef union {
432 #define CPU_NB_REGS 8 432 #define CPU_NB_REGS 8
433 #endif 433 #endif
434 434
  435 +#define NB_MMU_MODES 2
  436 +
435 typedef struct CPUX86State { 437 typedef struct CPUX86State {
436 #if TARGET_LONG_BITS > HOST_LONG_BITS 438 #if TARGET_LONG_BITS > HOST_LONG_BITS
437 /* temporaries if we cannot store them in host registers */ 439 /* temporaries if we cannot store them in host registers */
@@ -688,6 +690,15 @@ static inline int cpu_get_time_fast(void) @@ -688,6 +690,15 @@ static inline int cpu_get_time_fast(void)
688 #define cpu_gen_code cpu_x86_gen_code 690 #define cpu_gen_code cpu_x86_gen_code
689 #define cpu_signal_handler cpu_x86_signal_handler 691 #define cpu_signal_handler cpu_x86_signal_handler
690 692
  693 +/* MMU modes definitions */
  694 +#define MMU_MODE0_SUFFIX _kernel
  695 +#define MMU_MODE1_SUFFIX _user
  696 +#define MMU_USER_IDX 1
  697 +static inline int cpu_mmu_index (CPUState *env)
  698 +{
  699 + return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
  700 +}
  701 +
691 #include "cpu-all.h" 702 #include "cpu-all.h"
692 703
693 #include "svm.h" 704 #include "svm.h"
target-i386/exec.h
@@ -163,8 +163,8 @@ void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3); @@ -163,8 +163,8 @@ void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
163 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4); 163 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
164 void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr); 164 void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr);
165 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, 165 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
166 - int is_write, int is_user, int is_softmmu);  
167 -void tlb_fill(target_ulong addr, int is_write, int is_user, 166 + int is_write, int mmu_idx, int is_softmmu);
  167 +void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
168 void *retaddr); 168 void *retaddr);
169 void __hidden cpu_lock(void); 169 void __hidden cpu_lock(void);
170 void __hidden cpu_unlock(void); 170 void __hidden cpu_unlock(void);
target-i386/helper.c
@@ -3885,7 +3885,7 @@ void update_fp_status(void) @@ -3885,7 +3885,7 @@ void update_fp_status(void)
3885 NULL, it means that the function was called in C code (i.e. not 3885 NULL, it means that the function was called in C code (i.e. not
3886 from generated code or from helper.c) */ 3886 from generated code or from helper.c) */
3887 /* XXX: fix it to restore all registers */ 3887 /* XXX: fix it to restore all registers */
3888 -void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) 3888 +void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
3889 { 3889 {
3890 TranslationBlock *tb; 3890 TranslationBlock *tb;
3891 int ret; 3891 int ret;
@@ -3897,7 +3897,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) @@ -3897,7 +3897,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
3897 saved_env = env; 3897 saved_env = env;
3898 env = cpu_single_env; 3898 env = cpu_single_env;
3899 3899
3900 - ret = cpu_x86_handle_mmu_fault(env, addr, is_write, is_user, 1); 3900 + ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
3901 if (ret) { 3901 if (ret) {
3902 if (retaddr) { 3902 if (retaddr) {
3903 /* now we have a real cpu fault */ 3903 /* now we have a real cpu fault */
target-i386/helper2.c
@@ -571,7 +571,7 @@ void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr) @@ -571,7 +571,7 @@ void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr)
571 #if defined(CONFIG_USER_ONLY) 571 #if defined(CONFIG_USER_ONLY)
572 572
573 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, 573 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
574 - int is_write, int is_user, int is_softmmu) 574 + int is_write, int mmu_idx, int is_softmmu)
575 { 575 {
576 /* user mode only emulation */ 576 /* user mode only emulation */
577 is_write &= 1; 577 is_write &= 1;
@@ -598,14 +598,15 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) @@ -598,14 +598,15 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
598 2 = soft MMU activation required for this block 598 2 = soft MMU activation required for this block
599 */ 599 */
600 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, 600 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
601 - int is_write1, int is_user, int is_softmmu) 601 + int is_write1, int mmu_idx, int is_softmmu)
602 { 602 {
603 uint64_t ptep, pte; 603 uint64_t ptep, pte;
604 uint32_t pdpe_addr, pde_addr, pte_addr; 604 uint32_t pdpe_addr, pde_addr, pte_addr;
605 - int error_code, is_dirty, prot, page_size, ret, is_write; 605 + int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
606 unsigned long paddr, page_offset; 606 unsigned long paddr, page_offset;
607 target_ulong vaddr, virt_addr; 607 target_ulong vaddr, virt_addr;
608 608
  609 + is_user = mmu_idx == MMU_USER_IDX;
609 #if defined(DEBUG_MMU) 610 #if defined(DEBUG_MMU)
610 printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n", 611 printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
611 addr, is_write1, is_user, env->eip); 612 addr, is_write1, is_user, env->eip);
@@ -862,7 +863,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, @@ -862,7 +863,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
862 paddr = (pte & TARGET_PAGE_MASK) + page_offset; 863 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
863 vaddr = virt_addr + page_offset; 864 vaddr = virt_addr + page_offset;
864 865
865 - ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); 866 + ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
866 return ret; 867 return ret;
867 do_fault_protect: 868 do_fault_protect:
868 error_code = PG_ERROR_P_MASK; 869 error_code = PG_ERROR_P_MASK;
target-m68k/cpu.h
@@ -53,6 +53,8 @@ @@ -53,6 +53,8 @@
53 #define EXCP_RTE 0x100 53 #define EXCP_RTE 0x100
54 #define EXCP_HALT_INSN 0x101 54 #define EXCP_HALT_INSN 0x101
55 55
  56 +#define NB_MMU_MODES 2
  57 +
56 typedef struct CPUM68KState { 58 typedef struct CPUM68KState {
57 uint32_t dregs[8]; 59 uint32_t dregs[8];
58 uint32_t aregs[8]; 60 uint32_t aregs[8];
@@ -223,6 +225,15 @@ void register_m68k_insns (CPUM68KState *env); @@ -223,6 +225,15 @@ void register_m68k_insns (CPUM68KState *env);
223 #define cpu_gen_code cpu_m68k_gen_code 225 #define cpu_gen_code cpu_m68k_gen_code
224 #define cpu_signal_handler cpu_m68k_signal_handler 226 #define cpu_signal_handler cpu_m68k_signal_handler
225 227
  228 +/* MMU modes definitions */
  229 +#define MMU_MODE0_SUFFIX _kernel
  230 +#define MMU_MODE1_SUFFIX _user
  231 +#define MMU_USER_IDX 1
  232 +static inline int cpu_mmu_index (CPUState *env)
  233 +{
  234 + return (env->sr & SR_S) == 0 ? 1 : 0;
  235 +}
  236 +
226 #include "cpu-all.h" 237 #include "cpu-all.h"
227 238
228 #endif 239 #endif
target-m68k/exec.h
@@ -38,7 +38,7 @@ static inline void regs_to_env(void) @@ -38,7 +38,7 @@ static inline void regs_to_env(void)
38 } 38 }
39 39
40 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 40 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
41 - int is_user, int is_softmmu); 41 + int mmu_idx, int is_softmmu);
42 42
43 #if !defined(CONFIG_USER_ONLY) 43 #if !defined(CONFIG_USER_ONLY)
44 #include "softmmu_exec.h" 44 #include "softmmu_exec.h"
target-m68k/helper.c
@@ -301,7 +301,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) @@ -301,7 +301,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
301 #if defined(CONFIG_USER_ONLY) 301 #if defined(CONFIG_USER_ONLY)
302 302
303 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 303 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
304 - int is_user, int is_softmmu) 304 + int mmu_idx, int is_softmmu)
305 { 305 {
306 env->exception_index = EXCP_ACCESS; 306 env->exception_index = EXCP_ACCESS;
307 env->mmu.ar = address; 307 env->mmu.ar = address;
@@ -311,13 +311,13 @@ int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -311,13 +311,13 @@ int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
311 #else 311 #else
312 312
313 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 313 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
314 - int is_user, int is_softmmu) 314 + int mmu_idx, int is_softmmu)
315 { 315 {
316 int prot; 316 int prot;
317 317
318 address &= TARGET_PAGE_MASK; 318 address &= TARGET_PAGE_MASK;
319 prot = PAGE_READ | PAGE_WRITE; 319 prot = PAGE_READ | PAGE_WRITE;
320 - return tlb_set_page(env, address, address, prot, is_user, is_softmmu); 320 + return tlb_set_page(env, address, address, prot, mmu_idx, is_softmmu);
321 } 321 }
322 322
323 /* Notify CPU of a pending interrupt. Prioritization and vectoring should 323 /* Notify CPU of a pending interrupt. Prioritization and vectoring should
target-m68k/op_helper.c
@@ -49,7 +49,7 @@ extern int semihosting_enabled; @@ -49,7 +49,7 @@ extern int semihosting_enabled;
49 NULL, it means that the function was called in C code (i.e. not 49 NULL, it means that the function was called in C code (i.e. not
50 from generated code or from helper.c) */ 50 from generated code or from helper.c) */
51 /* XXX: fix it to restore all registers */ 51 /* XXX: fix it to restore all registers */
52 -void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) 52 +void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
53 { 53 {
54 TranslationBlock *tb; 54 TranslationBlock *tb;
55 CPUState *saved_env; 55 CPUState *saved_env;
@@ -60,7 +60,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) @@ -60,7 +60,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
60 generated code */ 60 generated code */
61 saved_env = env; 61 saved_env = env;
62 env = cpu_single_env; 62 env = cpu_single_env;
63 - ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, is_user, 1); 63 + ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
64 if (__builtin_expect(ret, 0)) { 64 if (__builtin_expect(ret, 0)) {
65 if (retaddr) { 65 if (retaddr) {
66 /* now we have a real cpu fault */ 66 /* now we have a real cpu fault */
target-mips/cpu.h
@@ -107,6 +107,8 @@ struct CPUMIPSFPUContext { @@ -107,6 +107,8 @@ struct CPUMIPSFPUContext {
107 #define FP_UNIMPLEMENTED 32 107 #define FP_UNIMPLEMENTED 32
108 }; 108 };
109 109
  110 +#define NB_MMU_MODES 2
  111 +
110 typedef struct CPUMIPSMVPContext CPUMIPSMVPContext; 112 typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
111 struct CPUMIPSMVPContext { 113 struct CPUMIPSMVPContext {
112 int32_t CP0_MVPControl; 114 int32_t CP0_MVPControl;
@@ -484,6 +486,15 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def); @@ -484,6 +486,15 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def);
484 #define cpu_signal_handler cpu_mips_signal_handler 486 #define cpu_signal_handler cpu_mips_signal_handler
485 #define cpu_list mips_cpu_list 487 #define cpu_list mips_cpu_list
486 488
  489 +/* MMU modes definitions */
  490 +#define MMU_MODE0_SUFFIX _kernel
  491 +#define MMU_MODE1_SUFFIX _user
  492 +#define MMU_USER_IDX 1
  493 +static inline int cpu_mmu_index (CPUState *env)
  494 +{
  495 + return (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM ? 1 : 0;
  496 +}
  497 +
487 #include "cpu-all.h" 498 #include "cpu-all.h"
488 499
489 /* Memory access type : 500 /* Memory access type :
target-mips/exec.h
@@ -105,7 +105,7 @@ void do_pmon (int function); @@ -105,7 +105,7 @@ void do_pmon (int function);
105 void dump_sc (void); 105 void dump_sc (void);
106 106
107 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 107 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
108 - int is_user, int is_softmmu); 108 + int mmu_idx, int is_softmmu);
109 void do_interrupt (CPUState *env); 109 void do_interrupt (CPUState *env);
110 void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra); 110 void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
111 111
target-mips/helper.c
@@ -229,7 +229,7 @@ void cpu_mips_init_mmu (CPUState *env) @@ -229,7 +229,7 @@ void cpu_mips_init_mmu (CPUState *env)
229 #endif /* !defined(CONFIG_USER_ONLY) */ 229 #endif /* !defined(CONFIG_USER_ONLY) */
230 230
231 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 231 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
232 - int is_user, int is_softmmu) 232 + int mmu_idx, int is_softmmu)
233 { 233 {
234 target_ulong physical; 234 target_ulong physical;
235 int prot; 235 int prot;
@@ -241,8 +241,8 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -241,8 +241,8 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
241 #if 0 241 #if 0
242 cpu_dump_state(env, logfile, fprintf, 0); 242 cpu_dump_state(env, logfile, fprintf, 0);
243 #endif 243 #endif
244 - fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d is_user %d smmu %d\n",  
245 - __func__, env->PC[env->current_tc], address, rw, is_user, is_softmmu); 244 + fprintf(logfile, "%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d smmu %d\n",
  245 + __func__, env->PC[env->current_tc], address, rw, mmu_idx, is_softmmu);
246 } 246 }
247 247
248 rw &= 1; 248 rw &= 1;
@@ -265,7 +265,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -265,7 +265,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
265 if (ret == TLBRET_MATCH) { 265 if (ret == TLBRET_MATCH) {
266 ret = tlb_set_page(env, address & TARGET_PAGE_MASK, 266 ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
267 physical & TARGET_PAGE_MASK, prot, 267 physical & TARGET_PAGE_MASK, prot,
268 - is_user, is_softmmu); 268 + mmu_idx, is_softmmu);
269 } else if (ret < 0) { 269 } else if (ret < 0) {
270 do_fault: 270 do_fault:
271 switch (ret) { 271 switch (ret) {
target-mips/op_helper.c
@@ -563,7 +563,7 @@ static void do_unaligned_access (target_ulong addr, int is_write, int is_user, v @@ -563,7 +563,7 @@ static void do_unaligned_access (target_ulong addr, int is_write, int is_user, v
563 do_raise_exception ((is_write == 1) ? EXCP_AdES : EXCP_AdEL); 563 do_raise_exception ((is_write == 1) ? EXCP_AdES : EXCP_AdEL);
564 } 564 }
565 565
566 -void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) 566 +void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
567 { 567 {
568 TranslationBlock *tb; 568 TranslationBlock *tb;
569 CPUState *saved_env; 569 CPUState *saved_env;
@@ -574,7 +574,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) @@ -574,7 +574,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
574 generated code */ 574 generated code */
575 saved_env = env; 575 saved_env = env;
576 env = cpu_single_env; 576 env = cpu_single_env;
577 - ret = cpu_mips_handle_mmu_fault(env, addr, is_write, is_user, 1); 577 + ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
578 if (ret) { 578 if (ret) {
579 if (retaddr) { 579 if (retaddr) {
580 /* now we have a real cpu fault */ 580 /* now we have a real cpu fault */
target-ppc/cpu.h
@@ -434,6 +434,12 @@ enum { @@ -434,6 +434,12 @@ enum {
434 POWERPC_FLAG_PMM = 0x00000400, 434 POWERPC_FLAG_PMM = 0x00000400,
435 }; 435 };
436 436
  437 +#if defined(TARGET_PPC64H)
  438 +#define NB_MMU_MODES 3
  439 +#else
  440 +#define NB_MMU_MODES 2
  441 +#endif
  442 +
437 /*****************************************************************************/ 443 /*****************************************************************************/
438 /* The whole PowerPC CPU context */ 444 /* The whole PowerPC CPU context */
439 struct CPUPPCState { 445 struct CPUPPCState {
@@ -575,6 +581,7 @@ struct CPUPPCState { @@ -575,6 +581,7 @@ struct CPUPPCState {
575 jmp_buf jmp_env; 581 jmp_buf jmp_env;
576 int user_mode_only; /* user mode only simulation */ 582 int user_mode_only; /* user mode only simulation */
577 target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */ 583 target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */
  584 + int mmu_idx; /* precomputed MMU index to speed up mem accesses */
578 585
579 /* Power management */ 586 /* Power management */
580 int power_mode; 587 int power_mode;
@@ -699,6 +706,18 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val); @@ -699,6 +706,18 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
699 #define cpu_signal_handler cpu_ppc_signal_handler 706 #define cpu_signal_handler cpu_ppc_signal_handler
700 #define cpu_list ppc_cpu_list 707 #define cpu_list ppc_cpu_list
701 708
  709 +/* MMU modes definitions */
  710 +#define MMU_MODE0_SUFFIX _user
  711 +#define MMU_MODE1_SUFFIX _kernel
  712 +#if defined(TARGET_PPC64H)
  713 +#define MMU_MODE2_SUFFIX _hypv
  714 +#endif
  715 +#define MMU_USER_IDX 0
  716 +static inline int cpu_mmu_index (CPUState *env)
  717 +{
  718 + return env->mmu_idx;
  719 +}
  720 +
702 #include "cpu-all.h" 721 #include "cpu-all.h"
703 722
704 /*****************************************************************************/ 723 /*****************************************************************************/
target-ppc/exec.h
@@ -112,7 +112,7 @@ static always_inline void regs_to_env (void) @@ -112,7 +112,7 @@ static always_inline void regs_to_env (void)
112 } 112 }
113 113
114 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 114 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
115 - int is_user, int is_softmmu); 115 + int mmu_idx, int is_softmmu);
116 116
117 static always_inline int cpu_halted (CPUState *env) 117 static always_inline int cpu_halted (CPUState *env)
118 { 118 {
target-ppc/helper.c
@@ -39,7 +39,7 @@ @@ -39,7 +39,7 @@
39 39
40 #if defined(CONFIG_USER_ONLY) 40 #if defined(CONFIG_USER_ONLY)
41 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 41 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
42 - int is_user, int is_softmmu) 42 + int mmu_idx, int is_softmmu)
43 { 43 {
44 int exception, error_code; 44 int exception, error_code;
45 45
@@ -1349,7 +1349,7 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) @@ -1349,7 +1349,7 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
1349 1349
1350 /* Perform address translation */ 1350 /* Perform address translation */
1351 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 1351 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1352 - int is_user, int is_softmmu) 1352 + int mmu_idx, int is_softmmu)
1353 { 1353 {
1354 mmu_ctx_t ctx; 1354 mmu_ctx_t ctx;
1355 int access_type; 1355 int access_type;
@@ -1370,7 +1370,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -1370,7 +1370,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1370 if (ret == 0) { 1370 if (ret == 0) {
1371 ret = tlb_set_page(env, address & TARGET_PAGE_MASK, 1371 ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
1372 ctx.raddr & TARGET_PAGE_MASK, ctx.prot, 1372 ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
1373 - is_user, is_softmmu); 1373 + mmu_idx, is_softmmu);
1374 } else if (ret < 0) { 1374 } else if (ret < 0) {
1375 #if defined (DEBUG_MMU) 1375 #if defined (DEBUG_MMU)
1376 if (loglevel != 0) 1376 if (loglevel != 0)
@@ -2083,7 +2083,12 @@ void do_compute_hflags (CPUPPCState *env) @@ -2083,7 +2083,12 @@ void do_compute_hflags (CPUPPCState *env)
2083 env->hflags |= msr_cm << MSR_CM; 2083 env->hflags |= msr_cm << MSR_CM;
2084 env->hflags |= (uint64_t)msr_sf << MSR_SF; 2084 env->hflags |= (uint64_t)msr_sf << MSR_SF;
2085 env->hflags |= (uint64_t)msr_hv << MSR_HV; 2085 env->hflags |= (uint64_t)msr_hv << MSR_HV;
  2086 + /* Precompute MMU index */
  2087 + if (msr_pr == 0 && msr_hv == 1)
  2088 + env->mmu_idx = 2;
  2089 + else
2086 #endif 2090 #endif
  2091 + env->mmu_idx = 1 - msr_pr;
2087 } 2092 }
2088 2093
2089 /*****************************************************************************/ 2094 /*****************************************************************************/
target-ppc/op_helper.c
@@ -2307,7 +2307,7 @@ DO_SPE_OP1(fsctuf); @@ -2307,7 +2307,7 @@ DO_SPE_OP1(fsctuf);
2307 NULL, it means that the function was called in C code (i.e. not 2307 NULL, it means that the function was called in C code (i.e. not
2308 from generated code or from helper.c) */ 2308 from generated code or from helper.c) */
2309 /* XXX: fix it to restore all registers */ 2309 /* XXX: fix it to restore all registers */
2310 -void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) 2310 +void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
2311 { 2311 {
2312 TranslationBlock *tb; 2312 TranslationBlock *tb;
2313 CPUState *saved_env; 2313 CPUState *saved_env;
@@ -2318,7 +2318,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) @@ -2318,7 +2318,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
2318 generated code */ 2318 generated code */
2319 saved_env = env; 2319 saved_env = env;
2320 env = cpu_single_env; 2320 env = cpu_single_env;
2321 - ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, is_user, 1); 2321 + ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
2322 if (unlikely(ret != 0)) { 2322 if (unlikely(ret != 0)) {
2323 if (likely(retaddr)) { 2323 if (likely(retaddr)) {
2324 /* now we have a real cpu fault */ 2324 /* now we have a real cpu fault */
target-ppc/translate.c
@@ -6693,15 +6693,8 @@ static always_inline int gen_intermediate_code_internal (CPUState *env, @@ -6693,15 +6693,8 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
6693 ctx.tb = tb; 6693 ctx.tb = tb;
6694 ctx.exception = POWERPC_EXCP_NONE; 6694 ctx.exception = POWERPC_EXCP_NONE;
6695 ctx.spr_cb = env->spr_cb; 6695 ctx.spr_cb = env->spr_cb;
6696 -#if defined(CONFIG_USER_ONLY)  
6697 - supervisor = 0;  
6698 -#else  
6699 -#if defined(TARGET_PPC64H)  
6700 - if (msr_pr == 0 && msr_hv == 1)  
6701 - supervisor = 2;  
6702 - else  
6703 -#endif  
6704 - supervisor = 1 - msr_pr; 6696 + supervisor = env->mmu_idx;
  6697 +#if !defined(CONFIG_USER_ONLY)
6705 ctx.supervisor = supervisor; 6698 ctx.supervisor = supervisor;
6706 #endif 6699 #endif
6707 #if defined(TARGET_PPC64) 6700 #if defined(TARGET_PPC64)
target-sh4/cpu.h
@@ -77,6 +77,8 @@ typedef struct tlb_t { @@ -77,6 +77,8 @@ typedef struct tlb_t {
77 #define UTLB_SIZE 64 77 #define UTLB_SIZE 64
78 #define ITLB_SIZE 4 78 #define ITLB_SIZE 4
79 79
  80 +#define NB_MMU_MODES 2
  81 +
80 typedef struct CPUSH4State { 82 typedef struct CPUSH4State {
81 uint32_t flags; /* general execution flags */ 83 uint32_t flags; /* general execution flags */
82 uint32_t gregs[24]; /* general registers */ 84 uint32_t gregs[24]; /* general registers */
@@ -134,6 +136,15 @@ int cpu_sh4_signal_handler(int host_signum, void *pinfo, @@ -134,6 +136,15 @@ int cpu_sh4_signal_handler(int host_signum, void *pinfo,
134 #define cpu_gen_code cpu_sh4_gen_code 136 #define cpu_gen_code cpu_sh4_gen_code
135 #define cpu_signal_handler cpu_sh4_signal_handler 137 #define cpu_signal_handler cpu_sh4_signal_handler
136 138
  139 +/* MMU modes definitions */
  140 +#define MMU_MODE0_SUFFIX _kernel
  141 +#define MMU_MODE1_SUFFIX _user
  142 +#define MMU_USER_IDX 1
  143 +static inline int cpu_mmu_index (CPUState *env)
  144 +{
  145 + return (env->sr & SR_MD) == 0 ? 1 : 0;
  146 +}
  147 +
137 #include "cpu-all.h" 148 #include "cpu-all.h"
138 149
139 /* Memory access type */ 150 /* Memory access type */
target-sh4/exec.h
@@ -63,7 +63,7 @@ static inline void env_to_regs(void) @@ -63,7 +63,7 @@ static inline void env_to_regs(void)
63 } 63 }
64 64
65 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, 65 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
66 - int is_user, int is_softmmu); 66 + int mmu_idx, int is_softmmu);
67 67
68 int find_itlb_entry(CPUState * env, target_ulong address, 68 int find_itlb_entry(CPUState * env, target_ulong address,
69 int use_asid, int update); 69 int use_asid, int update);
target-sh4/helper.c
@@ -36,7 +36,7 @@ void do_interrupt (CPUState *env) @@ -36,7 +36,7 @@ void do_interrupt (CPUState *env)
36 } 36 }
37 37
38 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, 38 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
39 - int is_user, int is_softmmu) 39 + int mmu_idx, int is_softmmu)
40 { 40 {
41 env->tea = address; 41 env->tea = address;
42 switch (rw) { 42 switch (rw) {
@@ -372,15 +372,15 @@ int get_physical_address(CPUState * env, target_ulong * physical, @@ -372,15 +372,15 @@ int get_physical_address(CPUState * env, target_ulong * physical,
372 } 372 }
373 373
374 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, 374 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
375 - int is_user, int is_softmmu) 375 + int mmu_idx, int is_softmmu)
376 { 376 {
377 target_ulong physical, page_offset, page_size; 377 target_ulong physical, page_offset, page_size;
378 int prot, ret, access_type; 378 int prot, ret, access_type;
379 379
380 /* XXXXX */ 380 /* XXXXX */
381 #if 0 381 #if 0
382 - fprintf(stderr, "%s pc %08x ad %08x rw %d is_user %d smmu %d\n",  
383 - __func__, env->pc, address, rw, is_user, is_softmmu); 382 + fprintf(stderr, "%s pc %08x ad %08x rw %d mmu_idx %d smmu %d\n",
  383 + __func__, env->pc, address, rw, mmu_idx, is_softmmu);
384 #endif 384 #endif
385 385
386 access_type = ACCESS_INT; 386 access_type = ACCESS_INT;
@@ -426,7 +426,7 @@ int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw, @@ -426,7 +426,7 @@ int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
426 address = (address & TARGET_PAGE_MASK) + page_offset; 426 address = (address & TARGET_PAGE_MASK) + page_offset;
427 physical = (physical & TARGET_PAGE_MASK) + page_offset; 427 physical = (physical & TARGET_PAGE_MASK) + page_offset;
428 428
429 - return tlb_set_page(env, address, physical, prot, is_user, is_softmmu); 429 + return tlb_set_page(env, address, physical, prot, mmu_idx, is_softmmu);
430 } 430 }
431 431
432 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) 432 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
target-sh4/op_helper.c
@@ -42,7 +42,7 @@ void do_raise_exception(void) @@ -42,7 +42,7 @@ void do_raise_exception(void)
42 #define SHIFT 3 42 #define SHIFT 3
43 #include "softmmu_template.h" 43 #include "softmmu_template.h"
44 44
45 -void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) 45 +void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
46 { 46 {
47 TranslationBlock *tb; 47 TranslationBlock *tb;
48 CPUState *saved_env; 48 CPUState *saved_env;
@@ -53,7 +53,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) @@ -53,7 +53,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
53 generated code */ 53 generated code */
54 saved_env = env; 54 saved_env = env;
55 env = cpu_single_env; 55 env = cpu_single_env;
56 - ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, is_user, 1); 56 + ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
57 if (ret) { 57 if (ret) {
58 if (retaddr) { 58 if (retaddr) {
59 /* now we have a real cpu fault */ 59 /* now we have a real cpu fault */
target-sparc/cpu.h
@@ -166,6 +166,8 @@ @@ -166,6 +166,8 @@
166 166
167 typedef struct sparc_def_t sparc_def_t; 167 typedef struct sparc_def_t sparc_def_t;
168 168
  169 +#define NB_MMU_MODES 2
  170 +
169 typedef struct CPUSPARCState { 171 typedef struct CPUSPARCState {
170 target_ulong gregs[8]; /* general registers */ 172 target_ulong gregs[8]; /* general registers */
171 target_ulong *regwptr; /* pointer to current register window */ 173 target_ulong *regwptr; /* pointer to current register window */
@@ -317,6 +319,15 @@ void cpu_check_irqs(CPUSPARCState *env); @@ -317,6 +319,15 @@ void cpu_check_irqs(CPUSPARCState *env);
317 #define cpu_signal_handler cpu_sparc_signal_handler 319 #define cpu_signal_handler cpu_sparc_signal_handler
318 #define cpu_list sparc_cpu_list 320 #define cpu_list sparc_cpu_list
319 321
  322 +/* MMU modes definitions */
  323 +#define MMU_MODE0_SUFFIX _kernel
  324 +#define MMU_MODE1_SUFFIX _user
  325 +#define MMU_USER_IDX 1
  326 +static inline int cpu_mmu_index (CPUState *env)
  327 +{
  328 + return env->psrs == 0 ? 1 : 0;
  329 +}
  330 +
320 #include "cpu-all.h" 331 #include "cpu-all.h"
321 332
322 #endif 333 #endif
target-sparc/exec.h
@@ -115,7 +115,7 @@ static inline void regs_to_env(void) @@ -115,7 +115,7 @@ static inline void regs_to_env(void)
115 } 115 }
116 116
117 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, 117 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
118 - int is_user, int is_softmmu); 118 + int mmu_idx, int is_softmmu);
119 119
120 static inline int cpu_halted(CPUState *env) { 120 static inline int cpu_halted(CPUState *env) {
121 if (!env->halted) 121 if (!env->halted)
target-sparc/helper.c
@@ -49,7 +49,7 @@ void cpu_unlock(void) @@ -49,7 +49,7 @@ void cpu_unlock(void)
49 #if defined(CONFIG_USER_ONLY) 49 #if defined(CONFIG_USER_ONLY)
50 50
51 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, 51 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
52 - int is_user, int is_softmmu) 52 + int mmu_idx, int is_softmmu)
53 { 53 {
54 if (rw & 2) 54 if (rw & 2)
55 env->exception_index = TT_TFAULT; 55 env->exception_index = TT_TFAULT;
@@ -100,15 +100,16 @@ static const int perm_table[2][8] = { @@ -100,15 +100,16 @@ static const int perm_table[2][8] = {
100 100
101 int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot, 101 int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
102 int *access_index, target_ulong address, int rw, 102 int *access_index, target_ulong address, int rw,
103 - int is_user) 103 + int mmu_idx)
104 { 104 {
105 int access_perms = 0; 105 int access_perms = 0;
106 target_phys_addr_t pde_ptr; 106 target_phys_addr_t pde_ptr;
107 uint32_t pde; 107 uint32_t pde;
108 target_ulong virt_addr; 108 target_ulong virt_addr;
109 - int error_code = 0, is_dirty; 109 + int error_code = 0, is_dirty, is_user;
110 unsigned long page_offset; 110 unsigned long page_offset;
111 111
  112 + is_user = mmu_idx == MMU_USER_IDX;
112 virt_addr = address & TARGET_PAGE_MASK; 113 virt_addr = address & TARGET_PAGE_MASK;
113 114
114 if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */ 115 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 @@ -216,13 +217,13 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
216 217
217 /* Perform address translation */ 218 /* Perform address translation */
218 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 219 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
219 - int is_user, int is_softmmu) 220 + int mmu_idx, int is_softmmu)
220 { 221 {
221 target_phys_addr_t paddr; 222 target_phys_addr_t paddr;
222 target_ulong vaddr; 223 target_ulong vaddr;
223 int error_code = 0, prot, ret = 0, access_index; 224 int error_code = 0, prot, ret = 0, access_index;
224 225
225 - error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user); 226 + error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx);
226 if (error_code == 0) { 227 if (error_code == 0) {
227 vaddr = address & TARGET_PAGE_MASK; 228 vaddr = address & TARGET_PAGE_MASK;
228 paddr &= TARGET_PAGE_MASK; 229 paddr &= TARGET_PAGE_MASK;
@@ -230,7 +231,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -230,7 +231,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
230 printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr " 231 printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
231 TARGET_FMT_lx "\n", address, paddr, vaddr); 232 TARGET_FMT_lx "\n", address, paddr, vaddr);
232 #endif 233 #endif
233 - ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); 234 + ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
234 return ret; 235 return ret;
235 } 236 }
236 237
@@ -246,7 +247,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -246,7 +247,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
246 // switching to normal mode. 247 // switching to normal mode.
247 vaddr = address & TARGET_PAGE_MASK; 248 vaddr = address & TARGET_PAGE_MASK;
248 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; 249 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
249 - ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); 250 + ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
250 return ret; 251 return ret;
251 } else { 252 } else {
252 if (rw & 2) 253 if (rw & 2)
@@ -484,8 +485,10 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical @@ -484,8 +485,10 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical
484 485
485 int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot, 486 int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
486 int *access_index, target_ulong address, int rw, 487 int *access_index, target_ulong address, int rw,
487 - int is_user) 488 + int mmu_idx)
488 { 489 {
  490 + int is_user = mmu_idx == MMU_USER_IDX;
  491 +
489 if (rw == 2) 492 if (rw == 2)
490 return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user); 493 return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
491 else 494 else
@@ -494,20 +497,20 @@ int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot, @@ -494,20 +497,20 @@ int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
494 497
495 /* Perform address translation */ 498 /* Perform address translation */
496 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 499 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
497 - int is_user, int is_softmmu) 500 + int mmu_idx, int is_softmmu)
498 { 501 {
499 target_ulong virt_addr, vaddr; 502 target_ulong virt_addr, vaddr;
500 target_phys_addr_t paddr; 503 target_phys_addr_t paddr;
501 int error_code = 0, prot, ret = 0, access_index; 504 int error_code = 0, prot, ret = 0, access_index;
502 505
503 - error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user); 506 + error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, mmu_idx);
504 if (error_code == 0) { 507 if (error_code == 0) {
505 virt_addr = address & TARGET_PAGE_MASK; 508 virt_addr = address & TARGET_PAGE_MASK;
506 vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1)); 509 vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
507 #ifdef DEBUG_MMU 510 #ifdef DEBUG_MMU
508 printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr); 511 printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
509 #endif 512 #endif
510 - ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); 513 + ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
511 return ret; 514 return ret;
512 } 515 }
513 // XXX 516 // XXX
target-sparc/op_helper.c
@@ -1522,7 +1522,7 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user, @@ -1522,7 +1522,7 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
1522 NULL, it means that the function was called in C code (i.e. not 1522 NULL, it means that the function was called in C code (i.e. not
1523 from generated code or from helper.c) */ 1523 from generated code or from helper.c) */
1524 /* XXX: fix it to restore all registers */ 1524 /* XXX: fix it to restore all registers */
1525 -void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) 1525 +void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
1526 { 1526 {
1527 TranslationBlock *tb; 1527 TranslationBlock *tb;
1528 int ret; 1528 int ret;
@@ -1534,7 +1534,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) @@ -1534,7 +1534,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
1534 saved_env = env; 1534 saved_env = env;
1535 env = cpu_single_env; 1535 env = cpu_single_env;
1536 1536
1537 - ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1); 1537 + ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
1538 if (ret) { 1538 if (ret) {
1539 if (retaddr) { 1539 if (retaddr) {
1540 /* now we have a real cpu fault */ 1540 /* now we have a real cpu fault */
target-sparc/translate.c
@@ -3689,7 +3689,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) @@ -3689,7 +3689,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
3689 #else 3689 #else
3690 extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot, 3690 extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
3691 int *access_index, target_ulong address, int rw, 3691 int *access_index, target_ulong address, int rw,
3692 - int is_user); 3692 + int mmu_idx);
3693 3693
3694 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) 3694 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
3695 { 3695 {