Commit 61382a500a9e54ef96ca28e0f221151f569cbb6e
1 parent
3a51dee6
full softmmu support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@410 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
10 changed files
with
594 additions
and
339 deletions
cpu-all.h
@@ -20,18 +20,19 @@ | @@ -20,18 +20,19 @@ | ||
20 | #ifndef CPU_ALL_H | 20 | #ifndef CPU_ALL_H |
21 | #define CPU_ALL_H | 21 | #define CPU_ALL_H |
22 | 22 | ||
23 | -/* all CPU memory access use these macros */ | ||
24 | -static inline int ldub(void *ptr) | 23 | +/* CPU memory access without any memory or io remapping */ |
24 | + | ||
25 | +static inline int ldub_raw(void *ptr) | ||
25 | { | 26 | { |
26 | return *(uint8_t *)ptr; | 27 | return *(uint8_t *)ptr; |
27 | } | 28 | } |
28 | 29 | ||
29 | -static inline int ldsb(void *ptr) | 30 | +static inline int ldsb_raw(void *ptr) |
30 | { | 31 | { |
31 | return *(int8_t *)ptr; | 32 | return *(int8_t *)ptr; |
32 | } | 33 | } |
33 | 34 | ||
34 | -static inline void stb(void *ptr, int v) | 35 | +static inline void stb_raw(void *ptr, int v) |
35 | { | 36 | { |
36 | *(uint8_t *)ptr = v; | 37 | *(uint8_t *)ptr = v; |
37 | } | 38 | } |
@@ -42,7 +43,7 @@ static inline void stb(void *ptr, int v) | @@ -42,7 +43,7 @@ static inline void stb(void *ptr, int v) | ||
42 | #if defined(WORDS_BIGENDIAN) || defined(__arm__) | 43 | #if defined(WORDS_BIGENDIAN) || defined(__arm__) |
43 | 44 | ||
44 | /* conservative code for little endian unaligned accesses */ | 45 | /* conservative code for little endian unaligned accesses */ |
45 | -static inline int lduw(void *ptr) | 46 | +static inline int lduw_raw(void *ptr) |
46 | { | 47 | { |
47 | #ifdef __powerpc__ | 48 | #ifdef __powerpc__ |
48 | int val; | 49 | int val; |
@@ -54,7 +55,7 @@ static inline int lduw(void *ptr) | @@ -54,7 +55,7 @@ static inline int lduw(void *ptr) | ||
54 | #endif | 55 | #endif |
55 | } | 56 | } |
56 | 57 | ||
57 | -static inline int ldsw(void *ptr) | 58 | +static inline int ldsw_raw(void *ptr) |
58 | { | 59 | { |
59 | #ifdef __powerpc__ | 60 | #ifdef __powerpc__ |
60 | int val; | 61 | int val; |
@@ -66,7 +67,7 @@ static inline int ldsw(void *ptr) | @@ -66,7 +67,7 @@ static inline int ldsw(void *ptr) | ||
66 | #endif | 67 | #endif |
67 | } | 68 | } |
68 | 69 | ||
69 | -static inline int ldl(void *ptr) | 70 | +static inline int ldl_raw(void *ptr) |
70 | { | 71 | { |
71 | #ifdef __powerpc__ | 72 | #ifdef __powerpc__ |
72 | int val; | 73 | int val; |
@@ -78,16 +79,16 @@ static inline int ldl(void *ptr) | @@ -78,16 +79,16 @@ static inline int ldl(void *ptr) | ||
78 | #endif | 79 | #endif |
79 | } | 80 | } |
80 | 81 | ||
81 | -static inline uint64_t ldq(void *ptr) | 82 | +static inline uint64_t ldq_raw(void *ptr) |
82 | { | 83 | { |
83 | uint8_t *p = ptr; | 84 | uint8_t *p = ptr; |
84 | uint32_t v1, v2; | 85 | uint32_t v1, v2; |
85 | - v1 = ldl(p); | ||
86 | - v2 = ldl(p + 4); | 86 | + v1 = ldl_raw(p); |
87 | + v2 = ldl_raw(p + 4); | ||
87 | return v1 | ((uint64_t)v2 << 32); | 88 | return v1 | ((uint64_t)v2 << 32); |
88 | } | 89 | } |
89 | 90 | ||
90 | -static inline void stw(void *ptr, int v) | 91 | +static inline void stw_raw(void *ptr, int v) |
91 | { | 92 | { |
92 | #ifdef __powerpc__ | 93 | #ifdef __powerpc__ |
93 | __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); | 94 | __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); |
@@ -98,7 +99,7 @@ static inline void stw(void *ptr, int v) | @@ -98,7 +99,7 @@ static inline void stw(void *ptr, int v) | ||
98 | #endif | 99 | #endif |
99 | } | 100 | } |
100 | 101 | ||
101 | -static inline void stl(void *ptr, int v) | 102 | +static inline void stl_raw(void *ptr, int v) |
102 | { | 103 | { |
103 | #ifdef __powerpc__ | 104 | #ifdef __powerpc__ |
104 | __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); | 105 | __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); |
@@ -111,104 +112,104 @@ static inline void stl(void *ptr, int v) | @@ -111,104 +112,104 @@ static inline void stl(void *ptr, int v) | ||
111 | #endif | 112 | #endif |
112 | } | 113 | } |
113 | 114 | ||
114 | -static inline void stq(void *ptr, uint64_t v) | 115 | +static inline void stq_raw(void *ptr, uint64_t v) |
115 | { | 116 | { |
116 | uint8_t *p = ptr; | 117 | uint8_t *p = ptr; |
117 | - stl(p, (uint32_t)v); | ||
118 | - stl(p + 4, v >> 32); | 118 | + stl_raw(p, (uint32_t)v); |
119 | + stl_raw(p + 4, v >> 32); | ||
119 | } | 120 | } |
120 | 121 | ||
121 | /* float access */ | 122 | /* float access */ |
122 | 123 | ||
123 | -static inline float ldfl(void *ptr) | 124 | +static inline float ldfl_raw(void *ptr) |
124 | { | 125 | { |
125 | union { | 126 | union { |
126 | float f; | 127 | float f; |
127 | uint32_t i; | 128 | uint32_t i; |
128 | } u; | 129 | } u; |
129 | - u.i = ldl(ptr); | 130 | + u.i = ldl_raw(ptr); |
130 | return u.f; | 131 | return u.f; |
131 | } | 132 | } |
132 | 133 | ||
133 | -static inline void stfl(void *ptr, float v) | 134 | +static inline void stfl_raw(void *ptr, float v) |
134 | { | 135 | { |
135 | union { | 136 | union { |
136 | float f; | 137 | float f; |
137 | uint32_t i; | 138 | uint32_t i; |
138 | } u; | 139 | } u; |
139 | u.f = v; | 140 | u.f = v; |
140 | - stl(ptr, u.i); | 141 | + stl_raw(ptr, u.i); |
141 | } | 142 | } |
142 | 143 | ||
143 | 144 | ||
144 | #if defined(__arm__) && !defined(WORDS_BIGENDIAN) | 145 | #if defined(__arm__) && !defined(WORDS_BIGENDIAN) |
145 | 146 | ||
146 | /* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ | 147 | /* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ |
147 | -static inline double ldfq(void *ptr) | 148 | +static inline double ldfq_raw(void *ptr) |
148 | { | 149 | { |
149 | union { | 150 | union { |
150 | double d; | 151 | double d; |
151 | uint32_t tab[2]; | 152 | uint32_t tab[2]; |
152 | } u; | 153 | } u; |
153 | - u.tab[1] = ldl(ptr); | ||
154 | - u.tab[0] = ldl(ptr + 4); | 154 | + u.tab[1] = ldl_raw(ptr); |
155 | + u.tab[0] = ldl_raw(ptr + 4); | ||
155 | return u.d; | 156 | return u.d; |
156 | } | 157 | } |
157 | 158 | ||
158 | -static inline void stfq(void *ptr, double v) | 159 | +static inline void stfq_raw(void *ptr, double v) |
159 | { | 160 | { |
160 | union { | 161 | union { |
161 | double d; | 162 | double d; |
162 | uint32_t tab[2]; | 163 | uint32_t tab[2]; |
163 | } u; | 164 | } u; |
164 | u.d = v; | 165 | u.d = v; |
165 | - stl(ptr, u.tab[1]); | ||
166 | - stl(ptr + 4, u.tab[0]); | 166 | + stl_raw(ptr, u.tab[1]); |
167 | + stl_raw(ptr + 4, u.tab[0]); | ||
167 | } | 168 | } |
168 | 169 | ||
169 | #else | 170 | #else |
170 | -static inline double ldfq(void *ptr) | 171 | +static inline double ldfq_raw(void *ptr) |
171 | { | 172 | { |
172 | union { | 173 | union { |
173 | double d; | 174 | double d; |
174 | uint64_t i; | 175 | uint64_t i; |
175 | } u; | 176 | } u; |
176 | - u.i = ldq(ptr); | 177 | + u.i = ldq_raw(ptr); |
177 | return u.d; | 178 | return u.d; |
178 | } | 179 | } |
179 | 180 | ||
180 | -static inline void stfq(void *ptr, double v) | 181 | +static inline void stfq_raw(void *ptr, double v) |
181 | { | 182 | { |
182 | union { | 183 | union { |
183 | double d; | 184 | double d; |
184 | uint64_t i; | 185 | uint64_t i; |
185 | } u; | 186 | } u; |
186 | u.d = v; | 187 | u.d = v; |
187 | - stq(ptr, u.i); | 188 | + stq_raw(ptr, u.i); |
188 | } | 189 | } |
189 | #endif | 190 | #endif |
190 | 191 | ||
191 | #elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN) | 192 | #elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN) |
192 | 193 | ||
193 | -static inline int lduw(void *ptr) | 194 | +static inline int lduw_raw(void *ptr) |
194 | { | 195 | { |
195 | uint8_t *b = (uint8_t *) ptr; | 196 | uint8_t *b = (uint8_t *) ptr; |
196 | return (b[0]<<8|b[1]); | 197 | return (b[0]<<8|b[1]); |
197 | } | 198 | } |
198 | 199 | ||
199 | -static inline int ldsw(void *ptr) | 200 | +static inline int ldsw_raw(void *ptr) |
200 | { | 201 | { |
201 | int8_t *b = (int8_t *) ptr; | 202 | int8_t *b = (int8_t *) ptr; |
202 | return (b[0]<<8|b[1]); | 203 | return (b[0]<<8|b[1]); |
203 | } | 204 | } |
204 | 205 | ||
205 | -static inline int ldl(void *ptr) | 206 | +static inline int ldl_raw(void *ptr) |
206 | { | 207 | { |
207 | uint8_t *b = (uint8_t *) ptr; | 208 | uint8_t *b = (uint8_t *) ptr; |
208 | return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]); | 209 | return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]); |
209 | } | 210 | } |
210 | 211 | ||
211 | -static inline uint64_t ldq(void *ptr) | 212 | +static inline uint64_t ldq_raw(void *ptr) |
212 | { | 213 | { |
213 | uint32_t a,b; | 214 | uint32_t a,b; |
214 | a = ldl (ptr); | 215 | a = ldl (ptr); |
@@ -216,14 +217,14 @@ static inline uint64_t ldq(void *ptr) | @@ -216,14 +217,14 @@ static inline uint64_t ldq(void *ptr) | ||
216 | return (((uint64_t)a<<32)|b); | 217 | return (((uint64_t)a<<32)|b); |
217 | } | 218 | } |
218 | 219 | ||
219 | -static inline void stw(void *ptr, int v) | 220 | +static inline void stw_raw(void *ptr, int v) |
220 | { | 221 | { |
221 | uint8_t *d = (uint8_t *) ptr; | 222 | uint8_t *d = (uint8_t *) ptr; |
222 | d[0] = v >> 8; | 223 | d[0] = v >> 8; |
223 | d[1] = v; | 224 | d[1] = v; |
224 | } | 225 | } |
225 | 226 | ||
226 | -static inline void stl(void *ptr, int v) | 227 | +static inline void stl_raw(void *ptr, int v) |
227 | { | 228 | { |
228 | uint8_t *d = (uint8_t *) ptr; | 229 | uint8_t *d = (uint8_t *) ptr; |
229 | d[0] = v >> 24; | 230 | d[0] = v >> 24; |
@@ -232,7 +233,7 @@ static inline void stl(void *ptr, int v) | @@ -232,7 +233,7 @@ static inline void stl(void *ptr, int v) | ||
232 | d[3] = v; | 233 | d[3] = v; |
233 | } | 234 | } |
234 | 235 | ||
235 | -static inline void stq(void *ptr, uint64_t v) | 236 | +static inline void stq_raw(void *ptr, uint64_t v) |
236 | { | 237 | { |
237 | stl (ptr, v); | 238 | stl (ptr, v); |
238 | stl (ptr+4, v >> 32); | 239 | stl (ptr+4, v >> 32); |
@@ -240,64 +241,102 @@ static inline void stq(void *ptr, uint64_t v) | @@ -240,64 +241,102 @@ static inline void stq(void *ptr, uint64_t v) | ||
240 | 241 | ||
241 | #else | 242 | #else |
242 | 243 | ||
243 | -static inline int lduw(void *ptr) | 244 | +static inline int lduw_raw(void *ptr) |
244 | { | 245 | { |
245 | return *(uint16_t *)ptr; | 246 | return *(uint16_t *)ptr; |
246 | } | 247 | } |
247 | 248 | ||
248 | -static inline int ldsw(void *ptr) | 249 | +static inline int ldsw_raw(void *ptr) |
249 | { | 250 | { |
250 | return *(int16_t *)ptr; | 251 | return *(int16_t *)ptr; |
251 | } | 252 | } |
252 | 253 | ||
253 | -static inline int ldl(void *ptr) | 254 | +static inline int ldl_raw(void *ptr) |
254 | { | 255 | { |
255 | return *(uint32_t *)ptr; | 256 | return *(uint32_t *)ptr; |
256 | } | 257 | } |
257 | 258 | ||
258 | -static inline uint64_t ldq(void *ptr) | 259 | +static inline uint64_t ldq_raw(void *ptr) |
259 | { | 260 | { |
260 | return *(uint64_t *)ptr; | 261 | return *(uint64_t *)ptr; |
261 | } | 262 | } |
262 | 263 | ||
263 | -static inline void stw(void *ptr, int v) | 264 | +static inline void stw_raw(void *ptr, int v) |
264 | { | 265 | { |
265 | *(uint16_t *)ptr = v; | 266 | *(uint16_t *)ptr = v; |
266 | } | 267 | } |
267 | 268 | ||
268 | -static inline void stl(void *ptr, int v) | 269 | +static inline void stl_raw(void *ptr, int v) |
269 | { | 270 | { |
270 | *(uint32_t *)ptr = v; | 271 | *(uint32_t *)ptr = v; |
271 | } | 272 | } |
272 | 273 | ||
273 | -static inline void stq(void *ptr, uint64_t v) | 274 | +static inline void stq_raw(void *ptr, uint64_t v) |
274 | { | 275 | { |
275 | *(uint64_t *)ptr = v; | 276 | *(uint64_t *)ptr = v; |
276 | } | 277 | } |
277 | 278 | ||
278 | /* float access */ | 279 | /* float access */ |
279 | 280 | ||
280 | -static inline float ldfl(void *ptr) | 281 | +static inline float ldfl_raw(void *ptr) |
281 | { | 282 | { |
282 | return *(float *)ptr; | 283 | return *(float *)ptr; |
283 | } | 284 | } |
284 | 285 | ||
285 | -static inline double ldfq(void *ptr) | 286 | +static inline double ldfq_raw(void *ptr) |
286 | { | 287 | { |
287 | return *(double *)ptr; | 288 | return *(double *)ptr; |
288 | } | 289 | } |
289 | 290 | ||
290 | -static inline void stfl(void *ptr, float v) | 291 | +static inline void stfl_raw(void *ptr, float v) |
291 | { | 292 | { |
292 | *(float *)ptr = v; | 293 | *(float *)ptr = v; |
293 | } | 294 | } |
294 | 295 | ||
295 | -static inline void stfq(void *ptr, double v) | 296 | +static inline void stfq_raw(void *ptr, double v) |
296 | { | 297 | { |
297 | *(double *)ptr = v; | 298 | *(double *)ptr = v; |
298 | } | 299 | } |
299 | #endif | 300 | #endif |
300 | 301 | ||
302 | +/* MMU memory access macros */ | ||
303 | + | ||
304 | +#if defined(CONFIG_USER_ONLY) | ||
305 | + | ||
306 | +/* if user mode, no other memory access functions */ | ||
307 | +#define ldub(p) ldub_raw(p) | ||
308 | +#define ldsb(p) ldsb_raw(p) | ||
309 | +#define lduw(p) lduw_raw(p) | ||
310 | +#define ldsw(p) ldsw_raw(p) | ||
311 | +#define ldl(p) ldl_raw(p) | ||
312 | +#define ldq(p) ldq_raw(p) | ||
313 | +#define ldfl(p) ldfl_raw(p) | ||
314 | +#define ldfq(p) ldfq_raw(p) | ||
315 | +#define stb(p, v) stb_raw(p, v) | ||
316 | +#define stw(p, v) stw_raw(p, v) | ||
317 | +#define stl(p, v) stl_raw(p, v) | ||
318 | +#define stq(p, v) stq_raw(p, v) | ||
319 | +#define stfl(p, v) stfl_raw(p, v) | ||
320 | +#define stfq(p, v) stfq_raw(p, v) | ||
321 | + | ||
322 | +#define ldub_code(p) ldub_raw(p) | ||
323 | +#define ldsb_code(p) ldsb_raw(p) | ||
324 | +#define lduw_code(p) lduw_raw(p) | ||
325 | +#define ldsw_code(p) ldsw_raw(p) | ||
326 | +#define ldl_code(p) ldl_raw(p) | ||
327 | + | ||
328 | +#define ldub_kernel(p) ldub_raw(p) | ||
329 | +#define ldsb_kernel(p) ldsb_raw(p) | ||
330 | +#define lduw_kernel(p) lduw_raw(p) | ||
331 | +#define ldsw_kernel(p) ldsw_raw(p) | ||
332 | +#define ldl_kernel(p) ldl_raw(p) | ||
333 | +#define stb_kernel(p, v) stb_raw(p, v) | ||
334 | +#define stw_kernel(p, v) stw_raw(p, v) | ||
335 | +#define stl_kernel(p, v) stl_raw(p, v) | ||
336 | +#define stq_kernel(p, v) stq_raw(p, v) | ||
337 | + | ||
338 | +#endif /* defined(CONFIG_USER_ONLY) */ | ||
339 | + | ||
301 | /* page related stuff */ | 340 | /* page related stuff */ |
302 | 341 | ||
303 | #define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS) | 342 | #define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS) |
exec.c
@@ -444,16 +444,20 @@ static inline void tb_alloc_page(TranslationBlock *tb, unsigned int page_index) | @@ -444,16 +444,20 @@ static inline void tb_alloc_page(TranslationBlock *tb, unsigned int page_index) | ||
444 | prot = 0; | 444 | prot = 0; |
445 | for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE) | 445 | for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE) |
446 | prot |= page_get_flags(addr); | 446 | prot |= page_get_flags(addr); |
447 | +#if !defined(CONFIG_SOFTMMU) | ||
447 | mprotect((void *)host_start, host_page_size, | 448 | mprotect((void *)host_start, host_page_size, |
448 | (prot & PAGE_BITS) & ~PAGE_WRITE); | 449 | (prot & PAGE_BITS) & ~PAGE_WRITE); |
450 | +#endif | ||
451 | +#if !defined(CONFIG_USER_ONLY) | ||
452 | + /* suppress soft TLB */ | ||
453 | + /* XXX: must flush on all processor with same address space */ | ||
454 | + tlb_flush_page_write(cpu_single_env, host_start); | ||
455 | +#endif | ||
449 | #ifdef DEBUG_TB_INVALIDATE | 456 | #ifdef DEBUG_TB_INVALIDATE |
450 | printf("protecting code page: 0x%08lx\n", | 457 | printf("protecting code page: 0x%08lx\n", |
451 | host_start); | 458 | host_start); |
452 | #endif | 459 | #endif |
453 | p->flags &= ~PAGE_WRITE; | 460 | p->flags &= ~PAGE_WRITE; |
454 | -#ifdef DEBUG_TB_CHECK | ||
455 | - tb_page_check(); | ||
456 | -#endif | ||
457 | } | 461 | } |
458 | } | 462 | } |
459 | 463 | ||
@@ -483,6 +487,9 @@ void tb_link(TranslationBlock *tb) | @@ -483,6 +487,9 @@ void tb_link(TranslationBlock *tb) | ||
483 | if (page_index2 != page_index1) { | 487 | if (page_index2 != page_index1) { |
484 | tb_alloc_page(tb, page_index2); | 488 | tb_alloc_page(tb, page_index2); |
485 | } | 489 | } |
490 | +#ifdef DEBUG_TB_CHECK | ||
491 | + tb_page_check(); | ||
492 | +#endif | ||
486 | tb->jmp_first = (TranslationBlock *)((long)tb | 2); | 493 | tb->jmp_first = (TranslationBlock *)((long)tb | 2); |
487 | tb->jmp_next[0] = NULL; | 494 | tb->jmp_next[0] = NULL; |
488 | tb->jmp_next[1] = NULL; | 495 | tb->jmp_next[1] = NULL; |
@@ -517,20 +524,23 @@ int page_unprotect(unsigned long address) | @@ -517,20 +524,23 @@ int page_unprotect(unsigned long address) | ||
517 | /* if the page was really writable, then we change its | 524 | /* if the page was really writable, then we change its |
518 | protection back to writable */ | 525 | protection back to writable */ |
519 | if (prot & PAGE_WRITE_ORG) { | 526 | if (prot & PAGE_WRITE_ORG) { |
520 | - mprotect((void *)host_start, host_page_size, | ||
521 | - (prot & PAGE_BITS) | PAGE_WRITE); | ||
522 | pindex = (address - host_start) >> TARGET_PAGE_BITS; | 527 | pindex = (address - host_start) >> TARGET_PAGE_BITS; |
523 | - p1[pindex].flags |= PAGE_WRITE; | ||
524 | - /* and since the content will be modified, we must invalidate | ||
525 | - the corresponding translated code. */ | ||
526 | - tb_invalidate_page(address); | 528 | + if (!(p1[pindex].flags & PAGE_WRITE)) { |
529 | +#if !defined(CONFIG_SOFTMMU) | ||
530 | + mprotect((void *)host_start, host_page_size, | ||
531 | + (prot & PAGE_BITS) | PAGE_WRITE); | ||
532 | +#endif | ||
533 | + p1[pindex].flags |= PAGE_WRITE; | ||
534 | + /* and since the content will be modified, we must invalidate | ||
535 | + the corresponding translated code. */ | ||
536 | + tb_invalidate_page(address); | ||
527 | #ifdef DEBUG_TB_CHECK | 537 | #ifdef DEBUG_TB_CHECK |
528 | - tb_invalidate_check(address); | 538 | + tb_invalidate_check(address); |
529 | #endif | 539 | #endif |
530 | - return 1; | ||
531 | - } else { | ||
532 | - return 0; | 540 | + return 1; |
541 | + } | ||
533 | } | 542 | } |
543 | + return 0; | ||
534 | } | 544 | } |
535 | 545 | ||
536 | /* call this function when system calls directly modify a memory area */ | 546 | /* call this function when system calls directly modify a memory area */ |
@@ -734,13 +744,17 @@ void cpu_abort(CPUState *env, const char *fmt, ...) | @@ -734,13 +744,17 @@ void cpu_abort(CPUState *env, const char *fmt, ...) | ||
734 | /* unmap all maped pages and flush all associated code */ | 744 | /* unmap all maped pages and flush all associated code */ |
735 | void page_unmap(void) | 745 | void page_unmap(void) |
736 | { | 746 | { |
737 | - PageDesc *p, *pmap; | ||
738 | - unsigned long addr; | ||
739 | - int i, j, ret, j1; | 747 | + PageDesc *pmap; |
748 | + int i; | ||
740 | 749 | ||
741 | for(i = 0; i < L1_SIZE; i++) { | 750 | for(i = 0; i < L1_SIZE; i++) { |
742 | pmap = l1_map[i]; | 751 | pmap = l1_map[i]; |
743 | if (pmap) { | 752 | if (pmap) { |
753 | +#if !defined(CONFIG_SOFTMMU) | ||
754 | + PageDesc *p; | ||
755 | + unsigned long addr; | ||
756 | + int j, ret, j1; | ||
757 | + | ||
744 | p = pmap; | 758 | p = pmap; |
745 | for(j = 0;j < L2_SIZE;) { | 759 | for(j = 0;j < L2_SIZE;) { |
746 | if (p->flags & PAGE_VALID) { | 760 | if (p->flags & PAGE_VALID) { |
@@ -763,6 +777,7 @@ void page_unmap(void) | @@ -763,6 +777,7 @@ void page_unmap(void) | ||
763 | j++; | 777 | j++; |
764 | } | 778 | } |
765 | } | 779 | } |
780 | +#endif | ||
766 | free(pmap); | 781 | free(pmap); |
767 | l1_map[i] = NULL; | 782 | l1_map[i] = NULL; |
768 | } | 783 | } |
@@ -773,7 +788,7 @@ void page_unmap(void) | @@ -773,7 +788,7 @@ void page_unmap(void) | ||
773 | 788 | ||
774 | void tlb_flush(CPUState *env) | 789 | void tlb_flush(CPUState *env) |
775 | { | 790 | { |
776 | -#if defined(TARGET_I386) | 791 | +#if !defined(CONFIG_USER_ONLY) |
777 | int i; | 792 | int i; |
778 | for(i = 0; i < CPU_TLB_SIZE; i++) { | 793 | for(i = 0; i < CPU_TLB_SIZE; i++) { |
779 | env->tlb_read[0][i].address = -1; | 794 | env->tlb_read[0][i].address = -1; |
@@ -784,16 +799,38 @@ void tlb_flush(CPUState *env) | @@ -784,16 +799,38 @@ void tlb_flush(CPUState *env) | ||
784 | #endif | 799 | #endif |
785 | } | 800 | } |
786 | 801 | ||
802 | +static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, uint32_t addr) | ||
803 | +{ | ||
804 | + if (addr == (tlb_entry->address & | ||
805 | + (TARGET_PAGE_MASK | TLB_INVALID_MASK))) | ||
806 | + tlb_entry->address = -1; | ||
807 | +} | ||
808 | + | ||
787 | void tlb_flush_page(CPUState *env, uint32_t addr) | 809 | void tlb_flush_page(CPUState *env, uint32_t addr) |
788 | { | 810 | { |
789 | -#if defined(TARGET_I386) | 811 | +#if !defined(CONFIG_USER_ONLY) |
812 | + int i; | ||
813 | + | ||
814 | + addr &= TARGET_PAGE_MASK; | ||
815 | + i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | ||
816 | + tlb_flush_entry(&env->tlb_read[0][i], addr); | ||
817 | + tlb_flush_entry(&env->tlb_write[0][i], addr); | ||
818 | + tlb_flush_entry(&env->tlb_read[1][i], addr); | ||
819 | + tlb_flush_entry(&env->tlb_write[1][i], addr); | ||
820 | +#endif | ||
821 | +} | ||
822 | + | ||
823 | +/* make all write to page 'addr' trigger a TLB exception to detect | ||
824 | + self modifying code */ | ||
825 | +void tlb_flush_page_write(CPUState *env, uint32_t addr) | ||
826 | +{ | ||
827 | +#if !defined(CONFIG_USER_ONLY) | ||
790 | int i; | 828 | int i; |
791 | 829 | ||
830 | + addr &= TARGET_PAGE_MASK; | ||
792 | i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 831 | i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
793 | - env->tlb_read[0][i].address = -1; | ||
794 | - env->tlb_write[0][i].address = -1; | ||
795 | - env->tlb_read[1][i].address = -1; | ||
796 | - env->tlb_write[1][i].address = -1; | 832 | + tlb_flush_entry(&env->tlb_write[0][i], addr); |
833 | + tlb_flush_entry(&env->tlb_write[1][i], addr); | ||
797 | #endif | 834 | #endif |
798 | } | 835 | } |
799 | 836 | ||
@@ -900,3 +937,25 @@ int cpu_register_io_memory(int io_index, | @@ -900,3 +937,25 @@ int cpu_register_io_memory(int io_index, | ||
900 | } | 937 | } |
901 | return io_index << IO_MEM_SHIFT; | 938 | return io_index << IO_MEM_SHIFT; |
902 | } | 939 | } |
940 | + | ||
941 | +#if !defined(CONFIG_USER_ONLY) | ||
942 | + | ||
943 | +#define MMUSUFFIX _cmmu | ||
944 | +#define GETPC() NULL | ||
945 | +#define env cpu_single_env | ||
946 | + | ||
947 | +#define SHIFT 0 | ||
948 | +#include "softmmu_template.h" | ||
949 | + | ||
950 | +#define SHIFT 1 | ||
951 | +#include "softmmu_template.h" | ||
952 | + | ||
953 | +#define SHIFT 2 | ||
954 | +#include "softmmu_template.h" | ||
955 | + | ||
956 | +#define SHIFT 3 | ||
957 | +#include "softmmu_template.h" | ||
958 | + | ||
959 | +#undef env | ||
960 | + | ||
961 | +#endif |
hw/vga_template.h
@@ -354,7 +354,7 @@ static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d, | @@ -354,7 +354,7 @@ static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d, | ||
354 | 354 | ||
355 | w = width; | 355 | w = width; |
356 | do { | 356 | do { |
357 | - v = lduw((void *)s); | 357 | + v = lduw_raw((void *)s); |
358 | r = (v >> 7) & 0xf8; | 358 | r = (v >> 7) & 0xf8; |
359 | g = (v >> 2) & 0xf8; | 359 | g = (v >> 2) & 0xf8; |
360 | b = (v << 3) & 0xf8; | 360 | b = (v << 3) & 0xf8; |
@@ -379,7 +379,7 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, | @@ -379,7 +379,7 @@ static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, | ||
379 | 379 | ||
380 | w = width; | 380 | w = width; |
381 | do { | 381 | do { |
382 | - v = lduw((void *)s); | 382 | + v = lduw_raw((void *)s); |
383 | r = (v >> 8) & 0xf8; | 383 | r = (v >> 8) & 0xf8; |
384 | g = (v >> 3) & 0xfc; | 384 | g = (v >> 3) & 0xfc; |
385 | b = (v << 3) & 0xf8; | 385 | b = (v << 3) & 0xf8; |
softmmu_header.h
@@ -19,26 +19,48 @@ | @@ -19,26 +19,48 @@ | ||
19 | */ | 19 | */ |
20 | #if DATA_SIZE == 8 | 20 | #if DATA_SIZE == 8 |
21 | #define SUFFIX q | 21 | #define SUFFIX q |
22 | +#define USUFFIX q | ||
22 | #define DATA_TYPE uint64_t | 23 | #define DATA_TYPE uint64_t |
23 | #elif DATA_SIZE == 4 | 24 | #elif DATA_SIZE == 4 |
24 | #define SUFFIX l | 25 | #define SUFFIX l |
26 | +#define USUFFIX l | ||
25 | #define DATA_TYPE uint32_t | 27 | #define DATA_TYPE uint32_t |
26 | #elif DATA_SIZE == 2 | 28 | #elif DATA_SIZE == 2 |
27 | #define SUFFIX w | 29 | #define SUFFIX w |
30 | +#define USUFFIX uw | ||
28 | #define DATA_TYPE uint16_t | 31 | #define DATA_TYPE uint16_t |
29 | #define DATA_STYPE int16_t | 32 | #define DATA_STYPE int16_t |
30 | #elif DATA_SIZE == 1 | 33 | #elif DATA_SIZE == 1 |
31 | #define SUFFIX b | 34 | #define SUFFIX b |
35 | +#define USUFFIX ub | ||
32 | #define DATA_TYPE uint8_t | 36 | #define DATA_TYPE uint8_t |
33 | #define DATA_STYPE int8_t | 37 | #define DATA_STYPE int8_t |
34 | #else | 38 | #else |
35 | #error unsupported data size | 39 | #error unsupported data size |
36 | #endif | 40 | #endif |
37 | 41 | ||
38 | -#if MEMUSER == 0 | ||
39 | -#define MEMSUFFIX _kernel | 42 | +#if ACCESS_TYPE == 0 |
43 | + | ||
44 | +#define CPU_MEM_INDEX 0 | ||
45 | +#define MMUSUFFIX _mmu | ||
46 | + | ||
47 | +#elif ACCESS_TYPE == 1 | ||
48 | + | ||
49 | +#define CPU_MEM_INDEX 1 | ||
50 | +#define MMUSUFFIX _mmu | ||
51 | + | ||
52 | +#elif ACCESS_TYPE == 2 | ||
53 | + | ||
54 | +#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) | ||
55 | +#define MMUSUFFIX _mmu | ||
56 | + | ||
57 | +#elif ACCESS_TYPE == 3 | ||
58 | + | ||
59 | +#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) | ||
60 | +#define MMUSUFFIX _cmmu | ||
61 | + | ||
40 | #else | 62 | #else |
41 | -#define MEMSUFFIX _user | 63 | +#error invalid ACCESS_TYPE |
42 | #endif | 64 | #endif |
43 | 65 | ||
44 | #if DATA_SIZE == 8 | 66 | #if DATA_SIZE == 8 |
@@ -48,24 +70,26 @@ | @@ -48,24 +70,26 @@ | ||
48 | #endif | 70 | #endif |
49 | 71 | ||
50 | 72 | ||
51 | -#if MEMUSER == 0 | ||
52 | -DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr); | ||
53 | -void REGPARM(2) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE v); | ||
54 | -#endif | 73 | +DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr, |
74 | + int is_user); | ||
75 | +void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr, DATA_TYPE v, int is_user); | ||
55 | 76 | ||
56 | -static inline int glue(glue(ldu, SUFFIX), MEMSUFFIX)(void *ptr) | 77 | +static inline int glue(glue(ld, USUFFIX), MEMSUFFIX)(void *ptr) |
57 | { | 78 | { |
58 | int index; | 79 | int index; |
59 | RES_TYPE res; | 80 | RES_TYPE res; |
60 | unsigned long addr, physaddr; | 81 | unsigned long addr, physaddr; |
82 | + int is_user; | ||
83 | + | ||
61 | addr = (unsigned long)ptr; | 84 | addr = (unsigned long)ptr; |
62 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 85 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
63 | - if (__builtin_expect(env->tlb_read[MEMUSER][index].address != | 86 | + is_user = CPU_MEM_INDEX; |
87 | + if (__builtin_expect(env->tlb_read[is_user][index].address != | ||
64 | (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { | 88 | (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { |
65 | - res = glue(glue(__ld, SUFFIX), _mmu)(addr); | 89 | + res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user); |
66 | } else { | 90 | } else { |
67 | - physaddr = addr + env->tlb_read[MEMUSER][index].addend; | ||
68 | - res = glue(glue(ldu, SUFFIX), _raw)((uint8_t *)physaddr); | 91 | + physaddr = addr + env->tlb_read[is_user][index].addend; |
92 | + res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); | ||
69 | } | 93 | } |
70 | return res; | 94 | return res; |
71 | } | 95 | } |
@@ -75,13 +99,16 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr) | @@ -75,13 +99,16 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr) | ||
75 | { | 99 | { |
76 | int res, index; | 100 | int res, index; |
77 | unsigned long addr, physaddr; | 101 | unsigned long addr, physaddr; |
102 | + int is_user; | ||
103 | + | ||
78 | addr = (unsigned long)ptr; | 104 | addr = (unsigned long)ptr; |
79 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 105 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
80 | - if (__builtin_expect(env->tlb_read[MEMUSER][index].address != | 106 | + is_user = CPU_MEM_INDEX; |
107 | + if (__builtin_expect(env->tlb_read[is_user][index].address != | ||
81 | (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { | 108 | (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { |
82 | - res = (DATA_STYPE)glue(glue(__ld, SUFFIX), _mmu)(addr); | 109 | + res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, is_user); |
83 | } else { | 110 | } else { |
84 | - physaddr = addr + env->tlb_read[MEMUSER][index].addend; | 111 | + physaddr = addr + env->tlb_read[is_user][index].addend; |
85 | res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr); | 112 | res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr); |
86 | } | 113 | } |
87 | return res; | 114 | return res; |
@@ -92,13 +119,16 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v) | @@ -92,13 +119,16 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v) | ||
92 | { | 119 | { |
93 | int index; | 120 | int index; |
94 | unsigned long addr, physaddr; | 121 | unsigned long addr, physaddr; |
122 | + int is_user; | ||
123 | + | ||
95 | addr = (unsigned long)ptr; | 124 | addr = (unsigned long)ptr; |
96 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 125 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
97 | - if (__builtin_expect(env->tlb_write[MEMUSER][index].address != | 126 | + is_user = CPU_MEM_INDEX; |
127 | + if (__builtin_expect(env->tlb_write[is_user][index].address != | ||
98 | (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { | 128 | (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { |
99 | - glue(glue(__st, SUFFIX), _mmu)(addr, v); | 129 | + glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, is_user); |
100 | } else { | 130 | } else { |
101 | - physaddr = addr + env->tlb_write[MEMUSER][index].addend; | 131 | + physaddr = addr + env->tlb_write[is_user][index].addend; |
102 | glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v); | 132 | glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v); |
103 | } | 133 | } |
104 | } | 134 | } |
@@ -107,5 +137,7 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v) | @@ -107,5 +137,7 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v) | ||
107 | #undef DATA_TYPE | 137 | #undef DATA_TYPE |
108 | #undef DATA_STYPE | 138 | #undef DATA_STYPE |
109 | #undef SUFFIX | 139 | #undef SUFFIX |
140 | +#undef USUFFIX | ||
110 | #undef DATA_SIZE | 141 | #undef DATA_SIZE |
111 | -#undef MEMSUFFIX | 142 | +#undef CPU_MEM_INDEX |
143 | +#undef MMUSUFFIX |
softmmu_template.h
@@ -21,23 +21,31 @@ | @@ -21,23 +21,31 @@ | ||
21 | 21 | ||
22 | #if DATA_SIZE == 8 | 22 | #if DATA_SIZE == 8 |
23 | #define SUFFIX q | 23 | #define SUFFIX q |
24 | +#define USUFFIX q | ||
24 | #define DATA_TYPE uint64_t | 25 | #define DATA_TYPE uint64_t |
25 | #elif DATA_SIZE == 4 | 26 | #elif DATA_SIZE == 4 |
26 | #define SUFFIX l | 27 | #define SUFFIX l |
28 | +#define USUFFIX l | ||
27 | #define DATA_TYPE uint32_t | 29 | #define DATA_TYPE uint32_t |
28 | #elif DATA_SIZE == 2 | 30 | #elif DATA_SIZE == 2 |
29 | #define SUFFIX w | 31 | #define SUFFIX w |
32 | +#define USUFFIX uw | ||
30 | #define DATA_TYPE uint16_t | 33 | #define DATA_TYPE uint16_t |
31 | #elif DATA_SIZE == 1 | 34 | #elif DATA_SIZE == 1 |
32 | #define SUFFIX b | 35 | #define SUFFIX b |
36 | +#define USUFFIX ub | ||
33 | #define DATA_TYPE uint8_t | 37 | #define DATA_TYPE uint8_t |
34 | #else | 38 | #else |
35 | #error unsupported data size | 39 | #error unsupported data size |
36 | #endif | 40 | #endif |
37 | 41 | ||
38 | -static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr); | ||
39 | -static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, | ||
40 | - void *retaddr); | 42 | +static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr, |
43 | + int is_user, | ||
44 | + void *retaddr); | ||
45 | +static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr, | ||
46 | + DATA_TYPE val, | ||
47 | + int is_user, | ||
48 | + void *retaddr); | ||
41 | 49 | ||
42 | static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr, | 50 | static inline DATA_TYPE glue(io_read, SUFFIX)(unsigned long physaddr, |
43 | unsigned long tlb_addr) | 51 | unsigned long tlb_addr) |
@@ -81,16 +89,16 @@ static inline void glue(io_write, SUFFIX)(unsigned long physaddr, | @@ -81,16 +89,16 @@ static inline void glue(io_write, SUFFIX)(unsigned long physaddr, | ||
81 | } | 89 | } |
82 | 90 | ||
83 | /* handle all cases except unaligned access which span two pages */ | 91 | /* handle all cases except unaligned access which span two pages */ |
84 | -DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr) | 92 | +DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), MMUSUFFIX)(unsigned long addr, |
93 | + int is_user) | ||
85 | { | 94 | { |
86 | DATA_TYPE res; | 95 | DATA_TYPE res; |
87 | - int is_user, index; | 96 | + int index; |
88 | unsigned long physaddr, tlb_addr; | 97 | unsigned long physaddr, tlb_addr; |
89 | void *retaddr; | 98 | void *retaddr; |
90 | 99 | ||
91 | /* test if there is match for unaligned or IO access */ | 100 | /* test if there is match for unaligned or IO access */ |
92 | /* XXX: could done more in memory macro in a non portable way */ | 101 | /* XXX: could done more in memory macro in a non portable way */ |
93 | - is_user = ((env->hflags & HF_CPL_MASK) == 3); | ||
94 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 102 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
95 | redo: | 103 | redo: |
96 | tlb_addr = env->tlb_read[is_user][index].address; | 104 | tlb_addr = env->tlb_read[is_user][index].address; |
@@ -104,29 +112,31 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr) | @@ -104,29 +112,31 @@ DATA_TYPE REGPARM(1) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr) | ||
104 | } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { | 112 | } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { |
105 | /* slow unaligned access (it spans two pages or IO) */ | 113 | /* slow unaligned access (it spans two pages or IO) */ |
106 | do_unaligned_access: | 114 | do_unaligned_access: |
107 | - retaddr = __builtin_return_address(0); | ||
108 | - res = glue(slow_ld, SUFFIX)(addr, retaddr); | 115 | + retaddr = GETPC(); |
116 | + res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr, | ||
117 | + is_user, retaddr); | ||
109 | } else { | 118 | } else { |
110 | /* unaligned access in the same page */ | 119 | /* unaligned access in the same page */ |
111 | - res = glue(glue(ldu, SUFFIX), _raw)((uint8_t *)physaddr); | 120 | + res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); |
112 | } | 121 | } |
113 | } else { | 122 | } else { |
114 | /* the page is not in the TLB : fill it */ | 123 | /* the page is not in the TLB : fill it */ |
115 | - retaddr = __builtin_return_address(0); | ||
116 | - tlb_fill(addr, 0, retaddr); | 124 | + retaddr = GETPC(); |
125 | + tlb_fill(addr, 0, is_user, retaddr); | ||
117 | goto redo; | 126 | goto redo; |
118 | } | 127 | } |
119 | return res; | 128 | return res; |
120 | } | 129 | } |
121 | 130 | ||
122 | /* handle all unaligned cases */ | 131 | /* handle all unaligned cases */ |
123 | -static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr) | 132 | +static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(unsigned long addr, |
133 | + int is_user, | ||
134 | + void *retaddr) | ||
124 | { | 135 | { |
125 | DATA_TYPE res, res1, res2; | 136 | DATA_TYPE res, res1, res2; |
126 | - int is_user, index, shift; | 137 | + int index, shift; |
127 | unsigned long physaddr, tlb_addr, addr1, addr2; | 138 | unsigned long physaddr, tlb_addr, addr1, addr2; |
128 | 139 | ||
129 | - is_user = ((env->hflags & HF_CPL_MASK) == 3); | ||
130 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 140 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
131 | redo: | 141 | redo: |
132 | tlb_addr = env->tlb_read[is_user][index].address; | 142 | tlb_addr = env->tlb_read[is_user][index].address; |
@@ -142,8 +152,10 @@ static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr) | @@ -142,8 +152,10 @@ static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr) | ||
142 | /* slow unaligned access (it spans two pages) */ | 152 | /* slow unaligned access (it spans two pages) */ |
143 | addr1 = addr & ~(DATA_SIZE - 1); | 153 | addr1 = addr & ~(DATA_SIZE - 1); |
144 | addr2 = addr1 + DATA_SIZE; | 154 | addr2 = addr1 + DATA_SIZE; |
145 | - res1 = glue(slow_ld, SUFFIX)(addr1, retaddr); | ||
146 | - res2 = glue(slow_ld, SUFFIX)(addr2, retaddr); | 155 | + res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1, |
156 | + is_user, retaddr); | ||
157 | + res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2, | ||
158 | + is_user, retaddr); | ||
147 | shift = (addr & (DATA_SIZE - 1)) * 8; | 159 | shift = (addr & (DATA_SIZE - 1)) * 8; |
148 | #ifdef TARGET_WORDS_BIGENDIAN | 160 | #ifdef TARGET_WORDS_BIGENDIAN |
149 | res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); | 161 | res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); |
@@ -152,24 +164,25 @@ static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr) | @@ -152,24 +164,25 @@ static DATA_TYPE glue(slow_ld, SUFFIX)(unsigned long addr, void *retaddr) | ||
152 | #endif | 164 | #endif |
153 | } else { | 165 | } else { |
154 | /* unaligned/aligned access in the same page */ | 166 | /* unaligned/aligned access in the same page */ |
155 | - res = glue(glue(ldu, SUFFIX), _raw)((uint8_t *)physaddr); | 167 | + res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr); |
156 | } | 168 | } |
157 | } else { | 169 | } else { |
158 | /* the page is not in the TLB : fill it */ | 170 | /* the page is not in the TLB : fill it */ |
159 | - tlb_fill(addr, 0, retaddr); | 171 | + tlb_fill(addr, 0, is_user, retaddr); |
160 | goto redo; | 172 | goto redo; |
161 | } | 173 | } |
162 | return res; | 174 | return res; |
163 | } | 175 | } |
164 | 176 | ||
165 | 177 | ||
166 | -void REGPARM(2) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE val) | 178 | +void REGPARM(2) glue(glue(__st, SUFFIX), MMUSUFFIX)(unsigned long addr, |
179 | + DATA_TYPE val, | ||
180 | + int is_user) | ||
167 | { | 181 | { |
168 | unsigned long physaddr, tlb_addr; | 182 | unsigned long physaddr, tlb_addr; |
169 | void *retaddr; | 183 | void *retaddr; |
170 | - int is_user, index; | 184 | + int index; |
171 | 185 | ||
172 | - is_user = ((env->hflags & HF_CPL_MASK) == 3); | ||
173 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 186 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
174 | redo: | 187 | redo: |
175 | tlb_addr = env->tlb_write[is_user][index].address; | 188 | tlb_addr = env->tlb_write[is_user][index].address; |
@@ -182,28 +195,30 @@ void REGPARM(2) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE val | @@ -182,28 +195,30 @@ void REGPARM(2) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE val | ||
182 | glue(io_write, SUFFIX)(physaddr, val, tlb_addr); | 195 | glue(io_write, SUFFIX)(physaddr, val, tlb_addr); |
183 | } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { | 196 | } else if (((addr & 0xfff) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) { |
184 | do_unaligned_access: | 197 | do_unaligned_access: |
185 | - retaddr = __builtin_return_address(0); | ||
186 | - glue(slow_st, SUFFIX)(addr, val, retaddr); | 198 | + retaddr = GETPC(); |
199 | + glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val, | ||
200 | + is_user, retaddr); | ||
187 | } else { | 201 | } else { |
188 | /* aligned/unaligned access in the same page */ | 202 | /* aligned/unaligned access in the same page */ |
189 | glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val); | 203 | glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, val); |
190 | } | 204 | } |
191 | } else { | 205 | } else { |
192 | /* the page is not in the TLB : fill it */ | 206 | /* the page is not in the TLB : fill it */ |
193 | - retaddr = __builtin_return_address(0); | ||
194 | - tlb_fill(addr, 1, retaddr); | 207 | + retaddr = GETPC(); |
208 | + tlb_fill(addr, 1, is_user, retaddr); | ||
195 | goto redo; | 209 | goto redo; |
196 | } | 210 | } |
197 | } | 211 | } |
198 | 212 | ||
199 | /* handles all unaligned cases */ | 213 | /* handles all unaligned cases */ |
200 | -static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, | ||
201 | - void *retaddr) | 214 | +static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(unsigned long addr, |
215 | + DATA_TYPE val, | ||
216 | + int is_user, | ||
217 | + void *retaddr) | ||
202 | { | 218 | { |
203 | unsigned long physaddr, tlb_addr; | 219 | unsigned long physaddr, tlb_addr; |
204 | - int is_user, index, i; | 220 | + int index, i; |
205 | 221 | ||
206 | - is_user = ((env->hflags & HF_CPL_MASK) == 3); | ||
207 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | 222 | index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
208 | redo: | 223 | redo: |
209 | tlb_addr = env->tlb_write[is_user][index].address; | 224 | tlb_addr = env->tlb_write[is_user][index].address; |
@@ -219,9 +234,11 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, | @@ -219,9 +234,11 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, | ||
219 | /* XXX: not efficient, but simple */ | 234 | /* XXX: not efficient, but simple */ |
220 | for(i = 0;i < DATA_SIZE; i++) { | 235 | for(i = 0;i < DATA_SIZE; i++) { |
221 | #ifdef TARGET_WORDS_BIGENDIAN | 236 | #ifdef TARGET_WORDS_BIGENDIAN |
222 | - slow_stb(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)), retaddr); | 237 | + glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)), |
238 | + is_user, retaddr); | ||
223 | #else | 239 | #else |
224 | - slow_stb(addr + i, val >> (i * 8), retaddr); | 240 | + glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8), |
241 | + is_user, retaddr); | ||
225 | #endif | 242 | #endif |
226 | } | 243 | } |
227 | } else { | 244 | } else { |
@@ -230,7 +247,7 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, | @@ -230,7 +247,7 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, | ||
230 | } | 247 | } |
231 | } else { | 248 | } else { |
232 | /* the page is not in the TLB : fill it */ | 249 | /* the page is not in the TLB : fill it */ |
233 | - tlb_fill(addr, 1, retaddr); | 250 | + tlb_fill(addr, 1, is_user, retaddr); |
234 | goto redo; | 251 | goto redo; |
235 | } | 252 | } |
236 | } | 253 | } |
@@ -238,4 +255,5 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, | @@ -238,4 +255,5 @@ static void glue(slow_st, SUFFIX)(unsigned long addr, DATA_TYPE val, | ||
238 | #undef SHIFT | 255 | #undef SHIFT |
239 | #undef DATA_TYPE | 256 | #undef DATA_TYPE |
240 | #undef SUFFIX | 257 | #undef SUFFIX |
258 | +#undef USUFFIX | ||
241 | #undef DATA_SIZE | 259 | #undef DATA_SIZE |
target-i386/exec.h
@@ -137,8 +137,10 @@ void helper_invlpg(unsigned int addr); | @@ -137,8 +137,10 @@ void helper_invlpg(unsigned int addr); | ||
137 | void cpu_x86_update_cr0(CPUX86State *env); | 137 | void cpu_x86_update_cr0(CPUX86State *env); |
138 | void cpu_x86_update_cr3(CPUX86State *env); | 138 | void cpu_x86_update_cr3(CPUX86State *env); |
139 | void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr); | 139 | void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr); |
140 | -int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write); | ||
141 | -void tlb_fill(unsigned long addr, int is_write, void *retaddr); | 140 | +int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, |
141 | + int is_write, int is_user, int is_softmmu); | ||
142 | +void tlb_fill(unsigned long addr, int is_write, int is_user, | ||
143 | + void *retaddr); | ||
142 | void __hidden cpu_lock(void); | 144 | void __hidden cpu_lock(void); |
143 | void __hidden cpu_unlock(void); | 145 | void __hidden cpu_unlock(void); |
144 | void do_interrupt(int intno, int is_int, int error_code, | 146 | void do_interrupt(int intno, int is_int, int error_code, |
@@ -366,26 +368,30 @@ static inline void load_eflags(int eflags, int update_mask) | @@ -366,26 +368,30 @@ static inline void load_eflags(int eflags, int update_mask) | ||
366 | (eflags & update_mask); | 368 | (eflags & update_mask); |
367 | } | 369 | } |
368 | 370 | ||
369 | -/* memory access macros */ | 371 | +/* XXX: move that to a generic header */ |
372 | +#if !defined(CONFIG_USER_ONLY) | ||
370 | 373 | ||
371 | -#define ldul ldl | ||
372 | -#define lduq ldq | ||
373 | #define ldul_user ldl_user | 374 | #define ldul_user ldl_user |
374 | #define ldul_kernel ldl_kernel | 375 | #define ldul_kernel ldl_kernel |
375 | 376 | ||
376 | -#define ldub_raw ldub | ||
377 | -#define ldsb_raw ldsb | ||
378 | -#define lduw_raw lduw | ||
379 | -#define ldsw_raw ldsw | ||
380 | -#define ldl_raw ldl | ||
381 | -#define ldq_raw ldq | 377 | +#define ACCESS_TYPE 0 |
378 | +#define MEMSUFFIX _kernel | ||
379 | +#define DATA_SIZE 1 | ||
380 | +#include "softmmu_header.h" | ||
381 | + | ||
382 | +#define DATA_SIZE 2 | ||
383 | +#include "softmmu_header.h" | ||
382 | 384 | ||
383 | -#define stb_raw stb | ||
384 | -#define stw_raw stw | ||
385 | -#define stl_raw stl | ||
386 | -#define stq_raw stq | 385 | +#define DATA_SIZE 4 |
386 | +#include "softmmu_header.h" | ||
387 | + | ||
388 | +#define DATA_SIZE 8 | ||
389 | +#include "softmmu_header.h" | ||
390 | +#undef ACCESS_TYPE | ||
391 | +#undef MEMSUFFIX | ||
387 | 392 | ||
388 | -#define MEMUSER 0 | 393 | +#define ACCESS_TYPE 1 |
394 | +#define MEMSUFFIX _user | ||
389 | #define DATA_SIZE 1 | 395 | #define DATA_SIZE 1 |
390 | #include "softmmu_header.h" | 396 | #include "softmmu_header.h" |
391 | 397 | ||
@@ -397,9 +403,12 @@ static inline void load_eflags(int eflags, int update_mask) | @@ -397,9 +403,12 @@ static inline void load_eflags(int eflags, int update_mask) | ||
397 | 403 | ||
398 | #define DATA_SIZE 8 | 404 | #define DATA_SIZE 8 |
399 | #include "softmmu_header.h" | 405 | #include "softmmu_header.h" |
406 | +#undef ACCESS_TYPE | ||
407 | +#undef MEMSUFFIX | ||
400 | 408 | ||
401 | -#undef MEMUSER | ||
402 | -#define MEMUSER 1 | 409 | +/* these access are slower, they must be as rare as possible */ |
410 | +#define ACCESS_TYPE 2 | ||
411 | +#define MEMSUFFIX _data | ||
403 | #define DATA_SIZE 1 | 412 | #define DATA_SIZE 1 |
404 | #include "softmmu_header.h" | 413 | #include "softmmu_header.h" |
405 | 414 | ||
@@ -411,6 +420,59 @@ static inline void load_eflags(int eflags, int update_mask) | @@ -411,6 +420,59 @@ static inline void load_eflags(int eflags, int update_mask) | ||
411 | 420 | ||
412 | #define DATA_SIZE 8 | 421 | #define DATA_SIZE 8 |
413 | #include "softmmu_header.h" | 422 | #include "softmmu_header.h" |
423 | +#undef ACCESS_TYPE | ||
424 | +#undef MEMSUFFIX | ||
425 | + | ||
426 | +#define ldub(p) ldub_data(p) | ||
427 | +#define ldsb(p) ldsb_data(p) | ||
428 | +#define lduw(p) lduw_data(p) | ||
429 | +#define ldsw(p) ldsw_data(p) | ||
430 | +#define ldl(p) ldl_data(p) | ||
431 | +#define ldq(p) ldq_data(p) | ||
432 | + | ||
433 | +#define stb(p, v) stb_data(p, v) | ||
434 | +#define stw(p, v) stw_data(p, v) | ||
435 | +#define stl(p, v) stl_data(p, v) | ||
436 | +#define stq(p, v) stq_data(p, v) | ||
437 | + | ||
438 | +static inline double ldfq(void *ptr) | ||
439 | +{ | ||
440 | + union { | ||
441 | + double d; | ||
442 | + uint64_t i; | ||
443 | + } u; | ||
444 | + u.i = ldq(ptr); | ||
445 | + return u.d; | ||
446 | +} | ||
447 | + | ||
448 | +static inline void stfq(void *ptr, double v) | ||
449 | +{ | ||
450 | + union { | ||
451 | + double d; | ||
452 | + uint64_t i; | ||
453 | + } u; | ||
454 | + u.d = v; | ||
455 | + stq(ptr, u.i); | ||
456 | +} | ||
414 | 457 | ||
415 | -#undef MEMUSER | 458 | +static inline float ldfl(void *ptr) |
459 | +{ | ||
460 | + union { | ||
461 | + float f; | ||
462 | + uint32_t i; | ||
463 | + } u; | ||
464 | + u.i = ldl(ptr); | ||
465 | + return u.f; | ||
466 | +} | ||
467 | + | ||
468 | +static inline void stfl(void *ptr, float v) | ||
469 | +{ | ||
470 | + union { | ||
471 | + float f; | ||
472 | + uint32_t i; | ||
473 | + } u; | ||
474 | + u.f = v; | ||
475 | + stl(ptr, u.i); | ||
476 | +} | ||
416 | 477 | ||
478 | +#endif /* !defined(CONFIG_USER_ONLY) */ |
target-i386/helper.c
@@ -153,11 +153,11 @@ static inline void get_ss_esp_from_tss(uint32_t *ss_ptr, | @@ -153,11 +153,11 @@ static inline void get_ss_esp_from_tss(uint32_t *ss_ptr, | ||
153 | if (index + (4 << shift) - 1 > env->tr.limit) | 153 | if (index + (4 << shift) - 1 > env->tr.limit) |
154 | raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc); | 154 | raise_exception_err(EXCP0A_TSS, env->tr.selector & 0xfffc); |
155 | if (shift == 0) { | 155 | if (shift == 0) { |
156 | - *esp_ptr = lduw(env->tr.base + index); | ||
157 | - *ss_ptr = lduw(env->tr.base + index + 2); | 156 | + *esp_ptr = lduw_kernel(env->tr.base + index); |
157 | + *ss_ptr = lduw_kernel(env->tr.base + index + 2); | ||
158 | } else { | 158 | } else { |
159 | - *esp_ptr = ldl(env->tr.base + index); | ||
160 | - *ss_ptr = lduw(env->tr.base + index + 4); | 159 | + *esp_ptr = ldl_kernel(env->tr.base + index); |
160 | + *ss_ptr = lduw_kernel(env->tr.base + index + 4); | ||
161 | } | 161 | } |
162 | } | 162 | } |
163 | 163 | ||
@@ -177,8 +177,8 @@ static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr, | @@ -177,8 +177,8 @@ static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr, | ||
177 | if ((index + 7) > dt->limit) | 177 | if ((index + 7) > dt->limit) |
178 | return -1; | 178 | return -1; |
179 | ptr = dt->base + index; | 179 | ptr = dt->base + index; |
180 | - *e1_ptr = ldl(ptr); | ||
181 | - *e2_ptr = ldl(ptr + 4); | 180 | + *e1_ptr = ldl_kernel(ptr); |
181 | + *e2_ptr = ldl_kernel(ptr + 4); | ||
182 | return 0; | 182 | return 0; |
183 | } | 183 | } |
184 | 184 | ||
@@ -226,8 +226,8 @@ static void do_interrupt_protected(int intno, int is_int, int error_code, | @@ -226,8 +226,8 @@ static void do_interrupt_protected(int intno, int is_int, int error_code, | ||
226 | if (intno * 8 + 7 > dt->limit) | 226 | if (intno * 8 + 7 > dt->limit) |
227 | raise_exception_err(EXCP0D_GPF, intno * 8 + 2); | 227 | raise_exception_err(EXCP0D_GPF, intno * 8 + 2); |
228 | ptr = dt->base + intno * 8; | 228 | ptr = dt->base + intno * 8; |
229 | - e1 = ldl(ptr); | ||
230 | - e2 = ldl(ptr + 4); | 229 | + e1 = ldl_kernel(ptr); |
230 | + e2 = ldl_kernel(ptr + 4); | ||
231 | /* check gate type */ | 231 | /* check gate type */ |
232 | type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; | 232 | type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; |
233 | switch(type) { | 233 | switch(type) { |
@@ -344,47 +344,47 @@ static void do_interrupt_protected(int intno, int is_int, int error_code, | @@ -344,47 +344,47 @@ static void do_interrupt_protected(int intno, int is_int, int error_code, | ||
344 | int old_eflags; | 344 | int old_eflags; |
345 | if (env->eflags & VM_MASK) { | 345 | if (env->eflags & VM_MASK) { |
346 | ssp -= 4; | 346 | ssp -= 4; |
347 | - stl(ssp, env->segs[R_GS].selector); | 347 | + stl_kernel(ssp, env->segs[R_GS].selector); |
348 | ssp -= 4; | 348 | ssp -= 4; |
349 | - stl(ssp, env->segs[R_FS].selector); | 349 | + stl_kernel(ssp, env->segs[R_FS].selector); |
350 | ssp -= 4; | 350 | ssp -= 4; |
351 | - stl(ssp, env->segs[R_DS].selector); | 351 | + stl_kernel(ssp, env->segs[R_DS].selector); |
352 | ssp -= 4; | 352 | ssp -= 4; |
353 | - stl(ssp, env->segs[R_ES].selector); | 353 | + stl_kernel(ssp, env->segs[R_ES].selector); |
354 | } | 354 | } |
355 | if (new_stack) { | 355 | if (new_stack) { |
356 | ssp -= 4; | 356 | ssp -= 4; |
357 | - stl(ssp, old_ss); | 357 | + stl_kernel(ssp, old_ss); |
358 | ssp -= 4; | 358 | ssp -= 4; |
359 | - stl(ssp, old_esp); | 359 | + stl_kernel(ssp, old_esp); |
360 | } | 360 | } |
361 | ssp -= 4; | 361 | ssp -= 4; |
362 | old_eflags = compute_eflags(); | 362 | old_eflags = compute_eflags(); |
363 | - stl(ssp, old_eflags); | 363 | + stl_kernel(ssp, old_eflags); |
364 | ssp -= 4; | 364 | ssp -= 4; |
365 | - stl(ssp, old_cs); | 365 | + stl_kernel(ssp, old_cs); |
366 | ssp -= 4; | 366 | ssp -= 4; |
367 | - stl(ssp, old_eip); | 367 | + stl_kernel(ssp, old_eip); |
368 | if (has_error_code) { | 368 | if (has_error_code) { |
369 | ssp -= 4; | 369 | ssp -= 4; |
370 | - stl(ssp, error_code); | 370 | + stl_kernel(ssp, error_code); |
371 | } | 371 | } |
372 | } else { | 372 | } else { |
373 | if (new_stack) { | 373 | if (new_stack) { |
374 | ssp -= 2; | 374 | ssp -= 2; |
375 | - stw(ssp, old_ss); | 375 | + stw_kernel(ssp, old_ss); |
376 | ssp -= 2; | 376 | ssp -= 2; |
377 | - stw(ssp, old_esp); | 377 | + stw_kernel(ssp, old_esp); |
378 | } | 378 | } |
379 | ssp -= 2; | 379 | ssp -= 2; |
380 | - stw(ssp, compute_eflags()); | 380 | + stw_kernel(ssp, compute_eflags()); |
381 | ssp -= 2; | 381 | ssp -= 2; |
382 | - stw(ssp, old_cs); | 382 | + stw_kernel(ssp, old_cs); |
383 | ssp -= 2; | 383 | ssp -= 2; |
384 | - stw(ssp, old_eip); | 384 | + stw_kernel(ssp, old_eip); |
385 | if (has_error_code) { | 385 | if (has_error_code) { |
386 | ssp -= 2; | 386 | ssp -= 2; |
387 | - stw(ssp, error_code); | 387 | + stw_kernel(ssp, error_code); |
388 | } | 388 | } |
389 | } | 389 | } |
390 | 390 | ||
@@ -410,8 +410,8 @@ static void do_interrupt_real(int intno, int is_int, int error_code, | @@ -410,8 +410,8 @@ static void do_interrupt_real(int intno, int is_int, int error_code, | ||
410 | if (intno * 4 + 3 > dt->limit) | 410 | if (intno * 4 + 3 > dt->limit) |
411 | raise_exception_err(EXCP0D_GPF, intno * 8 + 2); | 411 | raise_exception_err(EXCP0D_GPF, intno * 8 + 2); |
412 | ptr = dt->base + intno * 4; | 412 | ptr = dt->base + intno * 4; |
413 | - offset = lduw(ptr); | ||
414 | - selector = lduw(ptr + 2); | 413 | + offset = lduw_kernel(ptr); |
414 | + selector = lduw_kernel(ptr + 2); | ||
415 | esp = ESP; | 415 | esp = ESP; |
416 | ssp = env->segs[R_SS].base; | 416 | ssp = env->segs[R_SS].base; |
417 | if (is_int) | 417 | if (is_int) |
@@ -420,11 +420,11 @@ static void do_interrupt_real(int intno, int is_int, int error_code, | @@ -420,11 +420,11 @@ static void do_interrupt_real(int intno, int is_int, int error_code, | ||
420 | old_eip = env->eip; | 420 | old_eip = env->eip; |
421 | old_cs = env->segs[R_CS].selector; | 421 | old_cs = env->segs[R_CS].selector; |
422 | esp -= 2; | 422 | esp -= 2; |
423 | - stw(ssp + (esp & 0xffff), compute_eflags()); | 423 | + stw_kernel(ssp + (esp & 0xffff), compute_eflags()); |
424 | esp -= 2; | 424 | esp -= 2; |
425 | - stw(ssp + (esp & 0xffff), old_cs); | 425 | + stw_kernel(ssp + (esp & 0xffff), old_cs); |
426 | esp -= 2; | 426 | esp -= 2; |
427 | - stw(ssp + (esp & 0xffff), old_eip); | 427 | + stw_kernel(ssp + (esp & 0xffff), old_eip); |
428 | 428 | ||
429 | /* update processor state */ | 429 | /* update processor state */ |
430 | ESP = (ESP & ~0xffff) | (esp & 0xffff); | 430 | ESP = (ESP & ~0xffff) | (esp & 0xffff); |
@@ -445,7 +445,7 @@ void do_interrupt_user(int intno, int is_int, int error_code, | @@ -445,7 +445,7 @@ void do_interrupt_user(int intno, int is_int, int error_code, | ||
445 | 445 | ||
446 | dt = &env->idt; | 446 | dt = &env->idt; |
447 | ptr = dt->base + (intno * 8); | 447 | ptr = dt->base + (intno * 8); |
448 | - e2 = ldl(ptr + 4); | 448 | + e2 = ldl_kernel(ptr + 4); |
449 | 449 | ||
450 | dpl = (e2 >> DESC_DPL_SHIFT) & 3; | 450 | dpl = (e2 >> DESC_DPL_SHIFT) & 3; |
451 | cpl = env->hflags & HF_CPL_MASK; | 451 | cpl = env->hflags & HF_CPL_MASK; |
@@ -651,8 +651,8 @@ void helper_lldt_T0(void) | @@ -651,8 +651,8 @@ void helper_lldt_T0(void) | ||
651 | if ((index + 7) > dt->limit) | 651 | if ((index + 7) > dt->limit) |
652 | raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | 652 | raise_exception_err(EXCP0D_GPF, selector & 0xfffc); |
653 | ptr = dt->base + index; | 653 | ptr = dt->base + index; |
654 | - e1 = ldl(ptr); | ||
655 | - e2 = ldl(ptr + 4); | 654 | + e1 = ldl_kernel(ptr); |
655 | + e2 = ldl_kernel(ptr + 4); | ||
656 | if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) | 656 | if ((e2 & DESC_S_MASK) || ((e2 >> DESC_TYPE_SHIFT) & 0xf) != 2) |
657 | raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | 657 | raise_exception_err(EXCP0D_GPF, selector & 0xfffc); |
658 | if (!(e2 & DESC_P_MASK)) | 658 | if (!(e2 & DESC_P_MASK)) |
@@ -684,8 +684,8 @@ void helper_ltr_T0(void) | @@ -684,8 +684,8 @@ void helper_ltr_T0(void) | ||
684 | if ((index + 7) > dt->limit) | 684 | if ((index + 7) > dt->limit) |
685 | raise_exception_err(EXCP0D_GPF, selector & 0xfffc); | 685 | raise_exception_err(EXCP0D_GPF, selector & 0xfffc); |
686 | ptr = dt->base + index; | 686 | ptr = dt->base + index; |
687 | - e1 = ldl(ptr); | ||
688 | - e2 = ldl(ptr + 4); | 687 | + e1 = ldl_kernel(ptr); |
688 | + e2 = ldl_kernel(ptr + 4); | ||
689 | type = (e2 >> DESC_TYPE_SHIFT) & 0xf; | 689 | type = (e2 >> DESC_TYPE_SHIFT) & 0xf; |
690 | if ((e2 & DESC_S_MASK) || | 690 | if ((e2 & DESC_S_MASK) || |
691 | (type != 2 && type != 9)) | 691 | (type != 2 && type != 9)) |
@@ -694,7 +694,7 @@ void helper_ltr_T0(void) | @@ -694,7 +694,7 @@ void helper_ltr_T0(void) | ||
694 | raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); | 694 | raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); |
695 | load_seg_cache_raw_dt(&env->tr, e1, e2); | 695 | load_seg_cache_raw_dt(&env->tr, e1, e2); |
696 | e2 |= 0x00000200; /* set the busy bit */ | 696 | e2 |= 0x00000200; /* set the busy bit */ |
697 | - stl(ptr + 4, e2); | 697 | + stl_kernel(ptr + 4, e2); |
698 | } | 698 | } |
699 | env->tr.selector = selector; | 699 | env->tr.selector = selector; |
700 | } | 700 | } |
@@ -813,14 +813,14 @@ void helper_lcall_real_T0_T1(int shift, int next_eip) | @@ -813,14 +813,14 @@ void helper_lcall_real_T0_T1(int shift, int next_eip) | ||
813 | ssp = env->segs[R_SS].base; | 813 | ssp = env->segs[R_SS].base; |
814 | if (shift) { | 814 | if (shift) { |
815 | esp -= 4; | 815 | esp -= 4; |
816 | - stl(ssp + (esp & esp_mask), env->segs[R_CS].selector); | 816 | + stl_kernel(ssp + (esp & esp_mask), env->segs[R_CS].selector); |
817 | esp -= 4; | 817 | esp -= 4; |
818 | - stl(ssp + (esp & esp_mask), next_eip); | 818 | + stl_kernel(ssp + (esp & esp_mask), next_eip); |
819 | } else { | 819 | } else { |
820 | esp -= 2; | 820 | esp -= 2; |
821 | - stw(ssp + (esp & esp_mask), env->segs[R_CS].selector); | 821 | + stw_kernel(ssp + (esp & esp_mask), env->segs[R_CS].selector); |
822 | esp -= 2; | 822 | esp -= 2; |
823 | - stw(ssp + (esp & esp_mask), next_eip); | 823 | + stw_kernel(ssp + (esp & esp_mask), next_eip); |
824 | } | 824 | } |
825 | 825 | ||
826 | if (!(env->segs[R_SS].flags & DESC_B_MASK)) | 826 | if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
@@ -873,14 +873,14 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) | @@ -873,14 +873,14 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) | ||
873 | ssp = env->segs[R_SS].base + sp; | 873 | ssp = env->segs[R_SS].base + sp; |
874 | if (shift) { | 874 | if (shift) { |
875 | ssp -= 4; | 875 | ssp -= 4; |
876 | - stl(ssp, env->segs[R_CS].selector); | 876 | + stl_kernel(ssp, env->segs[R_CS].selector); |
877 | ssp -= 4; | 877 | ssp -= 4; |
878 | - stl(ssp, next_eip); | 878 | + stl_kernel(ssp, next_eip); |
879 | } else { | 879 | } else { |
880 | ssp -= 2; | 880 | ssp -= 2; |
881 | - stw(ssp, env->segs[R_CS].selector); | 881 | + stw_kernel(ssp, env->segs[R_CS].selector); |
882 | ssp -= 2; | 882 | ssp -= 2; |
883 | - stw(ssp, next_eip); | 883 | + stw_kernel(ssp, next_eip); |
884 | } | 884 | } |
885 | sp -= (4 << shift); | 885 | sp -= (4 << shift); |
886 | 886 | ||
@@ -975,23 +975,23 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) | @@ -975,23 +975,23 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) | ||
975 | ssp = env->segs[R_SS].base + sp; | 975 | ssp = env->segs[R_SS].base + sp; |
976 | if (shift) { | 976 | if (shift) { |
977 | ssp -= 4; | 977 | ssp -= 4; |
978 | - stl(ssp, old_ss); | 978 | + stl_kernel(ssp, old_ss); |
979 | ssp -= 4; | 979 | ssp -= 4; |
980 | - stl(ssp, old_esp); | 980 | + stl_kernel(ssp, old_esp); |
981 | ssp -= 4 * param_count; | 981 | ssp -= 4 * param_count; |
982 | for(i = 0; i < param_count; i++) { | 982 | for(i = 0; i < param_count; i++) { |
983 | - val = ldl(old_ssp + i * 4); | ||
984 | - stl(ssp + i * 4, val); | 983 | + val = ldl_kernel(old_ssp + i * 4); |
984 | + stl_kernel(ssp + i * 4, val); | ||
985 | } | 985 | } |
986 | } else { | 986 | } else { |
987 | ssp -= 2; | 987 | ssp -= 2; |
988 | - stw(ssp, old_ss); | 988 | + stw_kernel(ssp, old_ss); |
989 | ssp -= 2; | 989 | ssp -= 2; |
990 | - stw(ssp, old_esp); | 990 | + stw_kernel(ssp, old_esp); |
991 | ssp -= 2 * param_count; | 991 | ssp -= 2 * param_count; |
992 | for(i = 0; i < param_count; i++) { | 992 | for(i = 0; i < param_count; i++) { |
993 | - val = lduw(old_ssp + i * 2); | ||
994 | - stw(ssp + i * 2, val); | 993 | + val = lduw_kernel(old_ssp + i * 2); |
994 | + stw_kernel(ssp + i * 2, val); | ||
995 | } | 995 | } |
996 | } | 996 | } |
997 | } else { | 997 | } else { |
@@ -1004,14 +1004,14 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) | @@ -1004,14 +1004,14 @@ void helper_lcall_protected_T0_T1(int shift, int next_eip) | ||
1004 | 1004 | ||
1005 | if (shift) { | 1005 | if (shift) { |
1006 | ssp -= 4; | 1006 | ssp -= 4; |
1007 | - stl(ssp, env->segs[R_CS].selector); | 1007 | + stl_kernel(ssp, env->segs[R_CS].selector); |
1008 | ssp -= 4; | 1008 | ssp -= 4; |
1009 | - stl(ssp, next_eip); | 1009 | + stl_kernel(ssp, next_eip); |
1010 | } else { | 1010 | } else { |
1011 | ssp -= 2; | 1011 | ssp -= 2; |
1012 | - stw(ssp, env->segs[R_CS].selector); | 1012 | + stw_kernel(ssp, env->segs[R_CS].selector); |
1013 | ssp -= 2; | 1013 | ssp -= 2; |
1014 | - stw(ssp, next_eip); | 1014 | + stw_kernel(ssp, next_eip); |
1015 | } | 1015 | } |
1016 | 1016 | ||
1017 | sp -= push_size; | 1017 | sp -= push_size; |
@@ -1042,14 +1042,14 @@ void helper_iret_real(int shift) | @@ -1042,14 +1042,14 @@ void helper_iret_real(int shift) | ||
1042 | ssp = env->segs[R_SS].base + sp; | 1042 | ssp = env->segs[R_SS].base + sp; |
1043 | if (shift == 1) { | 1043 | if (shift == 1) { |
1044 | /* 32 bits */ | 1044 | /* 32 bits */ |
1045 | - new_eflags = ldl(ssp + 8); | ||
1046 | - new_cs = ldl(ssp + 4) & 0xffff; | ||
1047 | - new_eip = ldl(ssp) & 0xffff; | 1045 | + new_eflags = ldl_kernel(ssp + 8); |
1046 | + new_cs = ldl_kernel(ssp + 4) & 0xffff; | ||
1047 | + new_eip = ldl_kernel(ssp) & 0xffff; | ||
1048 | } else { | 1048 | } else { |
1049 | /* 16 bits */ | 1049 | /* 16 bits */ |
1050 | - new_eflags = lduw(ssp + 4); | ||
1051 | - new_cs = lduw(ssp + 2); | ||
1052 | - new_eip = lduw(ssp); | 1050 | + new_eflags = lduw_kernel(ssp + 4); |
1051 | + new_cs = lduw_kernel(ssp + 2); | ||
1052 | + new_eip = lduw_kernel(ssp); | ||
1053 | } | 1053 | } |
1054 | new_esp = sp + (6 << shift); | 1054 | new_esp = sp + (6 << shift); |
1055 | ESP = (ESP & 0xffff0000) | | 1055 | ESP = (ESP & 0xffff0000) | |
@@ -1078,17 +1078,17 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) | @@ -1078,17 +1078,17 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) | ||
1078 | if (shift == 1) { | 1078 | if (shift == 1) { |
1079 | /* 32 bits */ | 1079 | /* 32 bits */ |
1080 | if (is_iret) | 1080 | if (is_iret) |
1081 | - new_eflags = ldl(ssp + 8); | ||
1082 | - new_cs = ldl(ssp + 4) & 0xffff; | ||
1083 | - new_eip = ldl(ssp); | 1081 | + new_eflags = ldl_kernel(ssp + 8); |
1082 | + new_cs = ldl_kernel(ssp + 4) & 0xffff; | ||
1083 | + new_eip = ldl_kernel(ssp); | ||
1084 | if (is_iret && (new_eflags & VM_MASK)) | 1084 | if (is_iret && (new_eflags & VM_MASK)) |
1085 | goto return_to_vm86; | 1085 | goto return_to_vm86; |
1086 | } else { | 1086 | } else { |
1087 | /* 16 bits */ | 1087 | /* 16 bits */ |
1088 | if (is_iret) | 1088 | if (is_iret) |
1089 | - new_eflags = lduw(ssp + 4); | ||
1090 | - new_cs = lduw(ssp + 2); | ||
1091 | - new_eip = lduw(ssp); | 1089 | + new_eflags = lduw_kernel(ssp + 4); |
1090 | + new_cs = lduw_kernel(ssp + 2); | ||
1091 | + new_eip = lduw_kernel(ssp); | ||
1092 | } | 1092 | } |
1093 | if ((new_cs & 0xfffc) == 0) | 1093 | if ((new_cs & 0xfffc) == 0) |
1094 | raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); | 1094 | raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); |
@@ -1124,12 +1124,12 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) | @@ -1124,12 +1124,12 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) | ||
1124 | ssp += (4 << shift) + ((2 * is_iret) << shift) + addend; | 1124 | ssp += (4 << shift) + ((2 * is_iret) << shift) + addend; |
1125 | if (shift == 1) { | 1125 | if (shift == 1) { |
1126 | /* 32 bits */ | 1126 | /* 32 bits */ |
1127 | - new_esp = ldl(ssp); | ||
1128 | - new_ss = ldl(ssp + 4) & 0xffff; | 1127 | + new_esp = ldl_kernel(ssp); |
1128 | + new_ss = ldl_kernel(ssp + 4) & 0xffff; | ||
1129 | } else { | 1129 | } else { |
1130 | /* 16 bits */ | 1130 | /* 16 bits */ |
1131 | - new_esp = lduw(ssp); | ||
1132 | - new_ss = lduw(ssp + 2); | 1131 | + new_esp = lduw_kernel(ssp); |
1132 | + new_ss = lduw_kernel(ssp + 2); | ||
1133 | } | 1133 | } |
1134 | 1134 | ||
1135 | if ((new_ss & 3) != rpl) | 1135 | if ((new_ss & 3) != rpl) |
@@ -1175,12 +1175,12 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) | @@ -1175,12 +1175,12 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) | ||
1175 | return; | 1175 | return; |
1176 | 1176 | ||
1177 | return_to_vm86: | 1177 | return_to_vm86: |
1178 | - new_esp = ldl(ssp + 12); | ||
1179 | - new_ss = ldl(ssp + 16); | ||
1180 | - new_es = ldl(ssp + 20); | ||
1181 | - new_ds = ldl(ssp + 24); | ||
1182 | - new_fs = ldl(ssp + 28); | ||
1183 | - new_gs = ldl(ssp + 32); | 1178 | + new_esp = ldl_kernel(ssp + 12); |
1179 | + new_ss = ldl_kernel(ssp + 16); | ||
1180 | + new_es = ldl_kernel(ssp + 20); | ||
1181 | + new_ds = ldl_kernel(ssp + 24); | ||
1182 | + new_fs = ldl_kernel(ssp + 28); | ||
1183 | + new_gs = ldl_kernel(ssp + 32); | ||
1184 | 1184 | ||
1185 | /* modify processor state */ | 1185 | /* modify processor state */ |
1186 | load_eflags(new_eflags, FL_UPDATE_CPL0_MASK | VM_MASK | VIF_MASK | VIP_MASK); | 1186 | load_eflags(new_eflags, FL_UPDATE_CPL0_MASK | VM_MASK | VIF_MASK | VIP_MASK); |
@@ -1770,6 +1770,11 @@ void helper_frstor(uint8_t *ptr, int data32) | @@ -1770,6 +1770,11 @@ void helper_frstor(uint8_t *ptr, int data32) | ||
1770 | } | 1770 | } |
1771 | } | 1771 | } |
1772 | 1772 | ||
1773 | +#if !defined(CONFIG_USER_ONLY) | ||
1774 | + | ||
1775 | +#define MMUSUFFIX _mmu | ||
1776 | +#define GETPC() (__builtin_return_address(0)) | ||
1777 | + | ||
1773 | #define SHIFT 0 | 1778 | #define SHIFT 0 |
1774 | #include "softmmu_template.h" | 1779 | #include "softmmu_template.h" |
1775 | 1780 | ||
@@ -1782,22 +1787,41 @@ void helper_frstor(uint8_t *ptr, int data32) | @@ -1782,22 +1787,41 @@ void helper_frstor(uint8_t *ptr, int data32) | ||
1782 | #define SHIFT 3 | 1787 | #define SHIFT 3 |
1783 | #include "softmmu_template.h" | 1788 | #include "softmmu_template.h" |
1784 | 1789 | ||
1785 | -/* try to fill the TLB and return an exception if error */ | ||
1786 | -void tlb_fill(unsigned long addr, int is_write, void *retaddr) | 1790 | +#endif |
1791 | + | ||
1792 | +/* try to fill the TLB and return an exception if error. If retaddr is | ||
1793 | + NULL, it means that the function was called in C code (i.e. not | ||
1794 | + from generated code or from helper.c) */ | ||
1795 | +/* XXX: fix it to restore all registers */ | ||
1796 | +void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr) | ||
1787 | { | 1797 | { |
1788 | TranslationBlock *tb; | 1798 | TranslationBlock *tb; |
1789 | int ret; | 1799 | int ret; |
1790 | unsigned long pc; | 1800 | unsigned long pc; |
1791 | - ret = cpu_x86_handle_mmu_fault(env, addr, is_write); | 1801 | + CPUX86State *saved_env; |
1802 | + | ||
1803 | + /* XXX: hack to restore env in all cases, even if not called from | ||
1804 | + generated code */ | ||
1805 | + saved_env = env; | ||
1806 | + env = cpu_single_env; | ||
1807 | + if (is_write && page_unprotect(addr)) { | ||
1808 | + /* nothing more to do: the page was write protected because | ||
1809 | + there was code in it. page_unprotect() flushed the code. */ | ||
1810 | + } | ||
1811 | + | ||
1812 | + ret = cpu_x86_handle_mmu_fault(env, addr, is_write, is_user, 1); | ||
1792 | if (ret) { | 1813 | if (ret) { |
1793 | - /* now we have a real cpu fault */ | ||
1794 | - pc = (unsigned long)retaddr; | ||
1795 | - tb = tb_find_pc(pc); | ||
1796 | - if (tb) { | ||
1797 | - /* the PC is inside the translated code. It means that we have | ||
1798 | - a virtual CPU fault */ | ||
1799 | - cpu_restore_state(tb, env, pc); | 1814 | + if (retaddr) { |
1815 | + /* now we have a real cpu fault */ | ||
1816 | + pc = (unsigned long)retaddr; | ||
1817 | + tb = tb_find_pc(pc); | ||
1818 | + if (tb) { | ||
1819 | + /* the PC is inside the translated code. It means that we have | ||
1820 | + a virtual CPU fault */ | ||
1821 | + cpu_restore_state(tb, env, pc); | ||
1822 | + } | ||
1800 | } | 1823 | } |
1801 | raise_exception_err(EXCP0E_PAGE, env->error_code); | 1824 | raise_exception_err(EXCP0E_PAGE, env->error_code); |
1802 | } | 1825 | } |
1826 | + env = saved_env; | ||
1803 | } | 1827 | } |
target-i386/helper2.c
@@ -210,7 +210,9 @@ void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr) | @@ -210,7 +210,9 @@ void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr) | ||
210 | flags = page_get_flags(addr); | 210 | flags = page_get_flags(addr); |
211 | if (flags & PAGE_VALID) { | 211 | if (flags & PAGE_VALID) { |
212 | virt_addr = addr & ~0xfff; | 212 | virt_addr = addr & ~0xfff; |
213 | +#if !defined(CONFIG_SOFTMMU) | ||
213 | munmap((void *)virt_addr, 4096); | 214 | munmap((void *)virt_addr, 4096); |
215 | +#endif | ||
214 | page_set_flags(virt_addr, virt_addr + 4096, 0); | 216 | page_set_flags(virt_addr, virt_addr + 4096, 0); |
215 | } | 217 | } |
216 | } | 218 | } |
@@ -221,16 +223,14 @@ void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr) | @@ -221,16 +223,14 @@ void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr) | ||
221 | 1 = generate PF fault | 223 | 1 = generate PF fault |
222 | 2 = soft MMU activation required for this block | 224 | 2 = soft MMU activation required for this block |
223 | */ | 225 | */ |
224 | -int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | 226 | +int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, |
227 | + int is_write, int is_user, int is_softmmu) | ||
225 | { | 228 | { |
226 | uint8_t *pde_ptr, *pte_ptr; | 229 | uint8_t *pde_ptr, *pte_ptr; |
227 | uint32_t pde, pte, virt_addr; | 230 | uint32_t pde, pte, virt_addr; |
228 | - int cpl, error_code, is_dirty, is_user, prot, page_size, ret; | 231 | + int error_code, is_dirty, prot, page_size, ret; |
229 | unsigned long pd; | 232 | unsigned long pd; |
230 | 233 | ||
231 | - cpl = env->hflags & HF_CPL_MASK; | ||
232 | - is_user = (cpl == 3); | ||
233 | - | ||
234 | #ifdef DEBUG_MMU | 234 | #ifdef DEBUG_MMU |
235 | printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n", | 235 | printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n", |
236 | addr, is_write, is_user, env->eip); | 236 | addr, is_write, is_user, env->eip); |
@@ -252,7 +252,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | @@ -252,7 +252,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | ||
252 | 252 | ||
253 | /* page directory entry */ | 253 | /* page directory entry */ |
254 | pde_ptr = phys_ram_base + ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)); | 254 | pde_ptr = phys_ram_base + ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)); |
255 | - pde = ldl(pde_ptr); | 255 | + pde = ldl_raw(pde_ptr); |
256 | if (!(pde & PG_PRESENT_MASK)) { | 256 | if (!(pde & PG_PRESENT_MASK)) { |
257 | error_code = 0; | 257 | error_code = 0; |
258 | goto do_fault; | 258 | goto do_fault; |
@@ -274,7 +274,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | @@ -274,7 +274,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | ||
274 | pde |= PG_ACCESSED_MASK; | 274 | pde |= PG_ACCESSED_MASK; |
275 | if (is_dirty) | 275 | if (is_dirty) |
276 | pde |= PG_DIRTY_MASK; | 276 | pde |= PG_DIRTY_MASK; |
277 | - stl(pde_ptr, pde); | 277 | + stl_raw(pde_ptr, pde); |
278 | } | 278 | } |
279 | 279 | ||
280 | pte = pde & ~0x003ff000; /* align to 4MB */ | 280 | pte = pde & ~0x003ff000; /* align to 4MB */ |
@@ -283,12 +283,12 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | @@ -283,12 +283,12 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | ||
283 | } else { | 283 | } else { |
284 | if (!(pde & PG_ACCESSED_MASK)) { | 284 | if (!(pde & PG_ACCESSED_MASK)) { |
285 | pde |= PG_ACCESSED_MASK; | 285 | pde |= PG_ACCESSED_MASK; |
286 | - stl(pde_ptr, pde); | 286 | + stl_raw(pde_ptr, pde); |
287 | } | 287 | } |
288 | 288 | ||
289 | /* page directory entry */ | 289 | /* page directory entry */ |
290 | pte_ptr = phys_ram_base + ((pde & ~0xfff) + ((addr >> 10) & 0xffc)); | 290 | pte_ptr = phys_ram_base + ((pde & ~0xfff) + ((addr >> 10) & 0xffc)); |
291 | - pte = ldl(pte_ptr); | 291 | + pte = ldl_raw(pte_ptr); |
292 | if (!(pte & PG_PRESENT_MASK)) { | 292 | if (!(pte & PG_PRESENT_MASK)) { |
293 | error_code = 0; | 293 | error_code = 0; |
294 | goto do_fault; | 294 | goto do_fault; |
@@ -308,7 +308,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | @@ -308,7 +308,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | ||
308 | pte |= PG_ACCESSED_MASK; | 308 | pte |= PG_ACCESSED_MASK; |
309 | if (is_dirty) | 309 | if (is_dirty) |
310 | pte |= PG_DIRTY_MASK; | 310 | pte |= PG_DIRTY_MASK; |
311 | - stl(pte_ptr, pte); | 311 | + stl_raw(pte_ptr, pte); |
312 | } | 312 | } |
313 | page_size = 4096; | 313 | page_size = 4096; |
314 | virt_addr = addr & ~0xfff; | 314 | virt_addr = addr & ~0xfff; |
@@ -325,7 +325,10 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | @@ -325,7 +325,10 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | ||
325 | } | 325 | } |
326 | 326 | ||
327 | do_mapping: | 327 | do_mapping: |
328 | - if (env->hflags & HF_SOFTMMU_MASK) { | 328 | +#if !defined(CONFIG_SOFTMMU) |
329 | + if (is_softmmu) | ||
330 | +#endif | ||
331 | + { | ||
329 | unsigned long paddr, vaddr, address, addend, page_offset; | 332 | unsigned long paddr, vaddr, address, addend, page_offset; |
330 | int index; | 333 | int index; |
331 | 334 | ||
@@ -352,32 +355,39 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | @@ -352,32 +355,39 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write) | ||
352 | env->tlb_write[is_user][index].address = address; | 355 | env->tlb_write[is_user][index].address = address; |
353 | env->tlb_write[is_user][index].addend = addend; | 356 | env->tlb_write[is_user][index].addend = addend; |
354 | } | 357 | } |
358 | + page_set_flags(vaddr, vaddr + TARGET_PAGE_SIZE, | ||
359 | + PAGE_VALID | PAGE_EXEC | prot); | ||
360 | + ret = 0; | ||
355 | } | 361 | } |
356 | - ret = 0; | ||
357 | - /* XXX: incorrect for 4MB pages */ | ||
358 | - pd = physpage_find(pte & ~0xfff); | ||
359 | - if ((pd & 0xfff) != 0) { | ||
360 | - /* IO access: no mapping is done as it will be handled by the | ||
361 | - soft MMU */ | ||
362 | - if (!(env->hflags & HF_SOFTMMU_MASK)) | ||
363 | - ret = 2; | ||
364 | - } else { | ||
365 | - void *map_addr; | ||
366 | - map_addr = mmap((void *)virt_addr, page_size, prot, | ||
367 | - MAP_SHARED | MAP_FIXED, phys_ram_fd, pd); | ||
368 | - if (map_addr == MAP_FAILED) { | ||
369 | - fprintf(stderr, | ||
370 | - "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n", | ||
371 | - pte & ~0xfff, virt_addr); | ||
372 | - exit(1); | ||
373 | - } | 362 | +#if !defined(CONFIG_SOFTMMU) |
363 | + else { | ||
364 | + ret = 0; | ||
365 | + /* XXX: incorrect for 4MB pages */ | ||
366 | + pd = physpage_find(pte & ~0xfff); | ||
367 | + if ((pd & 0xfff) != 0) { | ||
368 | + /* IO access: no mapping is done as it will be handled by the | ||
369 | + soft MMU */ | ||
370 | + if (!(env->hflags & HF_SOFTMMU_MASK)) | ||
371 | + ret = 2; | ||
372 | + } else { | ||
373 | + void *map_addr; | ||
374 | + map_addr = mmap((void *)virt_addr, page_size, prot, | ||
375 | + MAP_SHARED | MAP_FIXED, phys_ram_fd, pd); | ||
376 | + if (map_addr == MAP_FAILED) { | ||
377 | + fprintf(stderr, | ||
378 | + "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n", | ||
379 | + pte & ~0xfff, virt_addr); | ||
380 | + exit(1); | ||
381 | + } | ||
374 | #ifdef DEBUG_MMU | 382 | #ifdef DEBUG_MMU |
375 | - printf("mmaping 0x%08x to virt 0x%08x pse=%d\n", | ||
376 | - pte & ~0xfff, virt_addr, (page_size != 4096)); | 383 | + printf("mmaping 0x%08x to virt 0x%08x pse=%d\n", |
384 | + pte & ~0xfff, virt_addr, (page_size != 4096)); | ||
377 | #endif | 385 | #endif |
378 | - page_set_flags(virt_addr, virt_addr + page_size, | ||
379 | - PAGE_VALID | PAGE_EXEC | prot); | 386 | + page_set_flags(virt_addr, virt_addr + page_size, |
387 | + PAGE_VALID | PAGE_EXEC | prot); | ||
388 | + } | ||
380 | } | 389 | } |
390 | +#endif | ||
381 | return ret; | 391 | return ret; |
382 | do_fault_protect: | 392 | do_fault_protect: |
383 | error_code = PG_ERROR_P_MASK; | 393 | error_code = PG_ERROR_P_MASK; |
target-i386/op.c
@@ -376,14 +376,16 @@ void OPPROTO op_andl_A0_ffff(void) | @@ -376,14 +376,16 @@ void OPPROTO op_andl_A0_ffff(void) | ||
376 | 376 | ||
377 | /* memory access */ | 377 | /* memory access */ |
378 | 378 | ||
379 | -#define MEMSUFFIX | 379 | +#define MEMSUFFIX _raw |
380 | #include "ops_mem.h" | 380 | #include "ops_mem.h" |
381 | 381 | ||
382 | +#if !defined(CONFIG_USER_ONLY) | ||
382 | #define MEMSUFFIX _user | 383 | #define MEMSUFFIX _user |
383 | #include "ops_mem.h" | 384 | #include "ops_mem.h" |
384 | 385 | ||
385 | #define MEMSUFFIX _kernel | 386 | #define MEMSUFFIX _kernel |
386 | #include "ops_mem.h" | 387 | #include "ops_mem.h" |
388 | +#endif | ||
387 | 389 | ||
388 | /* used for bit operations */ | 390 | /* used for bit operations */ |
389 | 391 |
target-i386/translate.c
@@ -570,10 +570,10 @@ static GenOpFunc *gen_op_bsx_T0_cc[2][2] = { | @@ -570,10 +570,10 @@ static GenOpFunc *gen_op_bsx_T0_cc[2][2] = { | ||
570 | }; | 570 | }; |
571 | 571 | ||
572 | static GenOpFunc *gen_op_lds_T0_A0[3 * 3] = { | 572 | static GenOpFunc *gen_op_lds_T0_A0[3 * 3] = { |
573 | - gen_op_ldsb_T0_A0, | ||
574 | - gen_op_ldsw_T0_A0, | 573 | + gen_op_ldsb_raw_T0_A0, |
574 | + gen_op_ldsw_raw_T0_A0, | ||
575 | NULL, | 575 | NULL, |
576 | - | 576 | +#ifndef CONFIG_USER_ONLY |
577 | gen_op_ldsb_kernel_T0_A0, | 577 | gen_op_ldsb_kernel_T0_A0, |
578 | gen_op_ldsw_kernel_T0_A0, | 578 | gen_op_ldsw_kernel_T0_A0, |
579 | NULL, | 579 | NULL, |
@@ -581,13 +581,15 @@ static GenOpFunc *gen_op_lds_T0_A0[3 * 3] = { | @@ -581,13 +581,15 @@ static GenOpFunc *gen_op_lds_T0_A0[3 * 3] = { | ||
581 | gen_op_ldsb_user_T0_A0, | 581 | gen_op_ldsb_user_T0_A0, |
582 | gen_op_ldsw_user_T0_A0, | 582 | gen_op_ldsw_user_T0_A0, |
583 | NULL, | 583 | NULL, |
584 | +#endif | ||
584 | }; | 585 | }; |
585 | 586 | ||
586 | static GenOpFunc *gen_op_ldu_T0_A0[3 * 3] = { | 587 | static GenOpFunc *gen_op_ldu_T0_A0[3 * 3] = { |
587 | - gen_op_ldub_T0_A0, | ||
588 | - gen_op_lduw_T0_A0, | 588 | + gen_op_ldub_raw_T0_A0, |
589 | + gen_op_lduw_raw_T0_A0, | ||
589 | NULL, | 590 | NULL, |
590 | 591 | ||
592 | +#ifndef CONFIG_USER_ONLY | ||
591 | gen_op_ldub_kernel_T0_A0, | 593 | gen_op_ldub_kernel_T0_A0, |
592 | gen_op_lduw_kernel_T0_A0, | 594 | gen_op_lduw_kernel_T0_A0, |
593 | NULL, | 595 | NULL, |
@@ -595,14 +597,16 @@ static GenOpFunc *gen_op_ldu_T0_A0[3 * 3] = { | @@ -595,14 +597,16 @@ static GenOpFunc *gen_op_ldu_T0_A0[3 * 3] = { | ||
595 | gen_op_ldub_user_T0_A0, | 597 | gen_op_ldub_user_T0_A0, |
596 | gen_op_lduw_user_T0_A0, | 598 | gen_op_lduw_user_T0_A0, |
597 | NULL, | 599 | NULL, |
600 | +#endif | ||
598 | }; | 601 | }; |
599 | 602 | ||
600 | /* sign does not matter, except for lidt/lgdt call (TODO: fix it) */ | 603 | /* sign does not matter, except for lidt/lgdt call (TODO: fix it) */ |
601 | static GenOpFunc *gen_op_ld_T0_A0[3 * 3] = { | 604 | static GenOpFunc *gen_op_ld_T0_A0[3 * 3] = { |
602 | - gen_op_ldub_T0_A0, | ||
603 | - gen_op_lduw_T0_A0, | ||
604 | - gen_op_ldl_T0_A0, | 605 | + gen_op_ldub_raw_T0_A0, |
606 | + gen_op_lduw_raw_T0_A0, | ||
607 | + gen_op_ldl_raw_T0_A0, | ||
605 | 608 | ||
609 | +#ifndef CONFIG_USER_ONLY | ||
606 | gen_op_ldub_kernel_T0_A0, | 610 | gen_op_ldub_kernel_T0_A0, |
607 | gen_op_lduw_kernel_T0_A0, | 611 | gen_op_lduw_kernel_T0_A0, |
608 | gen_op_ldl_kernel_T0_A0, | 612 | gen_op_ldl_kernel_T0_A0, |
@@ -610,13 +614,15 @@ static GenOpFunc *gen_op_ld_T0_A0[3 * 3] = { | @@ -610,13 +614,15 @@ static GenOpFunc *gen_op_ld_T0_A0[3 * 3] = { | ||
610 | gen_op_ldub_user_T0_A0, | 614 | gen_op_ldub_user_T0_A0, |
611 | gen_op_lduw_user_T0_A0, | 615 | gen_op_lduw_user_T0_A0, |
612 | gen_op_ldl_user_T0_A0, | 616 | gen_op_ldl_user_T0_A0, |
617 | +#endif | ||
613 | }; | 618 | }; |
614 | 619 | ||
615 | static GenOpFunc *gen_op_ld_T1_A0[3 * 3] = { | 620 | static GenOpFunc *gen_op_ld_T1_A0[3 * 3] = { |
616 | - gen_op_ldub_T1_A0, | ||
617 | - gen_op_lduw_T1_A0, | ||
618 | - gen_op_ldl_T1_A0, | 621 | + gen_op_ldub_raw_T1_A0, |
622 | + gen_op_lduw_raw_T1_A0, | ||
623 | + gen_op_ldl_raw_T1_A0, | ||
619 | 624 | ||
625 | +#ifndef CONFIG_USER_ONLY | ||
620 | gen_op_ldub_kernel_T1_A0, | 626 | gen_op_ldub_kernel_T1_A0, |
621 | gen_op_lduw_kernel_T1_A0, | 627 | gen_op_lduw_kernel_T1_A0, |
622 | gen_op_ldl_kernel_T1_A0, | 628 | gen_op_ldl_kernel_T1_A0, |
@@ -624,13 +630,15 @@ static GenOpFunc *gen_op_ld_T1_A0[3 * 3] = { | @@ -624,13 +630,15 @@ static GenOpFunc *gen_op_ld_T1_A0[3 * 3] = { | ||
624 | gen_op_ldub_user_T1_A0, | 630 | gen_op_ldub_user_T1_A0, |
625 | gen_op_lduw_user_T1_A0, | 631 | gen_op_lduw_user_T1_A0, |
626 | gen_op_ldl_user_T1_A0, | 632 | gen_op_ldl_user_T1_A0, |
633 | +#endif | ||
627 | }; | 634 | }; |
628 | 635 | ||
629 | static GenOpFunc *gen_op_st_T0_A0[3 * 3] = { | 636 | static GenOpFunc *gen_op_st_T0_A0[3 * 3] = { |
630 | - gen_op_stb_T0_A0, | ||
631 | - gen_op_stw_T0_A0, | ||
632 | - gen_op_stl_T0_A0, | 637 | + gen_op_stb_raw_T0_A0, |
638 | + gen_op_stw_raw_T0_A0, | ||
639 | + gen_op_stl_raw_T0_A0, | ||
633 | 640 | ||
641 | +#ifndef CONFIG_USER_ONLY | ||
634 | gen_op_stb_kernel_T0_A0, | 642 | gen_op_stb_kernel_T0_A0, |
635 | gen_op_stw_kernel_T0_A0, | 643 | gen_op_stw_kernel_T0_A0, |
636 | gen_op_stl_kernel_T0_A0, | 644 | gen_op_stl_kernel_T0_A0, |
@@ -638,6 +646,7 @@ static GenOpFunc *gen_op_st_T0_A0[3 * 3] = { | @@ -638,6 +646,7 @@ static GenOpFunc *gen_op_st_T0_A0[3 * 3] = { | ||
638 | gen_op_stb_user_T0_A0, | 646 | gen_op_stb_user_T0_A0, |
639 | gen_op_stw_user_T0_A0, | 647 | gen_op_stw_user_T0_A0, |
640 | gen_op_stl_user_T0_A0, | 648 | gen_op_stl_user_T0_A0, |
649 | +#endif | ||
641 | }; | 650 | }; |
642 | 651 | ||
643 | static inline void gen_string_movl_A0_ESI(DisasContext *s) | 652 | static inline void gen_string_movl_A0_ESI(DisasContext *s) |
@@ -1176,7 +1185,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | @@ -1176,7 +1185,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | ||
1176 | 1185 | ||
1177 | if (base == 4) { | 1186 | if (base == 4) { |
1178 | havesib = 1; | 1187 | havesib = 1; |
1179 | - code = ldub(s->pc++); | 1188 | + code = ldub_code(s->pc++); |
1180 | scale = (code >> 6) & 3; | 1189 | scale = (code >> 6) & 3; |
1181 | index = (code >> 3) & 7; | 1190 | index = (code >> 3) & 7; |
1182 | base = code & 7; | 1191 | base = code & 7; |
@@ -1186,18 +1195,18 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | @@ -1186,18 +1195,18 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | ||
1186 | case 0: | 1195 | case 0: |
1187 | if (base == 5) { | 1196 | if (base == 5) { |
1188 | base = -1; | 1197 | base = -1; |
1189 | - disp = ldl(s->pc); | 1198 | + disp = ldl_code(s->pc); |
1190 | s->pc += 4; | 1199 | s->pc += 4; |
1191 | } else { | 1200 | } else { |
1192 | disp = 0; | 1201 | disp = 0; |
1193 | } | 1202 | } |
1194 | break; | 1203 | break; |
1195 | case 1: | 1204 | case 1: |
1196 | - disp = (int8_t)ldub(s->pc++); | 1205 | + disp = (int8_t)ldub_code(s->pc++); |
1197 | break; | 1206 | break; |
1198 | default: | 1207 | default: |
1199 | case 2: | 1208 | case 2: |
1200 | - disp = ldl(s->pc); | 1209 | + disp = ldl_code(s->pc); |
1201 | s->pc += 4; | 1210 | s->pc += 4; |
1202 | break; | 1211 | break; |
1203 | } | 1212 | } |
@@ -1229,7 +1238,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | @@ -1229,7 +1238,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | ||
1229 | switch (mod) { | 1238 | switch (mod) { |
1230 | case 0: | 1239 | case 0: |
1231 | if (rm == 6) { | 1240 | if (rm == 6) { |
1232 | - disp = lduw(s->pc); | 1241 | + disp = lduw_code(s->pc); |
1233 | s->pc += 2; | 1242 | s->pc += 2; |
1234 | gen_op_movl_A0_im(disp); | 1243 | gen_op_movl_A0_im(disp); |
1235 | rm = 0; /* avoid SS override */ | 1244 | rm = 0; /* avoid SS override */ |
@@ -1239,11 +1248,11 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | @@ -1239,11 +1248,11 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_ | ||
1239 | } | 1248 | } |
1240 | break; | 1249 | break; |
1241 | case 1: | 1250 | case 1: |
1242 | - disp = (int8_t)ldub(s->pc++); | 1251 | + disp = (int8_t)ldub_code(s->pc++); |
1243 | break; | 1252 | break; |
1244 | default: | 1253 | default: |
1245 | case 2: | 1254 | case 2: |
1246 | - disp = lduw(s->pc); | 1255 | + disp = lduw_code(s->pc); |
1247 | s->pc += 2; | 1256 | s->pc += 2; |
1248 | break; | 1257 | break; |
1249 | } | 1258 | } |
@@ -1337,16 +1346,16 @@ static inline uint32_t insn_get(DisasContext *s, int ot) | @@ -1337,16 +1346,16 @@ static inline uint32_t insn_get(DisasContext *s, int ot) | ||
1337 | 1346 | ||
1338 | switch(ot) { | 1347 | switch(ot) { |
1339 | case OT_BYTE: | 1348 | case OT_BYTE: |
1340 | - ret = ldub(s->pc); | 1349 | + ret = ldub_code(s->pc); |
1341 | s->pc++; | 1350 | s->pc++; |
1342 | break; | 1351 | break; |
1343 | case OT_WORD: | 1352 | case OT_WORD: |
1344 | - ret = lduw(s->pc); | 1353 | + ret = lduw_code(s->pc); |
1345 | s->pc += 2; | 1354 | s->pc += 2; |
1346 | break; | 1355 | break; |
1347 | default: | 1356 | default: |
1348 | case OT_LONG: | 1357 | case OT_LONG: |
1349 | - ret = ldl(s->pc); | 1358 | + ret = ldl_code(s->pc); |
1350 | s->pc += 4; | 1359 | s->pc += 4; |
1351 | break; | 1360 | break; |
1352 | } | 1361 | } |
@@ -1756,7 +1765,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1756,7 +1765,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
1756 | dflag = s->code32; | 1765 | dflag = s->code32; |
1757 | s->override = -1; | 1766 | s->override = -1; |
1758 | next_byte: | 1767 | next_byte: |
1759 | - b = ldub(s->pc); | 1768 | + b = ldub_code(s->pc); |
1760 | s->pc++; | 1769 | s->pc++; |
1761 | /* check prefixes */ | 1770 | /* check prefixes */ |
1762 | switch (b) { | 1771 | switch (b) { |
@@ -1814,7 +1823,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1814,7 +1823,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
1814 | case 0x0f: | 1823 | case 0x0f: |
1815 | /**************************/ | 1824 | /**************************/ |
1816 | /* extended op code */ | 1825 | /* extended op code */ |
1817 | - b = ldub(s->pc++) | 0x100; | 1826 | + b = ldub_code(s->pc++) | 0x100; |
1818 | goto reswitch; | 1827 | goto reswitch; |
1819 | 1828 | ||
1820 | /**************************/ | 1829 | /**************************/ |
@@ -1839,7 +1848,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1839,7 +1848,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
1839 | 1848 | ||
1840 | switch(f) { | 1849 | switch(f) { |
1841 | case 0: /* OP Ev, Gv */ | 1850 | case 0: /* OP Ev, Gv */ |
1842 | - modrm = ldub(s->pc++); | 1851 | + modrm = ldub_code(s->pc++); |
1843 | reg = ((modrm >> 3) & 7); | 1852 | reg = ((modrm >> 3) & 7); |
1844 | mod = (modrm >> 6) & 3; | 1853 | mod = (modrm >> 6) & 3; |
1845 | rm = modrm & 7; | 1854 | rm = modrm & 7; |
@@ -1861,7 +1870,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1861,7 +1870,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
1861 | gen_op(s, op, ot, opreg); | 1870 | gen_op(s, op, ot, opreg); |
1862 | break; | 1871 | break; |
1863 | case 1: /* OP Gv, Ev */ | 1872 | case 1: /* OP Gv, Ev */ |
1864 | - modrm = ldub(s->pc++); | 1873 | + modrm = ldub_code(s->pc++); |
1865 | mod = (modrm >> 6) & 3; | 1874 | mod = (modrm >> 6) & 3; |
1866 | reg = ((modrm >> 3) & 7); | 1875 | reg = ((modrm >> 3) & 7); |
1867 | rm = modrm & 7; | 1876 | rm = modrm & 7; |
@@ -1895,7 +1904,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1895,7 +1904,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
1895 | else | 1904 | else |
1896 | ot = dflag ? OT_LONG : OT_WORD; | 1905 | ot = dflag ? OT_LONG : OT_WORD; |
1897 | 1906 | ||
1898 | - modrm = ldub(s->pc++); | 1907 | + modrm = ldub_code(s->pc++); |
1899 | mod = (modrm >> 6) & 3; | 1908 | mod = (modrm >> 6) & 3; |
1900 | rm = modrm & 7; | 1909 | rm = modrm & 7; |
1901 | op = (modrm >> 3) & 7; | 1910 | op = (modrm >> 3) & 7; |
@@ -1939,7 +1948,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -1939,7 +1948,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
1939 | else | 1948 | else |
1940 | ot = dflag ? OT_LONG : OT_WORD; | 1949 | ot = dflag ? OT_LONG : OT_WORD; |
1941 | 1950 | ||
1942 | - modrm = ldub(s->pc++); | 1951 | + modrm = ldub_code(s->pc++); |
1943 | mod = (modrm >> 6) & 3; | 1952 | mod = (modrm >> 6) & 3; |
1944 | rm = modrm & 7; | 1953 | rm = modrm & 7; |
1945 | op = (modrm >> 3) & 7; | 1954 | op = (modrm >> 3) & 7; |
@@ -2045,7 +2054,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2045,7 +2054,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2045 | else | 2054 | else |
2046 | ot = dflag ? OT_LONG : OT_WORD; | 2055 | ot = dflag ? OT_LONG : OT_WORD; |
2047 | 2056 | ||
2048 | - modrm = ldub(s->pc++); | 2057 | + modrm = ldub_code(s->pc++); |
2049 | mod = (modrm >> 6) & 3; | 2058 | mod = (modrm >> 6) & 3; |
2050 | rm = modrm & 7; | 2059 | rm = modrm & 7; |
2051 | op = (modrm >> 3) & 7; | 2060 | op = (modrm >> 3) & 7; |
@@ -2085,10 +2094,10 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2085,10 +2094,10 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2085 | gen_push_T0(s); | 2094 | gen_push_T0(s); |
2086 | gen_eob(s); | 2095 | gen_eob(s); |
2087 | break; | 2096 | break; |
2088 | - case 3: /*< lcall Ev */ | 2097 | + case 3: /* lcall Ev */ |
2089 | gen_op_ld_T1_A0[ot + s->mem_index](); | 2098 | gen_op_ld_T1_A0[ot + s->mem_index](); |
2090 | gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); | 2099 | gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); |
2091 | - gen_op_ld_T0_A0[OT_WORD + s->mem_index](); | 2100 | + gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); |
2092 | do_lcall: | 2101 | do_lcall: |
2093 | if (s->pe && !s->vm86) { | 2102 | if (s->pe && !s->vm86) { |
2094 | if (s->cc_op != CC_OP_DYNAMIC) | 2103 | if (s->cc_op != CC_OP_DYNAMIC) |
@@ -2109,7 +2118,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2109,7 +2118,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2109 | case 5: /* ljmp Ev */ | 2118 | case 5: /* ljmp Ev */ |
2110 | gen_op_ld_T1_A0[ot + s->mem_index](); | 2119 | gen_op_ld_T1_A0[ot + s->mem_index](); |
2111 | gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); | 2120 | gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); |
2112 | - gen_op_lduw_T0_A0(); | 2121 | + gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); |
2113 | do_ljmp: | 2122 | do_ljmp: |
2114 | if (s->pe && !s->vm86) { | 2123 | if (s->pe && !s->vm86) { |
2115 | if (s->cc_op != CC_OP_DYNAMIC) | 2124 | if (s->cc_op != CC_OP_DYNAMIC) |
@@ -2138,7 +2147,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2138,7 +2147,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2138 | else | 2147 | else |
2139 | ot = dflag ? OT_LONG : OT_WORD; | 2148 | ot = dflag ? OT_LONG : OT_WORD; |
2140 | 2149 | ||
2141 | - modrm = ldub(s->pc++); | 2150 | + modrm = ldub_code(s->pc++); |
2142 | mod = (modrm >> 6) & 3; | 2151 | mod = (modrm >> 6) & 3; |
2143 | rm = modrm & 7; | 2152 | rm = modrm & 7; |
2144 | reg = (modrm >> 3) & 7; | 2153 | reg = (modrm >> 3) & 7; |
@@ -2179,7 +2188,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2179,7 +2188,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2179 | case 0x69: /* imul Gv, Ev, I */ | 2188 | case 0x69: /* imul Gv, Ev, I */ |
2180 | case 0x6b: | 2189 | case 0x6b: |
2181 | ot = dflag ? OT_LONG : OT_WORD; | 2190 | ot = dflag ? OT_LONG : OT_WORD; |
2182 | - modrm = ldub(s->pc++); | 2191 | + modrm = ldub_code(s->pc++); |
2183 | reg = ((modrm >> 3) & 7) + OR_EAX; | 2192 | reg = ((modrm >> 3) & 7) + OR_EAX; |
2184 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); | 2193 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); |
2185 | if (b == 0x69) { | 2194 | if (b == 0x69) { |
@@ -2206,7 +2215,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2206,7 +2215,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2206 | ot = OT_BYTE; | 2215 | ot = OT_BYTE; |
2207 | else | 2216 | else |
2208 | ot = dflag ? OT_LONG : OT_WORD; | 2217 | ot = dflag ? OT_LONG : OT_WORD; |
2209 | - modrm = ldub(s->pc++); | 2218 | + modrm = ldub_code(s->pc++); |
2210 | reg = (modrm >> 3) & 7; | 2219 | reg = (modrm >> 3) & 7; |
2211 | mod = (modrm >> 6) & 3; | 2220 | mod = (modrm >> 6) & 3; |
2212 | if (mod == 3) { | 2221 | if (mod == 3) { |
@@ -2233,7 +2242,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2233,7 +2242,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2233 | ot = OT_BYTE; | 2242 | ot = OT_BYTE; |
2234 | else | 2243 | else |
2235 | ot = dflag ? OT_LONG : OT_WORD; | 2244 | ot = dflag ? OT_LONG : OT_WORD; |
2236 | - modrm = ldub(s->pc++); | 2245 | + modrm = ldub_code(s->pc++); |
2237 | reg = (modrm >> 3) & 7; | 2246 | reg = (modrm >> 3) & 7; |
2238 | mod = (modrm >> 6) & 3; | 2247 | mod = (modrm >> 6) & 3; |
2239 | gen_op_mov_TN_reg[ot][1][reg](); | 2248 | gen_op_mov_TN_reg[ot][1][reg](); |
@@ -2250,7 +2259,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2250,7 +2259,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2250 | s->cc_op = CC_OP_SUBB + ot; | 2259 | s->cc_op = CC_OP_SUBB + ot; |
2251 | break; | 2260 | break; |
2252 | case 0x1c7: /* cmpxchg8b */ | 2261 | case 0x1c7: /* cmpxchg8b */ |
2253 | - modrm = ldub(s->pc++); | 2262 | + modrm = ldub_code(s->pc++); |
2254 | mod = (modrm >> 6) & 3; | 2263 | mod = (modrm >> 6) & 3; |
2255 | if (mod == 3) | 2264 | if (mod == 3) |
2256 | goto illegal_op; | 2265 | goto illegal_op; |
@@ -2291,7 +2300,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2291,7 +2300,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2291 | break; | 2300 | break; |
2292 | case 0x8f: /* pop Ev */ | 2301 | case 0x8f: /* pop Ev */ |
2293 | ot = dflag ? OT_LONG : OT_WORD; | 2302 | ot = dflag ? OT_LONG : OT_WORD; |
2294 | - modrm = ldub(s->pc++); | 2303 | + modrm = ldub_code(s->pc++); |
2295 | gen_pop_T0(s); | 2304 | gen_pop_T0(s); |
2296 | s->popl_esp_hack = 2 << dflag; | 2305 | s->popl_esp_hack = 2 << dflag; |
2297 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); | 2306 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); |
@@ -2301,9 +2310,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2301,9 +2310,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2301 | case 0xc8: /* enter */ | 2310 | case 0xc8: /* enter */ |
2302 | { | 2311 | { |
2303 | int level; | 2312 | int level; |
2304 | - val = lduw(s->pc); | 2313 | + val = lduw_code(s->pc); |
2305 | s->pc += 2; | 2314 | s->pc += 2; |
2306 | - level = ldub(s->pc++); | 2315 | + level = ldub_code(s->pc++); |
2307 | gen_enter(s, val, level); | 2316 | gen_enter(s, val, level); |
2308 | } | 2317 | } |
2309 | break; | 2318 | break; |
@@ -2369,7 +2378,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2369,7 +2378,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2369 | ot = OT_BYTE; | 2378 | ot = OT_BYTE; |
2370 | else | 2379 | else |
2371 | ot = dflag ? OT_LONG : OT_WORD; | 2380 | ot = dflag ? OT_LONG : OT_WORD; |
2372 | - modrm = ldub(s->pc++); | 2381 | + modrm = ldub_code(s->pc++); |
2373 | reg = (modrm >> 3) & 7; | 2382 | reg = (modrm >> 3) & 7; |
2374 | 2383 | ||
2375 | /* generate a generic store */ | 2384 | /* generate a generic store */ |
@@ -2381,7 +2390,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2381,7 +2390,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2381 | ot = OT_BYTE; | 2390 | ot = OT_BYTE; |
2382 | else | 2391 | else |
2383 | ot = dflag ? OT_LONG : OT_WORD; | 2392 | ot = dflag ? OT_LONG : OT_WORD; |
2384 | - modrm = ldub(s->pc++); | 2393 | + modrm = ldub_code(s->pc++); |
2385 | mod = (modrm >> 6) & 3; | 2394 | mod = (modrm >> 6) & 3; |
2386 | if (mod != 3) | 2395 | if (mod != 3) |
2387 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); | 2396 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
@@ -2398,14 +2407,14 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2398,14 +2407,14 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2398 | ot = OT_BYTE; | 2407 | ot = OT_BYTE; |
2399 | else | 2408 | else |
2400 | ot = dflag ? OT_LONG : OT_WORD; | 2409 | ot = dflag ? OT_LONG : OT_WORD; |
2401 | - modrm = ldub(s->pc++); | 2410 | + modrm = ldub_code(s->pc++); |
2402 | reg = (modrm >> 3) & 7; | 2411 | reg = (modrm >> 3) & 7; |
2403 | 2412 | ||
2404 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); | 2413 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); |
2405 | gen_op_mov_reg_T0[ot][reg](); | 2414 | gen_op_mov_reg_T0[ot][reg](); |
2406 | break; | 2415 | break; |
2407 | case 0x8e: /* mov seg, Gv */ | 2416 | case 0x8e: /* mov seg, Gv */ |
2408 | - modrm = ldub(s->pc++); | 2417 | + modrm = ldub_code(s->pc++); |
2409 | reg = (modrm >> 3) & 7; | 2418 | reg = (modrm >> 3) & 7; |
2410 | if (reg >= 6 || reg == R_CS) | 2419 | if (reg >= 6 || reg == R_CS) |
2411 | goto illegal_op; | 2420 | goto illegal_op; |
@@ -2422,7 +2431,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2422,7 +2431,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2422 | } | 2431 | } |
2423 | break; | 2432 | break; |
2424 | case 0x8c: /* mov Gv, seg */ | 2433 | case 0x8c: /* mov Gv, seg */ |
2425 | - modrm = ldub(s->pc++); | 2434 | + modrm = ldub_code(s->pc++); |
2426 | reg = (modrm >> 3) & 7; | 2435 | reg = (modrm >> 3) & 7; |
2427 | mod = (modrm >> 6) & 3; | 2436 | mod = (modrm >> 6) & 3; |
2428 | if (reg >= 6) | 2437 | if (reg >= 6) |
@@ -2444,7 +2453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2444,7 +2453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2444 | d_ot = dflag + OT_WORD; | 2453 | d_ot = dflag + OT_WORD; |
2445 | /* ot is the size of source */ | 2454 | /* ot is the size of source */ |
2446 | ot = (b & 1) + OT_BYTE; | 2455 | ot = (b & 1) + OT_BYTE; |
2447 | - modrm = ldub(s->pc++); | 2456 | + modrm = ldub_code(s->pc++); |
2448 | reg = ((modrm >> 3) & 7) + OR_EAX; | 2457 | reg = ((modrm >> 3) & 7) + OR_EAX; |
2449 | mod = (modrm >> 6) & 3; | 2458 | mod = (modrm >> 6) & 3; |
2450 | rm = modrm & 7; | 2459 | rm = modrm & 7; |
@@ -2481,7 +2490,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2481,7 +2490,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2481 | 2490 | ||
2482 | case 0x8d: /* lea */ | 2491 | case 0x8d: /* lea */ |
2483 | ot = dflag ? OT_LONG : OT_WORD; | 2492 | ot = dflag ? OT_LONG : OT_WORD; |
2484 | - modrm = ldub(s->pc++); | 2493 | + modrm = ldub_code(s->pc++); |
2485 | reg = (modrm >> 3) & 7; | 2494 | reg = (modrm >> 3) & 7; |
2486 | /* we must ensure that no segment is added */ | 2495 | /* we must ensure that no segment is added */ |
2487 | s->override = -1; | 2496 | s->override = -1; |
@@ -2574,7 +2583,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2574,7 +2583,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2574 | ot = OT_BYTE; | 2583 | ot = OT_BYTE; |
2575 | else | 2584 | else |
2576 | ot = dflag ? OT_LONG : OT_WORD; | 2585 | ot = dflag ? OT_LONG : OT_WORD; |
2577 | - modrm = ldub(s->pc++); | 2586 | + modrm = ldub_code(s->pc++); |
2578 | reg = (modrm >> 3) & 7; | 2587 | reg = (modrm >> 3) & 7; |
2579 | mod = (modrm >> 6) & 3; | 2588 | mod = (modrm >> 6) & 3; |
2580 | if (mod == 3) { | 2589 | if (mod == 3) { |
@@ -2613,7 +2622,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2613,7 +2622,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2613 | op = R_GS; | 2622 | op = R_GS; |
2614 | do_lxx: | 2623 | do_lxx: |
2615 | ot = dflag ? OT_LONG : OT_WORD; | 2624 | ot = dflag ? OT_LONG : OT_WORD; |
2616 | - modrm = ldub(s->pc++); | 2625 | + modrm = ldub_code(s->pc++); |
2617 | reg = (modrm >> 3) & 7; | 2626 | reg = (modrm >> 3) & 7; |
2618 | mod = (modrm >> 6) & 3; | 2627 | mod = (modrm >> 6) & 3; |
2619 | if (mod == 3) | 2628 | if (mod == 3) |
@@ -2622,7 +2631,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2622,7 +2631,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2622 | gen_op_ld_T1_A0[ot + s->mem_index](); | 2631 | gen_op_ld_T1_A0[ot + s->mem_index](); |
2623 | gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); | 2632 | gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); |
2624 | /* load the segment first to handle exceptions properly */ | 2633 | /* load the segment first to handle exceptions properly */ |
2625 | - gen_op_lduw_T0_A0(); | 2634 | + gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); |
2626 | gen_movl_seg_T0(s, op, pc_start - s->cs_base); | 2635 | gen_movl_seg_T0(s, op, pc_start - s->cs_base); |
2627 | /* then put the data */ | 2636 | /* then put the data */ |
2628 | gen_op_mov_reg_T1[ot][reg](); | 2637 | gen_op_mov_reg_T1[ot][reg](); |
@@ -2645,7 +2654,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2645,7 +2654,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2645 | else | 2654 | else |
2646 | ot = dflag ? OT_LONG : OT_WORD; | 2655 | ot = dflag ? OT_LONG : OT_WORD; |
2647 | 2656 | ||
2648 | - modrm = ldub(s->pc++); | 2657 | + modrm = ldub_code(s->pc++); |
2649 | mod = (modrm >> 6) & 3; | 2658 | mod = (modrm >> 6) & 3; |
2650 | rm = modrm & 7; | 2659 | rm = modrm & 7; |
2651 | op = (modrm >> 3) & 7; | 2660 | op = (modrm >> 3) & 7; |
@@ -2662,7 +2671,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2662,7 +2671,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2662 | gen_shift(s, op, ot, opreg, OR_ECX); | 2671 | gen_shift(s, op, ot, opreg, OR_ECX); |
2663 | } else { | 2672 | } else { |
2664 | if (shift == 2) { | 2673 | if (shift == 2) { |
2665 | - shift = ldub(s->pc++); | 2674 | + shift = ldub_code(s->pc++); |
2666 | } | 2675 | } |
2667 | gen_shifti(s, op, ot, opreg, shift); | 2676 | gen_shifti(s, op, ot, opreg, shift); |
2668 | } | 2677 | } |
@@ -2696,7 +2705,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2696,7 +2705,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2696 | shift = 0; | 2705 | shift = 0; |
2697 | do_shiftd: | 2706 | do_shiftd: |
2698 | ot = dflag ? OT_LONG : OT_WORD; | 2707 | ot = dflag ? OT_LONG : OT_WORD; |
2699 | - modrm = ldub(s->pc++); | 2708 | + modrm = ldub_code(s->pc++); |
2700 | mod = (modrm >> 6) & 3; | 2709 | mod = (modrm >> 6) & 3; |
2701 | rm = modrm & 7; | 2710 | rm = modrm & 7; |
2702 | reg = (modrm >> 3) & 7; | 2711 | reg = (modrm >> 3) & 7; |
@@ -2710,7 +2719,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2710,7 +2719,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2710 | gen_op_mov_TN_reg[ot][1][reg](); | 2719 | gen_op_mov_TN_reg[ot][1][reg](); |
2711 | 2720 | ||
2712 | if (shift) { | 2721 | if (shift) { |
2713 | - val = ldub(s->pc++); | 2722 | + val = ldub_code(s->pc++); |
2714 | val &= 0x1f; | 2723 | val &= 0x1f; |
2715 | if (val) { | 2724 | if (val) { |
2716 | if (mod == 3) | 2725 | if (mod == 3) |
@@ -2739,7 +2748,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2739,7 +2748,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2739 | /************************/ | 2748 | /************************/ |
2740 | /* floats */ | 2749 | /* floats */ |
2741 | case 0xd8 ... 0xdf: | 2750 | case 0xd8 ... 0xdf: |
2742 | - modrm = ldub(s->pc++); | 2751 | + modrm = ldub_code(s->pc++); |
2743 | mod = (modrm >> 6) & 3; | 2752 | mod = (modrm >> 6) & 3; |
2744 | rm = modrm & 7; | 2753 | rm = modrm & 7; |
2745 | op = ((b & 7) << 3) | ((modrm >> 3) & 7); | 2754 | op = ((b & 7) << 3) | ((modrm >> 3) & 7); |
@@ -3256,7 +3265,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3256,7 +3265,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3256 | ot = OT_BYTE; | 3265 | ot = OT_BYTE; |
3257 | else | 3266 | else |
3258 | ot = dflag ? OT_LONG : OT_WORD; | 3267 | ot = dflag ? OT_LONG : OT_WORD; |
3259 | - val = ldub(s->pc++); | 3268 | + val = ldub_code(s->pc++); |
3260 | gen_op_movl_T0_im(val); | 3269 | gen_op_movl_T0_im(val); |
3261 | gen_op_in[ot](); | 3270 | gen_op_in[ot](); |
3262 | gen_op_mov_reg_T1[ot][R_EAX](); | 3271 | gen_op_mov_reg_T1[ot][R_EAX](); |
@@ -3271,7 +3280,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3271,7 +3280,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3271 | ot = OT_BYTE; | 3280 | ot = OT_BYTE; |
3272 | else | 3281 | else |
3273 | ot = dflag ? OT_LONG : OT_WORD; | 3282 | ot = dflag ? OT_LONG : OT_WORD; |
3274 | - val = ldub(s->pc++); | 3283 | + val = ldub_code(s->pc++); |
3275 | gen_op_movl_T0_im(val); | 3284 | gen_op_movl_T0_im(val); |
3276 | gen_op_mov_TN_reg[ot][1][R_EAX](); | 3285 | gen_op_mov_TN_reg[ot][1][R_EAX](); |
3277 | gen_op_out[ot](); | 3286 | gen_op_out[ot](); |
@@ -3309,7 +3318,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3309,7 +3318,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3309 | /************************/ | 3318 | /************************/ |
3310 | /* control */ | 3319 | /* control */ |
3311 | case 0xc2: /* ret im */ | 3320 | case 0xc2: /* ret im */ |
3312 | - val = ldsw(s->pc); | 3321 | + val = ldsw_code(s->pc); |
3313 | s->pc += 2; | 3322 | s->pc += 2; |
3314 | gen_pop_T0(s); | 3323 | gen_pop_T0(s); |
3315 | gen_stack_update(s, val + (2 << s->dflag)); | 3324 | gen_stack_update(s, val + (2 << s->dflag)); |
@@ -3327,7 +3336,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3327,7 +3336,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3327 | gen_eob(s); | 3336 | gen_eob(s); |
3328 | break; | 3337 | break; |
3329 | case 0xca: /* lret im */ | 3338 | case 0xca: /* lret im */ |
3330 | - val = ldsw(s->pc); | 3339 | + val = ldsw_code(s->pc); |
3331 | s->pc += 2; | 3340 | s->pc += 2; |
3332 | do_lret: | 3341 | do_lret: |
3333 | if (s->pe && !s->vm86) { | 3342 | if (s->pe && !s->vm86) { |
@@ -3443,13 +3452,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3443,13 +3452,13 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3443 | break; | 3452 | break; |
3444 | 3453 | ||
3445 | case 0x190 ... 0x19f: /* setcc Gv */ | 3454 | case 0x190 ... 0x19f: /* setcc Gv */ |
3446 | - modrm = ldub(s->pc++); | 3455 | + modrm = ldub_code(s->pc++); |
3447 | gen_setcc(s, b); | 3456 | gen_setcc(s, b); |
3448 | gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1); | 3457 | gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1); |
3449 | break; | 3458 | break; |
3450 | case 0x140 ... 0x14f: /* cmov Gv, Ev */ | 3459 | case 0x140 ... 0x14f: /* cmov Gv, Ev */ |
3451 | ot = dflag ? OT_LONG : OT_WORD; | 3460 | ot = dflag ? OT_LONG : OT_WORD; |
3452 | - modrm = ldub(s->pc++); | 3461 | + modrm = ldub_code(s->pc++); |
3453 | reg = (modrm >> 3) & 7; | 3462 | reg = (modrm >> 3) & 7; |
3454 | mod = (modrm >> 6) & 3; | 3463 | mod = (modrm >> 6) & 3; |
3455 | gen_setcc(s, b); | 3464 | gen_setcc(s, b); |
@@ -3542,7 +3551,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3542,7 +3551,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3542 | /* bit operations */ | 3551 | /* bit operations */ |
3543 | case 0x1ba: /* bt/bts/btr/btc Gv, im */ | 3552 | case 0x1ba: /* bt/bts/btr/btc Gv, im */ |
3544 | ot = dflag ? OT_LONG : OT_WORD; | 3553 | ot = dflag ? OT_LONG : OT_WORD; |
3545 | - modrm = ldub(s->pc++); | 3554 | + modrm = ldub_code(s->pc++); |
3546 | op = (modrm >> 3) & 7; | 3555 | op = (modrm >> 3) & 7; |
3547 | mod = (modrm >> 6) & 3; | 3556 | mod = (modrm >> 6) & 3; |
3548 | rm = modrm & 7; | 3557 | rm = modrm & 7; |
@@ -3553,7 +3562,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3553,7 +3562,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3553 | gen_op_mov_TN_reg[ot][0][rm](); | 3562 | gen_op_mov_TN_reg[ot][0][rm](); |
3554 | } | 3563 | } |
3555 | /* load shift */ | 3564 | /* load shift */ |
3556 | - val = ldub(s->pc++); | 3565 | + val = ldub_code(s->pc++); |
3557 | gen_op_movl_T1_im(val); | 3566 | gen_op_movl_T1_im(val); |
3558 | if (op < 4) | 3567 | if (op < 4) |
3559 | goto illegal_op; | 3568 | goto illegal_op; |
@@ -3581,7 +3590,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3581,7 +3590,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3581 | op = 3; | 3590 | op = 3; |
3582 | do_btx: | 3591 | do_btx: |
3583 | ot = dflag ? OT_LONG : OT_WORD; | 3592 | ot = dflag ? OT_LONG : OT_WORD; |
3584 | - modrm = ldub(s->pc++); | 3593 | + modrm = ldub_code(s->pc++); |
3585 | reg = (modrm >> 3) & 7; | 3594 | reg = (modrm >> 3) & 7; |
3586 | mod = (modrm >> 6) & 3; | 3595 | mod = (modrm >> 6) & 3; |
3587 | rm = modrm & 7; | 3596 | rm = modrm & 7; |
@@ -3610,7 +3619,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3610,7 +3619,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3610 | case 0x1bc: /* bsf */ | 3619 | case 0x1bc: /* bsf */ |
3611 | case 0x1bd: /* bsr */ | 3620 | case 0x1bd: /* bsr */ |
3612 | ot = dflag ? OT_LONG : OT_WORD; | 3621 | ot = dflag ? OT_LONG : OT_WORD; |
3613 | - modrm = ldub(s->pc++); | 3622 | + modrm = ldub_code(s->pc++); |
3614 | reg = (modrm >> 3) & 7; | 3623 | reg = (modrm >> 3) & 7; |
3615 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); | 3624 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); |
3616 | gen_op_bsx_T0_cc[ot - OT_WORD][b & 1](); | 3625 | gen_op_bsx_T0_cc[ot - OT_WORD][b & 1](); |
@@ -3646,12 +3655,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3646,12 +3655,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3646 | s->cc_op = CC_OP_EFLAGS; | 3655 | s->cc_op = CC_OP_EFLAGS; |
3647 | break; | 3656 | break; |
3648 | case 0xd4: /* aam */ | 3657 | case 0xd4: /* aam */ |
3649 | - val = ldub(s->pc++); | 3658 | + val = ldub_code(s->pc++); |
3650 | gen_op_aam(val); | 3659 | gen_op_aam(val); |
3651 | s->cc_op = CC_OP_LOGICB; | 3660 | s->cc_op = CC_OP_LOGICB; |
3652 | break; | 3661 | break; |
3653 | case 0xd5: /* aad */ | 3662 | case 0xd5: /* aad */ |
3654 | - val = ldub(s->pc++); | 3663 | + val = ldub_code(s->pc++); |
3655 | gen_op_aad(val); | 3664 | gen_op_aad(val); |
3656 | s->cc_op = CC_OP_LOGICB; | 3665 | s->cc_op = CC_OP_LOGICB; |
3657 | break; | 3666 | break; |
@@ -3665,7 +3674,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3665,7 +3674,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3665 | gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base); | 3674 | gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base); |
3666 | break; | 3675 | break; |
3667 | case 0xcd: /* int N */ | 3676 | case 0xcd: /* int N */ |
3668 | - val = ldub(s->pc++); | 3677 | + val = ldub_code(s->pc++); |
3669 | /* XXX: add error code for vm86 GPF */ | 3678 | /* XXX: add error code for vm86 GPF */ |
3670 | if (!s->vm86) | 3679 | if (!s->vm86) |
3671 | gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base); | 3680 | gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base); |
@@ -3718,7 +3727,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3718,7 +3727,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3718 | break; | 3727 | break; |
3719 | case 0x62: /* bound */ | 3728 | case 0x62: /* bound */ |
3720 | ot = dflag ? OT_LONG : OT_WORD; | 3729 | ot = dflag ? OT_LONG : OT_WORD; |
3721 | - modrm = ldub(s->pc++); | 3730 | + modrm = ldub_code(s->pc++); |
3722 | reg = (modrm >> 3) & 7; | 3731 | reg = (modrm >> 3) & 7; |
3723 | mod = (modrm >> 6) & 3; | 3732 | mod = (modrm >> 6) & 3; |
3724 | if (mod == 3) | 3733 | if (mod == 3) |
@@ -3785,7 +3794,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3785,7 +3794,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3785 | } | 3794 | } |
3786 | break; | 3795 | break; |
3787 | case 0x100: | 3796 | case 0x100: |
3788 | - modrm = ldub(s->pc++); | 3797 | + modrm = ldub_code(s->pc++); |
3789 | mod = (modrm >> 6) & 3; | 3798 | mod = (modrm >> 6) & 3; |
3790 | op = (modrm >> 3) & 7; | 3799 | op = (modrm >> 3) & 7; |
3791 | switch(op) { | 3800 | switch(op) { |
@@ -3828,7 +3837,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3828,7 +3837,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3828 | } | 3837 | } |
3829 | break; | 3838 | break; |
3830 | case 0x101: | 3839 | case 0x101: |
3831 | - modrm = ldub(s->pc++); | 3840 | + modrm = ldub_code(s->pc++); |
3832 | mod = (modrm >> 6) & 3; | 3841 | mod = (modrm >> 6) & 3; |
3833 | op = (modrm >> 3) & 7; | 3842 | op = (modrm >> 3) & 7; |
3834 | switch(op) { | 3843 | switch(op) { |
@@ -3904,7 +3913,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3904,7 +3913,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3904 | if (!s->pe || s->vm86) | 3913 | if (!s->pe || s->vm86) |
3905 | goto illegal_op; | 3914 | goto illegal_op; |
3906 | ot = dflag ? OT_LONG : OT_WORD; | 3915 | ot = dflag ? OT_LONG : OT_WORD; |
3907 | - modrm = ldub(s->pc++); | 3916 | + modrm = ldub_code(s->pc++); |
3908 | reg = (modrm >> 3) & 7; | 3917 | reg = (modrm >> 3) & 7; |
3909 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); | 3918 | gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); |
3910 | gen_op_mov_TN_reg[ot][1][reg](); | 3919 | gen_op_mov_TN_reg[ot][1][reg](); |
@@ -3918,7 +3927,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3918,7 +3927,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3918 | gen_op_mov_reg_T1[ot][reg](); | 3927 | gen_op_mov_reg_T1[ot][reg](); |
3919 | break; | 3928 | break; |
3920 | case 0x118: | 3929 | case 0x118: |
3921 | - modrm = ldub(s->pc++); | 3930 | + modrm = ldub_code(s->pc++); |
3922 | mod = (modrm >> 6) & 3; | 3931 | mod = (modrm >> 6) & 3; |
3923 | op = (modrm >> 3) & 7; | 3932 | op = (modrm >> 3) & 7; |
3924 | switch(op) { | 3933 | switch(op) { |
@@ -3940,7 +3949,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3940,7 +3949,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3940 | if (s->cpl != 0) { | 3949 | if (s->cpl != 0) { |
3941 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); | 3950 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); |
3942 | } else { | 3951 | } else { |
3943 | - modrm = ldub(s->pc++); | 3952 | + modrm = ldub_code(s->pc++); |
3944 | if ((modrm & 0xc0) != 0xc0) | 3953 | if ((modrm & 0xc0) != 0xc0) |
3945 | goto illegal_op; | 3954 | goto illegal_op; |
3946 | rm = modrm & 7; | 3955 | rm = modrm & 7; |
@@ -3970,7 +3979,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -3970,7 +3979,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
3970 | if (s->cpl != 0) { | 3979 | if (s->cpl != 0) { |
3971 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); | 3980 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); |
3972 | } else { | 3981 | } else { |
3973 | - modrm = ldub(s->pc++); | 3982 | + modrm = ldub_code(s->pc++); |
3974 | if ((modrm & 0xc0) != 0xc0) | 3983 | if ((modrm & 0xc0) != 0xc0) |
3975 | goto illegal_op; | 3984 | goto illegal_op; |
3976 | rm = modrm & 7; | 3985 | rm = modrm & 7; |