cpu-all.h 9.72 KB
Newer Older
bellard's avatar
bellard committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * defines common to all virtual CPUs
 * 
 *  Copyright (c) 2003 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#ifndef CPU_ALL_H
#define CPU_ALL_H

bellard's avatar
bellard committed
23
24
25
/* CPU memory access without any memory or io remapping */

static inline int ldub_raw(void *ptr)
bellard's avatar
bellard committed
26
27
28
29
{
    return *(uint8_t *)ptr;
}

bellard's avatar
bellard committed
30
static inline int ldsb_raw(void *ptr)
bellard's avatar
bellard committed
31
32
33
34
{
    return *(int8_t *)ptr;
}

bellard's avatar
bellard committed
35
static inline void stb_raw(void *ptr, int v)
bellard's avatar
bellard committed
36
37
38
39
40
41
42
43
44
45
{
    *(uint8_t *)ptr = v;
}

/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
   kernel handles unaligned load/stores may give better results, but
   it is a system wide setting : bad */
#if defined(WORDS_BIGENDIAN) || defined(__arm__)

/* conservative code for little endian unaligned accesses */
bellard's avatar
bellard committed
46
static inline int lduw_raw(void *ptr)
bellard's avatar
bellard committed
47
48
49
50
51
52
53
54
55
56
57
{
#ifdef __powerpc__
    int val;
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
    return val;
#else
    uint8_t *p = ptr;
    return p[0] | (p[1] << 8);
#endif
}

bellard's avatar
bellard committed
58
static inline int ldsw_raw(void *ptr)
bellard's avatar
bellard committed
59
60
61
62
63
64
65
66
67
68
69
{
#ifdef __powerpc__
    int val;
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
    return (int16_t)val;
#else
    uint8_t *p = ptr;
    return (int16_t)(p[0] | (p[1] << 8));
#endif
}

bellard's avatar
bellard committed
70
static inline int ldl_raw(void *ptr)
bellard's avatar
bellard committed
71
72
73
74
75
76
77
78
79
80
81
{
#ifdef __powerpc__
    int val;
    __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
    return val;
#else
    uint8_t *p = ptr;
    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
#endif
}

bellard's avatar
bellard committed
82
static inline uint64_t ldq_raw(void *ptr)
bellard's avatar
bellard committed
83
84
85
{
    uint8_t *p = ptr;
    uint32_t v1, v2;
bellard's avatar
bellard committed
86
87
    v1 = ldl_raw(p);
    v2 = ldl_raw(p + 4);
bellard's avatar
bellard committed
88
89
90
    return v1 | ((uint64_t)v2 << 32);
}

bellard's avatar
bellard committed
91
static inline void stw_raw(void *ptr, int v)
bellard's avatar
bellard committed
92
93
94
95
96
97
98
99
100
101
{
#ifdef __powerpc__
    __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
#else
    uint8_t *p = ptr;
    p[0] = v;
    p[1] = v >> 8;
#endif
}

bellard's avatar
bellard committed
102
static inline void stl_raw(void *ptr, int v)
bellard's avatar
bellard committed
103
104
105
106
107
108
109
110
111
112
113
114
{
#ifdef __powerpc__
    __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
#else
    uint8_t *p = ptr;
    p[0] = v;
    p[1] = v >> 8;
    p[2] = v >> 16;
    p[3] = v >> 24;
#endif
}

bellard's avatar
bellard committed
115
static inline void stq_raw(void *ptr, uint64_t v)
bellard's avatar
bellard committed
116
117
{
    uint8_t *p = ptr;
bellard's avatar
bellard committed
118
119
    stl_raw(p, (uint32_t)v);
    stl_raw(p + 4, v >> 32);
bellard's avatar
bellard committed
120
121
122
123
}

/* float access */

bellard's avatar
bellard committed
124
static inline float ldfl_raw(void *ptr)
bellard's avatar
bellard committed
125
126
127
128
129
{
    union {
        float f;
        uint32_t i;
    } u;
bellard's avatar
bellard committed
130
    u.i = ldl_raw(ptr);
bellard's avatar
bellard committed
131
132
133
    return u.f;
}

