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 112 target_phys_addr_t addend;
113 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 115 #define CPU_COMMON \
125 116 struct TranslationBlock *current_tb; /* currently executing TB */ \
126 117 /* soft mmu support */ \
... ...
cpu-exec.c
... ... @@ -884,8 +884,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
884 884 }
885 885  
886 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 888 if (ret < 0)
890 889 return 0; /* not an MMU fault */
891 890 if (ret == 0)
... ... @@ -934,7 +933,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
934 933 return 1;
935 934 }
936 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 937 if (ret < 0)
939 938 return 0; /* not an MMU fault */
940 939 if (ret == 0)
... ... @@ -970,7 +969,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
970 969 return 1;
971 970 }
972 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 973 if (ret < 0)
975 974 return 0; /* not an MMU fault */
976 975 if (ret == 0)
... ... @@ -1007,7 +1006,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1007 1006 }
1008 1007  
1009 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 1010 if (ret < 0)
1012 1011 return 0; /* not an MMU fault */
1013 1012 if (ret == 0)
... ... @@ -1056,7 +1055,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1056 1055 return 1;
1057 1056 }
1058 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 1059 if (ret < 0)
1061 1060 return 0; /* not an MMU fault */
1062 1061 if (ret == 0)
... ... @@ -1096,7 +1095,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1096 1095 }
1097 1096  
1098 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 1099 if (ret < 0)
1101 1100 return 0; /* not an MMU fault */
1102 1101 if (ret == 0)
... ... @@ -1146,7 +1145,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1146 1145 }
1147 1146  
1148 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 1149 if (ret < 0)
1151 1150 return 0; /* not an MMU fault */
1152 1151 if (ret == 0)
... ... @@ -1191,7 +1190,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1191 1190 }
1192 1191  
1193 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 1194 if (ret < 0)
1196 1195 return 0; /* not an MMU fault */
1197 1196 if (ret == 0)
... ... @@ -1235,7 +1234,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1235 1234 }
1236 1235  
1237 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 1238 if (ret < 0)
1240 1239 return 0; /* not an MMU fault */
1241 1240 if (ret == 0)
... ...
exec-all.h
... ... @@ -117,14 +117,14 @@ void tlb_flush_page(CPUState *env, target_ulong addr);
117 117 void tlb_flush(CPUState *env, int flush_global);
118 118 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
119 119 target_phys_addr_t paddr, int prot,
120   - int is_user, int is_softmmu);
  120 + int mmu_idx, int is_softmmu);
121 121 static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
122 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 125 if (prot & PAGE_READ)
126 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 130 #define CODE_GEN_MAX_SIZE 65536
... ... @@ -562,10 +562,10 @@ extern int tb_invalidated_flag;
562 562  
563 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 566 void *retaddr);
567 567  
568   -#define ACCESS_TYPE 3
  568 +#define ACCESS_TYPE (NB_MMU_MODES + 1)
569 569 #define MEMSUFFIX _code
570 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 598 is the offset relative to phys_ram_base */
599 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 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 606 (addr & TARGET_PAGE_MASK), 0)) {
627 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 610 if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
631 611 #ifdef TARGET_SPARC
632 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 614 cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
635 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 619 #endif
640 620  
... ...
... ... @@ -1608,7 +1608,7 @@ static inline void tlb_set_dirty(CPUState *env,
1608 1608 conflicting with the host address space). */
1609 1609 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1610 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 1613 PhysPageDesc *p;
1614 1614 unsigned long pd;
... ... @@ -1626,8 +1626,8 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1626 1626 pd = p->phys_offset;
1627 1627 }
1628 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 1631 #endif
1632 1632  
1633 1633 ret = 0;
... ... @@ -1664,7 +1664,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1664 1664  
1665 1665 index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1666 1666 addend -= vaddr;
1667   - te = &env->tlb_table[is_user][index];
  1667 + te = &env->tlb_table[mmu_idx][index];
1668 1668 te->addend = addend;
1669 1669 if (prot & PAGE_READ) {
1670 1670 te->addr_read = address;
... ... @@ -1790,7 +1790,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
1790 1790  
1791 1791 int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
1792 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 1795 return 0;
1796 1796 }
... ...
hw/alpha_palcode.c
... ... @@ -811,12 +811,14 @@ static int get_page_bits (CPUState *env)
811 811  
812 812 static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
813 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 816 uint64_t pteaddr, pte, pfn;
817 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 822 pteaddr = (ptebase << page_bits) + (8 * level);
821 823 pte = ldq_raw(pteaddr);
822 824 /* Decode all interresting PTE fields */
... ... @@ -871,7 +873,7 @@ static int get_pte (uint64_t *pfnp, int *zbitsp, int *protp,
871 873  
872 874 static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
873 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 878 uint64_t pfn, page_mask, lvl_mask, level1, level2, level3;
877 879 int lvl_bits, ret;
... ... @@ -909,7 +911,7 @@ static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
909 911 break;
910 912 }
911 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 915 if (ret & 0x1) {
914 916 /* Translation not valid */
915 917 ret = 1;
... ... @@ -943,7 +945,7 @@ static int paddr_from_pte (uint64_t *paddr, int *zbitsp, int *prot,
943 945  
944 946 static int virtual_to_physical (CPUState *env, uint64_t *physp,
945 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 950 uint64_t sva, ptebase;
949 951 int seg, page_bits, ret;
... ... @@ -961,16 +963,16 @@ static int virtual_to_physical (CPUState *env, uint64_t *physp,
961 963 case 0:
962 964 /* seg1: 3 levels of PTE */
963 965 ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
964   - virtual, is_user, rw);
  966 + virtual, mmu_idx, rw);
965 967 break;
966 968 case 1:
967 969 /* seg1: 2 levels of PTE */
968 970 ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
969   - virtual, is_user, rw);
  971 + virtual, mmu_idx, rw);
