Commit b4ab4b4e1b8119ac1d9b28510d90682e30259c38

Authored by ths
1 parent a6763a58

Preliminary MIPS 64-bit MMU implementation, by Aurelien Jarno.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2794 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 57 additions and 5 deletions
target-mips/helper.c
... ... @@ -77,8 +77,13 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
77 77 int *prot, target_ulong address,
78 78 int rw, int access_type)
79 79 {
80   - /* User mode can only access useg */
  80 + /* User mode can only access useg/xuseg */
81 81 int user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
  82 +#ifdef TARGET_MIPS64
  83 + int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
  84 + int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
  85 + int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
  86 +#endif
82 87 int ret = TLBRET_MATCH;
83 88  
84 89 #if 0
... ... @@ -87,10 +92,18 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
87 92 user_mode, env->hflags);
88 93 }
89 94 #endif
  95 +
  96 +#ifdef TARGET_MIPS64
  97 + if (user_mode && address > 0x3FFFFFFFFFFFFFFFULL)
  98 + return TLBRET_BADADDR;
  99 +#else
90 100 if (user_mode && address > 0x7FFFFFFFUL)
91 101 return TLBRET_BADADDR;
92   - if (address < (int32_t)0x80000000UL) {
93   - if (!(env->CP0_Status & (1 << CP0St_ERL))) {
  102 +#endif
  103 +
  104 + if (address <= (int32_t)0x7FFFFFFFUL) {
  105 + /* useg */
  106 + if (!(env->CP0_Status & (1 << CP0St_ERL) && user_mode)) {
94 107 #ifdef MIPS_USES_R4K_TLB
95 108 ret = map_address(env, physical, prot, address, rw, access_type);
96 109 #else
... ... @@ -101,6 +114,45 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
101 114 *physical = address;
102 115 *prot = PAGE_READ | PAGE_WRITE;
103 116 }
  117 +#ifdef TARGET_MIPS64
  118 +/*
  119 + XXX: Assuming :
  120 + - PABITS = 36 (correct for MIPS64R1)
  121 + - SEGBITS = 40
  122 +*/
  123 + } else if (address < 0x3FFFFFFFFFFFFFFFULL) {
  124 + /* xuseg */
  125 + if (UX && address < 0x000000FFFFFFFFFFULL) {
  126 + ret = map_address(env, physical, prot, address, rw, access_type);
  127 + } else {
  128 + ret = TLBRET_BADADDR;
  129 + }
  130 + } else if (address < 0x7FFFFFFFFFFFFFFFULL) {
  131 + /* xsseg */
  132 + if (SX && address < 0x400000FFFFFFFFFFULL) {
  133 + ret = map_address(env, physical, prot, address, rw, access_type);
  134 + } else {
  135 + ret = TLBRET_BADADDR;
  136 + }
  137 + } else if (address < 0xBFFFFFFFFFFFFFFFULL) {
  138 + /* xkphys */
  139 + /* XXX: check supervisor mode */
  140 + if (KX && (address & 0x03FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL)
  141 + {
  142 + *physical = address & 0X000000FFFFFFFFFFULL;
  143 + *prot = PAGE_READ | PAGE_WRITE;
  144 + } else {
  145 + ret = TLBRET_BADADDR;
  146 + }
  147 + } else if (address < 0xFFFFFFFF7FFFFFFFULL) {
  148 + /* xkseg */
  149 + /* XXX: check supervisor mode */
  150 + if (KX && address < 0xC00000FF7FFFFFFFULL) {
  151 + ret = map_address(env, physical, prot, address, rw, access_type);
  152 + } else {
  153 + ret = TLBRET_BADADDR;
  154 + }
  155 +#endif
104 156 } else if (address < (int32_t)0xA0000000UL) {
105 157 /* kseg0 */
106 158 /* XXX: check supervisor mode */
... ... @@ -116,7 +168,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
116 168 #ifdef MIPS_USES_R4K_TLB
117 169 ret = map_address(env, physical, prot, address, rw, access_type);
118 170 #else
119   - *physical = address;
  171 + *physical = address & 0xFFFFFFFF;
120 172 *prot = PAGE_READ | PAGE_WRITE;
121 173 #endif
122 174 } else {
... ... @@ -126,7 +178,7 @@ static int get_physical_address (CPUState *env, target_ulong *physical,
126 178 #ifdef MIPS_USES_R4K_TLB
127 179 ret = map_address(env, physical, prot, address, rw, access_type);
128 180 #else
129   - *physical = address;
  181 + *physical = address & 0xFFFFFFFF;
130 182 *prot = PAGE_READ | PAGE_WRITE;
131 183 #endif
132 184 }
... ...