cpu-all.h 15.3 KB
Newer Older
B
bellard 已提交
1 2
/*
 * defines common to all virtual CPUs
3
 *
B
bellard 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16
 *  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
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
B
bellard 已提交
18 19 20 21
 */
#ifndef CPU_ALL_H
#define CPU_ALL_H

B
blueswir1 已提交
22
#include "qemu-common.h"
P
Paolo Bonzini 已提交
23
#include "qemu-tls.h"
P
Paul Brook 已提交
24
#include "cpu-common.h"
B
bellard 已提交
25

26 27
/* some important defines:
 *
B
bellard 已提交
28 29
 * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
 * memory accesses.
30
 *
31
 * HOST_WORDS_BIGENDIAN : if defined, the host cpu is big endian and
B
bellard 已提交
32
 * otherwise little endian.
33
 *
B
bellard 已提交
34
 * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
35
 *
B
bellard 已提交
36 37 38
 * TARGET_WORDS_BIGENDIAN : same for target cpu
 */

39
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
#define BSWAP_NEEDED
#endif

#ifdef BSWAP_NEEDED

static inline uint16_t tswap16(uint16_t s)
{
    return bswap16(s);
}

static inline uint32_t tswap32(uint32_t s)
{
    return bswap32(s);
}

static inline uint64_t tswap64(uint64_t s)
{
    return bswap64(s);
}

static inline void tswap16s(uint16_t *s)
{
    *s = bswap16(*s);
}

static inline void tswap32s(uint32_t *s)
{
    *s = bswap32(*s);
}

static inline void tswap64s(uint64_t *s)
{
    *s = bswap64(*s);
}

#else

static inline uint16_t tswap16(uint16_t s)
{
    return s;
}

static inline uint32_t tswap32(uint32_t s)
{
    return s;
}

static inline uint64_t tswap64(uint64_t s)
{
    return s;
}

static inline void tswap16s(uint16_t *s)
{
}

static inline void tswap32s(uint32_t *s)
{
}

static inline void tswap64s(uint64_t *s)
{
}

#endif

#if TARGET_LONG_SIZE == 4
#define tswapl(s) tswap32(s)
#define tswapls(s) tswap32s((uint32_t *)(s))
B
bellard 已提交
109
#define bswaptls(s) bswap32s(s)
110 111 112
#else
#define tswapl(s) tswap64(s)
#define tswapls(s) tswap64s((uint64_t *)(s))
B
bellard 已提交
113
#define bswaptls(s) bswap64s(s)
114 115
#endif

B
bellard 已提交
116 117
/* CPU memory access without any memory or io remapping */

118 119 120 121 122 123 124 125 126 127
/*
 * the generic syntax for the memory accesses is:
 *
 * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
 *
 * store: st{type}{size}{endian}_{access_type}(ptr, val)
 *
 * type is:
 * (empty): integer access
 *   f    : float access
128
 *
129 130 131 132 133 134 135 136 137 138
 * sign is:
 * (empty): for floats or 32 bit size
 *   u    : unsigned
 *   s    : signed
 *
 * size is:
 *   b: 8 bits
 *   w: 16 bits
 *   l: 32 bits
 *   q: 64 bits
139
 *
140 141 142 143 144 145 146 147 148 149 150
 * endian is:
 * (empty): target cpu endianness or 8 bit access
 *   r    : reversed target cpu endianness (not implemented yet)
 *   be   : big endian (not implemented yet)
 *   le   : little endian (not implemented yet)
 *
 * access_type is:
 *   raw    : host memory access
 *   user   : user mode access using soft MMU
 *   kernel : kernel mode access using soft MMU
 */
151