970 972 break;
971 973 case 2:
972 974 /* kernel segment */
973   - if (is_user) {
  975 + if (mmu_idx != 0) {
974 976 ret = 2;
975 977 } else {
976 978 *physp = virtual;
... ... @@ -979,7 +981,7 @@ static int virtual_to_physical (CPUState *env, uint64_t *physp,
979 981 case 3:
980 982 /* seg1: TB mapped */
981 983 ret = paddr_from_pte(physp, zbitsp, protp, ptebase, page_bits,
982   - virtual, is_user, rw);
  984 + virtual, mmu_idx, rw);
983 985 break;
984 986 default:
985 987 ret = 1;
... ... @@ -991,7 +993,7 @@ static int virtual_to_physical (CPUState *env, uint64_t *physp,
991 993  
992 994 /* XXX: code provision */
993 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 998 uint64_t physical, page_size, end;
997 999 int prot, zbits, ret;
... ... @@ -1000,7 +1002,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
1000 1002 ret = 2;
1001 1003 } else {
1002 1004 ret = virtual_to_physical(env, &physical, &zbits, &prot,
1003   - address, is_user, rw);
  1005 + address, mmu_idx, rw);
1004 1006 }
1005 1007 switch (ret) {
1006 1008 case 0:
... ... @@ -1009,7 +1011,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
1009 1011 address &= ~(page_size - 1);
1010 1012 for (end = physical + page_size; physical < end; physical += 0x1000) {
1011 1013 ret = tlb_set_page(env, address, physical, prot,
1012   - is_user, is_softmmu);
  1014 + mmu_idx, is_softmmu);
1013 1015 address += 0x1000;
1014 1016 }
1015 1017 break;
... ...
softmmu_exec.h
1 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 12 #define ACCESS_TYPE 0
7   -#define MEMSUFFIX _kernel
  13 +#define MEMSUFFIX MMU_MODE0_SUFFIX
8 14 #define DATA_SIZE 1
9 15 #include "softmmu_header.h"
10 16  
... ... @@ -20,7 +26,7 @@
20 26 #undef MEMSUFFIX
21 27  
22 28 #define ACCESS_TYPE 1
23   -#define MEMSUFFIX _user
  29 +#define MEMSUFFIX MMU_MODE1_SUFFIX
24 30 #define DATA_SIZE 1
25 31 #include "softmmu_header.h"
26 32  
... ... @@ -35,8 +41,50 @@
35 41 #undef ACCESS_TYPE
36 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 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 88 #define MEMSUFFIX _data
41 89 #define DATA_SIZE 1
42 90 #include "softmmu_header.h"
... ...
softmmu_header.h
... ... @@ -39,66 +39,19 @@
39 39 #error unsupported data size
40 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 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 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 55 #define MMUSUFFIX _cmmu
103 56  
104 57 #else
... ... @@ -111,18 +64,18 @@
111 64 #define RES_TYPE int
112 65 #endif
113 66  
114   -#if ACCESS_TYPE == 3
  67 +#if ACCESS_TYPE == (NB_MMU_MODES + 1)
115 68 #define ADDR_READ addr_code
116 69 #else
117 70 #define ADDR_READ addr_read
118 71 #endif
119 72  
120 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 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 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 114 "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
162 115 "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
163 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 119 "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
167 120 : "%eax", "%ecx", "%edx", "memory", "cc");
168 121 return res;
... ... @@ -208,8 +161,8 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
208 161 "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
209 162 "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
210 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 166 "m" (*(uint8_t *)&glue(glue(__ld, SUFFIX), MMUSUFFIX))
214 167 : "%eax", "%ecx", "%edx", "memory", "cc");
215 168 return res;
... ... @@ -260,8 +213,8 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
260 213 "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS),
261 214 "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS),
262 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 218 "m" (*(uint8_t *)&glue(glue(__st, SUFFIX), MMUSUFFIX))
266 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 229 RES_TYPE res;
277 230 target_ulong addr;
278 231 unsigned long physaddr;
279   - int is_user;
  232 + int mmu_idx;