bellard's avatar
bellard committed
134
static inline void stfl_raw(void *ptr, float v)
bellard's avatar
bellard committed
135
136
137
138
139
140
{
    union {
        float f;
        uint32_t i;
    } u;
    u.f = v;
bellard's avatar
bellard committed
141
    stl_raw(ptr, u.i);
bellard's avatar
bellard committed
142
143
}

144

bellard's avatar
bellard committed
145
146
147
#if defined(__arm__) && !defined(WORDS_BIGENDIAN)

/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
bellard's avatar
bellard committed
148
static inline double ldfq_raw(void *ptr)
bellard's avatar
bellard committed
149
150
151
152
153
{
    union {
        double d;
        uint32_t tab[2];
    } u;
bellard's avatar
bellard committed
154
155
    u.tab[1] = ldl_raw(ptr);
    u.tab[0] = ldl_raw(ptr + 4);
bellard's avatar
bellard committed
156
157
158
    return u.d;
}

bellard's avatar
bellard committed
159
static inline void stfq_raw(void *ptr, double v)
bellard's avatar
bellard committed
160
161
162
163
164
165
{
    union {
        double d;
        uint32_t tab[2];
    } u;
    u.d = v;
bellard's avatar
bellard committed
166
167
    stl_raw(ptr, u.tab[1]);
    stl_raw(ptr + 4, u.tab[0]);
bellard's avatar
bellard committed
168
169
170
}

#else
bellard's avatar
bellard committed
171
static inline double ldfq_raw(void *ptr)
bellard's avatar
bellard committed
172
173
174
175
176
{
    union {
        double d;
        uint64_t i;
    } u;
bellard's avatar
bellard committed
177
    u.i = ldq_raw(ptr);
bellard's avatar
bellard committed
178
179
180
    return u.d;
}

bellard's avatar
bellard committed
181
static inline void stfq_raw(void *ptr, double v)
bellard's avatar
bellard committed
182
183
184
185
186
187
{
    union {
        double d;
        uint64_t i;
    } u;
    u.d = v;
bellard's avatar
bellard committed
188
    stq_raw(ptr, u.i);
bellard's avatar
bellard committed
189
190
191
}
#endif

192
193
#elif defined(TARGET_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)

bellard's avatar
bellard committed
194
static inline int lduw_raw(void *ptr)
195
196
197
198
199
{
    uint8_t *b = (uint8_t *) ptr;
    return (b[0]<<8|b[1]);
}

bellard's avatar
bellard committed
200
static inline int ldsw_raw(void *ptr)
201
202
203
204
205
{
    int8_t *b = (int8_t *) ptr;
    return (b[0]<<8|b[1]);
}

bellard's avatar
bellard committed
206
static inline int ldl_raw(void *ptr)
207
208
209
210
211
{
    uint8_t *b = (uint8_t *) ptr;
    return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]);
}

bellard's avatar
bellard committed
212
static inline uint64_t ldq_raw(void *ptr)
213
214
{
    uint32_t a,b;
bellard's avatar
bellard committed
215
216
    a = ldl_raw(ptr);
    b = ldl_raw(ptr+4);
217
218
219
    return (((uint64_t)a<<32)|b);
}

bellard's avatar
bellard committed
220
static inline void stw_raw(void *ptr, int v)
221
222
223
224
225
226
{
    uint8_t *d = (uint8_t *) ptr;
    d[0] = v >> 8;
    d[1] = v;
}

bellard's avatar
bellard committed
227
static inline void stl_raw(void *ptr, int v)
228
229
230
231
232
233
234
235
{
    uint8_t *d = (uint8_t *) ptr;
    d[0] = v >> 24;
    d[1] = v >> 16;
    d[2] = v >> 8;
    d[3] = v;
}