152
/* target-endianness CPU memory access functions */
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
#if defined(TARGET_WORDS_BIGENDIAN)
#define lduw_p(p) lduw_be_p(p)
#define ldsw_p(p) ldsw_be_p(p)
#define ldl_p(p) ldl_be_p(p)
#define ldq_p(p) ldq_be_p(p)
#define ldfl_p(p) ldfl_be_p(p)
#define ldfq_p(p) ldfq_be_p(p)
#define stw_p(p, v) stw_be_p(p, v)
#define stl_p(p, v) stl_be_p(p, v)
#define stq_p(p, v) stq_be_p(p, v)
#define stfl_p(p, v) stfl_be_p(p, v)
#define stfq_p(p, v) stfq_be_p(p, v)
#else
#define lduw_p(p) lduw_le_p(p)
#define ldsw_p(p) ldsw_le_p(p)
#define ldl_p(p) ldl_le_p(p)
#define ldq_p(p) ldq_le_p(p)
#define ldfl_p(p) ldfl_le_p(p)
#define ldfq_p(p) ldfq_le_p(p)
#define stw_p(p, v) stw_le_p(p, v)
#define stl_p(p, v) stl_le_p(p, v)
#define stq_p(p, v) stq_le_p(p, v)
#define stfl_p(p, v) stfl_le_p(p, v)
#define stfq_p(p, v) stfq_le_p(p, v)
B
bellard 已提交
177 178
#endif

B
bellard 已提交
179 180
/* MMU memory access macros */

181
#if defined(CONFIG_USER_ONLY)
A
aurel32 已提交
182 183 184
#include <assert.h>
#include "qemu-types.h"

185 186 187
/* On some host systems the guest address space is reserved on the host.
 * This allows the guest address space to be offset to a convenient location.
 */
P
Paul Brook 已提交
188 189 190
#if defined(CONFIG_USE_GUEST_BASE)
extern unsigned long guest_base;
extern int have_guest_base;
P
Paul Brook 已提交
191
extern unsigned long reserved_va;
P
Paul Brook 已提交
192
#define GUEST_BASE guest_base
193
#define RESERVED_VA reserved_va
P
Paul Brook 已提交
194 195
#else
#define GUEST_BASE 0ul
196
#define RESERVED_VA 0ul
P
Paul Brook 已提交
197
#endif
198 199

/* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
200
#define g2h(x) ((void *)((unsigned long)(target_ulong)(x) + GUEST_BASE))
201 202 203 204 205 206

#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
#define h2g_valid(x) 1
#else
#define h2g_valid(x) ({ \
    unsigned long __guest = (unsigned long)(x) - GUEST_BASE; \
207 208
    (__guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS)) && \
    (!RESERVED_VA || (__guest < RESERVED_VA)); \
209 210 211
})
#endif

A
aurel32 已提交
212 213 214
#define h2g(x) ({ \
    unsigned long __ret = (unsigned long)(x) - GUEST_BASE; \
    /* Check if given address fits target address space */ \
215
    assert(h2g_valid(x)); \
A
aurel32 已提交
216 217
    (abi_ulong)__ret; \
})
218 219 220 221 222

#define saddr(x) g2h(x)
#define laddr(x) g2h(x)

#else /* !CONFIG_USER_ONLY */
B
bellard 已提交
223 224
/* NOTE: we use double casts if pointers and target_ulong have
   different sizes */
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
#define saddr(x) (uint8_t *)(long)(x)
#define laddr(x) (uint8_t *)(long)(x)
#endif

#define ldub_raw(p) ldub_p(laddr((p)))
#define ldsb_raw(p) ldsb_p(laddr((p)))
#define lduw_raw(p) lduw_p(laddr((p)))
#define ldsw_raw(p) ldsw_p(laddr((p)))
#define ldl_raw(p) ldl_p(laddr((p)))
#define ldq_raw(p) ldq_p(laddr((p)))
#define ldfl_raw(p) ldfl_p(laddr((p)))
#define ldfq_raw(p) ldfq_p(laddr((p)))
#define stb_raw(p, v) stb_p(saddr((p)), v)
#define stw_raw(p, v) stw_p(saddr((p)), v)
#define stl_raw(p, v) stl_p(saddr((p)), v)
#define stq_raw(p, v) stq_p(saddr((p)), v)
#define stfl_raw(p, v) stfl_p(saddr((p)), v)
#define stfq_raw(p, v) stfq_p(saddr((p)), v)
B
bellard 已提交
243 244


