cpu-all.h 16.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 200

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

#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; \
    __guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS); \
})
#endif

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

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

#else /* !CONFIG_USER_ONLY */
B
bellard 已提交
222 223
/* NOTE: we use double casts if pointers and target_ulong have
   different sizes */
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
#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 已提交
242 243


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

/* 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)
J
j_mayer 已提交
267
#define ldq_code(p) ldq_raw(p)
B
bellard 已提交
268 269 270 271 272 273

#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 已提交
274
#define ldq_kernel(p) ldq_raw(p)
B
bellard 已提交
275 276
#define ldfl_kernel(p) ldfl_raw(p)
#define ldfq_kernel(p) ldfq_raw(p)
B
bellard 已提交
277 278 279 280
#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 已提交
281 282
#define stfl_kernel(p, v) stfl_raw(p, v)
#define stfq_kernel(p, vt) stfq_raw(p, v)
B
bellard 已提交
283 284 285

#endif /* defined(CONFIG_USER_ONLY) */

B
bellard 已提交
286 287
/* page related stuff */

288
#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
B
bellard 已提交
289 290 291
#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)

292
/* ??? These should be the larger of unsigned long and target_ulong.  */
293 294 295
extern unsigned long qemu_real_host_page_size;
extern unsigned long qemu_host_page_size;
extern unsigned long qemu_host_page_mask;
B
bellard 已提交
296

297
#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
B
bellard 已提交
298 299 300 301 302 303 304 305 306

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

P
Paul Brook 已提交
313
#if defined(CONFIG_USER_ONLY)
B
bellard 已提交
314
void page_dump(FILE *f);
315

P
Paul Brook 已提交
316 317
typedef int (*walk_memory_regions_fn)(void *, abi_ulong,
                                      abi_ulong, unsigned long);
318 319
int walk_memory_regions(void *, walk_memory_regions_fn);

320 321
int page_get_flags(target_ulong address);
void page_set_flags(target_ulong start, target_ulong end, int flags);
322
int page_check_range(target_ulong start, target_ulong len, int flags);
P
Paul Brook 已提交
323
#endif
B
bellard 已提交
324

325
CPUState *cpu_copy(CPUState *env);
G
Glauber Costa 已提交
326
CPUState *qemu_get_cpu(int cpu);
327

328 329
#define CPU_DUMP_CODE 0x00010000

330
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
B
bellard 已提交
331
                    int flags);
332 333
void cpu_dump_statistics(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                         int flags);
B
bellard 已提交
334

M
malc 已提交
335
void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
336
    GCC_FMT_ATTR(2, 3);
B
bellard 已提交
337
extern CPUState *first_cpu;
P
Paolo Bonzini 已提交
338 339
DECLARE_TLS(CPUState *,cpu_single_env);
#define cpu_single_env get_tls(cpu_single_env)
P
Paolo Bonzini 已提交
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
/* 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 已提交
371
   preceding target-specific interrupts in that they are intended to
372 373 374 375 376 377 378 379 380
   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

/* First unused bit: 0x2000.  */

381 382 383 384 385 386 387 388
/* 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 已提交
389

390 391 392 393 394 395 396 397 398 399 400 401 402
#ifndef CONFIG_USER_ONLY
typedef void (*CPUInterruptHandler)(CPUState *, int);

extern CPUInterruptHandler cpu_interrupt_handler;

static inline void cpu_interrupt(CPUState *s, int mask)
{
    cpu_interrupt_handler(s, mask);
}
#else /* USER_ONLY */
void cpu_interrupt(CPUState *env, int mask);
#endif /* USER_ONLY */

403
void cpu_reset_interrupt(CPUState *env, int mask);
B
bellard 已提交
404

405 406
void cpu_exit(CPUState *s);

407
bool qemu_cpu_has_work(CPUState *env);
408

409 410 411 412
/* Breakpoint/watchpoint flags */
#define BP_MEM_READ           0x01
#define BP_MEM_WRITE          0x02
#define BP_MEM_ACCESS         (BP_MEM_READ | BP_MEM_WRITE)
413
#define BP_STOP_BEFORE_ACCESS 0x04
414
#define BP_WATCHPOINT_HIT     0x08
415
#define BP_GDB                0x10
416
#define BP_CPU                0x20
417 418 419 420 421 422 423 424 425 426 427 428

int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
                          CPUBreakpoint **breakpoint);
int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags);
void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint);
void cpu_breakpoint_remove_all(CPUState *env, int mask);
int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
                          int flags, CPUWatchpoint **watchpoint);
int cpu_watchpoint_remove(CPUState *env, target_ulong addr,
                          target_ulong len, int flags);
void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint);
void cpu_watchpoint_remove_all(CPUState *env, int mask);
429 430 431 432 433

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