bellard's avatar
bellard committed
236
static inline void stq_raw(void *ptr, uint64_t v)
237
{
bellard's avatar
bellard committed
238
239
    stl_raw(ptr, v);
    stl_raw(ptr+4, v >> 32);
240
241
}

bellard's avatar
bellard committed
242
243
#else

bellard's avatar
bellard committed
244
static inline int lduw_raw(void *ptr)
bellard's avatar
bellard committed
245
246
247
248
{
    return *(uint16_t *)ptr;
}

bellard's avatar
bellard committed
249
static inline int ldsw_raw(void *ptr)
bellard's avatar
bellard committed
250
251
252
253
{
    return *(int16_t *)ptr;
}

bellard's avatar
bellard committed
254
static inline int ldl_raw(void *ptr)
bellard's avatar
bellard committed
255
256
257
258
{
    return *(uint32_t *)ptr;
}

bellard's avatar
bellard committed
259
static inline uint64_t ldq_raw(void *ptr)
bellard's avatar
bellard committed
260
261
262
263
{
    return *(uint64_t *)ptr;
}

bellard's avatar
bellard committed
264
static inline void stw_raw(void *ptr, int v)
bellard's avatar
bellard committed
265
266
267
268
{
    *(uint16_t *)ptr = v;
}

bellard's avatar
bellard committed
269
static inline void stl_raw(void *ptr, int v)
bellard's avatar
bellard committed
270
271
272
273
{
    *(uint32_t *)ptr = v;
}

bellard's avatar
bellard committed
274
static inline void stq_raw(void *ptr, uint64_t v)
bellard's avatar
bellard committed
275
276
277
278
279
280
{
    *(uint64_t *)ptr = v;
}

/* float access */

bellard's avatar
bellard committed
281
static inline float ldfl_raw(void *ptr)
bellard's avatar
bellard committed
282
283
284
285
{
    return *(float *)ptr;
}

bellard's avatar
bellard committed
286
static inline double ldfq_raw(void *ptr)
bellard's avatar
bellard committed
287
288
289
290
{
    return *(double *)ptr;
}

bellard's avatar
bellard committed
291
static inline void stfl_raw(void *ptr, float v)
bellard's avatar
bellard committed
292
293
294
295
{
    *(float *)ptr = v;
}

bellard's avatar
bellard committed
296
static inline void stfq_raw(void *ptr, double v)
bellard's avatar
bellard committed
297
298
299
300
301
{
    *(double *)ptr = v;
}
#endif

bellard's avatar
bellard committed
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
/* MMU memory access macros */

#if defined(CONFIG_USER_ONLY) 

/* if user mode, no other memory access functions */
#define ldub(p) ldub_raw(p)
#define ldsb(p) ldsb_raw(p)
#define lduw(p) lduw_raw(p)
#define ldsw(p) ldsw_raw(p)
#define ldl(p) ldl_raw(p)
#define ldq(p) ldq_raw(p)
#define ldfl(p) ldfl_raw(p)
#define ldfq(p) ldfq_raw(p)
#define stb(p, v) stb_raw(p, v)
#define stw(p, v) stw_raw(p, v)
#define stl(p, v) stl_raw(p, v)
#define stq(p, v) stq_raw(p, v)
#define stfl(p, v) stfl_raw(p, v)
#define stfq(p, v) stfq_raw(p, v)

#define ldub_code(p) ldub_raw(p)
#define ldsb_code(p) ldsb_raw(p)
#define lduw_code(p) lduw_raw(p)
#define ldsw_code(p) ldsw_raw(p)
#define ldl_code(p) ldl_raw(p)

#define ldub_kernel(p) ldub_raw(p)
#define ldsb_kernel(p) ldsb_raw(p)
#define lduw_kernel(p) lduw_raw(p)
#define ldsw_kernel(p) ldsw_raw(p)
#define ldl_kernel(p) ldl_raw(p)
#define stb_kernel(p, v) stb_raw(p, v)
#define stw_kernel(p, v) stw_raw(p, v)
#define stl_kernel(p, v) stl_raw(p, v)
#define stq_kernel(p, v) stq_raw(p, v)