245
#if defined(CONFIG_USER_ONLY)
B
bellard 已提交
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262

/* 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)

263
#ifndef CONFIG_TCG_PASS_AREG0
B
bellard 已提交
264 265 266 267 268
#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)
J
j_mayer 已提交
269
#define ldq_code(p) ldq_raw(p)
270 271 272 273 274 275 276 277
#else
#define cpu_ldub_code(env1, p) ldub_raw(p)
#define cpu_ldsb_code(env1, p) ldsb_raw(p)
#define cpu_lduw_code(env1, p) lduw_raw(p)
#define cpu_ldsw_code(env1, p) ldsw_raw(p)
#define cpu_ldl_code(env1, p) ldl_raw(p)
#define cpu_ldq_code(env1, p) ldq_raw(p)
#endif
B
bellard 已提交
278 279 280 281 282 283

#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)
J
j_mayer 已提交
284
#define ldq_kernel(p) ldq_raw(p)
B
bellard 已提交
285 286
#define ldfl_kernel(p) ldfl_raw(p)
#define ldfq_kernel(p) ldfq_raw(p)
B
bellard 已提交
287 288 289 290
#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)
B
bellard 已提交
291 292
#define stfl_kernel(p, v) stfl_raw(p, v)
#define stfq_kernel(p, vt) stfq_raw(p, v)
B
bellard 已提交
293 294 295

#endif /* defined(CONFIG_USER_ONLY) */

B
bellard 已提交
296 297
/* page related stuff */

298
#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
B
bellard 已提交
299 300 301
#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)

302
/* ??? These should be the larger of unsigned long and target_ulong.  */
303 304 305
extern unsigned long qemu_real_host_page_size;
extern unsigned long qemu_host_page_size;
extern unsigned long qemu_host_page_mask;
B
bellard 已提交
306

307
#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
B
bellard 已提交
308 309 310 311 312 313 314 315 316

/* 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 */
317
#define PAGE_WRITE_ORG 0x0010
P
Paul Brook 已提交
318 319
#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
/* FIXME: Code that sets/uses this is broken and needs to go away.  */
320
#define PAGE_RESERVED  0x0020
P
Paul Brook 已提交
321
#endif
B
bellard 已提交
322

P
Paul Brook 已提交
323
#if defined(CONFIG_USER_ONLY)
B
bellard 已提交
324
void page_dump(FILE *f);
325

P
Paul Brook 已提交
326 327
typedef int (*walk_memory_regions_fn)(void *, abi_ulong,
                                      abi_ulong, unsigned long);
328 329
int walk_memory_regions(void *, walk_memory_regions_fn);

330 331
int page_get_flags(target_ulong address);
void page_set_flags(target_ulong start, target_ulong end, int flags);
332
int page_check_range(target_ulong start, target_ulong len, int flags);
P
Paul Brook 已提交
333
#endif
B
bellard 已提交
334

335 336
CPUArchState *cpu_copy(CPUArchState *env);
CPUArchState *qemu_get_cpu(int cpu);
337

338 339
#define CPU_DUMP_CODE 0x00010000

340
void cpu_dump_state(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
B
bellard 已提交
341
                    int flags);
342
void cpu_dump_statistics(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
343
                         int flags);
B
bellard 已提交
344

345
void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
346
    GCC_FMT_ATTR(2, 3);
347 348
extern CPUArchState *first_cpu;
DECLARE_TLS(CPUArchState *,cpu_single_env);
J
Jan Kiszka 已提交
349
#define cpu_single_env tls_var(cpu_single_env)
P
Paolo Bonzini 已提交
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
/* Flags for use in ENV->INTERRUPT_PENDING.

   The numbers assigned here are non-sequential in order to preserve
   binary compatibility with the vmstate dump.  Bit 0 (0x0001) was
   previously used for CPU_INTERRUPT_EXIT, and is cleared when loading
   the vmstate dump.  */

