Statistics
| Branch: | Revision:

root / cpu-all.h @ 2a4188a3

History | View | Annotate | Download (22.2 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
#include "bswap.h"
41

    
42
#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
43
#define BSWAP_NEEDED
44
#endif
45

    
46
#ifdef BSWAP_NEEDED
47

    
48
static inline uint16_t tswap16(uint16_t s)
49
{
50
    return bswap16(s);
51
}
52

    
53
static inline uint32_t tswap32(uint32_t s)
54
{
55
    return bswap32(s);
56
}
57

    
58
static inline uint64_t tswap64(uint64_t s)
59
{
60
    return bswap64(s);
61
}
62

    
63
static inline void tswap16s(uint16_t *s)
64
{
65
    *s = bswap16(*s);
66
}
67

    
68
static inline void tswap32s(uint32_t *s)
69
{
70
    *s = bswap32(*s);
71
}
72

    
73
static inline void tswap64s(uint64_t *s)
74
{
75
    *s = bswap64(*s);
76
}
77

    
78
#else
79

    
80
static inline uint16_t tswap16(uint16_t s)
81
{
82
    return s;
83
}
84

    
85
static inline uint32_t tswap32(uint32_t s)
86
{
87
    return s;
88
}
89

    
90
static inline uint64_t tswap64(uint64_t s)
91
{
92
    return s;
93
}
94

    
95
static inline void tswap16s(uint16_t *s)
96
{
97
}
98

    
99
static inline void tswap32s(uint32_t *s)
100
{
101
}
102

    
103
static inline void tswap64s(uint64_t *s)
104
{
105
}
106

    
107
#endif
108

    
109
#if TARGET_LONG_SIZE == 4
110
#define tswapl(s) tswap32(s)
111
#define tswapls(s) tswap32s((uint32_t *)(s))
112
#define bswaptls(s) bswap32s(s)
113
#else
114
#define tswapl(s) tswap64(s)
115
#define tswapls(s) tswap64s((uint64_t *)(s))
116
#define bswaptls(s) bswap64s(s)
117
#endif
118

    
119
/* NOTE: arm FPA is horrible as double 32 bit words are stored in big
120
   endian ! */
121
typedef union {
122
    float64 d;
123
#if defined(WORDS_BIGENDIAN) \
124
    || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
125
    struct {
126
        uint32_t upper;
127
        uint32_t lower;
128
    } l;
129
#else
130
    struct {
131
        uint32_t lower;
132
        uint32_t upper;
133
    } l;
134
#endif
135
    uint64_t ll;
136
} CPU_DoubleU;
137

    
138
/* CPU memory access without any memory or io remapping */
139

    
140
/*
141
 * the generic syntax for the memory accesses is:
142
 *
143
 * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
144
 *
145
 * store: st{type}{size}{endian}_{access_type}(ptr, val)
146
 *
147
 * type is:
148
 * (empty): integer access
149
 *   f    : float access
150
 * 
151
 * sign is:
152
 * (empty): for floats or 32 bit size
153
 *   u    : unsigned
154
 *   s    : signed
155
 *
156
 * size is:
157
 *   b: 8 bits
158
 *   w: 16 bits
159
 *   l: 32 bits
160
 *   q: 64 bits
161
 * 
162
 * endian is:
163
 * (empty): target cpu endianness or 8 bit access
164
 *   r    : reversed target cpu endianness (not implemented yet)
165
 *   be   : big endian (not implemented yet)
166
 *   le   : little endian (not implemented yet)
167
 *
168
 * access_type is:
169
 *   raw    : host memory access
170
 *   user   : user mode access using soft MMU
171
 *   kernel : kernel mode access using soft MMU
172
 */
173
static inline int ldub_p(void *ptr)
174
{
175
    return *(uint8_t *)ptr;
176
}
177

    
178
static inline int ldsb_p(void *ptr)
179
{
180
    return *(int8_t *)ptr;
181
}
182

    
183
static inline void stb_p(void *ptr, int v)
184
{
185
    *(uint8_t *)ptr = v;
186
}
187

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

    
193
/* conservative code for little endian unaligned accesses */
194
static inline int lduw_le_p(void *ptr)
195
{
196
#ifdef __powerpc__
197
    int val;
198
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
199
    return val;
200
#else
201
    uint8_t *p = ptr;
202
    return p[0] | (p[1] << 8);
203
#endif
204
}
205

    
206
static inline int ldsw_le_p(void *ptr)
207
{
208
#ifdef __powerpc__
209
    int val;
210
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
211
    return (int16_t)val;
212
#else
213
    uint8_t *p = ptr;
214
    return (int16_t)(p[0] | (p[1] << 8));
215
#endif
216
}
217

    
218
static inline int ldl_le_p(void *ptr)
219
{
220
#ifdef __powerpc__
221
    int val;
222
    __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
223
    return val;
224
#else
225
    uint8_t *p = ptr;
226
    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
227
#endif
228
}
229

    
230
static inline uint64_t ldq_le_p(void *ptr)
231
{
232
    uint8_t *p = ptr;
233
    uint32_t v1, v2;
234
    v1 = ldl_le_p(p);
235
    v2 = ldl_le_p(p + 4);
236
    return v1 | ((uint64_t)v2 << 32);
237
}
238

    
239
static inline void stw_le_p(void *ptr, int v)
240
{
241
#ifdef __powerpc__
242
    __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
243
#else
244
    uint8_t *p = ptr;
245
    p[0] = v;
246
    p[1] = v >> 8;
247
#endif
248
}
249

    
250
static inline void stl_le_p(void *ptr, int v)
251
{
252
#ifdef __powerpc__
253
    __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
254
#else
255
    uint8_t *p = ptr;
256
    p[0] = v;
257
    p[1] = v >> 8;
258
    p[2] = v >> 16;
259
    p[3] = v >> 24;
260
#endif
261
}
262

    
263
static inline void stq_le_p(void *ptr, uint64_t v)
264
{
265
    uint8_t *p = ptr;
266
    stl_le_p(p, (uint32_t)v);
267
    stl_le_p(p + 4, v >> 32);
268
}
269

    
270
/* float access */
271

    
272
static inline float32 ldfl_le_p(void *ptr)
273
{
274
    union {
275
        float32 f;
276
        uint32_t i;
277
    } u;
278
    u.i = ldl_le_p(ptr);
279
    return u.f;
280
}
281

    
282
static inline void stfl_le_p(void *ptr, float32 v)
283
{
284
    union {
285
        float32 f;
286
        uint32_t i;
287
    } u;
288
    u.f = v;
289
    stl_le_p(ptr, u.i);
290
}
291

    
292
static inline float64 ldfq_le_p(void *ptr)
293
{
294
    CPU_DoubleU u;
295
    u.l.lower = ldl_le_p(ptr);
296
    u.l.upper = ldl_le_p(ptr + 4);
297
    return u.d;
298
}
299

    
300
static inline void stfq_le_p(void *ptr, float64 v)
301
{
302
    CPU_DoubleU u;
303
    u.d = v;
304
    stl_le_p(ptr, u.l.lower);
305
    stl_le_p(ptr + 4, u.l.upper);
306
}
307

    
308
#else
309

    
310
static inline int lduw_le_p(void *ptr)
311
{
312
    return *(uint16_t *)ptr;
313
}
314

    
315
static inline int ldsw_le_p(void *ptr)
316
{
317
    return *(int16_t *)ptr;
318
}
319

    
320
static inline int ldl_le_p(void *ptr)
321
{
322
    return *(uint32_t *)ptr;
323
}
324

    
325
static inline uint64_t ldq_le_p(void *ptr)
326
{
327
    return *(uint64_t *)ptr;
328
}
329

    
330
static inline void stw_le_p(void *ptr, int v)
331
{
332
    *(uint16_t *)ptr = v;
333
}
334

    
335
static inline void stl_le_p(void *ptr, int v)
336
{
337
    *(uint32_t *)ptr = v;
338
}
339

    
340
static inline void stq_le_p(void *ptr, uint64_t v)
341
{
342
    *(uint64_t *)ptr = v;
343
}
344

    
345
/* float access */
346

    
347
static inline float32 ldfl_le_p(void *ptr)
348
{
349
    return *(float32 *)ptr;
350
}
351

    
352
static inline float64 ldfq_le_p(void *ptr)
353
{
354
    return *(float64 *)ptr;
355
}
356

    
357
static inline void stfl_le_p(void *ptr, float32 v)
358
{
359
    *(float32 *)ptr = v;
360
}
361

    
362
static inline void stfq_le_p(void *ptr, float64 v)
363
{
364
    *(float64 *)ptr = v;
365
}
366
#endif
367

    
368
#if !defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
369

    
370
static inline int lduw_be_p(void *ptr)
371
{
372
#if defined(__i386__)
373
    int val;
374
    asm volatile ("movzwl %1, %0\n"
375
                  "xchgb %b0, %h0\n"
376
                  : "=q" (val)
377
                  : "m" (*(uint16_t *)ptr));
378
    return val;
379
#else
380
    uint8_t *b = (uint8_t *) ptr;
381
    return ((b[0] << 8) | b[1]);
382
#endif
383
}
384

    
385
static inline int ldsw_be_p(void *ptr)
386
{
387
#if defined(__i386__)
388
    int val;
389
    asm volatile ("movzwl %1, %0\n"
390
                  "xchgb %b0, %h0\n"
391
                  : "=q" (val)
392
                  : "m" (*(uint16_t *)ptr));
393
    return (int16_t)val;
394
#else
395
    uint8_t *b = (uint8_t *) ptr;
396
    return (int16_t)((b[0] << 8) | b[1]);
397
#endif
398
}
399

    
400
static inline int ldl_be_p(void *ptr)
401
{
402
#if defined(__i386__) || defined(__x86_64__)
403
    int val;
404
    asm volatile ("movl %1, %0\n"
405
                  "bswap %0\n"
406
                  : "=r" (val)
407
                  : "m" (*(uint32_t *)ptr));
408
    return val;
409
#else
410
    uint8_t *b = (uint8_t *) ptr;
411
    return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
412
#endif
413
}
414

    
415
static inline uint64_t ldq_be_p(void *ptr)
416
{
417
    uint32_t a,b;
418
    a = ldl_be_p(ptr);
419
    b = ldl_be_p(ptr+4);
420
    return (((uint64_t)a<<32)|b);
421
}
422

    
423
static inline void stw_be_p(void *ptr, int v)
424
{
425
#if defined(__i386__)
426
    asm volatile ("xchgb %b0, %h0\n"
427
                  "movw %w0, %1\n"
428
                  : "=q" (v)
429
                  : "m" (*(uint16_t *)ptr), "0" (v));
430
#else
431
    uint8_t *d = (uint8_t *) ptr;
432
    d[0] = v >> 8;
433
    d[1] = v;
434
#endif
435
}
436

    
437
static inline void stl_be_p(void *ptr, int v)
438
{
439
#if defined(__i386__) || defined(__x86_64__)
440
    asm volatile ("bswap %0\n"
441
                  "movl %0, %1\n"
442
                  : "=r" (v)
443
                  : "m" (*(uint32_t *)ptr), "0" (v));
444
#else
445
    uint8_t *d = (uint8_t *) ptr;
446
    d[0] = v >> 24;
447
    d[1] = v >> 16;
448
    d[2] = v >> 8;
449
    d[3] = v;
450
#endif
451
}
452

    
453
static inline void stq_be_p(void *ptr, uint64_t v)
454
{
455
    stl_be_p(ptr, v >> 32);
456
    stl_be_p(ptr + 4, v);
457
}
458

    
459
/* float access */
460

    
461
static inline float32 ldfl_be_p(void *ptr)
462
{
463
    union {
464
        float32 f;
465
        uint32_t i;
466
    } u;
467
    u.i = ldl_be_p(ptr);
468
    return u.f;
469
}
470

    
471
static inline void stfl_be_p(void *ptr, float32 v)
472
{
473
    union {
474
        float32 f;
475
        uint32_t i;
476
    } u;
477
    u.f = v;
478
    stl_be_p(ptr, u.i);
479
}
480

    
481
static inline float64 ldfq_be_p(void *ptr)
482
{
483
    CPU_DoubleU u;
484
    u.l.upper = ldl_be_p(ptr);
485
    u.l.lower = ldl_be_p(ptr + 4);
486
    return u.d;
487
}
488

    
489
static inline void stfq_be_p(void *ptr, float64 v)
490
{
491
    CPU_DoubleU u;
492
    u.d = v;
493
    stl_be_p(ptr, u.l.upper);
494
    stl_be_p(ptr + 4, u.l.lower);
495
}
496

    
497
#else
498

    
499
static inline int lduw_be_p(void *ptr)
500
{
501
    return *(uint16_t *)ptr;
502
}
503

    
504
static inline int ldsw_be_p(void *ptr)
505
{
506
    return *(int16_t *)ptr;
507
}
508

    
509
static inline int ldl_be_p(void *ptr)
510
{
511
    return *(uint32_t *)ptr;
512
}
513

    
514
static inline uint64_t ldq_be_p(void *ptr)
515
{
516
    return *(uint64_t *)ptr;
517
}
518

    
519
static inline void stw_be_p(void *ptr, int v)
520
{
521
    *(uint16_t *)ptr = v;
522
}
523

    
524
static inline void stl_be_p(void *ptr, int v)
525
{
526
    *(uint32_t *)ptr = v;
527
}
528

    
529
static inline void stq_be_p(void *ptr, uint64_t v)
530
{
531
    *(uint64_t *)ptr = v;
532
}
533

    
534
/* float access */
535

    
536
static inline float32 ldfl_be_p(void *ptr)
537
{
538
    return *(float32 *)ptr;
539
}
540

    
541
static inline float64 ldfq_be_p(void *ptr)
542
{
543
    return *(float64 *)ptr;
544
}
545

    
546
static inline void stfl_be_p(void *ptr, float32 v)
547
{
548
    *(float32 *)ptr = v;
549
}
550

    
551
static inline void stfq_be_p(void *ptr, float64 v)
552
{
553
    *(float64 *)ptr = v;
554
}
555

    
556
#endif
557

    
558
/* target CPU memory access functions */
559
#if defined(TARGET_WORDS_BIGENDIAN)
560
#define lduw_p(p) lduw_be_p(p)
561
#define ldsw_p(p) ldsw_be_p(p)
562
#define ldl_p(p) ldl_be_p(p)
563
#define ldq_p(p) ldq_be_p(p)
564
#define ldfl_p(p) ldfl_be_p(p)
565
#define ldfq_p(p) ldfq_be_p(p)
566
#define stw_p(p, v) stw_be_p(p, v)
567
#define stl_p(p, v) stl_be_p(p, v)
568
#define stq_p(p, v) stq_be_p(p, v)
569
#define stfl_p(p, v) stfl_be_p(p, v)
570
#define stfq_p(p, v) stfq_be_p(p, v)
571
#else
572
#define lduw_p(p) lduw_le_p(p)
573
#define ldsw_p(p) ldsw_le_p(p)
574
#define ldl_p(p) ldl_le_p(p)
575
#define ldq_p(p) ldq_le_p(p)
576
#define ldfl_p(p) ldfl_le_p(p)
577
#define ldfq_p(p) ldfq_le_p(p)
578
#define stw_p(p, v) stw_le_p(p, v)
579
#define stl_p(p, v) stl_le_p(p, v)
580
#define stq_p(p, v) stq_le_p(p, v)
581
#define stfl_p(p, v) stfl_le_p(p, v)
582
#define stfq_p(p, v) stfq_le_p(p, v)
583
#endif
584

    
585
/* MMU memory access macros */
586

    
587
#if defined(CONFIG_USER_ONLY)
588
/* On some host systems the guest address space is reserved on the host.
589
 * This allows the guest address space to be offset to a convenient location.
590
 */
591
//#define GUEST_BASE 0x20000000
592
#define GUEST_BASE 0
593

    
594
/* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
595
#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
596
#define h2g(x) ((target_ulong)(x - GUEST_BASE))
597

    
598
#define saddr(x) g2h(x)
599
#define laddr(x) g2h(x)
600

    
601
#else /* !CONFIG_USER_ONLY */
602
/* NOTE: we use double casts if pointers and target_ulong have
603
   different sizes */
604
#define saddr(x) (uint8_t *)(long)(x)
605
#define laddr(x) (uint8_t *)(long)(x)
606
#endif
607

    
608
#define ldub_raw(p) ldub_p(laddr((p)))
609
#define ldsb_raw(p) ldsb_p(laddr((p)))
610
#define lduw_raw(p) lduw_p(laddr((p)))
611
#define ldsw_raw(p) ldsw_p(laddr((p)))
612
#define ldl_raw(p) ldl_p(laddr((p)))
613
#define ldq_raw(p) ldq_p(laddr((p)))
614
#define ldfl_raw(p) ldfl_p(laddr((p)))
615
#define ldfq_raw(p) ldfq_p(laddr((p)))
616
#define stb_raw(p, v) stb_p(saddr((p)), v)
617
#define stw_raw(p, v) stw_p(saddr((p)), v)
618
#define stl_raw(p, v) stl_p(saddr((p)), v)
619
#define stq_raw(p, v) stq_p(saddr((p)), v)
620
#define stfl_raw(p, v) stfl_p(saddr((p)), v)
621
#define stfq_raw(p, v) stfq_p(saddr((p)), v)
622

    
623

    
624
#if defined(CONFIG_USER_ONLY) 
625

    
626
/* if user mode, no other memory access functions */
627
#define ldub(p) ldub_raw(p)
628
#define ldsb(p) ldsb_raw(p)
629
#define lduw(p) lduw_raw(p)
630
#define ldsw(p) ldsw_raw(p)
631
#define ldl(p) ldl_raw(p)
632
#define ldq(p) ldq_raw(p)
633
#define ldfl(p) ldfl_raw(p)
634
#define ldfq(p) ldfq_raw(p)
635
#define stb(p, v) stb_raw(p, v)
636
#define stw(p, v) stw_raw(p, v)
637
#define stl(p, v) stl_raw(p, v)
638
#define stq(p, v) stq_raw(p, v)
639
#define stfl(p, v) stfl_raw(p, v)
640
#define stfq(p, v) stfq_raw(p, v)
641

    
642
#define ldub_code(p) ldub_raw(p)
643
#define ldsb_code(p) ldsb_raw(p)
644
#define lduw_code(p) lduw_raw(p)
645
#define ldsw_code(p) ldsw_raw(p)
646
#define ldl_code(p) ldl_raw(p)
647

    
648
#define ldub_kernel(p) ldub_raw(p)
649
#define ldsb_kernel(p) ldsb_raw(p)
650
#define lduw_kernel(p) lduw_raw(p)
651
#define ldsw_kernel(p) ldsw_raw(p)
652
#define ldl_kernel(p) ldl_raw(p)
653
#define ldfl_kernel(p) ldfl_raw(p)
654
#define ldfq_kernel(p) ldfq_raw(p)
655
#define stb_kernel(p, v) stb_raw(p, v)
656
#define stw_kernel(p, v) stw_raw(p, v)
657
#define stl_kernel(p, v) stl_raw(p, v)
658
#define stq_kernel(p, v) stq_raw(p, v)
659
#define stfl_kernel(p, v) stfl_raw(p, v)
660
#define stfq_kernel(p, vt) stfq_raw(p, v)
661

    
662
#endif /* defined(CONFIG_USER_ONLY) */
663

    
664
/* page related stuff */
665

    
666
#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
667
#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
668
#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
669

    
670
/* ??? These should be the larger of unsigned long and target_ulong.  */
671
extern unsigned long qemu_real_host_page_size;
672
extern unsigned long qemu_host_page_bits;
673
extern unsigned long qemu_host_page_size;
674
extern unsigned long qemu_host_page_mask;
675

    
676
#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
677

    
678
/* same as PROT_xxx */
679
#define PAGE_READ      0x0001
680
#define PAGE_WRITE     0x0002
681
#define PAGE_EXEC      0x0004
682
#define PAGE_BITS      (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
683
#define PAGE_VALID     0x0008
684
/* original state of the write flag (used when tracking self-modifying
685
   code */
686
#define PAGE_WRITE_ORG 0x0010 
687

    
688
void page_dump(FILE *f);
689
int page_get_flags(target_ulong address);
690
void page_set_flags(target_ulong start, target_ulong end, int flags);
691
void page_unprotect_range(target_ulong data, target_ulong data_size);
692

    
693
#define SINGLE_CPU_DEFINES
694
#ifdef SINGLE_CPU_DEFINES
695

    
696
#if defined(TARGET_I386)
697

    
698
#define CPUState CPUX86State
699
#define cpu_init cpu_x86_init
700
#define cpu_exec cpu_x86_exec
701
#define cpu_gen_code cpu_x86_gen_code
702
#define cpu_signal_handler cpu_x86_signal_handler
703

    
704
#elif defined(TARGET_ARM)
705

    
706
#define CPUState CPUARMState
707
#define cpu_init cpu_arm_init
708
#define cpu_exec cpu_arm_exec
709
#define cpu_gen_code cpu_arm_gen_code
710
#define cpu_signal_handler cpu_arm_signal_handler
711

    
712
#elif defined(TARGET_SPARC)
713

    
714
#define CPUState CPUSPARCState
715
#define cpu_init cpu_sparc_init
716
#define cpu_exec cpu_sparc_exec
717
#define cpu_gen_code cpu_sparc_gen_code
718
#define cpu_signal_handler cpu_sparc_signal_handler
719

    
720
#elif defined(TARGET_PPC)
721

    
722
#define CPUState CPUPPCState
723
#define cpu_init cpu_ppc_init
724
#define cpu_exec cpu_ppc_exec
725
#define cpu_gen_code cpu_ppc_gen_code
726
#define cpu_signal_handler cpu_ppc_signal_handler
727

    
728
#elif defined(TARGET_MIPS)
729
#define CPUState CPUMIPSState
730
#define cpu_init cpu_mips_init
731
#define cpu_exec cpu_mips_exec
732
#define cpu_gen_code cpu_mips_gen_code
733
#define cpu_signal_handler cpu_mips_signal_handler
734

    
735
#elif defined(TARGET_SH4)
736
#define CPUState CPUSH4State
737
#define cpu_init cpu_sh4_init
738
#define cpu_exec cpu_sh4_exec
739
#define cpu_gen_code cpu_sh4_gen_code
740
#define cpu_signal_handler cpu_sh4_signal_handler
741

    
742
#else
743

    
744
#error unsupported target CPU
745

    
746
#endif
747

    
748
#endif /* SINGLE_CPU_DEFINES */
749

    
750
void cpu_dump_state(CPUState *env, FILE *f, 
751
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
752
                    int flags);
753

    
754
void cpu_abort(CPUState *env, const char *fmt, ...);
755
extern CPUState *first_cpu;
756
extern CPUState *cpu_single_env;
757
extern int code_copy_enabled;
758

    
759
#define CPU_INTERRUPT_EXIT   0x01 /* wants exit from main loop */
760
#define CPU_INTERRUPT_HARD   0x02 /* hardware interrupt pending */
761
#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
762
#define CPU_INTERRUPT_TIMER  0x08 /* internal timer exception pending */
763
#define CPU_INTERRUPT_FIQ    0x10 /* Fast interrupt pending.  */
764
#define CPU_INTERRUPT_HALT   0x20 /* CPU halt wanted */
765

    
766
void cpu_interrupt(CPUState *s, int mask);
767
void cpu_reset_interrupt(CPUState *env, int mask);
768

    
769
int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
770
int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
771
void cpu_single_step(CPUState *env, int enabled);
772
void cpu_reset(CPUState *s);
773

    
774
/* Return the physical page corresponding to a virtual one. Use it
775
   only for debugging because no protection checks are done. Return -1
776
   if no page found. */
777
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
778

    
779
#define CPU_LOG_TB_OUT_ASM (1 << 0) 
780
#define CPU_LOG_TB_IN_ASM  (1 << 1)
781
#define CPU_LOG_TB_OP      (1 << 2)
782
#define CPU_LOG_TB_OP_OPT  (1 << 3)
783
#define CPU_LOG_INT        (1 << 4)
784
#define CPU_LOG_EXEC       (1 << 5)
785
#define CPU_LOG_PCALL      (1 << 6)
786
#define CPU_LOG_IOPORT     (1 << 7)
787
#define CPU_LOG_TB_CPU     (1 << 8)
788

    
789
/* define log items */
790
typedef struct CPULogItem {
791
    int mask;
792
    const char *name;
793
    const char *help;
794
} CPULogItem;
795

    
796
extern CPULogItem cpu_log_items[];
797

    
798
void cpu_set_log(int log_flags);
799
void cpu_set_log_filename(const char *filename);
800
int cpu_str_to_log_mask(const char *str);
801

    
802
/* IO ports API */
803

    
804
/* NOTE: as these functions may be even used when there is an isa
805
   brige on non x86 targets, we always defined them */
806
#ifndef NO_CPU_IO_DEFS
807
void cpu_outb(CPUState *env, int addr, int val);
808
void cpu_outw(CPUState *env, int addr, int val);
809
void cpu_outl(CPUState *env, int addr, int val);
810
int cpu_inb(CPUState *env, int addr);
811
int cpu_inw(CPUState *env, int addr);
812
int cpu_inl(CPUState *env, int addr);
813
#endif
814

    
815
/* memory API */
816

    
817
extern int phys_ram_size;
818
extern int phys_ram_fd;
819
extern uint8_t *phys_ram_base;
820
extern uint8_t *phys_ram_dirty;
821

    
822
/* physical memory access */
823
#define TLB_INVALID_MASK   (1 << 3)
824
#define IO_MEM_SHIFT       4
825
#define IO_MEM_NB_ENTRIES  (1 << (TARGET_PAGE_BITS  - IO_MEM_SHIFT))
826

    
827
#define IO_MEM_RAM         (0 << IO_MEM_SHIFT) /* hardcoded offset */
828
#define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
829
#define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
830
#define IO_MEM_NOTDIRTY    (4 << IO_MEM_SHIFT) /* used internally, never use directly */
831
/* acts like a ROM when read and like a device when written. As an
832
   exception, the write memory callback gets the ram offset instead of
833
   the physical address */
834
#define IO_MEM_ROMD        (1)
835

    
836
typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
837
typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
838

    
839
void cpu_register_physical_memory(target_phys_addr_t start_addr, 
840
                                  unsigned long size,
841
                                  unsigned long phys_offset);
842
int cpu_register_io_memory(int io_index,
843
                           CPUReadMemoryFunc **mem_read,
844
                           CPUWriteMemoryFunc **mem_write,
845
                           void *opaque);
846
CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
847
CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
848

    
849
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
850
                            int len, int is_write);