280 233  
281 234 addr = ptr;
282 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 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 240 } else {
288   - physaddr = addr + env->tlb_table[is_user][index].addend;
  241 + physaddr = addr + env->tlb_table[mmu_idx][index].addend;
289 242 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
290 243 }
291 244 return res;
... ... @@ -297,23 +250,23 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
297 250 int res, index;
298 251 target_ulong addr;
299 252 unsigned long physaddr;
300   - int is_user;
  253 + int mmu_idx;
301 254  
302 255 addr = ptr;
303 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 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 261 } else {
309   - physaddr = addr + env->tlb_table[is_user][index].addend;
  262 + physaddr = addr + env->tlb_table[mmu_idx][index].addend;
310 263 res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
311 264 }
312 265 return res;
313 266 }
314 267 #endif
315 268  
316   -#if ACCESS_TYPE != 3
  269 +#if ACCESS_TYPE != (NB_MMU_MODES + 1)
317 270  
318 271 /* generic store macro */
319 272  
... ... @@ -322,25 +275,25 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE
322 275 int index;
323 276 target_ulong addr;
324 277 unsigned long physaddr;
325   - int is_user;
  278 + int mmu_idx;
326 279  
327 280 addr = ptr;
328 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 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 286 } else {
334   - physaddr = addr + env->tlb_table[is_user][index].addend;
  287 + physaddr = addr + env->tlb_table[mmu_idx][index].addend;
335 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 294 #endif /* !asm */
342 295  
343   -#if ACCESS_TYPE != 3
  296 +#if ACCESS_TYPE != (NB_MMU_MODES + 1)
344 297  
345 298 #if DATA_SIZE == 8
346 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 339 }
387 340 #endif /* DATA_SIZE == 4 */
388 341  
389   -#endif /* ACCESS_TYPE != 3 */
  342 +#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
390 343  
391 344 #undef RES_TYPE
392 345 #undef DATA_TYPE
... ... @@ -394,6 +347,6 @@ static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
394 347 #undef SUFFIX
395 348 #undef USUFFIX
396 349 #undef DATA_SIZE
397   -#undef CPU_MEM_INDEX
  350 +#undef CPU_MMU_INDEX
398 351 #undef MMUSUFFIX
399 352 #undef ADDR_READ
... ...
softmmu_template.h
... ... @@ -48,7 +48,7 @@
48 48 #endif
49 49  
50 50 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
51   - int is_user,
  51 + int mmu_idx,
52 52 void *retaddr);
53 53 static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
54 54 target_ulong tlb_addr)
... ... @@ -76,7 +76,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
76 76  
77 77 /* handle all cases except unaligned access which span two pages */
78 78 DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
79   - int is_user)
  79 + int mmu_idx)
80 80 {
81 81 DATA_TYPE res;
82 82 int index;
... ... @@ -88,9 +88,9 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
88 88 /* XXX: could done more in memory macro in a non portable way */
89 89 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
90 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 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 94 if (tlb_addr & ~TARGET_PAGE_MASK) {
95 95 /* IO access */
96 96 if ((addr & (DATA_SIZE - 1)) != 0)
... ... @@ -101,16 +101,16 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
101 101 do_unaligned_access:
102 102 retaddr = GETPC();
103 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 105 #endif
106 106 res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
107   - is_user, retaddr);
  107 + mmu_idx, retaddr);
108 108 } else {
109 109 /* unaligned/aligned access in the same page */
110 110 #ifdef ALIGNED_ONLY
111 111 if ((addr & (DATA_SIZE - 1)) != 0) {
112 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 115 #endif
116 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 120 retaddr = GETPC();
121 121 #ifdef ALIGNED_ONLY
122 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 124 #endif
125   - tlb_fill(addr, READ_ACCESS_TYPE, is_user, retaddr);
  125 + tlb_fill(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
126 126 goto redo;
127 127 }
128 128 return res;
... ... @@ -130,7 +130,7 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
130 130  
131 131 /* handle all unaligned cases */
132 132 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
133   - int is_user,
  133 + int mmu_idx,
134 134 void *retaddr)
135 135 {
136 136 DATA_TYPE res, res1, res2;
... ... @@ -140,9 +140,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
140 140  
141 141 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
142 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 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 146 if (tlb_addr & ~TARGET_PAGE_MASK) {
147 147 /* IO access */
148 148 if ((addr & (DATA_SIZE - 1)) != 0)
... ... @@ -154,9 +154,9 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
154 154 addr1 = addr & ~(DATA_SIZE - 1);
155 155 addr2 = addr1 + DATA_SIZE;
156 156 res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
157   - is_user, retaddr);
  157 + mmu_idx, retaddr);
158 158 res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
159   - is_user, retaddr);
  159 + mmu_idx, retaddr);
160 160 shift = (addr & (DATA_SIZE - 1)) * 8;
161 161 #ifdef TARGET_WORDS_BIGENDIAN
162 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 170 }
171 171 } else {
172 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 174 goto redo;
175 175 }
176 176 return res;
... ... @@ -180,7 +180,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
180 180  
181 181 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
182 182 DATA_TYPE val,
183   - int is_user,
  183 + int mmu_idx,
