]> git.proxmox.com Git - qemu.git/blame - cpu-all.h
aalib support with SDL
[qemu.git] / cpu-all.h
CommitLineData
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 ! */
41typedef 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
59static inline int ldub_raw(void *ptr)
5a9fdfec
FB
60{
61 return *(uint8_t *)ptr;
62}
63
61382a50 64static inline int ldsb_raw(void *ptr)
5a9fdfec
FB
65{
66 return *(int8_t *)ptr;
67}
68
61382a50 69static inline void stb_raw(void *ptr, int v)
5a9fdfec
FB
70{
71 *(uint8_t *)ptr = v;
72}
73
74/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
75 kernel handles unaligned load/stores may give better results, but
76 it is a system wide setting : bad */
0ac4bd56 77#if !defined(TARGET_WORDS_BIGENDIAN) && (defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
5a9fdfec
FB
78
79/* conservative code for little endian unaligned accesses */
61382a50 80static inline int lduw_raw(void *ptr)
5a9fdfec
FB
81{
82#ifdef __powerpc__
83 int val;
84 __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
85 return val;
86#else
87 uint8_t *p = ptr;
88 return p[0] | (p[1] << 8);
89#endif
90}
91
61382a50 92static inline int ldsw_raw(void *ptr)
5a9fdfec
FB
93{
94#ifdef __powerpc__
95 int val;
96 __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
97 return (int16_t)val;
98#else
99 uint8_t *p = ptr;
100 return (int16_t)(p[0] | (p[1] << 8));
101#endif
102}
103
61382a50 104static inline int ldl_raw(void *ptr)
5a9fdfec
FB
105{
106#ifdef __powerpc__
107 int val;
108 __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
109 return val;
110#else
111 uint8_t *p = ptr;
112 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
113#endif
114}
115
61382a50 116static inline uint64_t ldq_raw(void *ptr)
5a9fdfec
FB
117{
118 uint8_t *p = ptr;
119 uint32_t v1, v2;
61382a50
FB
120 v1 = ldl_raw(p);
121 v2 = ldl_raw(p + 4);
5a9fdfec
FB
122 return v1 | ((uint64_t)v2 << 32);
123}
124
61382a50 125static inline void stw_raw(void *ptr, int v)
5a9fdfec
FB
126{
127#ifdef __powerpc__
128 __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
129#else
130 uint8_t *p = ptr;
131 p[0] = v;
132 p[1] = v >> 8;
133#endif
134}
135
61382a50 136static inline void stl_raw(void *ptr, int v)
5a9fdfec
FB
137{
138#ifdef __powerpc__
139 __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
140#else
141 uint8_t *p = ptr;
142 p[0] = v;
143 p[1] = v >> 8;
144 p[2] = v >> 16;
145 p[3] = v >> 24;
146#endif
147}
148
61382a50 149static inline void stq_raw(void *ptr, uint64_t v)
5a9fdfec
FB
150{
151 uint8_t *p = ptr;
61382a50
FB
152 stl_raw(p, (uint32_t)v);
153 stl_raw(p + 4, v >> 32);
5a9fdfec
FB
154}
155
156/* float access */
157
61382a50 158static inline float ldfl_raw(void *ptr)
5a9fdfec
FB
159{
160 union {
161 float f;
162 uint32_t i;
163 } u;
61382a50 164 u.i = ldl_raw(ptr);
5a9fdfec
FB
165 return u.f;
166}
167
61382a50 168static inline void stfl_raw(void *ptr, float v)
5a9fdfec
FB
169{
170 union {
171 float f;
172 uint32_t i;
173 } u;
174 u.f = v;
61382a50 175 stl_raw(ptr, u.i);
5a9fdfec
FB
176}
177
61382a50 178static inline double ldfq_raw(void *ptr)
5a9fdfec 179{
0ac4bd56
FB
180 CPU_DoubleU u;
181 u.l.lower = ldl_raw(ptr);
182 u.l.upper = ldl_raw(ptr + 4);
5a9fdfec
FB
183 return u.d;
184}
185
61382a50 186static inline void stfq_raw(void *ptr, double v)
5a9fdfec 187{
0ac4bd56 188 CPU_DoubleU u;
5a9fdfec 189 u.d = v;
0ac4bd56
FB
190 stl_raw(ptr, u.l.lower);
191 stl_raw(ptr + 4, u.l.upper);
5a9fdfec
FB
192}
193
0ac4bd56 194#elif defined(TARGET_WORDS_BIGENDIAN) && (!defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
93ac68bc 195
61382a50 196static inline int lduw_raw(void *ptr)
93ac68bc
FB
197{
198 uint8_t *b = (uint8_t *) ptr;
199 return (b[0]<<8|b[1]);
200}
201
61382a50 202static inline int ldsw_raw(void *ptr)
93ac68bc
FB
203{
204 int8_t *b = (int8_t *) ptr;
205 return (b[0]<<8|b[1]);
206}
207
61382a50 208static inline int ldl_raw(void *ptr)
93ac68bc
FB
209{
210 uint8_t *b = (uint8_t *) ptr;
211 return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]);
212}
213
61382a50 214static inline uint64_t ldq_raw(void *ptr)
93ac68bc
FB
215{
216 uint32_t a,b;
9f05cc34
FB
217 a = ldl_raw(ptr);
218 b = ldl_raw(ptr+4);
93ac68bc
FB
219 return (((uint64_t)a<<32)|b);
220}
221
61382a50 222static inline void stw_raw(void *ptr, int v)
93ac68bc
FB
223{
224 uint8_t *d = (uint8_t *) ptr;
225 d[0] = v >> 8;
226 d[1] = v;
227}
228
61382a50 229static inline void stl_raw(void *ptr, int v)
93ac68bc
FB
230{
231 uint8_t *d = (uint8_t *) ptr;
232 d[0] = v >> 24;
233 d[1] = v >> 16;
234 d[2] = v >> 8;
235 d[3] = v;
236}
237
61382a50 238static inline void stq_raw(void *ptr, uint64_t v)
93ac68bc 239{
0ac4bd56
FB
240 stl_raw(ptr, v >> 32);
241 stl_raw(ptr + 4, v);
242}
243
244/* float access */
245
246static inline float ldfl_raw(void *ptr)
247{
248 union {
249 float f;
250 uint32_t i;
251 } u;
252 u.i = ldl_raw(ptr);
253 return u.f;
254}
255
256static inline void stfl_raw(void *ptr, float v)
257{
258 union {
259 float f;
260 uint32_t i;
261 } u;
262 u.f = v;
263 stl_raw(ptr, u.i);
264}
265
266static inline double ldfq_raw(void *ptr)
267{
268 CPU_DoubleU u;
269 u.l.upper = ldl_raw(ptr);
270 u.l.lower = ldl_raw(ptr + 4);
271 return u.d;
272}
273
274static inline void stfq_raw(void *ptr, double v)
275{
276 CPU_DoubleU u;
277 u.d = v;
278 stl_raw(ptr, u.l.upper);
279 stl_raw(ptr + 4, u.l.lower);
93ac68bc
FB
280}
281
5a9fdfec
FB
282#else
283
61382a50 284static inline int lduw_raw(void *ptr)
5a9fdfec
FB
285{
286 return *(uint16_t *)ptr;
287}
288
61382a50 289static inline int ldsw_raw(void *ptr)
5a9fdfec
FB
290{
291 return *(int16_t *)ptr;
292}
293
61382a50 294static inline int ldl_raw(void *ptr)
5a9fdfec
FB
295{
296 return *(uint32_t *)ptr;
297}
298
61382a50 299static inline uint64_t ldq_raw(void *ptr)
5a9fdfec
FB
300{
301 return *(uint64_t *)ptr;
302}
303
61382a50 304static inline void stw_raw(void *ptr, int v)
5a9fdfec
FB
305{
306 *(uint16_t *)ptr = v;
307}
308
61382a50 309static inline void stl_raw(void *ptr, int v)
5a9fdfec
FB
310{
311 *(uint32_t *)ptr = v;
312}
313
61382a50 314static inline void stq_raw(void *ptr, uint64_t v)
5a9fdfec
FB
315{
316 *(uint64_t *)ptr = v;
317}
318
319/* float access */
320
61382a50 321static inline float ldfl_raw(void *ptr)
5a9fdfec
FB
322{
323 return *(float *)ptr;
324}
325
61382a50 326static inline double ldfq_raw(void *ptr)
5a9fdfec
FB
327{
328 return *(double *)ptr;
329}
330
61382a50 331static inline void stfl_raw(void *ptr, float v)
5a9fdfec
FB
332{
333 *(float *)ptr = v;
334}
335
61382a50 336static inline void stfq_raw(void *ptr, double v)
5a9fdfec
FB
337{
338 *(double *)ptr = v;
339}
340#endif
341
61382a50
FB
342/* MMU memory access macros */
343
344#if defined(CONFIG_USER_ONLY)
345
346/* if user mode, no other memory access functions */
347#define ldub(p) ldub_raw(p)
348#define ldsb(p) ldsb_raw(p)
349#define lduw(p) lduw_raw(p)
350#define ldsw(p) ldsw_raw(p)
351#define ldl(p) ldl_raw(p)
352#define ldq(p) ldq_raw(p)
353#define ldfl(p) ldfl_raw(p)
354#define ldfq(p) ldfq_raw(p)
355#define stb(p, v) stb_raw(p, v)
356#define stw(p, v) stw_raw(p, v)
357#define stl(p, v) stl_raw(p, v)
358#define stq(p, v) stq_raw(p, v)
359#define stfl(p, v) stfl_raw(p, v)
360#define stfq(p, v) stfq_raw(p, v)
361
362#define ldub_code(p) ldub_raw(p)
363#define ldsb_code(p) ldsb_raw(p)
364#define lduw_code(p) lduw_raw(p)
365#define ldsw_code(p) ldsw_raw(p)
366#define ldl_code(p) ldl_raw(p)
367
368#define ldub_kernel(p) ldub_raw(p)
369#define ldsb_kernel(p) ldsb_raw(p)
370#define lduw_kernel(p) lduw_raw(p)
371#define ldsw_kernel(p) ldsw_raw(p)
372#define ldl_kernel(p) ldl_raw(p)
0ac4bd56
FB
373#define ldfl_kernel(p) ldfl_raw(p)
374#define ldfq_kernel(p) ldfq_raw(p)
61382a50
FB
375#define stb_kernel(p, v) stb_raw(p, v)
376#define stw_kernel(p, v) stw_raw(p, v)
377#define stl_kernel(p, v) stl_raw(p, v)
378#define stq_kernel(p, v) stq_raw(p, v)
0ac4bd56
FB
379#define stfl_kernel(p, v) stfl_raw(p, v)
380#define stfq_kernel(p, vt) stfq_raw(p, v)
61382a50
FB
381
382#endif /* defined(CONFIG_USER_ONLY) */
383
5a9fdfec
FB
384/* page related stuff */
385
386#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
387#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
388#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
389
390extern unsigned long real_host_page_size;
391extern unsigned long host_page_bits;
392extern unsigned long host_page_size;
393extern unsigned long host_page_mask;
394
395#define HOST_PAGE_ALIGN(addr) (((addr) + host_page_size - 1) & host_page_mask)
396
397/* same as PROT_xxx */
398#define PAGE_READ 0x0001
399#define PAGE_WRITE 0x0002
400#define PAGE_EXEC 0x0004
401#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
402#define PAGE_VALID 0x0008
403/* original state of the write flag (used when tracking self-modifying
404 code */
405#define PAGE_WRITE_ORG 0x0010
406
407void page_dump(FILE *f);
408int page_get_flags(unsigned long address);
409void page_set_flags(unsigned long start, unsigned long end, int flags);
410void page_unprotect_range(uint8_t *data, unsigned long data_size);
411
412#define SINGLE_CPU_DEFINES
413#ifdef SINGLE_CPU_DEFINES
414
415#if defined(TARGET_I386)
416
417#define CPUState CPUX86State
418#define cpu_init cpu_x86_init
419#define cpu_exec cpu_x86_exec
420#define cpu_gen_code cpu_x86_gen_code
421#define cpu_interrupt cpu_x86_interrupt
422#define cpu_signal_handler cpu_x86_signal_handler
423
424#elif defined(TARGET_ARM)
425
426#define CPUState CPUARMState
427#define cpu_init cpu_arm_init
428#define cpu_exec cpu_arm_exec
429#define cpu_gen_code cpu_arm_gen_code
430#define cpu_interrupt cpu_arm_interrupt
431#define cpu_signal_handler cpu_arm_signal_handler
432
93ac68bc
FB
433#elif defined(TARGET_SPARC)
434
435#define CPUState CPUSPARCState
436#define cpu_init cpu_sparc_init
437#define cpu_exec cpu_sparc_exec
438#define cpu_gen_code cpu_sparc_gen_code
439#define cpu_interrupt cpu_sparc_interrupt
440#define cpu_signal_handler cpu_sparc_signal_handler
441
67867308
FB
442#elif defined(TARGET_PPC)
443
444#define CPUState CPUPPCState
445#define cpu_init cpu_ppc_init
446#define cpu_exec cpu_ppc_exec
447#define cpu_gen_code cpu_ppc_gen_code
448#define cpu_interrupt cpu_ppc_interrupt
449#define cpu_signal_handler cpu_ppc_signal_handler
450
5a9fdfec
FB
451#else
452
453#error unsupported target CPU
454
455#endif
456
972ddf78
FB
457#endif /* SINGLE_CPU_DEFINES */
458
3b0dca51
FB
459#define DEFAULT_GDBSTUB_PORT 1234
460
972ddf78 461void cpu_abort(CPUState *env, const char *fmt, ...);
e2f22898 462extern CPUState *cpu_single_env;
5a9fdfec 463
68a79315
FB
464#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
465#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
4690764b 466void cpu_interrupt(CPUState *s, int mask);
68a79315 467
4c3a88a2
FB
468int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
469int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
c33a346e 470void cpu_single_step(CPUState *env, int enabled);
4c3a88a2 471
34865134
FB
472#define CPU_LOG_ALL 1
473void cpu_set_log(int log_flags);
474void cpu_set_log_filename(const char *filename);
475
33417e70
FB
476/* memory API */
477
edf75d59
FB
478extern int phys_ram_size;
479extern int phys_ram_fd;
480extern uint8_t *phys_ram_base;
481
482/* physical memory access */
483#define IO_MEM_NB_ENTRIES 256
484#define TLB_INVALID_MASK (1 << 3)
485#define IO_MEM_SHIFT 4
486
487#define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */
488#define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */
489#define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT)
490#define IO_MEM_CODE (3 << IO_MEM_SHIFT)
491
33417e70
FB
492typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
493typedef uint32_t CPUReadMemoryFunc(uint32_t addr);
494
495void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
496 long phys_offset);
497int cpu_register_io_memory(int io_index,
498 CPUReadMemoryFunc **mem_read,
499 CPUWriteMemoryFunc **mem_write);
500
3b0dca51
FB
501/* gdb stub API */
502extern int gdbstub_fd;
503CPUState *cpu_gdbstub_get_env(void *opaque);
4c3a88a2 504int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port);
3b0dca51 505
5a9fdfec 506#endif /* CPU_ALL_H */