/* External hardware interrupt pending.  This is typically used for
   interrupts from devices.  */
#define CPU_INTERRUPT_HARD        0x0002

/* Exit the current TB.  This is typically used when some system-level device
   makes some change to the memory mapping.  E.g. the a20 line change.  */
#define CPU_INTERRUPT_EXITTB      0x0004

/* Halt the CPU.  */
#define CPU_INTERRUPT_HALT        0x0020

/* Debug event pending.  */
#define CPU_INTERRUPT_DEBUG       0x0080

/* Several target-specific external hardware interrupts.  Each target/cpu.h
   should define proper names based on these defines.  */
#define CPU_INTERRUPT_TGT_EXT_0   0x0008
#define CPU_INTERRUPT_TGT_EXT_1   0x0010
#define CPU_INTERRUPT_TGT_EXT_2   0x0040
#define CPU_INTERRUPT_TGT_EXT_3   0x0200
#define CPU_INTERRUPT_TGT_EXT_4   0x1000

/* Several target-specific internal interrupts.  These differ from the
D
Dong Xu Wang 已提交
381
   preceding target-specific interrupts in that they are intended to
382 383 384 385 386 387
   originate from within the cpu itself, typically in response to some
   instruction being executed.  These, therefore, are not masked while
   single-stepping within the debugger.  */
#define CPU_INTERRUPT_TGT_INT_0   0x0100
#define CPU_INTERRUPT_TGT_INT_1   0x0400
#define CPU_INTERRUPT_TGT_INT_2   0x0800
388
#define CPU_INTERRUPT_TGT_INT_3   0x2000
389

390
/* First unused bit: 0x4000.  */
391

392 393 394 395 396 397 398 399
/* The set of all bits that should be masked when single-stepping.  */
#define CPU_INTERRUPT_SSTEP_MASK \
    (CPU_INTERRUPT_HARD          \
     | CPU_INTERRUPT_TGT_EXT_0   \
     | CPU_INTERRUPT_TGT_EXT_1   \
     | CPU_INTERRUPT_TGT_EXT_2   \
     | CPU_INTERRUPT_TGT_EXT_3   \
     | CPU_INTERRUPT_TGT_EXT_4)
B
bellard 已提交
400

401
#ifndef CONFIG_USER_ONLY
402
typedef void (*CPUInterruptHandler)(CPUArchState *, int);
403 404 405

extern CPUInterruptHandler cpu_interrupt_handler;

406
static inline void cpu_interrupt(CPUArchState *s, int mask)
407 408 409 410
{
    cpu_interrupt_handler(s, mask);
}
#else /* USER_ONLY */
411
void cpu_interrupt(CPUArchState *env, int mask);
412 413
#endif /* USER_ONLY */

414
void cpu_reset_interrupt(CPUArchState *env, int mask);
B
bellard 已提交
415

416
void cpu_exit(CPUArchState *s);
417

418
bool qemu_cpu_has_work(CPUArchState *env);
419

420 421 422 423
/* Breakpoint/watchpoint flags */
#define BP_MEM_READ           0x01
#define BP_MEM_WRITE          0x02
#define BP_MEM_ACCESS         (BP_MEM_READ | BP_MEM_WRITE)
424
#define BP_STOP_BEFORE_ACCESS 0x04
425
#define BP_WATCHPOINT_HIT     0x08
426
#define BP_GDB                0x10
427
#define BP_CPU                0x20
428

429
int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
430
                          CPUBreakpoint **breakpoint);
431 432 433 434
int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags);
void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint);
void cpu_breakpoint_remove_all(CPUArchState *env, int mask);
int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
435
                          int flags, CPUWatchpoint **watchpoint);
436
int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr,
437
                          target_ulong len, int flags);
438 439
void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
440 441 442 443 444

#define SSTEP_ENABLE  0x1  /* Enable simulated HW single stepping */
#define SSTEP_NOIRQ   0x2  /* Do not use IRQ while single stepping */
#define SSTEP_NOTIMER 0x4  /* Do not Timers while single stepping */