184 184 void *retaddr);
185 185  
186 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 211  
212 212 void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
213 213 DATA_TYPE val,
214   - int is_user)
  214 + int mmu_idx)
215 215 {
216 216 target_phys_addr_t physaddr;
217 217 target_ulong tlb_addr;
... ... @@ -220,9 +220,9 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
220 220  
221 221 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
222 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 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 226 if (tlb_addr & ~TARGET_PAGE_MASK) {
227 227 /* IO access */
228 228 if ((addr & (DATA_SIZE - 1)) != 0)
... ... @@ -233,16 +233,16 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
233 233 do_unaligned_access:
234 234 retaddr = GETPC();
235 235 #ifdef ALIGNED_ONLY
236   - do_unaligned_access(addr, 1, is_user, retaddr);
  236 + do_unaligned_access(addr, 1, mmu_idx, retaddr);
237 237 #endif
238 238 glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
239   - is_user, retaddr);
  239 + mmu_idx, retaddr);
240 240 } else {
241 241 /* aligned/unaligned access in the same page */
242 242 #ifdef ALIGNED_ONLY
243 243 if ((addr & (DATA_SIZE - 1)) != 0) {
244 244 retaddr = GETPC();
245   - do_unaligned_access(addr, 1, is_user, retaddr);
  245 + do_unaligned_access(addr, 1, mmu_idx, retaddr);
246 246 }
247 247 #endif
248 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 252 retaddr = GETPC();
253 253 #ifdef ALIGNED_ONLY
254 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 256 #endif
257   - tlb_fill(addr, 1, is_user, retaddr);
  257 + tlb_fill(addr, 1, mmu_idx, retaddr);
258 258 goto redo;
259 259 }
260 260 }
... ... @@ -262,7 +262,7 @@ void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
262 262 /* handles all unaligned cases */
263 263 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
264 264 DATA_TYPE val,
265   - int is_user,
  265 + int mmu_idx,
266 266 void *retaddr)
267 267 {
268 268 target_phys_addr_t physaddr;
... ... @@ -271,9 +271,9 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
271 271  
272 272 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
273 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 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 277 if (tlb_addr & ~TARGET_PAGE_MASK) {
278 278 /* IO access */
279 279 if ((addr & (DATA_SIZE - 1)) != 0)
... ... @@ -285,10 +285,10 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
285 285 for(i = 0;i < DATA_SIZE; i++) {
286 286 #ifdef TARGET_WORDS_BIGENDIAN
287 287 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
288   - is_user, retaddr);
  288 + mmu_idx, retaddr);
289 289 #else
290 290 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
291   - is_user, retaddr);
  291 + mmu_idx, retaddr);
292 292 #endif
293 293 }
294 294 } else {
... ... @@ -297,7 +297,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
297 297 }
298 298 } else {
299 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 301 goto redo;
302 302 }
303 303 }
... ...
target-alpha/cpu.h
... ... @@ -256,6 +256,8 @@ struct pal_handler_t {
256 256 void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
257 257 };
258 258  
  259 +#define NB_MMU_MODES 4
  260 +
