]> git.proxmox.com Git - qemu.git/blame - cpu-all.h
fixed blr/bctr cases
[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
09683d35 423#define cpu_dump_state cpu_x86_dump_state
5a9fdfec
FB
424
425#elif defined(TARGET_ARM)
426
427#define CPUState CPUARMState
428#define cpu_init cpu_arm_init
429#define cpu_exec cpu_arm_exec
430#define cpu_gen_code cpu_arm_gen_code
431#define cpu_interrupt cpu_arm_interrupt
432#define cpu_signal_handler cpu_arm_signal_handler
09683d35 433#define cpu_dump_state cpu_arm_dump_state
5a9fdfec 434
93ac68bc
FB
435#elif defined(TARGET_SPARC)
436
437#define CPUState CPUSPARCState
438#define cpu_init cpu_sparc_init
439#define cpu_exec cpu_sparc_exec
440#define cpu_gen_code cpu_sparc_gen_code
441#define cpu_interrupt cpu_sparc_interrupt
442#define cpu_signal_handler cpu_sparc_signal_handler
09683d35 443#define cpu_dump_state cpu_sparc_dump_state
93ac68bc 444
67867308
FB
445#elif defined(TARGET_PPC)
446
447#define CPUState CPUPPCState
448#define cpu_init cpu_ppc_init
449#define cpu_exec cpu_ppc_exec
450#define cpu_gen_code cpu_ppc_gen_code
451#define cpu_interrupt cpu_ppc_interrupt
452#define cpu_signal_handler cpu_ppc_signal_handler
09683d35 453#define cpu_dump_state cpu_ppc_dump_state
67867308 454
5a9fdfec
FB
455#else
456
457#error unsupported target CPU
458
459#endif
460
972ddf78
FB
461#endif /* SINGLE_CPU_DEFINES */
462
3b0dca51
FB
463#define DEFAULT_GDBSTUB_PORT 1234
464
972ddf78 465void cpu_abort(CPUState *env, const char *fmt, ...);
e2f22898 466extern CPUState *cpu_single_env;
9acbed06 467extern int code_copy_enabled;
5a9fdfec 468
9acbed06
FB
469#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
470#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
471#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
4690764b 472void cpu_interrupt(CPUState *s, int mask);
68a79315 473
4c3a88a2
FB
474int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
475int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
c33a346e 476void cpu_single_step(CPUState *env, int enabled);
4c3a88a2 477
13eb76e0
FB
478/* Return the physical page corresponding to a virtual one. Use it
479 only for debugging because no protection checks are done. Return -1
480 if no page found. */
481target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
482
34865134
FB
483#define CPU_LOG_ALL 1
484void cpu_set_log(int log_flags);
485void cpu_set_log_filename(const char *filename);
486
09683d35
FB
487/* IO ports API */
488
489/* NOTE: as these functions may be even used when there is an isa
490 brige on non x86 targets, we always defined them */
491#ifndef NO_CPU_IO_DEFS
492void cpu_outb(CPUState *env, int addr, int val);
493void cpu_outw(CPUState *env, int addr, int val);
494void cpu_outl(CPUState *env, int addr, int val);
495int cpu_inb(CPUState *env, int addr);
496int cpu_inw(CPUState *env, int addr);
497int cpu_inl(CPUState *env, int addr);
498#endif
499
33417e70
FB
500/* memory API */
501
edf75d59
FB
502extern int phys_ram_size;
503extern int phys_ram_fd;
504extern uint8_t *phys_ram_base;
1ccde1cb 505extern uint8_t *phys_ram_dirty;
edf75d59
FB
506
507/* physical memory access */
508#define IO_MEM_NB_ENTRIES 256
509#define TLB_INVALID_MASK (1 << 3)
510#define IO_MEM_SHIFT 4
511
512#define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */
513#define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */
514#define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT)
1ccde1cb
FB
515#define IO_MEM_CODE (3 << IO_MEM_SHIFT) /* used internally, never use directly */
516#define IO_MEM_NOTDIRTY (4 << IO_MEM_SHIFT) /* used internally, never use directly */
edf75d59 517
1ccde1cb
FB
518/* NOTE: vaddr is only used internally. Never use it except if you know what you do */
519typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value, uint32_t vaddr);
33417e70
FB
520typedef uint32_t CPUReadMemoryFunc(uint32_t addr);
521
522void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
523 long phys_offset);
524int cpu_register_io_memory(int io_index,
525 CPUReadMemoryFunc **mem_read,
526 CPUWriteMemoryFunc **mem_write);
527
13eb76e0
FB
528void cpu_physical_memory_rw(CPUState *env, uint8_t *buf, target_ulong addr,
529 int len, int is_write);
530int cpu_memory_rw_debug(CPUState *env,
531 uint8_t *buf, target_ulong addr, int len, int is_write);
532
1ccde1cb
FB
533/* read dirty bit (return 0 or 1) */
534static inline int cpu_physical_memory_is_dirty(target_ulong addr)
535{
536 return phys_ram_dirty[addr >> TARGET_PAGE_BITS];
537}
538
539static inline void cpu_physical_memory_set_dirty(target_ulong addr)
540{
541 phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 1;
542}
543
544void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end);
545
3b0dca51
FB
546/* gdb stub API */
547extern int gdbstub_fd;
548CPUState *cpu_gdbstub_get_env(void *opaque);
4c3a88a2 549int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port);
3b0dca51 550
5a9fdfec 551#endif /* CPU_ALL_H */