445 446 447 448
void cpu_single_step(CPUArchState *env, int enabled);
void cpu_state_reset(CPUArchState *s);
int cpu_is_stopped(CPUArchState *env);
void run_on_cpu(CPUArchState *env, void (*func)(void *data), void *data);
B
bellard 已提交
449

450
#define CPU_LOG_TB_OUT_ASM (1 << 0)
451
#define CPU_LOG_TB_IN_ASM  (1 << 1)
452 453 454 455 456
#define CPU_LOG_TB_OP      (1 << 2)
#define CPU_LOG_TB_OP_OPT  (1 << 3)
#define CPU_LOG_INT        (1 << 4)
#define CPU_LOG_EXEC       (1 << 5)
#define CPU_LOG_PCALL      (1 << 6)
457
#define CPU_LOG_IOPORT     (1 << 7)
458
#define CPU_LOG_TB_CPU     (1 << 8)
A
aliguori 已提交
459
#define CPU_LOG_RESET      (1 << 9)
460 461 462 463 464 465 466 467

/* define log items */
typedef struct CPULogItem {
    int mask;
    const char *name;
    const char *help;
} CPULogItem;

B
blueswir1 已提交
468
extern const CPULogItem cpu_log_items[];
469

470 471
void cpu_set_log(int log_flags);
void cpu_set_log_filename(const char *filename);
472
int cpu_str_to_log_mask(const char *str);
473

474 475
#if !defined(CONFIG_USER_ONLY)

476 477 478
/* Return the physical page corresponding to a virtual one. Use it
   only for debugging because no protection checks are done. Return -1
   if no page found. */
479
target_phys_addr_t cpu_get_phys_page_debug(CPUArchState *env, target_ulong addr);
480

481 482
/* memory API */

B
bellard 已提交
483
extern int phys_ram_fd;
A
Anthony Liguori 已提交
484
extern ram_addr_t ram_size;
A
Alex Williamson 已提交
485

H
Huang Ying 已提交
486 487 488
/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
#define RAM_PREALLOC_MASK   (1 << 0)

A
Alex Williamson 已提交
489
typedef struct RAMBlock {
A
Avi Kivity 已提交
490
    struct MemoryRegion *mr;
A
Alex Williamson 已提交
491 492 493
    uint8_t *host;
    ram_addr_t offset;
    ram_addr_t length;
H
Huang Ying 已提交
494
    uint32_t flags;
495
    char idstr[256];
A
Alex Williamson 已提交
496
    QLIST_ENTRY(RAMBlock) next;
A
Alex Williamson 已提交
497 498 499
#if defined(__linux__) && !defined(TARGET_S390X)
    int fd;
#endif
A
Alex Williamson 已提交
500 501 502 503
} RAMBlock;

typedef struct RAMList {
    uint8_t *phys_dirty;
P
Paolo Bonzini 已提交
504
    QLIST_HEAD(, RAMBlock) blocks;
A
Alex Williamson 已提交
505 506
} RAMList;
extern RAMList ram_list;
B
bellard 已提交
507

508 509 510
extern const char *mem_path;
extern int mem_prealloc;

P
pbrook 已提交
511 512 513 514 515 516 517 518 519 520
/* Flags stored in the low bits of the TLB virtual address.  These are
   defined so that fast path ram access is all zeros.  */
/* Zero if TLB entry is valid.  */
#define TLB_INVALID_MASK   (1 << 3)
/* Set if TLB entry references a clean RAM page.  The iotlb entry will
   contain the page physical address.  */
#define TLB_NOTDIRTY    (1 << 4)
/* Set if TLB entry is an IO callback.  */
#define TLB_MMIO        (1 << 5)

521
void cpu_tlb_update_dirty(CPUArchState *env);
522

523
void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
524 525
#endif /* !CONFIG_USER_ONLY */

526
int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
527 528
                        uint8_t *buf, int len, int is_write);

B
bellard 已提交
529
#endif /* CPU_ALL_H */