]>
Commit | Line | Data |
---|---|---|
5a9fdfec FB |
1 | /* |
2 | * defines common to all virtual CPUs | |
3 | * | |
4 | * Copyright (c) 2003 Fabrice Bellard | |
5 | * | |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, write to the Free Software | |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | */ | |
20 | #ifndef CPU_ALL_H | |
21 | #define CPU_ALL_H | |
22 | ||
0ac4bd56 FB |
23 | #if defined(__arm__) || defined(__sparc__) |
24 | #define WORDS_ALIGNED | |
25 | #endif | |
26 | ||
27 | /* some important defines: | |
28 | * | |
29 | * WORDS_ALIGNED : if defined, the host cpu can only make word aligned | |
30 | * memory accesses. | |
31 | * | |
32 | * WORDS_BIGENDIAN : if defined, the host cpu is big endian and | |
33 | * otherwise little endian. | |
34 | * | |
35 | * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet)) | |
36 | * | |
37 | * TARGET_WORDS_BIGENDIAN : same for target cpu | |
38 | */ | |
39 | ||
40 | /* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ | |
41 | typedef union { | |
42 | double d; | |
43 | #if !defined(WORDS_BIGENDIAN) && !defined(__arm__) | |
44 | struct { | |
45 | uint32_t lower; | |
46 | uint32_t upper; | |
47 | } l; | |
48 | #else | |
49 | struct { | |
50 | uint32_t upper; | |
51 | uint32_t lower; | |
52 | } l; | |
53 | #endif | |
54 | uint64_t ll; | |
55 | } CPU_DoubleU; | |
56 | ||
61382a50 FB |
57 | /* CPU memory access without any memory or io remapping */ |
58 | ||
83d73968 FB |
59 | /* |
60 | * the generic syntax for the memory accesses is: | |
61 | * | |
62 | * load: ld{type}{sign}{size}{endian}_{access_type}(ptr) | |
63 | * | |
64 | * store: st{type}{size}{endian}_{access_type}(ptr, val) | |
65 | * | |
66 | * type is: | |
67 | * (empty): integer access | |
68 | * f : float access | |
69 | * | |
70 | * sign is: | |
71 | * (empty): for floats or 32 bit size | |
72 | * u : unsigned | |
73 | * s : signed | |
74 | * | |
75 | * size is: | |
76 | * b: 8 bits | |
77 | * w: 16 bits | |
78 | * l: 32 bits | |
79 | * q: 64 bits | |
80 | * | |
81 | * endian is: | |
82 | * (empty): target cpu endianness or 8 bit access | |
83 | * r : reversed target cpu endianness (not implemented yet) | |
84 | * be : big endian (not implemented yet) | |
85 | * le : little endian (not implemented yet) | |
86 | * | |
87 | * access_type is: | |
88 | * raw : host memory access | |
89 | * user : user mode access using soft MMU | |
90 | * kernel : kernel mode access using soft MMU | |
91 | */ | |
61382a50 | 92 | static inline int ldub_raw(void *ptr) |
5a9fdfec FB |
93 | { |
94 | return *(uint8_t *)ptr; | |
95 | } | |
96 | ||
61382a50 | 97 | static inline int ldsb_raw(void *ptr) |
5a9fdfec FB |
98 | { |
99 | return *(int8_t *)ptr; | |
100 | } | |
101 | ||
61382a50 | 102 | static inline void stb_raw(void *ptr, int v) |
5a9fdfec FB |
103 | { |
104 | *(uint8_t *)ptr = v; | |
105 | } | |
106 | ||
107 | /* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the | |
108 | kernel handles unaligned load/stores may give better results, but | |
109 | it is a system wide setting : bad */ | |
0ac4bd56 | 110 | #if !defined(TARGET_WORDS_BIGENDIAN) && (defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)) |
5a9fdfec FB |
111 | |
112 | /* conservative code for little endian unaligned accesses */ | |
61382a50 | 113 | static inline int lduw_raw(void *ptr) |
5a9fdfec FB |
114 | { |
115 | #ifdef __powerpc__ | |
116 | int val; | |
117 | __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | |
118 | return val; | |
119 | #else | |
120 | uint8_t *p = ptr; | |
121 | return p[0] | (p[1] << 8); | |
122 | #endif | |
123 | } | |
124 | ||
61382a50 | 125 | static inline int ldsw_raw(void *ptr) |
5a9fdfec FB |
126 | { |
127 | #ifdef __powerpc__ | |
128 | int val; | |
129 | __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | |
130 | return (int16_t)val; | |
131 | #else | |
132 | uint8_t *p = ptr; | |
133 | return (int16_t)(p[0] | (p[1] << 8)); | |
134 | #endif | |
135 | } | |
136 | ||
61382a50 | 137 | static inline int ldl_raw(void *ptr) |
5a9fdfec FB |
138 | { |
139 | #ifdef __powerpc__ | |
140 | int val; | |
141 | __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | |
142 | return val; | |
143 | #else | |
144 | uint8_t *p = ptr; | |
145 | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); | |
146 | #endif | |
147 | } | |
148 | ||
61382a50 | 149 | static inline uint64_t ldq_raw(void *ptr) |
5a9fdfec FB |
150 | { |
151 | uint8_t *p = ptr; | |
152 | uint32_t v1, v2; | |
61382a50 FB |
153 | v1 = ldl_raw(p); |
154 | v2 = ldl_raw(p + 4); | |
5a9fdfec FB |
155 | return v1 | ((uint64_t)v2 << 32); |
156 | } | |
157 | ||
61382a50 | 158 | static inline void stw_raw(void *ptr, int v) |
5a9fdfec FB |
159 | { |
160 | #ifdef __powerpc__ | |
161 | __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); | |
162 | #else | |
163 | uint8_t *p = ptr; | |
164 | p[0] = v; | |
165 | p[1] = v >> 8; | |
166 | #endif | |
167 | } | |
168 | ||
61382a50 | 169 | static inline void stl_raw(void *ptr, int v) |
5a9fdfec FB |
170 | { |
171 | #ifdef __powerpc__ | |
172 | __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); | |
173 | #else | |
174 | uint8_t *p = ptr; | |
175 | p[0] = v; | |
176 | p[1] = v >> 8; | |
177 | p[2] = v >> 16; | |
178 | p[3] = v >> 24; | |
179 | #endif | |
180 | } | |
181 | ||
61382a50 | 182 | static inline void stq_raw(void *ptr, uint64_t v) |
5a9fdfec FB |
183 | { |
184 | uint8_t *p = ptr; | |
61382a50 FB |
185 | stl_raw(p, (uint32_t)v); |
186 | stl_raw(p + 4, v >> 32); | |
5a9fdfec FB |
187 | } |
188 | ||
189 | /* float access */ | |
190 | ||
61382a50 | 191 | static inline float ldfl_raw(void *ptr) |
5a9fdfec FB |
192 | { |
193 | union { | |
194 | float f; | |
195 | uint32_t i; | |
196 | } u; | |
61382a50 | 197 | u.i = ldl_raw(ptr); |
5a9fdfec FB |
198 | return u.f; |
199 | } | |
200 | ||
61382a50 | 201 | static inline void stfl_raw(void *ptr, float v) |
5a9fdfec FB |
202 | { |
203 | union { | |
204 | float f; | |
205 | uint32_t i; | |
206 | } u; | |
207 | u.f = v; | |
61382a50 | 208 | stl_raw(ptr, u.i); |
5a9fdfec FB |
209 | } |
210 | ||
61382a50 | 211 | static inline double ldfq_raw(void *ptr) |
5a9fdfec | 212 | { |
0ac4bd56 FB |
213 | CPU_DoubleU u; |
214 | u.l.lower = ldl_raw(ptr); | |
215 | u.l.upper = ldl_raw(ptr + 4); | |
5a9fdfec FB |
216 | return u.d; |
217 | } | |
218 | ||
61382a50 | 219 | static inline void stfq_raw(void *ptr, double v) |
5a9fdfec | 220 | { |
0ac4bd56 | 221 | CPU_DoubleU u; |
5a9fdfec | 222 | u.d = v; |
0ac4bd56 FB |
223 | stl_raw(ptr, u.l.lower); |
224 | stl_raw(ptr + 4, u.l.upper); | |
5a9fdfec FB |
225 | } |
226 | ||
0ac4bd56 | 227 | #elif defined(TARGET_WORDS_BIGENDIAN) && (!defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)) |
93ac68bc | 228 | |
61382a50 | 229 | static inline int lduw_raw(void *ptr) |
93ac68bc | 230 | { |
83d73968 FB |
231 | #if defined(__i386__) |
232 | int val; | |
233 | asm volatile ("movzwl %1, %0\n" | |
234 | "xchgb %b0, %h0\n" | |
235 | : "=q" (val) | |
236 | : "m" (*(uint16_t *)ptr)); | |
237 | return val; | |
238 | #else | |
93ac68bc | 239 | uint8_t *b = (uint8_t *) ptr; |
83d73968 FB |
240 | return ((b[0] << 8) | b[1]); |
241 | #endif | |
93ac68bc FB |
242 | } |
243 | ||
61382a50 | 244 | static inline int ldsw_raw(void *ptr) |
93ac68bc | 245 | { |
83d73968 FB |
246 | #if defined(__i386__) |
247 | int val; | |
248 | asm volatile ("movzwl %1, %0\n" | |
249 | "xchgb %b0, %h0\n" | |
250 | : "=q" (val) | |
251 | : "m" (*(uint16_t *)ptr)); | |
252 | return (int16_t)val; | |
253 | #else | |
254 | uint8_t *b = (uint8_t *) ptr; | |
255 | return (int16_t)((b[0] << 8) | b[1]); | |
256 | #endif | |
93ac68bc FB |
257 | } |
258 | ||
61382a50 | 259 | static inline int ldl_raw(void *ptr) |
93ac68bc | 260 | { |
83d73968 FB |
261 | #if defined(__i386__) |
262 | int val; | |
263 | asm volatile ("movl %1, %0\n" | |
264 | "bswap %0\n" | |
265 | : "=r" (val) | |
266 | : "m" (*(uint32_t *)ptr)); | |
267 | return val; | |
268 | #else | |
93ac68bc | 269 | uint8_t *b = (uint8_t *) ptr; |
83d73968 FB |
270 | return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; |
271 | #endif | |
93ac68bc FB |
272 | } |
273 | ||
61382a50 | 274 | static inline uint64_t ldq_raw(void *ptr) |
93ac68bc FB |
275 | { |
276 | uint32_t a,b; | |
9f05cc34 FB |
277 | a = ldl_raw(ptr); |
278 | b = ldl_raw(ptr+4); | |
93ac68bc FB |
279 | return (((uint64_t)a<<32)|b); |
280 | } | |
281 | ||
61382a50 | 282 | static inline void stw_raw(void *ptr, int v) |
93ac68bc | 283 | { |
83d73968 FB |
284 | #if defined(__i386__) |
285 | asm volatile ("xchgb %b0, %h0\n" | |
286 | "movw %w0, %1\n" | |
287 | : "=q" (v) | |
288 | : "m" (*(uint16_t *)ptr), "0" (v)); | |
289 | #else | |
93ac68bc FB |
290 | uint8_t *d = (uint8_t *) ptr; |
291 | d[0] = v >> 8; | |
292 | d[1] = v; | |
83d73968 | 293 | #endif |
93ac68bc FB |
294 | } |
295 | ||
61382a50 | 296 | static inline void stl_raw(void *ptr, int v) |
93ac68bc | 297 | { |
83d73968 FB |
298 | #if defined(__i386__) |
299 | asm volatile ("bswap %0\n" | |
300 | "movl %0, %1\n" | |
301 | : "=r" (v) | |
302 | : "m" (*(uint32_t *)ptr), "0" (v)); | |
303 | #else | |
93ac68bc FB |
304 | uint8_t *d = (uint8_t *) ptr; |
305 | d[0] = v >> 24; | |
306 | d[1] = v >> 16; | |
307 | d[2] = v >> 8; | |
308 | d[3] = v; | |
83d73968 | 309 | #endif |
93ac68bc FB |
310 | } |
311 | ||
61382a50 | 312 | static inline void stq_raw(void *ptr, uint64_t v) |
93ac68bc | 313 | { |
0ac4bd56 FB |
314 | stl_raw(ptr, v >> 32); |
315 | stl_raw(ptr + 4, v); | |
316 | } | |
317 | ||
318 | /* float access */ | |
319 | ||
320 | static inline float ldfl_raw(void *ptr) | |
321 | { | |
322 | union { | |
323 | float f; | |
324 | uint32_t i; | |
325 | } u; | |
326 | u.i = ldl_raw(ptr); | |
327 | return u.f; | |
328 | } | |
329 | ||
330 | static inline void stfl_raw(void *ptr, float v) | |
331 | { | |
332 | union { | |
333 | float f; | |
334 | uint32_t i; | |
335 | } u; | |
336 | u.f = v; | |
337 | stl_raw(ptr, u.i); | |
338 | } | |
339 | ||
340 | static inline double ldfq_raw(void *ptr) | |
341 | { | |
342 | CPU_DoubleU u; | |
343 | u.l.upper = ldl_raw(ptr); | |
344 | u.l.lower = ldl_raw(ptr + 4); | |
345 | return u.d; | |
346 | } | |
347 | ||
348 | static inline void stfq_raw(void *ptr, double v) | |
349 | { | |
350 | CPU_DoubleU u; | |
351 | u.d = v; | |
352 | stl_raw(ptr, u.l.upper); | |
353 | stl_raw(ptr + 4, u.l.lower); | |
93ac68bc FB |
354 | } |
355 | ||
5a9fdfec FB |
356 | #else |
357 | ||
61382a50 | 358 | static inline int lduw_raw(void *ptr) |
5a9fdfec FB |
359 | { |
360 | return *(uint16_t *)ptr; | |
361 | } | |
362 | ||
61382a50 | 363 | static inline int ldsw_raw(void *ptr) |
5a9fdfec FB |
364 | { |
365 | return *(int16_t *)ptr; | |
366 | } | |
367 | ||
61382a50 | 368 | static inline int ldl_raw(void *ptr) |
5a9fdfec FB |
369 | { |
370 | return *(uint32_t *)ptr; | |
371 | } | |
372 | ||
61382a50 | 373 | static inline uint64_t ldq_raw(void *ptr) |
5a9fdfec FB |
374 | { |
375 | return *(uint64_t *)ptr; | |
376 | } | |
377 | ||
61382a50 | 378 | static inline void stw_raw(void *ptr, int v) |
5a9fdfec FB |
379 | { |
380 | *(uint16_t *)ptr = v; | |
381 | } | |
382 | ||
61382a50 | 383 | static inline void stl_raw(void *ptr, int v) |
5a9fdfec FB |
384 | { |
385 | *(uint32_t *)ptr = v; | |
386 | } | |
387 | ||
61382a50 | 388 | static inline void stq_raw(void *ptr, uint64_t v) |
5a9fdfec FB |
389 | { |
390 | *(uint64_t *)ptr = v; | |
391 | } | |
392 | ||
393 | /* float access */ | |
394 | ||
61382a50 | 395 | static inline float ldfl_raw(void *ptr) |
5a9fdfec FB |
396 | { |
397 | return *(float *)ptr; | |
398 | } | |
399 | ||
61382a50 | 400 | static inline double ldfq_raw(void *ptr) |
5a9fdfec FB |
401 | { |
402 | return *(double *)ptr; | |
403 | } | |
404 | ||
61382a50 | 405 | static inline void stfl_raw(void *ptr, float v) |
5a9fdfec FB |
406 | { |
407 | *(float *)ptr = v; | |
408 | } | |
409 | ||
61382a50 | 410 | static inline void stfq_raw(void *ptr, double v) |
5a9fdfec FB |
411 | { |
412 | *(double *)ptr = v; | |
413 | } | |
414 | #endif | |
415 | ||
61382a50 FB |
416 | /* MMU memory access macros */ |
417 | ||
418 | #if defined(CONFIG_USER_ONLY) | |
419 | ||
420 | /* if user mode, no other memory access functions */ | |
421 | #define ldub(p) ldub_raw(p) | |
422 | #define ldsb(p) ldsb_raw(p) | |
423 | #define lduw(p) lduw_raw(p) | |
424 | #define ldsw(p) ldsw_raw(p) | |
425 | #define ldl(p) ldl_raw(p) | |
426 | #define ldq(p) ldq_raw(p) | |
427 | #define ldfl(p) ldfl_raw(p) | |
428 | #define ldfq(p) ldfq_raw(p) | |
429 | #define stb(p, v) stb_raw(p, v) | |
430 | #define stw(p, v) stw_raw(p, v) | |
431 | #define stl(p, v) stl_raw(p, v) | |
432 | #define stq(p, v) stq_raw(p, v) | |
433 | #define stfl(p, v) stfl_raw(p, v) | |
434 | #define stfq(p, v) stfq_raw(p, v) | |
435 | ||
436 | #define ldub_code(p) ldub_raw(p) | |
437 | #define ldsb_code(p) ldsb_raw(p) | |
438 | #define lduw_code(p) lduw_raw(p) | |
439 | #define ldsw_code(p) ldsw_raw(p) | |
440 | #define ldl_code(p) ldl_raw(p) | |
441 | ||
442 | #define ldub_kernel(p) ldub_raw(p) | |
443 | #define ldsb_kernel(p) ldsb_raw(p) | |
444 | #define lduw_kernel(p) lduw_raw(p) | |
445 | #define ldsw_kernel(p) ldsw_raw(p) | |
446 | #define ldl_kernel(p) ldl_raw(p) | |
0ac4bd56 FB |
447 | #define ldfl_kernel(p) ldfl_raw(p) |
448 | #define ldfq_kernel(p) ldfq_raw(p) | |
61382a50 FB |
449 | #define stb_kernel(p, v) stb_raw(p, v) |
450 | #define stw_kernel(p, v) stw_raw(p, v) | |
451 | #define stl_kernel(p, v) stl_raw(p, v) | |
452 | #define stq_kernel(p, v) stq_raw(p, v) | |
0ac4bd56 FB |
453 | #define stfl_kernel(p, v) stfl_raw(p, v) |
454 | #define stfq_kernel(p, vt) stfq_raw(p, v) | |
61382a50 FB |
455 | |
456 | #endif /* defined(CONFIG_USER_ONLY) */ | |
457 | ||
5a9fdfec FB |
458 | /* page related stuff */ |
459 | ||
460 | #define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS) | |
461 | #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1) | |
462 | #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK) | |
463 | ||
464 | extern unsigned long real_host_page_size; | |
465 | extern unsigned long host_page_bits; | |
466 | extern unsigned long host_page_size; | |
467 | extern unsigned long host_page_mask; | |
468 | ||
469 | #define HOST_PAGE_ALIGN(addr) (((addr) + host_page_size - 1) & host_page_mask) | |
470 | ||
471 | /* same as PROT_xxx */ | |
472 | #define PAGE_READ 0x0001 | |
473 | #define PAGE_WRITE 0x0002 | |
474 | #define PAGE_EXEC 0x0004 | |
475 | #define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC) | |
476 | #define PAGE_VALID 0x0008 | |
477 | /* original state of the write flag (used when tracking self-modifying | |
478 | code */ | |
479 | #define PAGE_WRITE_ORG 0x0010 | |
480 | ||
481 | void page_dump(FILE *f); | |
482 | int page_get_flags(unsigned long address); | |
483 | void page_set_flags(unsigned long start, unsigned long end, int flags); | |
484 | void page_unprotect_range(uint8_t *data, unsigned long data_size); | |
485 | ||
486 | #define SINGLE_CPU_DEFINES | |
487 | #ifdef SINGLE_CPU_DEFINES | |
488 | ||
489 | #if defined(TARGET_I386) | |
490 | ||
491 | #define CPUState CPUX86State | |
492 | #define cpu_init cpu_x86_init | |
493 | #define cpu_exec cpu_x86_exec | |
494 | #define cpu_gen_code cpu_x86_gen_code | |
495 | #define cpu_interrupt cpu_x86_interrupt | |
496 | #define cpu_signal_handler cpu_x86_signal_handler | |
09683d35 | 497 | #define cpu_dump_state cpu_x86_dump_state |
5a9fdfec FB |
498 | |
499 | #elif defined(TARGET_ARM) | |
500 | ||
501 | #define CPUState CPUARMState | |
502 | #define cpu_init cpu_arm_init | |
503 | #define cpu_exec cpu_arm_exec | |
504 | #define cpu_gen_code cpu_arm_gen_code | |
505 | #define cpu_interrupt cpu_arm_interrupt | |
506 | #define cpu_signal_handler cpu_arm_signal_handler | |
09683d35 | 507 | #define cpu_dump_state cpu_arm_dump_state |
5a9fdfec | 508 | |
93ac68bc FB |
509 | #elif defined(TARGET_SPARC) |
510 | ||
511 | #define CPUState CPUSPARCState | |
512 | #define cpu_init cpu_sparc_init | |
513 | #define cpu_exec cpu_sparc_exec | |
514 | #define cpu_gen_code cpu_sparc_gen_code | |
515 | #define cpu_interrupt cpu_sparc_interrupt | |
516 | #define cpu_signal_handler cpu_sparc_signal_handler | |
09683d35 | 517 | #define cpu_dump_state cpu_sparc_dump_state |
93ac68bc | 518 | |
67867308 FB |
519 | #elif defined(TARGET_PPC) |
520 | ||
521 | #define CPUState CPUPPCState | |
522 | #define cpu_init cpu_ppc_init | |
523 | #define cpu_exec cpu_ppc_exec | |
524 | #define cpu_gen_code cpu_ppc_gen_code | |
525 | #define cpu_interrupt cpu_ppc_interrupt | |
526 | #define cpu_signal_handler cpu_ppc_signal_handler | |
09683d35 | 527 | #define cpu_dump_state cpu_ppc_dump_state |
67867308 | 528 | |
5a9fdfec FB |
529 | #else |
530 | ||
531 | #error unsupported target CPU | |
532 | ||
533 | #endif | |
534 | ||
972ddf78 FB |
535 | #endif /* SINGLE_CPU_DEFINES */ |
536 | ||
3b0dca51 FB |
537 | #define DEFAULT_GDBSTUB_PORT 1234 |
538 | ||
972ddf78 | 539 | void cpu_abort(CPUState *env, const char *fmt, ...); |
e2f22898 | 540 | extern CPUState *cpu_single_env; |
9acbed06 | 541 | extern int code_copy_enabled; |
5a9fdfec | 542 | |
9acbed06 FB |
543 | #define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */ |
544 | #define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */ | |
545 | #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */ | |
4690764b | 546 | void cpu_interrupt(CPUState *s, int mask); |
68a79315 | 547 | |
4c3a88a2 FB |
548 | int cpu_breakpoint_insert(CPUState *env, uint32_t pc); |
549 | int cpu_breakpoint_remove(CPUState *env, uint32_t pc); | |
c33a346e | 550 | void cpu_single_step(CPUState *env, int enabled); |
4c3a88a2 | 551 | |
13eb76e0 FB |
552 | /* Return the physical page corresponding to a virtual one. Use it |
553 | only for debugging because no protection checks are done. Return -1 | |
554 | if no page found. */ | |
555 | target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr); | |
556 | ||
34865134 FB |
557 | #define CPU_LOG_ALL 1 |
558 | void cpu_set_log(int log_flags); | |
559 | void cpu_set_log_filename(const char *filename); | |
560 | ||
09683d35 FB |
561 | /* IO ports API */ |
562 | ||
563 | /* NOTE: as these functions may be even used when there is an isa | |
564 | brige on non x86 targets, we always defined them */ | |
565 | #ifndef NO_CPU_IO_DEFS | |
566 | void cpu_outb(CPUState *env, int addr, int val); | |
567 | void cpu_outw(CPUState *env, int addr, int val); | |
568 | void cpu_outl(CPUState *env, int addr, int val); | |
569 | int cpu_inb(CPUState *env, int addr); | |
570 | int cpu_inw(CPUState *env, int addr); | |
571 | int cpu_inl(CPUState *env, int addr); | |
572 | #endif | |
573 | ||
33417e70 FB |
574 | /* memory API */ |
575 | ||
edf75d59 FB |
576 | extern int phys_ram_size; |
577 | extern int phys_ram_fd; | |
578 | extern uint8_t *phys_ram_base; | |
1ccde1cb | 579 | extern uint8_t *phys_ram_dirty; |
edf75d59 FB |
580 | |
581 | /* physical memory access */ | |
582 | #define IO_MEM_NB_ENTRIES 256 | |
583 | #define TLB_INVALID_MASK (1 << 3) | |
584 | #define IO_MEM_SHIFT 4 | |
585 | ||
586 | #define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */ | |
587 | #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ | |
588 | #define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT) | |
1ccde1cb FB |
589 | #define IO_MEM_CODE (3 << IO_MEM_SHIFT) /* used internally, never use directly */ |
590 | #define IO_MEM_NOTDIRTY (4 << IO_MEM_SHIFT) /* used internally, never use directly */ | |
edf75d59 | 591 | |
1ccde1cb FB |
592 | /* NOTE: vaddr is only used internally. Never use it except if you know what you do */ |
593 | typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value, uint32_t vaddr); | |
33417e70 FB |
594 | typedef uint32_t CPUReadMemoryFunc(uint32_t addr); |
595 | ||
596 | void cpu_register_physical_memory(unsigned long start_addr, unsigned long size, | |
597 | long phys_offset); | |
598 | int cpu_register_io_memory(int io_index, | |
599 | CPUReadMemoryFunc **mem_read, | |
600 | CPUWriteMemoryFunc **mem_write); | |
601 | ||
13eb76e0 FB |
602 | void cpu_physical_memory_rw(CPUState *env, uint8_t *buf, target_ulong addr, |
603 | int len, int is_write); | |
604 | int cpu_memory_rw_debug(CPUState *env, | |
605 | uint8_t *buf, target_ulong addr, int len, int is_write); | |
606 | ||
1ccde1cb FB |
607 | /* read dirty bit (return 0 or 1) */ |
608 | static inline int cpu_physical_memory_is_dirty(target_ulong addr) | |
609 | { | |
610 | return phys_ram_dirty[addr >> TARGET_PAGE_BITS]; | |
611 | } | |
612 | ||
613 | static inline void cpu_physical_memory_set_dirty(target_ulong addr) | |
614 | { | |
615 | phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 1; | |
616 | } | |
617 | ||
618 | void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end); | |
619 | ||
3b0dca51 FB |
620 | /* gdb stub API */ |
621 | extern int gdbstub_fd; | |
622 | CPUState *cpu_gdbstub_get_env(void *opaque); | |
4c3a88a2 | 623 | int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port); |
3b0dca51 | 624 | |
5a9fdfec | 625 | #endif /* CPU_ALL_H */ |