Statistics
| Branch: | Revision:

root / cpu-all.h @ 6c9bf893

History | View | Annotate | Download (12 kB)

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

    
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 ! */
41
typedef 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

    
57
/* CPU memory access without any memory or io remapping */
58

    
59
static inline int ldub_raw(void *ptr)
60
{
61
    return *(uint8_t *)ptr;
62
}
63

    
64
static inline int ldsb_raw(void *ptr)
65
{
66
    return *(int8_t *)ptr;
67
}
68

    
69
static inline void stb_raw(void *ptr, int v)
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 */
77
#if !defined(TARGET_WORDS_BIGENDIAN) && (defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
78

    
79
/* conservative code for little endian unaligned accesses */
80
static inline int lduw_raw(void *ptr)
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

    
92
static inline int ldsw_raw(void *ptr)
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

    
104
static inline int ldl_raw(void *ptr)
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

    
116
static inline uint64_t ldq_raw(void *ptr)
117
{
118
    uint8_t *p = ptr;
119
    uint32_t v1, v2;
120
    v1 = ldl_raw(p);
121
    v2 = ldl_raw(p + 4);
122
    return v1 | ((uint64_t)v2 << 32);
123
}
124

    
125
static inline void stw_raw(void *ptr, int v)
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

    
136
static inline void stl_raw(void *ptr, int v)
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

    
149
static inline void stq_raw(void *ptr, uint64_t v)
150
{
151
    uint8_t *p = ptr;
152
    stl_raw(p, (uint32_t)v);
153
    stl_raw(p + 4, v >> 32);
154
}
155

    
156
/* float access */
157

    
158
static inline float ldfl_raw(void *ptr)
159
{
160
    union {
161
        float f;
162
        uint32_t i;
163
    } u;
164
    u.i = ldl_raw(ptr);
165
    return u.f;
166
}
167

    
168
static inline void stfl_raw(void *ptr, float v)
169
{
170
    union {
171
        float f;
172
        uint32_t i;
173
    } u;
174
    u.f = v;
175
    stl_raw(ptr, u.i);
176
}
177

    
178
static inline double ldfq_raw(void *ptr)
179
{
180
    CPU_DoubleU u;
181
    u.l.lower = ldl_raw(ptr);
182
    u.l.upper = ldl_raw(ptr + 4);
183
    return u.d;
184
}
185

    
186
static inline void stfq_raw(void *ptr, double v)
187
{
188
    CPU_DoubleU u;
189
    u.d = v;
190
    stl_raw(ptr, u.l.lower);
191
    stl_raw(ptr + 4, u.l.upper);
192
}
193

    
194
#elif defined(TARGET_WORDS_BIGENDIAN) && (!defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
195

    
196
static inline int lduw_raw(void *ptr)
197
{
198
    uint8_t *b = (uint8_t *) ptr;
199
    return (b[0]<<8|b[1]);
200
}
201

    
202
static inline int ldsw_raw(void *ptr)
203
{
204
    int8_t *b = (int8_t *) ptr;
205
    return (b[0]<<8|b[1]);
206
}
207

    
208
static inline int ldl_raw(void *ptr)
209
{
210
    uint8_t *b = (uint8_t *) ptr;
211
    return (b[0]<<24|b[1]<<16|b[2]<<8|b[3]);
212
}
213

    
214
static inline uint64_t ldq_raw(void *ptr)
215
{
216
    uint32_t a,b;
217
    a = ldl_raw(ptr);
218
    b = ldl_raw(ptr+4);
219
    return (((uint64_t)a<<32)|b);
220
}
221

    
222
static inline void stw_raw(void *ptr, int v)
223
{
224
    uint8_t *d = (uint8_t *) ptr;
225
    d[0] = v >> 8;
226
    d[1] = v;
227
}
228

    
229
static inline void stl_raw(void *ptr, int v)
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

    
238
static inline void stq_raw(void *ptr, uint64_t v)
239
{
240
    stl_raw(ptr, v >> 32);
241
    stl_raw(ptr + 4, v);
242
}
243

    
244
/* float access */
245

    
246
static 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

    
256
static 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

    
266
static 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

    
274
static 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);
280
}
281

    
282
#else
283

    
284
static inline int lduw_raw(void *ptr)
285
{
286
    return *(uint16_t *)ptr;
287
}
288

    
289
static inline int ldsw_raw(void *ptr)
290
{
291
    return *(int16_t *)ptr;
292
}
293

    
294
static inline int ldl_raw(void *ptr)
295
{
296
    return *(uint32_t *)ptr;
297
}
298

    
299
static inline uint64_t ldq_raw(void *ptr)
300
{
301
    return *(uint64_t *)ptr;
302
}
303

    
304
static inline void stw_raw(void *ptr, int v)
305
{
306
    *(uint16_t *)ptr = v;
307
}
308

    
309
static inline void stl_raw(void *ptr, int v)
310
{
311
    *(uint32_t *)ptr = v;
312
}
313

    
314
static inline void stq_raw(void *ptr, uint64_t v)
315
{
316
    *(uint64_t *)ptr = v;
317
}
318

    
319
/* float access */
320

    
321
static inline float ldfl_raw(void *ptr)
322
{
323
    return *(float *)ptr;
324
}
325

    
326
static inline double ldfq_raw(void *ptr)
327
{
328
    return *(double *)ptr;
329
}
330

    
331
static inline void stfl_raw(void *ptr, float v)
332
{
333
    *(float *)ptr = v;
334
}
335

    
336
static inline void stfq_raw(void *ptr, double v)
337
{
338
    *(double *)ptr = v;
339
}
340
#endif
341

    
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)
373
#define ldfl_kernel(p) ldfl_raw(p)
374
#define ldfq_kernel(p) ldfq_raw(p)
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)
379
#define stfl_kernel(p, v) stfl_raw(p, v)
380
#define stfq_kernel(p, vt) stfq_raw(p, v)
381

    
382
#endif /* defined(CONFIG_USER_ONLY) */
383

    
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

    
390
extern unsigned long real_host_page_size;
391
extern unsigned long host_page_bits;
392
extern unsigned long host_page_size;
393
extern 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

    
407
void page_dump(FILE *f);
408
int page_get_flags(unsigned long address);
409
void page_set_flags(unsigned long start, unsigned long end, int flags);
410
void 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
#define cpu_dump_state cpu_x86_dump_state
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
433
#define cpu_dump_state cpu_arm_dump_state
434

    
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
443
#define cpu_dump_state cpu_sparc_dump_state
444

    
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
453
#define cpu_dump_state cpu_ppc_dump_state
454

    
455
#else
456

    
457
#error unsupported target CPU
458

    
459
#endif
460

    
461
#endif /* SINGLE_CPU_DEFINES */
462

    
463
#define DEFAULT_GDBSTUB_PORT 1234
464

    
465
void cpu_abort(CPUState *env, const char *fmt, ...);
466
extern CPUState *cpu_single_env;
467

    
468
#define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */
469
#define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */
470
void cpu_interrupt(CPUState *s, int mask);
471

    
472
int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
473
int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
474
void cpu_single_step(CPUState *env, int enabled);
475

    
476
#define CPU_LOG_ALL 1
477
void cpu_set_log(int log_flags);
478
void cpu_set_log_filename(const char *filename);
479

    
480
/* IO ports API */
481

    
482
/* NOTE: as these functions may be even used when there is an isa
483
   brige on non x86 targets, we always defined them */