#endif /* defined(CONFIG_USER_ONLY) */

bellard's avatar
bellard committed
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
/* page related stuff */

#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)

extern unsigned long real_host_page_size;
extern unsigned long host_page_bits;
extern unsigned long host_page_size;
extern unsigned long host_page_mask;

#define HOST_PAGE_ALIGN(addr) (((addr) + host_page_size - 1) & host_page_mask)

/* same as PROT_xxx */
#define PAGE_READ      0x0001
#define PAGE_WRITE     0x0002
#define PAGE_EXEC      0x0004
#define PAGE_BITS      (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
#define PAGE_VALID     0x0008
/* original state of the write flag (used when tracking self-modifying
   code */
#define PAGE_WRITE_ORG 0x0010 

void page_dump(FILE *f);
int page_get_flags(unsigned long address);
void page_set_flags(unsigned long start, unsigned long end, int flags);
void page_unprotect_range(uint8_t *data, unsigned long data_size);

#define SINGLE_CPU_DEFINES
#ifdef SINGLE_CPU_DEFINES

#if defined(TARGET_I386)

#define CPUState CPUX86State
#define cpu_init cpu_x86_init
#define cpu_exec cpu_x86_exec
#define cpu_gen_code cpu_x86_gen_code
#define cpu_interrupt cpu_x86_interrupt
#define cpu_signal_handler cpu_x86_signal_handler

#elif defined(TARGET_ARM)

#define CPUState CPUARMState
#define cpu_init cpu_arm_init
#define cpu_exec cpu_arm_exec
#define cpu_gen_code cpu_arm_gen_code
#define cpu_interrupt cpu_arm_interrupt
#define cpu_signal_handler cpu_arm_signal_handler

389
390
391
392
393
394
395
396
397
#elif defined(TARGET_SPARC)

#define CPUState CPUSPARCState
#define cpu_init cpu_sparc_init
#define cpu_exec cpu_sparc_exec
#define cpu_gen_code cpu_sparc_gen_code
#define cpu_interrupt cpu_sparc_interrupt
#define cpu_signal_handler cpu_sparc_signal_handler

bellard's avatar
bellard committed
398
399
400
401
402
403
#else

#error unsupported target CPU

#endif

bellard's avatar
bellard committed
404
405
#endif /* SINGLE_CPU_DEFINES */

bellard's avatar
bellard committed
406
407
#define DEFAULT_GDBSTUB_PORT 1234

bellard's avatar
bellard committed
408
void cpu_abort(CPUState *env, const char *fmt, ...);
bellard's avatar
bellard committed
409
extern CPUState *cpu_single_env;
bellard's avatar
bellard committed
410

bellard's avatar
bellard committed
411
412
#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
bellard's avatar
update    
bellard committed
413
void cpu_interrupt(CPUState *s, int mask);
bellard's avatar
bellard committed
414

bellard's avatar
bellard committed
415
416
int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
417
void cpu_single_step(CPUState *env, int enabled);
bellard's avatar
bellard committed
418

419
420
421
422
#define CPU_LOG_ALL 1
void cpu_set_log(int log_flags);
void cpu_set_log_filename(const char *filename);

423
424
425
426
427
428
429
430
431
432
433
/* memory API */

typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
typedef uint32_t CPUReadMemoryFunc(uint32_t addr);

void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
                                  long phys_offset);
int cpu_register_io_memory(int io_index,
                           CPUReadMemoryFunc **mem_read,
                           CPUWriteMemoryFunc **mem_write);

bellard's avatar
bellard committed
434
435
436
/* gdb stub API */
extern int gdbstub_fd;
CPUState *cpu_gdbstub_get_env(void *opaque);
bellard's avatar
bellard committed
437
int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port);
bellard's avatar
bellard committed
438

bellard's avatar
bellard committed
439
#endif /* CPU_ALL_H */