851
static inline void cpu_physical_memory_read(target_phys_addr_t addr, 
852
                                            uint8_t *buf, int len)
853
{
854
    cpu_physical_memory_rw(addr, buf, len, 0);
855
}
856
static inline void cpu_physical_memory_write(target_phys_addr_t addr, 
857
                                             const uint8_t *buf, int len)
858
{
859
    cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
860
}
861
uint32_t ldub_phys(target_phys_addr_t addr);
862
uint32_t lduw_phys(target_phys_addr_t addr);
863
uint32_t ldl_phys(target_phys_addr_t addr);
864
uint64_t ldq_phys(target_phys_addr_t addr);
865
void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val);
866
void stb_phys(target_phys_addr_t addr, uint32_t val);
867
void stw_phys(target_phys_addr_t addr, uint32_t val);
868
void stl_phys(target_phys_addr_t addr, uint32_t val);
869
void stq_phys(target_phys_addr_t addr, uint64_t val);
870

    
871
void cpu_physical_memory_write_rom(target_phys_addr_t addr, 
872
                                   const uint8_t *buf, int len);
873
int cpu_memory_rw_debug(CPUState *env, target_ulong addr, 
874
                        uint8_t *buf, int len, int is_write);
875

    
876
#define VGA_DIRTY_FLAG  0x01
877
#define CODE_DIRTY_FLAG 0x02
878

    
879
/* read dirty bit (return 0 or 1) */
880
static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
881
{
882
    return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
883
}
884

    
885
static inline int cpu_physical_memory_get_dirty(ram_addr_t addr, 
886
                                                int dirty_flags)
887
{
888
    return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
889
}
890

    
891
static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
892
{
893
    phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
894
}
895

    
896
void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
897
                                     int dirty_flags);
898
void cpu_tlb_update_dirty(CPUState *env);
899

    
900
void dump_exec_info(FILE *f,
901
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
902

    
903
/* profiling */
904
#ifdef CONFIG_PROFILER
905
static inline int64_t profile_getclock(void)
906
{
907
    int64_t val;
908
    asm volatile ("rdtsc" : "=A" (val));
909
    return val;
910
}
911

    
912
extern int64_t kqemu_time, kqemu_time_start;
913
extern int64_t qemu_time, qemu_time_start;
914
extern int64_t tlb_flush_time;
915
extern int64_t kqemu_exec_count;
916
extern int64_t dev_time;
917
extern int64_t kqemu_ret_int_count;
918
extern int64_t kqemu_ret_excp_count;
919
extern int64_t kqemu_ret_intr_count;
920

    
921
#endif
922

    
923
#endif /* CPU_ALL_H */