484
#ifndef NO_CPU_IO_DEFS
485
void cpu_outb(CPUState *env, int addr, int val);
486
void cpu_outw(CPUState *env, int addr, int val);
487
void cpu_outl(CPUState *env, int addr, int val);
488
int cpu_inb(CPUState *env, int addr);
489
int cpu_inw(CPUState *env, int addr);
490
int cpu_inl(CPUState *env, int addr);
491
#endif
492

    
493
/* memory API */
494

    
495
extern int phys_ram_size;
496
extern int phys_ram_fd;
497
extern uint8_t *phys_ram_base;
498

    
499
/* physical memory access */
500
#define IO_MEM_NB_ENTRIES  256
501
#define TLB_INVALID_MASK   (1 << 3)
502
#define IO_MEM_SHIFT       4
503

    
504
#define IO_MEM_RAM         (0 << IO_MEM_SHIFT) /* hardcoded offset */
505
#define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
506
#define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
507
#define IO_MEM_CODE        (3 << IO_MEM_SHIFT)
508

    
509
typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
510
typedef uint32_t CPUReadMemoryFunc(uint32_t addr);
511

    
512
void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
513
                                  long phys_offset);
514
int cpu_register_io_memory(int io_index,
515
                           CPUReadMemoryFunc **mem_read,
516
                           CPUWriteMemoryFunc **mem_write);
517

    
518
/* gdb stub API */
519
extern int gdbstub_fd;
520
CPUState *cpu_gdbstub_get_env(void *opaque);
521
int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port);
522

    
523
#endif /* CPU_ALL_H */