cpu-all.h 14.9 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
#define saddr(x) (uint8_t *)(intptr_t)(x)
#define laddr(x) (uint8_t *)(intptr_t)(x)
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
#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 296 297 298 299 300 301 302
#ifdef CONFIG_TCG_PASS_AREG0
#define cpu_ldub_data(env, addr) ldub_raw(addr)
#define cpu_lduw_data(env, addr) lduw_raw(addr)
#define cpu_ldl_data(env, addr) ldl_raw(addr)

#define cpu_stb_data(env, addr, data) stb_raw(addr, data)
#define cpu_stw_data(env, addr, data) stw_raw(addr, data)
#define cpu_stl_data(env, addr, data) stl_raw(addr, data)
#endif
B
bellard 已提交
303 304
#endif /* defined(CONFIG_USER_ONLY) */

B
bellard 已提交
305 306
/* page related stuff */

307
#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
B
bellard 已提交
308 309 310
#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)

311 312 313 314
/* ??? These should be the larger of uintptr_t and target_ulong.  */
extern uintptr_t qemu_real_host_page_size;
extern uintptr_t qemu_host_page_size;
extern uintptr_t qemu_host_page_mask;
B
bellard 已提交
315

316
#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
B
bellard 已提交
317 318 319 320 321 322 323 324 325

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

P
Paul Brook 已提交
332
#if defined(CONFIG_USER_ONLY)
B
bellard 已提交
333
void page_dump(FILE *f);
334

P
Paul Brook 已提交
335 336
typedef int (*walk_memory_regions_fn)(void *, abi_ulong,
                                      abi_ulong, unsigned long);
337 338
int walk_memory_regions(void *, walk_memory_regions_fn);

339 340
int page_get_flags(target_ulong address);
void page_set_flags(target_ulong start, target_ulong end, int flags);
341
int page_check_range(target_ulong start, target_ulong len, int flags);
P
Paul Brook 已提交
342
#endif
B
bellard 已提交
343

344 345
CPUArchState *cpu_copy(CPUArchState *env);
CPUArchState *qemu_get_cpu(int cpu);
346

347 348
#define CPU_DUMP_CODE 0x00010000

349
void cpu_dump_state(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
B
bellard 已提交
350
                    int flags);
351
void cpu_dump_statistics(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
352
                         int flags);
B
bellard 已提交
353

354
void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
355
    GCC_FMT_ATTR(2, 3);
356 357
extern CPUArchState *first_cpu;
DECLARE_TLS(CPUArchState *,cpu_single_env);
J
Jan Kiszka 已提交
358
#define cpu_single_env tls_var(cpu_single_env)
P
Paolo Bonzini 已提交
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 389
/* 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 已提交
390
   preceding target-specific interrupts in that they are intended to
391 392 393 394 395 396
   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
397
#define CPU_INTERRUPT_TGT_INT_3   0x2000
398

399
/* First unused bit: 0x4000.  */
400

401 402 403 404 405 406 407 408
/* 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 已提交
409

410
#ifndef CONFIG_USER_ONLY
411
typedef void (*CPUInterruptHandler)(CPUArchState *, int);
412 413 414

extern CPUInterruptHandler cpu_interrupt_handler;

415
static inline void cpu_interrupt(CPUArchState *s, int mask)
416 417 418 419
{
    cpu_interrupt_handler(s, mask);
}
#else /* USER_ONLY */
420
void cpu_interrupt(CPUArchState *env, int mask);
421 422
#endif /* USER_ONLY */

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

425
void cpu_exit(CPUArchState *s);
426

427
bool qemu_cpu_has_work(CPUArchState *env);
428

429 430 431 432
/* Breakpoint/watchpoint flags */
#define BP_MEM_READ           0x01
#define BP_MEM_WRITE          0x02
#define BP_MEM_ACCESS         (BP_MEM_READ | BP_MEM_WRITE)
433
#define BP_STOP_BEFORE_ACCESS 0x04
434
#define BP_WATCHPOINT_HIT     0x08
435
#define BP_GDB                0x10
436
#define BP_CPU                0x20
437

438
int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
439
                          CPUBreakpoint **breakpoint);
440 441 442 443
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,
444
                          int flags, CPUWatchpoint **watchpoint);
445
int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr,
446
                          target_ulong len, int flags);
447 448
void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
449 450 451 452 453

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

454 455 456
void cpu_single_step(CPUArchState *env, int enabled);
int cpu_is_stopped(CPUArchState *env);
void run_on_cpu(CPUArchState *env, void (*func)(void *data), void *data);
B
bellard 已提交
457

458 459
#if !defined(CONFIG_USER_ONLY)

460 461 462
/* 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. */
463
target_phys_addr_t cpu_get_phys_page_debug(CPUArchState *env, target_ulong addr);
464

465 466
/* memory API */

B
bellard 已提交
467
extern int phys_ram_fd;
A
Anthony Liguori 已提交
468
extern ram_addr_t ram_size;
A
Alex Williamson 已提交
469

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

A
Alex Williamson 已提交
473
typedef struct RAMBlock {
A
Avi Kivity 已提交
474
    struct MemoryRegion *mr;
A
Alex Williamson 已提交
475 476 477
    uint8_t *host;
    ram_addr_t offset;
    ram_addr_t length;
H
Huang Ying 已提交
478
    uint32_t flags;
479
    char idstr[256];
A
Alex Williamson 已提交
480
    QLIST_ENTRY(RAMBlock) next;
A
Alex Williamson 已提交
481 482 483
#if defined(__linux__) && !defined(TARGET_S390X)
    int fd;
#endif
A
Alex Williamson 已提交
484 485 486 487
} RAMBlock;

typedef struct RAMList {
    uint8_t *phys_dirty;
P
Paolo Bonzini 已提交
488
    QLIST_HEAD(, RAMBlock) blocks;
489
    uint64_t dirty_pages;
A
Alex Williamson 已提交
490 491
} RAMList;
extern RAMList ram_list;
B
bellard 已提交
492

493 494 495
extern const char *mem_path;
extern int mem_prealloc;

P
pbrook 已提交
496 497 498 499 500 501 502 503 504 505
/* 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)

506
void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
507 508
#endif /* !CONFIG_USER_ONLY */

509
int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
510 511
                        uint8_t *buf, int len, int is_write);

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