blob: c7491a00cf70d7f6d48799e29bc299a9cdfff285 [file] [log] [blame]
bellard5a9fdfe2003-06-15 20:02:25 +00001/*
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
bellard61382a52003-10-27 21:22:23 +000023/* CPU memory access without any memory or io remapping */
24
25static inline int ldub_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +000026{
27 return *(uint8_t *)ptr;
28}
29
bellard61382a52003-10-27 21:22:23 +000030static inline int ldsb_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +000031{
32 return *(int8_t *)ptr;
33}
34
bellard61382a52003-10-27 21:22:23 +000035static inline void stb_raw(void *ptr, int v)
bellard5a9fdfe2003-06-15 20:02:25 +000036{
37 *(uint8_t *)ptr = v;
38}
39
40/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
41 kernel handles unaligned load/stores may give better results, but
42 it is a system wide setting : bad */
43#if defined(WORDS_BIGENDIAN) || defined(__arm__)
44
45/* conservative code for little endian unaligned accesses */
bellard61382a52003-10-27 21:22:23 +000046static inline int lduw_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +000047{
48#ifdef __powerpc__
49 int val;
50 __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
51 return val;
52#else
53 uint8_t *p = ptr;
54 return p[0] | (p[1] << 8);
55#endif
56}
57
bellard61382a52003-10-27 21:22:23 +000058static inline int ldsw_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +000059{
60#ifdef __powerpc__
61 int val;
62 __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
63 return (int16_t)val;
64#else
65 uint8_t *p = ptr;
66 return (int16_t)(p[0] | (p[1] << 8));
67#endif
68}
69
bellard61382a52003-10-27 21:22:23 +000070static inline int ldl_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +000071{
72#ifdef __powerpc__
73 int val;
74 __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
75 return val;
76#else
77 uint8_t *p = ptr;
78 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
79#endif
80}
81
bellard61382a52003-10-27 21:22:23 +000082static inline uint64_t ldq_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +000083{
84 uint8_t *p = ptr;
85 uint32_t v1, v2;
bellard61382a52003-10-27 21:22:23 +000086 v1 = ldl_raw(p);
87 v2 = ldl_raw(p + 4);
bellard5a9fdfe2003-06-15 20:02:25 +000088 return v1 | ((uint64_t)v2 << 32);
89}
90
bellard61382a52003-10-27 21:22:23 +000091static inline void stw_raw(void *ptr, int v)
bellard5a9fdfe2003-06-15 20:02:25 +000092{
93#ifdef __powerpc__
94 __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
95#else
96 uint8_t *p = ptr;
97 p[0] = v;
98 p[1] = v >> 8;
99#endif
100}
101
bellard61382a52003-10-27 21:22:23 +0000102static inline void stl_raw(void *ptr, int v)
bellard5a9fdfe2003-06-15 20:02:25 +0000103{
104#ifdef __powerpc__
105 __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
106#else
107 uint8_t *p = ptr;
108 p[0] = v;
109 p[1] = v >> 8;
110 p[2] = v >> 16;
111 p[3] = v >> 24;
112#endif
113}
114
bellard61382a52003-10-27 21:22:23 +0000115static inline void stq_raw(void *ptr, uint64_t v)
bellard5a9fdfe2003-06-15 20:02:25 +0000116{
117 uint8_t *p = ptr;
bellard61382a52003-10-27 21:22:23 +0000118 stl_raw(p, (uint32_t)v);
119 stl_raw(p + 4, v >> 32);
bellard5a9fdfe2003-06-15 20:02:25 +0000120}
121
122/* float access */
123
bellard61382a52003-10-27 21:22:23 +0000124static inline float ldfl_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +0000125{
126 union {
127 float f;
128 uint32_t i;
129 } u;
bellard61382a52003-10-27 21:22:23 +0000130 u.i = ldl_raw(ptr);
bellard5a9fdfe2003-06-15 20:02:25 +0000131 return u.f;
132}
133
bellard61382a52003-10-27 21:22:23 +0000134static inline void stfl_raw(void *ptr, float v)
bellard5a9fdfe2003-06-15 20:02:25 +0000135{
136 union {
137 float f;
138 uint32_t i;
139 } u;
140 u.f = v;
bellard61382a52003-10-27 21:22:23 +0000141 stl_raw(ptr, u.i);
bellard5a9fdfe2003-06-15 20:02:25 +0000142}
143
bellard33417e72003-08-10 21:47:01 +0000144
bellard5a9fdfe2003-06-15 20:02:25 +0000145#if defined(__arm__) && !defined(WORDS_BIGENDIAN)
146
147/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
bellard61382a52003-10-27 21:22:23 +0000148static inline double ldfq_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +0000149{
150 union {
151 double d;
152 uint32_t tab[2];
153 } u;
bellard61382a52003-10-27 21:22:23 +0000154 u.tab[1] = ldl_raw(ptr);
155 u.tab[0] = ldl_raw(ptr + 4);
bellard5a9fdfe2003-06-15 20:02:25 +0000156 return u.d;
157}
158
bellard61382a52003-10-27 21:22:23 +0000159static inline void stfq_raw(void *ptr, double v)
bellard5a9fdfe2003-06-15 20:02:25 +0000160{
161 union {
162 double d;
163 uint32_t tab[2];
164 } u;
165 u.d = v;
bellard61382a52003-10-27 21:22:23 +0000166 stl_raw(ptr, u.tab[1]);
167 stl_raw(ptr + 4, u.tab[0]);
bellard5a9fdfe2003-06-15 20:02:25 +0000168}
169
170#else
bellard61382a52003-10-27 21:22:23 +0000171static inline double ldfq_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +0000172{
173 union {
174 double d;
175 uint64_t i;
176 } u;
bellard61382a52003-10-27 21:22:23 +0000177 u.i = ldq_raw(ptr);
bellard5a9fdfe2003-06-15 20:02:25 +0000178 return u.d;
179}
180
bellard61382a52003-10-27 21:22:23 +0000181static inline void stfq_raw(void *ptr, double v)
bellard5a9fdfe2003-06-15 20:02:25 +0000182{
183 union {
184 double d;
185 uint64_t i;
186 } u;
187 u.d = v;
bellard61382a52003-10-27 21:22:23 +0000188 stq_raw(ptr, u.i);
bellard5a9fdfe2003-06-15 20:02:25 +0000189}
190#endif
191
bellard93ac68b2003-09-30 20:57:29 +0000192#elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)
193
bellard61382a52003-10-27 21:22:23 +0000194static inline int lduw_raw(void *ptr)
bellard93ac68b2003-09-30 20:57:29 +0000195{
196 uint8_t *b = (uint8_t *) ptr;
197 return (b[0]<<8|b[1]);
198}
199
bellard61382a52003-10-27 21:22:23 +0000200static inline int ldsw_raw(void *ptr)
bellard93ac68b2003-09-30 20:57:29 +0000201{
202 int8_t *b = (int8_t *) ptr;
203 return (b[0]<<8|b[1]);
204}
205
bellard61382a52003-10-27 21:22:23 +0000206static inline int ldl_raw(void *ptr)
bellard93ac68b2003-09-30 20:57:29 +0000207{
208 uint8_t *b = (uint8_t *) ptr;
209 return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]);
210}
211
bellard61382a52003-10-27 21:22:23 +0000212static inline uint64_t ldq_raw(void *ptr)
bellard93ac68b2003-09-30 20:57:29 +0000213{
214 uint32_t a,b;
bellard9f05cc32003-10-28 00:09:28 +0000215 a = ldl_raw(ptr);
216 b = ldl_raw(ptr+4);
bellard93ac68b2003-09-30 20:57:29 +0000217 return (((uint64_t)a<<32)|b);
218}
219
bellard61382a52003-10-27 21:22:23 +0000220static inline void stw_raw(void *ptr, int v)
bellard93ac68b2003-09-30 20:57:29 +0000221{
222 uint8_t *d = (uint8_t *) ptr;
223 d[0] = v >> 8;
224 d[1] = v;
225}
226
bellard61382a52003-10-27 21:22:23 +0000227static inline void stl_raw(void *ptr, int v)
bellard93ac68b2003-09-30 20:57:29 +0000228{
229 uint8_t *d = (uint8_t *) ptr;
230 d[0] = v >> 24;
231 d[1] = v >> 16;
232 d[2] = v >> 8;
233 d[3] = v;
234}
235
bellard61382a52003-10-27 21:22:23 +0000236static inline void stq_raw(void *ptr, uint64_t v)
bellard93ac68b2003-09-30 20:57:29 +0000237{
bellard9f05cc32003-10-28 00:09:28 +0000238 stl_raw(ptr, v);
239 stl_raw(ptr+4, v >> 32);
bellard93ac68b2003-09-30 20:57:29 +0000240}
241
bellard5a9fdfe2003-06-15 20:02:25 +0000242#else
243
bellard61382a52003-10-27 21:22:23 +0000244static inline int lduw_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +0000245{
246 return *(uint16_t *)ptr;
247}
248
bellard61382a52003-10-27 21:22:23 +0000249static inline int ldsw_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +0000250{
251 return *(int16_t *)ptr;
252}
253
bellard61382a52003-10-27 21:22:23 +0000254static inline int ldl_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +0000255{
256 return *(uint32_t *)ptr;
257}
258
bellard61382a52003-10-27 21:22:23 +0000259static inline uint64_t ldq_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +0000260{
261 return *(uint64_t *)ptr;
262}
263
bellard61382a52003-10-27 21:22:23 +0000264static inline void stw_raw(void *ptr, int v)
bellard5a9fdfe2003-06-15 20:02:25 +0000265{
266 *(uint16_t *)ptr = v;
267}
268
bellard61382a52003-10-27 21:22:23 +0000269static inline void stl_raw(void *ptr, int v)
bellard5a9fdfe2003-06-15 20:02:25 +0000270{
271 *(uint32_t *)ptr = v;
272}
273
bellard61382a52003-10-27 21:22:23 +0000274static inline void stq_raw(void *ptr, uint64_t v)
bellard5a9fdfe2003-06-15 20:02:25 +0000275{
276 *(uint64_t *)ptr = v;
277}
278
279/* float access */
280
bellard61382a52003-10-27 21:22:23 +0000281static inline float ldfl_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +0000282{
283 return *(float *)ptr;
284}
285
bellard61382a52003-10-27 21:22:23 +0000286static inline double ldfq_raw(void *ptr)
bellard5a9fdfe2003-06-15 20:02:25 +0000287{
288 return *(double *)ptr;
289}
290
bellard61382a52003-10-27 21:22:23 +0000291static inline void stfl_raw(void *ptr, float v)
bellard5a9fdfe2003-06-15 20:02:25 +0000292{
293 *(float *)ptr = v;
294}
295
bellard61382a52003-10-27 21:22:23 +0000296static inline void stfq_raw(void *ptr, double v)
bellard5a9fdfe2003-06-15 20:02:25 +0000297{
298 *(double *)ptr = v;
299}
300#endif
301
bellard61382a52003-10-27 21:22:23 +0000302/* 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
bellard5a9fdfe2003-06-15 20:02:25 +0000340/* page related stuff */
341
342#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
343#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
344#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
345
346extern unsigned long real_host_page_size;
347extern unsigned long host_page_bits;
348extern unsigned long host_page_size;
349extern unsigned long host_page_mask;
350
351#define HOST_PAGE_ALIGN(addr) (((addr) + host_page_size - 1) & host_page_mask)
352
353/* same as PROT_xxx */
354#define PAGE_READ 0x0001
355#define PAGE_WRITE 0x0002
356#define PAGE_EXEC 0x0004
357#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
358#define PAGE_VALID 0x0008
359/* original state of the write flag (used when tracking self-modifying
360 code */
361#define PAGE_WRITE_ORG 0x0010
362
363void page_dump(FILE *f);
364int page_get_flags(unsigned long address);
365void page_set_flags(unsigned long start, unsigned long end, int flags);
366void page_unprotect_range(uint8_t *data, unsigned long data_size);
367
368#define SINGLE_CPU_DEFINES
369#ifdef SINGLE_CPU_DEFINES
370
371#if defined(TARGET_I386)
372
373#define CPUState CPUX86State
374#define cpu_init cpu_x86_init
375#define cpu_exec cpu_x86_exec
376#define cpu_gen_code cpu_x86_gen_code
377#define cpu_interrupt cpu_x86_interrupt
378#define cpu_signal_handler cpu_x86_signal_handler
379
380#elif defined(TARGET_ARM)
381
382#define CPUState CPUARMState
383#define cpu_init cpu_arm_init
384#define cpu_exec cpu_arm_exec
385#define cpu_gen_code cpu_arm_gen_code
386#define cpu_interrupt cpu_arm_interrupt
387#define cpu_signal_handler cpu_arm_signal_handler
388
bellard93ac68b2003-09-30 20:57:29 +0000389#elif defined(TARGET_SPARC)
390
391#define CPUState CPUSPARCState
392#define cpu_init cpu_sparc_init
393#define cpu_exec cpu_sparc_exec
394#define cpu_gen_code cpu_sparc_gen_code
395#define cpu_interrupt cpu_sparc_interrupt
396#define cpu_signal_handler cpu_sparc_signal_handler
397
bellard5a9fdfe2003-06-15 20:02:25 +0000398#else
399
400#error unsupported target CPU
401
402#endif
403
bellard972ddf72003-06-21 13:08:39 +0000404#endif /* SINGLE_CPU_DEFINES */
405
bellard3b0dca52003-06-27 18:52:23 +0000406#define DEFAULT_GDBSTUB_PORT 1234
407
bellard972ddf72003-06-21 13:08:39 +0000408void cpu_abort(CPUState *env, const char *fmt, ...);
bellarde2f22892003-06-25 16:09:48 +0000409extern CPUState *cpu_single_env;
bellard5a9fdfe2003-06-15 20:02:25 +0000410
bellard68a79312003-06-30 13:12:32 +0000411#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
412#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
bellard46907642003-07-07 12:17:46 +0000413void cpu_interrupt(CPUState *s, int mask);
bellard68a79312003-06-30 13:12:32 +0000414
bellard4c3a88a2003-07-26 12:06:08 +0000415int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
416int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
bellardc33a3462003-07-29 20:50:33 +0000417void cpu_single_step(CPUState *env, int enabled);
bellard4c3a88a2003-07-26 12:06:08 +0000418
bellard34865132003-10-05 14:28:56 +0000419#define CPU_LOG_ALL 1
420void cpu_set_log(int log_flags);
421void cpu_set_log_filename(const char *filename);
422
bellard33417e72003-08-10 21:47:01 +0000423/* memory API */
424
425typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
426typedef uint32_t CPUReadMemoryFunc(uint32_t addr);
427
428void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
429 long phys_offset);
430int cpu_register_io_memory(int io_index,
431 CPUReadMemoryFunc **mem_read,
432 CPUWriteMemoryFunc **mem_write);
433
bellard3b0dca52003-06-27 18:52:23 +0000434/* gdb stub API */
435extern int gdbstub_fd;
436CPUState *cpu_gdbstub_get_env(void *opaque);
bellard4c3a88a2003-07-26 12:06:08 +0000437int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port);
bellard3b0dca52003-06-27 18:52:23 +0000438
bellard5a9fdfe2003-06-15 20:02:25 +0000439#endif /* CPU_ALL_H */