B
bellard 已提交
434
void cpu_single_step(CPUState *env, int enabled);
B
bellard 已提交
435
void cpu_reset(CPUState *s);
M
Marcelo Tosatti 已提交
436
int cpu_is_stopped(CPUState *env);
M
Marcelo Tosatti 已提交
437
void run_on_cpu(CPUState *env, void (*func)(void *data), void *data);
B
bellard 已提交
438

439
#define CPU_LOG_TB_OUT_ASM (1 << 0)
440
#define CPU_LOG_TB_IN_ASM  (1 << 1)
441 442 443 444 445
#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)
446
#define CPU_LOG_IOPORT     (1 << 7)
447
#define CPU_LOG_TB_CPU     (1 << 8)
A
aliguori 已提交
448
#define CPU_LOG_RESET      (1 << 9)
449 450 451 452 453 454 455 456

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

B
blueswir1 已提交
457
extern const CPULogItem cpu_log_items[];
458

459 460
void cpu_set_log(int log_flags);
void cpu_set_log_filename(const char *filename);
461
int cpu_str_to_log_mask(const char *str);
462

463 464
#if !defined(CONFIG_USER_ONLY)

465 466 467 468 469
/* 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. */
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);

470 471
/* memory API */

B
bellard 已提交
472
extern int phys_ram_fd;
A
Anthony Liguori 已提交
473
extern ram_addr_t ram_size;
A
Alex Williamson 已提交
474

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

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

typedef struct RAMList {
    uint8_t *phys_dirty;
P
Paolo Bonzini 已提交
492
    QLIST_HEAD(, RAMBlock) blocks;
A
Alex Williamson 已提交
493 494
} RAMList;
extern RAMList ram_list;
B
bellard 已提交
495

496 497 498
extern const char *mem_path;
extern int mem_prealloc;

B
bellard 已提交
499
/* physical memory access */
P
pbrook 已提交
500 501 502 503 504

/* MMIO pages are identified by a combination of an IO device index and
   3 flags.  The ROMD code stores the page ram offset in iotlb entry, 
   so only a limited number of ids are avaiable.  */

B
bellard 已提交
505
#define IO_MEM_NB_ENTRIES  (1 << (TARGET_PAGE_BITS  - IO_MEM_SHIFT))
B
bellard 已提交
506

P
pbrook 已提交
507 508 509 510 511 512 513 514 515 516
/* 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)

A
aliguori 已提交
517 518 519
#define VGA_DIRTY_FLAG       0x01
#define CODE_DIRTY_FLAG      0x02
#define MIGRATION_DIRTY_FLAG 0x08
B
bellard 已提交
520

521
/* read dirty bit (return 0 or 1) */
A
Anthony Liguori 已提交
522
static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
523
{
A
Alex Williamson 已提交
524
    return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
B
bellard 已提交
525 526
}

527 528
static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr)
{
A
Alex Williamson 已提交
529
    return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS];
530 531
}

A
Anthony Liguori 已提交
532
static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
B
bellard 已提交
533 534
                                                int dirty_flags)
{
A
Alex Williamson 已提交
535
    return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
536 537
}

A
Anthony Liguori 已提交
538
static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
539
{
A
Alex Williamson 已提交
540
    ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
541 542
}

543 544 545
static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr,
                                                      int dirty_flags)
{
A
Alex Williamson 已提交
546
    return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] |= dirty_flags;
547 548 549 550 551 552 553 554 555 556 557
}

static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start,
                                                        int length,
                                                        int dirty_flags)
{
    int i, mask, len;
    uint8_t *p;

    len = length >> TARGET_PAGE_BITS;
    mask = ~dirty_flags;
A
Alex Williamson 已提交
558
    p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS);
559 560 561 562 563
    for (i = 0; i < len; i++) {
        p[i] &= mask;
    }
}

A
Anthony Liguori 已提交
564
void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
B
bellard 已提交
565
                                     int dirty_flags);
B
bellard 已提交
566
void cpu_tlb_update_dirty(CPUState *env);
567

A
aliguori 已提交
568 569 570 571
int cpu_physical_memory_set_dirty_tracking(int enable);

int cpu_physical_memory_get_dirty_tracking(void);

A
Anthony Liguori 已提交
572 573
int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
                                   target_phys_addr_t end_addr);
A
aliguori 已提交
574

575 576 577 578 579 580
int cpu_physical_log_start(target_phys_addr_t start_addr,
                           ram_addr_t size);

int cpu_physical_log_stop(target_phys_addr_t start_addr,
                          ram_addr_t size);

581
void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
582 583 584 585 586
#endif /* !CONFIG_USER_ONLY */

int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
                        uint8_t *buf, int len, int is_write);

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