259 261 struct CPUAlphaState {
260 262 uint64_t ir[31];
261 263 float64 fir[31];
... ... @@ -302,6 +304,17 @@ struct CPUAlphaState {
302 304 #define cpu_gen_code cpu_alpha_gen_code
303 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 318 #include "cpu-all.h"
306 319  
307 320 enum {
... ...
target-alpha/exec.h
... ... @@ -73,7 +73,7 @@ static inline void regs_to_env(void)
73 73 }
74 74  
75 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 77 int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
78 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 28 #if defined(CONFIG_USER_ONLY)
29 29  
30 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 33 if (rw == 2)
34 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 57 }
58 58  
59 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 62 uint32_t opc;
63 63  
... ...
target-alpha/op_helper.c
... ... @@ -1164,20 +1164,20 @@ void helper_mtpr (int iprn)
1164 1164 void helper_ld_phys_to_virt (void)
1165 1165 {
1166 1166 uint64_t tlb_addr, physaddr;
1167   - int index, is_user;
  1167 + int index, mmu_idx;
1168 1168 void *retaddr;
1169 1169  
1170   - is_user = (env->ps >> 3) & 3;
  1170 + mmu_idx = cpu_mmu_index(env);
1171 1171 index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1172 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 1174 if ((T0 & TARGET_PAGE_MASK) ==
1175 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 1177 } else {
1178 1178 /* the page is not in the TLB : fill it */
1179 1179 retaddr = GETPC();
1180   - tlb_fill(T0, 0, is_user, retaddr);
  1180 + tlb_fill(T0, 0, mmu_idx, retaddr);
1181 1181 goto redo;
1182 1182 }
1183 1183 T0 = physaddr;
... ... @@ -1186,20 +1186,20 @@ void helper_ld_phys_to_virt (void)
1186 1186 void helper_st_phys_to_virt (void)
1187 1187 {
1188 1188 uint64_t tlb_addr, physaddr;
1189   - int index, is_user;
  1189 + int index, mmu_idx;
1190 1190 void *retaddr;
1191 1191  
1192   - is_user = (env->ps >> 3) & 3;
  1192 + mmu_idx = cpu_mmu_index(env);
1193 1193 index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1194 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 1196 if ((T0 & TARGET_PAGE_MASK) ==
1197 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 1199 } else {
1200 1200 /* the page is not in the TLB : fill it */
1201 1201 retaddr = GETPC();
1202   - tlb_fill(T0, 1, is_user, retaddr);
  1202 + tlb_fill(T0, 1, mmu_idx, retaddr);
1203 1203 goto redo;
1204 1204 }
1205 1205 T0 = physaddr;
... ... @@ -1223,7 +1223,7 @@ void helper_st_phys_to_virt (void)
1223 1223 NULL, it means that the function was called in C code (i.e. not
1224 1224 from generated code or from helper.c) */
1225 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 1228 TranslationBlock *tb;
1229 1229 CPUState *saved_env;
... ... @@ -1234,7 +1234,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
1234 1234 generated code */
1235 1235 saved_env = env;
1236 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 1238 if (!likely(ret == 0)) {
1239 1239 if (likely(retaddr)) {
1240 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 43 typedef uint32_t ARMReadCPFunc(void *opaque, int cp_info,
44 44 int dstreg, int operand);
45 45  
  46 +#define NB_MMU_MODES 2
  47 +
46 48 /* We currently assume float and double are IEEE single and double
47 49 precision respectively.
48 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 303 #define cpu_signal_handler cpu_arm_signal_handler
302 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 315 #include "cpu-all.h"
305 316  
306 317 #endif
... ...
target-arm/exec.h
... ... @@ -46,7 +46,7 @@ static inline void regs_to_env(void)
46 46 }
47 47  
48 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 51 static inline int cpu_halted(CPUState *env) {
52 52 if (!env->halted)
... ...
target-arm/helper.c
... ... @@ -169,7 +169,7 @@ void do_interrupt (CPUState *env)
169 169 }
170 170  
171 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 174 if (rw == 2) {
175 175 env->exception_index = EXCP_PREFETCH_ABORT;
... ... @@ -547,18 +547,19 @@ do_fault:
547 547 }
548 548  
549 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 552 uint32_t phys_addr;
553 553 int prot;
554   - int ret;
  554 + int ret, is_user;
555 555  
  556 + is_user = mmu_idx == MMU_USER_IDX;
556 557 ret = get_phys_addr(env, address, access_type, is_user, &phys_addr, &prot);
557 558 if (ret == 0) {
558 559 /* Map a single [sub]page. */
559 560 phys_addr &= ~(uint32_t)0x3ff;
560 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 563 is_softmmu);
563 564 }
564 565  
... ...
target-arm/op_helper.c
... ... @@ -196,7 +196,7 @@ void do_vfp_get_fpscr(void)
196 196 NULL, it means that the function was called in C code (i.e. not
197 197 from generated code or from helper.c) */
198 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 201 TranslationBlock *tb;
202 202 CPUState *saved_env;
... ... @@ -207,7 +207,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
207 207 generated code */
208 208 saved_env = env;
209 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 211 if (__builtin_expect(ret, 0)) {
212 212 if (retaddr) {
213 213 /* now we have a real cpu fault */
... ...
target-cris/cpu.h
... ... @@ -74,6 +74,8 @@
74 74 /* Internal flags for the implementation. */
75 75 #define F_DELAYSLOT 1
76 76  
  77 +#define NB_MMU_MODES 2
  78 +
77 79 typedef struct CPUCRISState {
78 80 uint32_t debug1;
79 81 uint32_t debug2;
... ... @@ -229,6 +231,16 @@ void register_cris_insns (CPUCRISState *env);
229 231 #define cpu_gen_code cpu_cris_gen_code
230 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 244 #include "cpu-all.h"
233 245  
234 246 /* Register aliases. */
... ...
target-cris/exec.h
... ... @@ -45,8 +45,8 @@ static inline void regs_to_env(void)
45 45 }
46 46  
47 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 51 #if !defined(CONFIG_USER_ONLY)
52 52 #include "softmmu_exec.h"
... ...
target-cris/helper.c
... ... @@ -35,7 +35,7 @@ void do_interrupt (CPUState *env)
35 35 }
36 36  
37 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 40 env->exception_index = 0xaa;
41 41 env->debug1 = address;
... ... @@ -52,7 +52,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
52 52 #else /* !CONFIG_USER_ONLY */
53 53  
54 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 57 struct cris_mmu_result_t res;
58 58 int prot, miss;
... ... @@ -61,7 +61,7 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
61 61 address &= TARGET_PAGE_MASK;
62 62 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
63 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 65 if (miss)
66 66 {
67 67 /* handle the miss. */
... ... @@ -73,7 +73,7 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
73 73 phy = res.phy;
74 74 }
75 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 111  
112 112 int cris_mmu_translate(struct cris_mmu_result_t *res,
113 113 CPUState *env, uint32_t vaddr,
114   - int rw, int is_user)
  114 + int rw, int mmu_idx)
115 115 {
116 116 uint32_t phy = vaddr;
117 117 int seg;
118 118 int miss = 0;
  119 + int is_user = mmu_idx == MMU_USER_IDX;
119 120  
120 121 if (!cris_mmu_enabled(env->sregs[SFR_RW_GC_CFG])) {
121 122 res->phy = vaddr;
... ...
target-cris/mmu.h
... ... @@ -17,4 +17,4 @@ struct cris_mmu_result_t
17 17  
18 18 int cris_mmu_translate(struct cris_mmu_result_t *res,
19 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 41 NULL, it means that the function was called in C code (i.e. not
42 42 from generated code or from helper.c) */
43 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 46 TranslationBlock *tb;
47 47 CPUState *saved_env;
... ... @@ -52,7 +52,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
52 52 generated code */
53 53 saved_env = env;
54 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 56 if (__builtin_expect(ret, 0)) {
57 57 if (retaddr) {
58 58 /* now we have a real cpu fault */
... ...
target-i386/cpu.h
... ... @@ -432,6 +432,8 @@ typedef union {
432 432 #define CPU_NB_REGS 8
433 433 #endif
434 434  
  435 +#define NB_MMU_MODES 2
  436 +
435 437 typedef struct CPUX86State {
436 438 #if TARGET_LONG_BITS > HOST_LONG_BITS
437 439 /* temporaries if we cannot store them in host registers */
... ... @@ -688,6 +690,15 @@ static inline int cpu_get_time_fast(void)
688 690 #define cpu_gen_code cpu_x86_gen_code
689 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 702 #include "cpu-all.h"
692 703  
693 704 #include "svm.h"
... ...
target-i386/exec.h
... ... @@ -163,8 +163,8 @@ void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
163 163 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
164 164 void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr);
165 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 168 void *retaddr);
169 169 void __hidden cpu_lock(void);
170 170 void __hidden cpu_unlock(void);
... ...
target-i386/helper.c
... ... @@ -3885,7 +3885,7 @@ void update_fp_status(void)
3885 3885 NULL, it means that the function was called in C code (i.e. not
3886 3886 from generated code or from helper.c) */
3887 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 3890 TranslationBlock *tb;
3891 3891 int ret;
... ... @@ -3897,7 +3897,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
3897 3897 saved_env = env;
3898 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 3901 if (ret) {
3902 3902 if (retaddr) {
3903 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 571 #if defined(CONFIG_USER_ONLY)
572 572  
573 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 576 /* user mode only emulation */
577 577 is_write &= 1;
... ... @@ -598,14 +598,15 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
598 598 2 = soft MMU activation required for this block
599 599 */
600 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 603 uint64_t ptep, pte;
604 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 606 unsigned long paddr, page_offset;
607 607 target_ulong vaddr, virt_addr;
608 608  
  609 + is_user = mmu_idx == MMU_USER_IDX;
609 610 #if defined(DEBUG_MMU)
610 611 printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
611 612 addr, is_write1, is_user, env->eip);
... ... @@ -862,7 +863,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
862 863 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
863 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 867 return ret;
867 868 do_fault_protect:
868 869 error_code = PG_ERROR_P_MASK;
... ...
target-m68k/cpu.h
... ... @@ -53,6 +53,8 @@
53 53 #define EXCP_RTE 0x100
54 54 #define EXCP_HALT_INSN 0x101
55 55  
  56 +#define NB_MMU_MODES 2
  57 +
56 58 typedef struct CPUM68KState {
57 59 uint32_t dregs[8];
58 60 uint32_t aregs[8];
... ... @@ -223,6 +225,15 @@ void register_m68k_insns (CPUM68KState *env);
223 225 #define cpu_gen_code cpu_m68k_gen_code
224 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 237 #include "cpu-all.h"
227 238  
228 239 #endif
... ...
target-m68k/exec.h
... ... @@ -38,7 +38,7 @@ static inline void regs_to_env(void)
38 38 }
39 39  
40 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 43 #if !defined(CONFIG_USER_ONLY)
44 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 301 #if defined(CONFIG_USER_ONLY)
302 302  
303 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 306 env->exception_index = EXCP_ACCESS;
307 307 env->mmu.ar = address;
... ... @@ -311,13 +311,13 @@ int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
311 311 #else
312 312  
313 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 316 int prot;
317 317  
318 318 address &= TARGET_PAGE_MASK;
319 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 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 49 NULL, it means that the function was called in C code (i.e. not
50 50 from generated code or from helper.c) */
51 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 54 TranslationBlock *tb;
55 55 CPUState *saved_env;
... ... @@ -60,7 +60,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
60 60 generated code */
61 61 saved_env = env;
62 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 64 if (__builtin_expect(ret, 0)) {
65 65 if (retaddr) {
66 66 /* now we have a real cpu fault */
... ...
target-mips/cpu.h
... ... @@ -107,6 +107,8 @@ struct CPUMIPSFPUContext {
107 107 #define FP_UNIMPLEMENTED 32
108 108 };
109 109  
  110 +#define NB_MMU_MODES 2
  111 +
110 112 typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
111 113 struct CPUMIPSMVPContext {
112 114 int32_t CP0_MVPControl;
... ... @@ -484,6 +486,15 @@ int cpu_mips_register (CPUMIPSState *env, mips_def_t *def);
484 486 #define cpu_signal_handler cpu_mips_signal_handler
485 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 498 #include "cpu-all.h"
488 499  
489 500 /* Memory access type :
... ...
target-mips/exec.h
... ... @@ -105,7 +105,7 @@ void do_pmon (int function);
105 105 void dump_sc (void);
106 106  
107 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 109 void do_interrupt (CPUState *env);
110 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 229 #endif /* !defined(CONFIG_USER_ONLY) */
230 230  
231 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 234 target_ulong physical;
235 235 int prot;
... ... @@ -241,8 +241,8 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
241 241 #if 0
242 242 cpu_dump_state(env, logfile, fprintf, 0);
243 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 248 rw &= 1;
... ... @@ -265,7 +265,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
265 265 if (ret == TLBRET_MATCH) {
266 266 ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
267 267 physical & TARGET_PAGE_MASK, prot,
268   - is_user, is_softmmu);
  268 + mmu_idx, is_softmmu);
269 269 } else if (ret < 0) {
270 270 do_fault:
271 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 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 568 TranslationBlock *tb;
569 569 CPUState *saved_env;
... ... @@ -574,7 +574,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
574 574 generated code */
575 575 saved_env = env;
576 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 578 if (ret) {
579 579 if (retaddr) {
580 580 /* now we have a real cpu fault */
... ...
target-ppc/cpu.h
... ... @@ -434,6 +434,12 @@ enum {
434 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 444 /* The whole PowerPC CPU context */
439 445 struct CPUPPCState {
... ... @@ -575,6 +581,7 @@ struct CPUPPCState {
575 581 jmp_buf jmp_env;
576 582 int user_mode_only; /* user mode only simulation */
577 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 586 /* Power management */
580 587 int power_mode;
... ... @@ -699,6 +706,18 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
699 706 #define cpu_signal_handler cpu_ppc_signal_handler
700 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 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 112 }
113 113  
114 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 117 static always_inline int cpu_halted (CPUState *env)
118 118 {
... ...
target-ppc/helper.c
... ... @@ -39,7 +39,7 @@
39 39  
40 40 #if defined(CONFIG_USER_ONLY)
41 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 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 1349  
1350 1350 /* Perform address translation */
1351 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 1354 mmu_ctx_t ctx;
1355 1355 int access_type;
... ... @@ -1370,7 +1370,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1370 1370 if (ret == 0) {
1371 1371 ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
1372 1372 ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
1373   - is_user, is_softmmu);
  1373 + mmu_idx, is_softmmu);
1374 1374 } else if (ret < 0) {
1375 1375 #if defined (DEBUG_MMU)
1376 1376 if (loglevel != 0)
... ... @@ -2083,7 +2083,12 @@ void do_compute_hflags (CPUPPCState *env)
2083 2083 env->hflags |= msr_cm << MSR_CM;
2084 2084 env->hflags |= (uint64_t)msr_sf << MSR_SF;
2085 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 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 2307 NULL, it means that the function was called in C code (i.e. not
2308 2308 from generated code or from helper.c) */
2309 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 2312 TranslationBlock *tb;
2313 2313 CPUState *saved_env;
... ... @@ -2318,7 +2318,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
2318 2318 generated code */
2319 2319 saved_env = env;
2320 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 2322 if (unlikely(ret != 0)) {
2323 2323 if (likely(retaddr)) {
2324 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 6693 ctx.tb = tb;
6694 6694 ctx.exception = POWERPC_EXCP_NONE;
6695 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 6698 ctx.supervisor = supervisor;
6706 6699 #endif
6707 6700 #if defined(TARGET_PPC64)
... ...
target-sh4/cpu.h
... ... @@ -77,6 +77,8 @@ typedef struct tlb_t {
77 77 #define UTLB_SIZE 64
78 78 #define ITLB_SIZE 4
79 79  
  80 +#define NB_MMU_MODES 2
  81 +
80 82 typedef struct CPUSH4State {
81 83 uint32_t flags; /* general execution flags */
82 84 uint32_t gregs[24]; /* general registers */
... ... @@ -134,6 +136,15 @@ int cpu_sh4_signal_handler(int host_signum, void *pinfo,
134 136 #define cpu_gen_code cpu_sh4_gen_code
135 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 148 #include "cpu-all.h"
138 149  
139 150 /* Memory access type */
... ...
target-sh4/exec.h
... ... @@ -63,7 +63,7 @@ static inline void env_to_regs(void)
63 63 }
64 64  
65 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 68 int find_itlb_entry(CPUState * env, target_ulong address,
69 69 int use_asid, int update);
... ...
target-sh4/helper.c
... ... @@ -36,7 +36,7 @@ void do_interrupt (CPUState *env)
36 36 }
37 37  
38 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 41 env->tea = address;
42 42 switch (rw) {
... ... @@ -372,15 +372,15 @@ int get_physical_address(CPUState * env, target_ulong * physical,
372 372 }
373 373  
374 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 377 target_ulong physical, page_offset, page_size;
378 378 int prot, ret, access_type;
379 379  
380 380 /* XXXXX */
381 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 384 #endif
385 385  
386 386 access_type = ACCESS_INT;
... ... @@ -426,7 +426,7 @@ int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
426 426 address = (address & TARGET_PAGE_MASK) + page_offset;
427 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 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 42 #define SHIFT 3
43 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 47 TranslationBlock *tb;
48 48 CPUState *saved_env;
... ... @@ -53,7 +53,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
53 53 generated code */
54 54 saved_env = env;
55 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 57 if (ret) {
58 58 if (retaddr) {
59 59 /* now we have a real cpu fault */
... ...
target-sparc/cpu.h
... ... @@ -166,6 +166,8 @@
166 166  
167 167 typedef struct sparc_def_t sparc_def_t;
168 168  
  169 +#define NB_MMU_MODES 2
  170 +
169 171 typedef struct CPUSPARCState {
170 172 target_ulong gregs[8]; /* general registers */
171 173 target_ulong *regwptr; /* pointer to current register window */
... ... @@ -317,6 +319,15 @@ void cpu_check_irqs(CPUSPARCState *env);
317 319 #define cpu_signal_handler cpu_sparc_signal_handler
318 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 331 #include "cpu-all.h"
321 332  
322 333 #endif
... ...
target-sparc/exec.h
... ... @@ -115,7 +115,7 @@ static inline void regs_to_env(void)
115 115 }
116 116  
117 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 120 static inline int cpu_halted(CPUState *env) {
121 121 if (!env->halted)
... ...
target-sparc/helper.c
... ... @@ -49,7 +49,7 @@ void cpu_unlock(void)
49 49 #if defined(CONFIG_USER_ONLY)
50 50  
51 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 54 if (rw & 2)
55 55 env->exception_index = TT_TFAULT;
... ... @@ -100,15 +100,16 @@ static const int perm_table[2][8] = {
100 100  
101 101 int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
102 102 int *access_index, target_ulong address, int rw,
103   - int is_user)
  103 + int mmu_idx)
104 104 {
105 105 int access_perms = 0;
106 106 target_phys_addr_t pde_ptr;
107 107 uint32_t pde;
108 108 target_ulong virt_addr;
109   - int error_code = 0, is_dirty;
  109 + int error_code = 0, is_dirty, is_user;
110 110 unsigned long page_offset;
111 111  
  112 + is_user = mmu_idx == MMU_USER_IDX;
112 113 virt_addr = address & TARGET_PAGE_MASK;
113 114  
114 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 217  
217 218 /* Perform address translation */
218 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 222 target_phys_addr_t paddr;
222 223 target_ulong vaddr;
223 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 227 if (error_code == 0) {
227 228 vaddr = address & TARGET_PAGE_MASK;
228 229 paddr &= TARGET_PAGE_MASK;
... ... @@ -230,7 +231,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
230 231 printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr "
231 232 TARGET_FMT_lx "\n", address, paddr, vaddr);
232 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 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 247 // switching to normal mode.
247 248 vaddr = address & TARGET_PAGE_MASK;
248 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 251 return ret;
251 252 } else {
252 253 if (rw & 2)
... ... @@ -484,8 +485,10 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical
484 485  
485 486 int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
486 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 492 if (rw == 2)
490 493 return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
491 494 else
... ... @@ -494,20 +497,20 @@ int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
494 497  
495 498 /* Perform address translation */
496 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 502 target_ulong virt_addr, vaddr;
500 503 target_phys_addr_t paddr;
501 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 507 if (error_code == 0) {
505 508 virt_addr = address & TARGET_PAGE_MASK;
506 509 vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
507 510 #ifdef DEBUG_MMU
508 511 printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 "\n", address, paddr, vaddr);
509 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 514 return ret;
512 515 }
513 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 1522 NULL, it means that the function was called in C code (i.e. not
1523 1523 from generated code or from helper.c) */
1524 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 1527 TranslationBlock *tb;
1528 1528 int ret;
... ... @@ -1534,7 +1534,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
1534 1534 saved_env = env;
1535 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 1538 if (ret) {
1539 1539 if (retaddr) {
1540 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 3689 #else
3690 3690 extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
3691 3691 int *access_index, target_ulong address, int rw,
3692   - int is_user);
  3692 + int mmu_idx);
3693 3693  
3694 3694 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
3695 3695 {
... ...