]> git.proxmox.com Git - qemu.git/blame - cpu-all.h
update
[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
61382a50
FB
23/* CPU memory access without any memory or io remapping */
24
25static inline int ldub_raw(void *ptr)
5a9fdfec
FB
26{
27 return *(uint8_t *)ptr;
28}
29
61382a50 30static inline int ldsb_raw(void *ptr)
5a9fdfec
FB
31{
32 return *(int8_t *)ptr;
33}
34
61382a50 35static inline void stb_raw(void *ptr, int v)
5a9fdfec
FB
36{
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 */
61382a50 46static inline int lduw_raw(void *ptr)
5a9fdfec
FB
47{
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
61382a50 58static inline int ldsw_raw(void *ptr)
5a9fdfec
FB
59{
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
61382a50 70static inline int ldl_raw(void *ptr)
5a9fdfec
FB
71{
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
61382a50 82static inline uint64_t ldq_raw(void *ptr)
5a9fdfec
FB
83{
84 uint8_t *p = ptr;
85 uint32_t v1, v2;
61382a50
FB
86 v1 = ldl_raw(p);
87 v2 = ldl_raw(p + 4);
5a9fdfec
FB
88 return v1 | ((uint64_t)v2 << 32);
89}
90
61382a50 91static inline void stw_raw(void *ptr, int v)
5a9fdfec
FB
92{
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
61382a50 102static inline void stl_raw(void *ptr, int v)
5a9fdfec
FB
103{
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
61382a50 115static inline void stq_raw(void *ptr, uint64_t v)
5a9fdfec
FB
116{
117 uint8_t *p = ptr;
61382a50
FB
118 stl_raw(p, (uint32_t)v);
119 stl_raw(p + 4, v >> 32);
5a9fdfec
FB
120}
121
122/* float access */
123
61382a50 124static inline float ldfl_raw(void *ptr)
5a9fdfec
FB
125{
126 union {
127 float f;
128 uint32_t i;
129 } u;
61382a50 130 u.i = ldl_raw(ptr);
5a9fdfec
FB
131 return u.f;
132}
133
61382a50 134static inline void stfl_raw(void *ptr, float v)
5a9fdfec
FB
135{
136 union {
137 float f;
138 uint32_t i;
139 } u;
140 u.f = v;
61382a50 141 stl_raw(ptr, u.i);
5a9fdfec
FB
142}
143
33417e70 144
5a9fdfec
FB
145#if defined(__arm__) && !defined(WORDS_BIGENDIAN)
146
147/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
61382a50 148static inline double ldfq_raw(void *ptr)
5a9fdfec
FB
149{
150 union {
151 double d;
152 uint32_t tab[2];
153 } u;
61382a50
FB
154 u.tab[1] = ldl_raw(ptr);
155 u.tab[0] = ldl_raw(ptr + 4);
5a9fdfec
FB
156 return u.d;
157}
158
61382a50 159static inline void stfq_raw(void *ptr, double v)
5a9fdfec
FB
160{
161 union {
162 double d;
163 uint32_t tab[2];
164 } u;
165 u.d = v;
61382a50
FB
166 stl_raw(ptr, u.tab[1]);
167 stl_raw(ptr + 4, u.tab[0]);
5a9fdfec
FB
168}
169
170#else
61382a50 171static inline double ldfq_raw(void *ptr)
5a9fdfec
FB
172{
173 union {
174 double d;
175 uint64_t i;
176 } u;
61382a50 177 u.i = ldq_raw(ptr);
5a9fdfec
FB
178 return u.d;
179}
180
61382a50 181static inline void stfq_raw(void *ptr, double v)
5a9fdfec
FB
182{
183 union {
184 double d;
185 uint64_t i;
186 } u;
187 u.d = v;
61382a50 188 stq_raw(ptr, u.i);
5a9fdfec
FB
189}
190#endif
191
93ac68bc
FB
192#elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)
193
61382a50 194static inline int lduw_raw(void *ptr)
93ac68bc
FB
195{
196 uint8_t *b = (uint8_t *) ptr;
197 return (b[0]<<8|b[1]);
198}
199
61382a50 200static inline int ldsw_raw(void *ptr)
93ac68bc
FB
201{
202 int8_t *b = (int8_t *) ptr;
203 return (b[0]<<8|b[1]);
204}
205
61382a50 206static inline int ldl_raw(void *ptr)
93ac68bc
FB
207{
208 uint8_t *b = (uint8_t *) ptr;
209 return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]);
210}
211
61382a50 212static inline uint64_t ldq_raw(void *ptr)
93ac68bc
FB
213{
214 uint32_t a,b;
9f05cc34
FB
215 a = ldl_raw(ptr);
216 b = ldl_raw(ptr+4);
93ac68bc
FB
217 return (((uint64_t)a<<32)|b);
218}
219
61382a50 220static inline void stw_raw(void *ptr, int v)
93ac68bc
FB
221{
222 uint8_t *d = (uint8_t *) ptr;
223 d[0] = v >> 8;
224 d[1] = v;
225}
226
61382a50 227static inline void stl_raw(void *ptr, int v)
93ac68bc
FB
228{
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
61382a50 236static inline void stq_raw(void *ptr, uint64_t v)
93ac68bc 237{
9f05cc34
FB
238 stl_raw(ptr, v);
239 stl_raw(ptr+4, v >> 32);
93ac68bc
FB
240}
241
5a9fdfec
FB
242#else
243
61382a50 244static inline int lduw_raw(void *ptr)
5a9fdfec
FB
245{
246 return *(uint16_t *)ptr;
247}
248
61382a50 249static inline int ldsw_raw(void *ptr)
5a9fdfec
FB
250{
251 return *(int16_t *)ptr;
252}
253
61382a50 254static inline int ldl_raw(void *ptr)
5a9fdfec
FB
255{
256 return *(uint32_t *)ptr;
257}
258
61382a50 259static inline uint64_t ldq_raw(void *ptr)
5a9fdfec
FB
260{
261 return *(uint64_t *)ptr;
262}
263
61382a50 264static inline void stw_raw(void *ptr, int v)
5a9fdfec
FB
265{
266 *(uint16_t *)ptr = v;
267}
268
61382a50 269static inline void stl_raw(void *ptr, int v)
5a9fdfec
FB
270{
271 *(uint32_t *)ptr = v;
272}
273
61382a50 274static inline void stq_raw(void *ptr, uint64_t v)
5a9fdfec
FB
275{
276 *(uint64_t *)ptr = v;
277}
278
279/* float access */
280
61382a50 281static inline float ldfl_raw(void *ptr)
5a9fdfec
FB
282{
283 return *(float *)ptr;
284}
285
61382a50 286static inline double ldfq_raw(void *ptr)
5a9fdfec
FB
287{
288 return *(double *)ptr;
289}
290
61382a50 291static inline void stfl_raw(void *ptr, float v)
5a9fdfec
FB
292{
293 *(float *)ptr = v;
294}
295
61382a50 296static inline void stfq_raw(void *ptr, double v)
5a9fdfec
FB
297{
298 *(double *)ptr = v;
299}
300#endif
301
61382a50
FB
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
5a9fdfec
FB
340/* 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
93ac68bc
FB
389#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
67867308
FB
398#elif defined(TARGET_PPC)
399
400#define CPUState CPUPPCState
401#define cpu_init cpu_ppc_init
402#define cpu_exec cpu_ppc_exec
403#define cpu_gen_code cpu_ppc_gen_code
404#define cpu_interrupt cpu_ppc_interrupt
405#define cpu_signal_handler cpu_ppc_signal_handler
406
5a9fdfec
FB
407#else
408
409#error unsupported target CPU
410
411#endif
412
972ddf78
FB
413#endif /* SINGLE_CPU_DEFINES */
414
3b0dca51
FB
415#define DEFAULT_GDBSTUB_PORT 1234
416
972ddf78 417void cpu_abort(CPUState *env, const char *fmt, ...);
e2f22898 418extern CPUState *cpu_single_env;
5a9fdfec 419
68a79315
FB
420#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
421#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
4690764b 422void cpu_interrupt(CPUState *s, int mask);
68a79315 423
4c3a88a2
FB
424int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
425int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
c33a346e 426void cpu_single_step(CPUState *env, int enabled);
4c3a88a2 427
34865134
FB
428#define CPU_LOG_ALL 1
429void cpu_set_log(int log_flags);
430void cpu_set_log_filename(const char *filename);
431
33417e70
FB
432/* memory API */
433
434typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
435typedef uint32_t CPUReadMemoryFunc(uint32_t addr);
436
437void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
438 long phys_offset);
439int cpu_register_io_memory(int io_index,
440 CPUReadMemoryFunc **mem_read,
441 CPUWriteMemoryFunc **mem_write);
442
3b0dca51
FB
443/* gdb stub API */
444extern int gdbstub_fd;
445CPUState *cpu_gdbstub_get_env(void *opaque);
4c3a88a2 446int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port);
3b0dca51 447
5a9fdfec 448#endif /* CPU_ALL_H */