exec.c 71.5 KB
Newer Older
B
bellard 已提交
1
/*
2
 *  Virtual page mapping
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
 */
B
bellard 已提交
19
#include "config.h"
B
bellard 已提交
20 21 22
#ifdef _WIN32
#include <windows.h>
#else
B
bellard 已提交
23
#include <sys/types.h>
B
bellard 已提交
24 25
#include <sys/mman.h>
#endif
B
bellard 已提交
26

27
#include "qemu-common.h"
B
bellard 已提交
28
#include "cpu.h"
B
bellard 已提交
29
#include "tcg.h"
30
#include "hw/hw.h"
31
#include "hw/qdev.h"
32
#include "qemu/osdep.h"
33
#include "sysemu/kvm.h"
34
#include "sysemu/sysemu.h"
P
Paolo Bonzini 已提交
35
#include "hw/xen/xen.h"
36 37
#include "qemu/timer.h"
#include "qemu/config-file.h"
38
#include "exec/memory.h"
39
#include "sysemu/dma.h"
40
#include "exec/address-spaces.h"
41 42
#if defined(CONFIG_USER_ONLY)
#include <qemu.h>
J
Jun Nakajima 已提交
43
#else /* !CONFIG_USER_ONLY */
44
#include "sysemu/xen-mapcache.h"
45
#include "trace.h"
46
#endif
47
#include "exec/cpu-all.h"
B
bellard 已提交
48

49
#include "exec/cputlb.h"
50
#include "translate-all.h"
51

52
#include "exec/memory-internal.h"
53

54
//#define DEBUG_SUBPAGE
T
ths 已提交
55

56
#if !defined(CONFIG_USER_ONLY)
A
aliguori 已提交
57
static int in_migration;
P
pbrook 已提交
58

P
Paolo Bonzini 已提交
59
RAMList ram_list = { .blocks = QTAILQ_HEAD_INITIALIZER(ram_list.blocks) };
A
Avi Kivity 已提交
60 61

static MemoryRegion *system_memory;
62
static MemoryRegion *system_io;
A
Avi Kivity 已提交
63

64 65
AddressSpace address_space_io;
AddressSpace address_space_memory;
66

67
MemoryRegion io_mem_rom, io_mem_notdirty;
68
static MemoryRegion io_mem_unassigned;
69

70
#endif
71

A
Andreas Färber 已提交
72
struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
B
bellard 已提交
73 74
/* current CPU in the current thread. It is only valid inside
   cpu_exec() */
75
DEFINE_TLS(CPUState *, current_cpu);
P
pbrook 已提交
76
/* 0 = Do not count executed instructions.
T
ths 已提交
77
   1 = Precise instruction counting.
P
pbrook 已提交
78
   2 = Adaptive rate instruction counting.  */
79
int use_icount;
B
bellard 已提交
80

81
#if !defined(CONFIG_USER_ONLY)
82

83 84 85 86 87 88 89 90
typedef struct PhysPageEntry PhysPageEntry;

struct PhysPageEntry {
    uint16_t is_leaf : 1;
     /* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */
    uint16_t ptr : 15;
};

91 92
typedef PhysPageEntry Node[L2_SIZE];

93 94 95 96 97
struct AddressSpaceDispatch {
    /* This is a multi-level map on the physical address space.
     * The bottom level has pointers to MemoryRegionSections.
     */
    PhysPageEntry phys_map;
98 99
    Node *nodes;
    MemoryRegionSection *sections;
100
    AddressSpace *as;
101 102
};

103 104 105
#define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
typedef struct subpage_t {
    MemoryRegion iomem;
106
    AddressSpace *as;
107 108 109 110
    hwaddr base;
    uint16_t sub_section[TARGET_PAGE_SIZE];
} subpage_t;

111 112 113 114
#define PHYS_SECTION_UNASSIGNED 0
#define PHYS_SECTION_NOTDIRTY 1
#define PHYS_SECTION_ROM 2
#define PHYS_SECTION_WATCH 3
115

116 117 118 119 120 121 122 123 124
typedef struct PhysPageMap {
    unsigned sections_nb;
    unsigned sections_nb_alloc;
    unsigned nodes_nb;
    unsigned nodes_nb_alloc;
    Node *nodes;
    MemoryRegionSection *sections;
} PhysPageMap;

P
Paolo Bonzini 已提交
125
static PhysPageMap *prev_map;
126
static PhysPageMap next_map;
127

128
#define PHYS_MAP_NODE_NIL (((uint16_t)~0) >> 1)
129

130
static void io_mem_init(void);
A
Avi Kivity 已提交
131
static void memory_map_init(void);
132

133
static MemoryRegion io_mem_watch;
134
#endif
B
bellard 已提交
135

136
#if !defined(CONFIG_USER_ONLY)
137

138
static void phys_map_node_reserve(unsigned nodes)
139
{
140 141 142 143 144 145 146
    if (next_map.nodes_nb + nodes > next_map.nodes_nb_alloc) {
        next_map.nodes_nb_alloc = MAX(next_map.nodes_nb_alloc * 2,
                                            16);
        next_map.nodes_nb_alloc = MAX(next_map.nodes_nb_alloc,
                                      next_map.nodes_nb + nodes);
        next_map.nodes = g_renew(Node, next_map.nodes,
                                 next_map.nodes_nb_alloc);
147
    }
148 149 150 151 152 153 154
}

static uint16_t phys_map_node_alloc(void)
{
    unsigned i;
    uint16_t ret;

155
    ret = next_map.nodes_nb++;
156
    assert(ret != PHYS_MAP_NODE_NIL);
157
    assert(ret != next_map.nodes_nb_alloc);
158
    for (i = 0; i < L2_SIZE; ++i) {
159 160
        next_map.nodes[ret][i].is_leaf = 0;
        next_map.nodes[ret][i].ptr = PHYS_MAP_NODE_NIL;
161
    }
162
    return ret;
163 164
}

A
Avi Kivity 已提交
165 166
static void phys_page_set_level(PhysPageEntry *lp, hwaddr *index,
                                hwaddr *nb, uint16_t leaf,
167
                                int level)
168 169 170
{
    PhysPageEntry *p;
    int i;
A
Avi Kivity 已提交
171
    hwaddr step = (hwaddr)1 << (level * L2_BITS);
172

173
    if (!lp->is_leaf && lp->ptr == PHYS_MAP_NODE_NIL) {
174
        lp->ptr = phys_map_node_alloc();
175
        p = next_map.nodes[lp->ptr];
176 177
        if (level == 0) {
            for (i = 0; i < L2_SIZE; i++) {
178
                p[i].is_leaf = 1;
179
                p[i].ptr = PHYS_SECTION_UNASSIGNED;
180
            }
P
pbrook 已提交
181
        }
182
    } else {
183
        p = next_map.nodes[lp->ptr];
B
bellard 已提交
184
    }
185
    lp = &p[(*index >> (level * L2_BITS)) & (L2_SIZE - 1)];
186

187
    while (*nb && lp < &p[L2_SIZE]) {
188 189
        if ((*index & (step - 1)) == 0 && *nb >= step) {
            lp->is_leaf = true;
190
            lp->ptr = leaf;
191 192
            *index += step;
            *nb -= step;
193 194 195 196
        } else {
            phys_page_set_level(lp, index, nb, leaf, level - 1);
        }
        ++lp;
197 198 199
    }
}

A
Avi Kivity 已提交
200
static void phys_page_set(AddressSpaceDispatch *d,
A
Avi Kivity 已提交
201
                          hwaddr index, hwaddr nb,
202
                          uint16_t leaf)
203
{
204
    /* Wildly overreserve - it doesn't matter much. */
205
    phys_map_node_reserve(3 * P_L2_LEVELS);
206

A
Avi Kivity 已提交
207
    phys_page_set_level(&d->phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
B
bellard 已提交
208 209
}

210 211
static MemoryRegionSection *phys_page_find(PhysPageEntry lp, hwaddr index,
                                           Node *nodes, MemoryRegionSection *sections)
B
bellard 已提交
212
{
213 214
    PhysPageEntry *p;
    int i;
215

216
    for (i = P_L2_LEVELS - 1; i >= 0 && !lp.is_leaf; i--) {
217
        if (lp.ptr == PHYS_MAP_NODE_NIL) {
218
            return &sections[PHYS_SECTION_UNASSIGNED];
219
        }
220
        p = nodes[lp.ptr];
221
        lp = p[(index >> (i * L2_BITS)) & (L2_SIZE - 1)];
222
    }
223
    return &sections[lp.ptr];
224 225
}

B
Blue Swirl 已提交
226 227
bool memory_region_is_unassigned(MemoryRegion *mr)
{
P
Paolo Bonzini 已提交
228
    return mr != &io_mem_rom && mr != &io_mem_notdirty && !mr->rom_device
229
        && mr != &io_mem_watch;
B
bellard 已提交
230
}
231

232
static MemoryRegionSection *address_space_lookup_region(AddressSpaceDispatch *d,
233 234
                                                        hwaddr addr,
                                                        bool resolve_subpage)
235
{
236 237 238
    MemoryRegionSection *section;
    subpage_t *subpage;

239 240
    section = phys_page_find(d->phys_map, addr >> TARGET_PAGE_BITS,
                             d->nodes, d->sections);
241 242
    if (resolve_subpage && section->mr->subpage) {
        subpage = container_of(section->mr, subpage_t, iomem);
243
        section = &d->sections[subpage->sub_section[SUBPAGE_IDX(addr)]];
244 245
    }
    return section;
246 247
}

248
static MemoryRegionSection *
249
address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *xlat,
250
                                 hwaddr *plen, bool resolve_subpage)
251 252 253 254
{
    MemoryRegionSection *section;
    Int128 diff;

255
    section = address_space_lookup_region(d, addr, resolve_subpage);
256 257 258 259 260 261 262
    /* Compute offset within MemoryRegionSection */
    addr -= section->offset_within_address_space;

    /* Compute offset within MemoryRegion */
    *xlat = addr + section->offset_within_region;

    diff = int128_sub(section->mr->size, int128_make64(addr));
263
    *plen = int128_get64(int128_min(diff, int128_make64(*plen)));
264 265
    return section;
}
266

267 268 269
MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
                                      hwaddr *xlat, hwaddr *plen,
                                      bool is_write)
270
{
A
Avi Kivity 已提交
271 272 273 274 275 276
    IOMMUTLBEntry iotlb;
    MemoryRegionSection *section;
    MemoryRegion *mr;
    hwaddr len = *plen;

    for (;;) {
277
        section = address_space_translate_internal(as->dispatch, addr, &addr, plen, true);
A
Avi Kivity 已提交
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
        mr = section->mr;

        if (!mr->iommu_ops) {
            break;
        }

        iotlb = mr->iommu_ops->translate(mr, addr);
        addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
                | (addr & iotlb.addr_mask));
        len = MIN(len, (addr | iotlb.addr_mask) - addr + 1);
        if (!(iotlb.perm & (1 << is_write))) {
            mr = &io_mem_unassigned;
            break;
        }

        as = iotlb.target_as;
    }

    *plen = len;
    *xlat = addr;
    return mr;
299 300 301 302 303 304
}

MemoryRegionSection *
address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat,
                                  hwaddr *plen)
{
A
Avi Kivity 已提交
305
    MemoryRegionSection *section;
306
    section = address_space_translate_internal(as->dispatch, addr, xlat, plen, false);
A
Avi Kivity 已提交
307 308 309

    assert(!section->mr->iommu_ops);
    return section;
310
}
311
#endif
B
bellard 已提交
312

313
void cpu_exec_init_all(void)
314
{
315
#if !defined(CONFIG_USER_ONLY)
316
    qemu_mutex_init(&ram_list.mutex);
317 318
    memory_map_init();
    io_mem_init();
319
#endif
320
}
321

322
#if !defined(CONFIG_USER_ONLY)
323 324

static int cpu_common_post_load(void *opaque, int version_id)
B
bellard 已提交
325
{
326
    CPUState *cpu = opaque;
B
bellard 已提交
327

328 329
    /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
       version_id is increased. */
330 331
    cpu->interrupt_request &= ~0x01;
    tlb_flush(cpu->env_ptr, 1);
332 333

    return 0;
B
bellard 已提交
334
}
B
bellard 已提交
335

336
const VMStateDescription vmstate_cpu_common = {
337 338 339 340 341 342
    .name = "cpu_common",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .post_load = cpu_common_post_load,
    .fields      = (VMStateField []) {
343 344
        VMSTATE_UINT32(halted, CPUState),
        VMSTATE_UINT32(interrupt_request, CPUState),
345 346 347
        VMSTATE_END_OF_LIST()
    }
};
348

349
#endif
B
bellard 已提交
350

351
CPUState *qemu_get_cpu(int index)
B
bellard 已提交
352
{
A
Andreas Färber 已提交
353
    CPUState *cpu;
B
bellard 已提交
354

A
Andreas Färber 已提交
355
    CPU_FOREACH(cpu) {
356
        if (cpu->cpu_index == index) {
A
Andreas Färber 已提交
357
            return cpu;
358
        }
B
bellard 已提交
359
    }
360

A
Andreas Färber 已提交
361
    return NULL;
B
bellard 已提交
362 363
}

364
void cpu_exec_init(CPUArchState *env)
B
bellard 已提交
365
{
366
    CPUState *cpu = ENV_GET_CPU(env);
367
    CPUClass *cc = CPU_GET_CLASS(cpu);
A
Andreas Färber 已提交
368
    CPUState *some_cpu;
369 370 371 372 373 374
    int cpu_index;

#if defined(CONFIG_USER_ONLY)
    cpu_list_lock();
#endif
    cpu_index = 0;
A
Andreas Färber 已提交
375
    CPU_FOREACH(some_cpu) {
376 377
        cpu_index++;
    }
378
    cpu->cpu_index = cpu_index;
379
    cpu->numa_node = 0;
380 381 382 383 384
    QTAILQ_INIT(&env->breakpoints);
    QTAILQ_INIT(&env->watchpoints);
#ifndef CONFIG_USER_ONLY
    cpu->thread_id = qemu_get_thread_id();
#endif
A
Andreas Färber 已提交
385
    QTAILQ_INSERT_TAIL(&cpus, cpu, node);
386 387 388
#if defined(CONFIG_USER_ONLY)
    cpu_list_unlock();
#endif
389 390 391
    if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
        vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
    }
392 393 394
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
    register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
                    cpu_save, cpu_load, env);
395
    assert(cc->vmsd == NULL);
396
    assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);
397
#endif
398 399 400
    if (cc->vmsd != NULL) {
        vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
    }
B
bellard 已提交
401 402
}

B
bellard 已提交
403
#if defined(TARGET_HAS_ICE)
404
#if defined(CONFIG_USER_ONLY)
405
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
406 407 408 409
{
    tb_invalidate_phys_page_range(pc, pc + 1, 0);
}
#else
410
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
411
{
412 413 414 415
    hwaddr phys = cpu_get_phys_page_debug(cpu, pc);
    if (phys != -1) {
        tb_invalidate_phys_addr(phys | (pc & ~TARGET_PAGE_MASK));
    }
416
}
B
bellard 已提交
417
#endif
418
#endif /* TARGET_HAS_ICE */
B
bellard 已提交
419

420
#if defined(CONFIG_USER_ONLY)
421
void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
422 423 424 425

{
}

426
int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
427 428 429 430 431
                          int flags, CPUWatchpoint **watchpoint)
{
    return -ENOSYS;
}
#else
432
/* Add a watchpoint.  */
433
int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
434
                          int flags, CPUWatchpoint **watchpoint)
435
{
436
    target_ulong len_mask = ~(len - 1);
437
    CPUWatchpoint *wp;
438

439
    /* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */
440 441
    if ((len & (len - 1)) || (addr & ~len_mask) ||
            len == 0 || len > TARGET_PAGE_SIZE) {
442 443 444 445
        fprintf(stderr, "qemu: tried to set invalid watchpoint at "
                TARGET_FMT_lx ", len=" TARGET_FMT_lu "\n", addr, len);
        return -EINVAL;
    }
446
    wp = g_malloc(sizeof(*wp));
447 448

    wp->vaddr = addr;
449
    wp->len_mask = len_mask;
450 451
    wp->flags = flags;

452
    /* keep all GDB-injected watchpoints in front */
453
    if (flags & BP_GDB)
B
Blue Swirl 已提交
454
        QTAILQ_INSERT_HEAD(&env->watchpoints, wp, entry);
455
    else
B
Blue Swirl 已提交
456
        QTAILQ_INSERT_TAIL(&env->watchpoints, wp, entry);
457 458

    tlb_flush_page(env, addr);
459 460 461 462

    if (watchpoint)
        *watchpoint = wp;
    return 0;
463 464
}

465
/* Remove a specific watchpoint.  */
466
int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, target_ulong len,
467
                          int flags)
468
{
469
    target_ulong len_mask = ~(len - 1);
470
    CPUWatchpoint *wp;
471

B
Blue Swirl 已提交
472
    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
473
        if (addr == wp->vaddr && len_mask == wp->len_mask
474
                && flags == (wp->flags & ~BP_WATCHPOINT_HIT)) {
475
            cpu_watchpoint_remove_by_ref(env, wp);
476 477 478
            return 0;
        }
    }
479
    return -ENOENT;
480 481
}

482
/* Remove a specific watchpoint by reference.  */
483
void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint)
484
{
B
Blue Swirl 已提交
485
    QTAILQ_REMOVE(&env->watchpoints, watchpoint, entry);
486

487 488
    tlb_flush_page(env, watchpoint->vaddr);

489
    g_free(watchpoint);
490 491 492
}

/* Remove all matching watchpoints.  */
493
void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
494
{
495
    CPUWatchpoint *wp, *next;
496

B
Blue Swirl 已提交
497
    QTAILQ_FOREACH_SAFE(wp, &env->watchpoints, entry, next) {
498 499
        if (wp->flags & mask)
            cpu_watchpoint_remove_by_ref(env, wp);
500
    }
501
}
502
#endif
503

504
/* Add a breakpoint.  */
505
int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
506
                          CPUBreakpoint **breakpoint)
B
bellard 已提交
507
{
B
bellard 已提交
508
#if defined(TARGET_HAS_ICE)
509
    CPUBreakpoint *bp;
510

511
    bp = g_malloc(sizeof(*bp));
B
bellard 已提交
512

513 514 515
    bp->pc = pc;
    bp->flags = flags;

516
    /* keep all GDB-injected breakpoints in front */
517
    if (flags & BP_GDB) {
B
Blue Swirl 已提交
518
        QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
519
    } else {
B
Blue Swirl 已提交
520
        QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
521
    }
522

523
    breakpoint_invalidate(ENV_GET_CPU(env), pc);
524

525
    if (breakpoint) {
526
        *breakpoint = bp;
527
    }
B
bellard 已提交
528 529
    return 0;
#else
530
    return -ENOSYS;
B
bellard 已提交
531 532 533
#endif
}

534
/* Remove a specific breakpoint.  */
535
int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags)
536
{
537
#if defined(TARGET_HAS_ICE)
538 539
    CPUBreakpoint *bp;

B
Blue Swirl 已提交
540
    QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
541 542 543 544
        if (bp->pc == pc && bp->flags == flags) {
            cpu_breakpoint_remove_by_ref(env, bp);
            return 0;
        }
545
    }
546 547 548
    return -ENOENT;
#else
    return -ENOSYS;
549 550 551
#endif
}

552
/* Remove a specific breakpoint by reference.  */
553
void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
B
bellard 已提交
554
{
B
bellard 已提交
555
#if defined(TARGET_HAS_ICE)
B
Blue Swirl 已提交
556
    QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
B
bellard 已提交
557

558
    breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc);
559

560
    g_free(breakpoint);
561 562 563 564
#endif
}

/* Remove all matching breakpoints. */
565
void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
566 567
{
#if defined(TARGET_HAS_ICE)
568
    CPUBreakpoint *bp, *next;
569

B
Blue Swirl 已提交
570
    QTAILQ_FOREACH_SAFE(bp, &env->breakpoints, entry, next) {
571 572
        if (bp->flags & mask)
            cpu_breakpoint_remove_by_ref(env, bp);
573
    }
B
bellard 已提交
574 575 576
#endif
}

B
bellard 已提交
577 578
/* enable or disable single step mode. EXCP_DEBUG is returned by the
   CPU loop after each instruction */
579
void cpu_single_step(CPUState *cpu, int enabled)
B
bellard 已提交
580
{
B
bellard 已提交
581
#if defined(TARGET_HAS_ICE)
582 583 584
    if (cpu->singlestep_enabled != enabled) {
        cpu->singlestep_enabled = enabled;
        if (kvm_enabled()) {
585
            kvm_update_guest_debug(cpu, 0);
586
        } else {
S
Stuart Brady 已提交
587
            /* must flush all the translated code to avoid inconsistencies */
588
            /* XXX: only flush what is necessary */
589
            CPUArchState *env = cpu->env_ptr;
590 591
            tb_flush(env);
        }
B
bellard 已提交
592 593 594 595
    }
#endif
}

596
void cpu_abort(CPUArchState *env, const char *fmt, ...)
B
bellard 已提交
597
{
598
    CPUState *cpu = ENV_GET_CPU(env);
B
bellard 已提交
599
    va_list ap;
P
pbrook 已提交
600
    va_list ap2;
B
bellard 已提交
601 602

    va_start(ap, fmt);
P
pbrook 已提交
603
    va_copy(ap2, ap);
B
bellard 已提交
604 605 606
    fprintf(stderr, "qemu: fatal: ");
    vfprintf(stderr, fmt, ap);
    fprintf(stderr, "\n");
607
    cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP);
608 609 610 611
    if (qemu_log_enabled()) {
        qemu_log("qemu: fatal: ");
        qemu_log_vprintf(fmt, ap2);
        qemu_log("\n");
612
        log_cpu_state(cpu, CPU_DUMP_FPU | CPU_DUMP_CCOP);
613
        qemu_log_flush();
614
        qemu_log_close();
615
    }
P
pbrook 已提交
616
    va_end(ap2);
617
    va_end(ap);
618 619 620 621 622 623 624 625
#if defined(CONFIG_USER_ONLY)
    {
        struct sigaction act;
        sigfillset(&act.sa_mask);
        act.sa_handler = SIG_DFL;
        sigaction(SIGABRT, &act, NULL);
    }
#endif
B
bellard 已提交
626 627 628
    abort();
}

629
#if !defined(CONFIG_USER_ONLY)
P
Paolo Bonzini 已提交
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
static RAMBlock *qemu_get_ram_block(ram_addr_t addr)
{
    RAMBlock *block;

    /* The list is protected by the iothread lock here.  */
    block = ram_list.mru_block;
    if (block && addr - block->offset < block->length) {
        goto found;
    }
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
        if (addr - block->offset < block->length) {
            goto found;
        }
    }

    fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
    abort();

found:
    ram_list.mru_block = block;
    return block;
}

J
Juan Quintela 已提交
653 654 655
static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t end,
                                      uintptr_t length)
{
P
Paolo Bonzini 已提交
656 657
    RAMBlock *block;
    ram_addr_t start1;
J
Juan Quintela 已提交
658

P
Paolo Bonzini 已提交
659 660 661 662
    block = qemu_get_ram_block(start);
    assert(block == qemu_get_ram_block(end - 1));
    start1 = (uintptr_t)block->host + (start - block->offset);
    cpu_tlb_reset_dirty_all(start1, length);
J
Juan Quintela 已提交
663 664
}

P
pbrook 已提交
665
/* Note: start and end must be within the same ram block.  */
A
Anthony Liguori 已提交
666
void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
B
bellard 已提交
667
                                     int dirty_flags)
668
{
J
Juan Quintela 已提交
669
    uintptr_t length;
670 671 672 673 674 675 676

    start &= TARGET_PAGE_MASK;
    end = TARGET_PAGE_ALIGN(end);

    length = end - start;
    if (length == 0)
        return;
677
    cpu_physical_memory_mask_dirty_range(start, length, dirty_flags);
B
bellard 已提交
678

J
Juan Quintela 已提交
679 680
    if (tcg_enabled()) {
        tlb_reset_dirty_range_all(start, end, length);
P
pbrook 已提交
681
    }
682 683
}

B
Blue Swirl 已提交
684
static int cpu_physical_memory_set_dirty_tracking(int enable)
A
aliguori 已提交
685
{
M
Michael S. Tsirkin 已提交
686
    int ret = 0;
A
aliguori 已提交
687
    in_migration = enable;
M
Michael S. Tsirkin 已提交
688
    return ret;
A
aliguori 已提交
689 690
}

A
Avi Kivity 已提交
691
hwaddr memory_region_section_get_iotlb(CPUArchState *env,
692 693 694 695 696
                                       MemoryRegionSection *section,
                                       target_ulong vaddr,
                                       hwaddr paddr, hwaddr xlat,
                                       int prot,
                                       target_ulong *address)
B
Blue Swirl 已提交
697
{
A
Avi Kivity 已提交
698
    hwaddr iotlb;
B
Blue Swirl 已提交
699 700
    CPUWatchpoint *wp;

701
    if (memory_region_is_ram(section->mr)) {
B
Blue Swirl 已提交
702 703
        /* Normal RAM.  */
        iotlb = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
704
            + xlat;
B
Blue Swirl 已提交
705
        if (!section->readonly) {
706
            iotlb |= PHYS_SECTION_NOTDIRTY;
B
Blue Swirl 已提交
707
        } else {
708
            iotlb |= PHYS_SECTION_ROM;
B
Blue Swirl 已提交
709 710
        }
    } else {
711
        iotlb = section - address_space_memory.dispatch->sections;
712
        iotlb += xlat;
B
Blue Swirl 已提交
713 714 715 716 717 718 719 720
    }

    /* Make accesses to pages with watchpoints go via the
       watchpoint trap routines.  */
    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
        if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
            /* Avoid trapping reads of pages with a write breakpoint. */
            if ((prot & PAGE_WRITE) || (wp->flags & BP_MEM_READ)) {
721
                iotlb = PHYS_SECTION_WATCH + paddr;
B
Blue Swirl 已提交
722 723 724 725 726 727 728 729
                *address |= TLB_MMIO;
                break;
            }
        }
    }

    return iotlb;
}
730 731
#endif /* defined(CONFIG_USER_ONLY) */

732
#if !defined(CONFIG_USER_ONLY)
733

A
Anthony Liguori 已提交
734
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
735
                             uint16_t section);
736
static subpage_t *subpage_init(AddressSpace *as, hwaddr base);
737

738
static void *(*phys_mem_alloc)(size_t size) = qemu_anon_ram_alloc;
739 740 741 742 743 744

/*
 * Set a custom physical guest memory alloator.
 * Accelerators with unusual needs may need this.  Hopefully, we can
 * get rid of it eventually.
 */
745
void phys_mem_set_alloc(void *(*alloc)(size_t))
746 747 748 749
{
    phys_mem_alloc = alloc;
}

750 751
static uint16_t phys_section_add(MemoryRegionSection *section)
{
752 753 754 755
    /* The physical section number is ORed with a page-aligned
     * pointer to produce the iotlb entries.  Thus it should
     * never overflow into the page-aligned value.
     */
756
    assert(next_map.sections_nb < TARGET_PAGE_SIZE);
757

758 759 760 761 762
    if (next_map.sections_nb == next_map.sections_nb_alloc) {
        next_map.sections_nb_alloc = MAX(next_map.sections_nb_alloc * 2,
                                         16);
        next_map.sections = g_renew(MemoryRegionSection, next_map.sections,
                                    next_map.sections_nb_alloc);
763
    }
764
    next_map.sections[next_map.sections_nb] = *section;
P
Paolo Bonzini 已提交
765
    memory_region_ref(section->mr);
766
    return next_map.sections_nb++;
767 768
}

769 770
static void phys_section_destroy(MemoryRegion *mr)
{
P
Paolo Bonzini 已提交
771 772
    memory_region_unref(mr);

773 774 775 776 777 778 779
    if (mr->subpage) {
        subpage_t *subpage = container_of(mr, subpage_t, iomem);
        memory_region_destroy(&subpage->iomem);
        g_free(subpage);
    }
}

P
Paolo Bonzini 已提交
780
static void phys_sections_free(PhysPageMap *map)
781
{
782 783
    while (map->sections_nb > 0) {
        MemoryRegionSection *section = &map->sections[--map->sections_nb];
784 785
        phys_section_destroy(section->mr);
    }
786 787
    g_free(map->sections);
    g_free(map->nodes);
P
Paolo Bonzini 已提交
788
    g_free(map);
789 790
}

A
Avi Kivity 已提交
791
static void register_subpage(AddressSpaceDispatch *d, MemoryRegionSection *section)
792 793
{
    subpage_t *subpage;
A
Avi Kivity 已提交
794
    hwaddr base = section->offset_within_address_space
795
        & TARGET_PAGE_MASK;
796 797
    MemoryRegionSection *existing = phys_page_find(d->phys_map, base >> TARGET_PAGE_BITS,
                                                   next_map.nodes, next_map.sections);
798 799
    MemoryRegionSection subsection = {
        .offset_within_address_space = base,
800
        .size = int128_make64(TARGET_PAGE_SIZE),
801
    };
A
Avi Kivity 已提交
802
    hwaddr start, end;
803

804
    assert(existing->mr->subpage || existing->mr == &io_mem_unassigned);
805

806
    if (!(existing->mr->subpage)) {
807
        subpage = subpage_init(d->as, base);
808
        subsection.mr = &subpage->iomem;
A
Avi Kivity 已提交
809
        phys_page_set(d, base >> TARGET_PAGE_BITS, 1,
810
                      phys_section_add(&subsection));
811
    } else {
812
        subpage = container_of(existing->mr, subpage_t, iomem);
813 814
    }
    start = section->offset_within_address_space & ~TARGET_PAGE_MASK;
815
    end = start + int128_get64(section->size) - 1;
816 817 818 819
    subpage_register(subpage, start, end, phys_section_add(section));
}


820 821
static void register_multipage(AddressSpaceDispatch *d,
                               MemoryRegionSection *section)
822
{
A
Avi Kivity 已提交
823
    hwaddr start_addr = section->offset_within_address_space;
824
    uint16_t section_index = phys_section_add(section);
825 826
    uint64_t num_pages = int128_get64(int128_rshift(section->size,
                                                    TARGET_PAGE_BITS));
827

828 829
    assert(num_pages);
    phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
830 831
}

A
Avi Kivity 已提交
832
static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
833
{
834
    AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
835
    AddressSpaceDispatch *d = as->next_dispatch;
836
    MemoryRegionSection now = *section, remain = *section;
837
    Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
838

839 840 841 842
    if (now.offset_within_address_space & ~TARGET_PAGE_MASK) {
        uint64_t left = TARGET_PAGE_ALIGN(now.offset_within_address_space)
                       - now.offset_within_address_space;

843
        now.size = int128_min(int128_make64(left), now.size);
A
Avi Kivity 已提交
844
        register_subpage(d, &now);
845
    } else {
846
        now.size = int128_zero();
847
    }
848 849 850 851
    while (int128_ne(remain.size, now.size)) {
        remain.size = int128_sub(remain.size, now.size);
        remain.offset_within_address_space += int128_get64(now.size);
        remain.offset_within_region += int128_get64(now.size);
852
        now = remain;
853
        if (int128_lt(remain.size, page_size)) {
854
            register_subpage(d, &now);
855
        } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
856
            now.size = page_size;
A
Avi Kivity 已提交
857
            register_subpage(d, &now);
858
        } else {
859
            now.size = int128_and(now.size, int128_neg(page_size));
A
Avi Kivity 已提交
860
            register_multipage(d, &now);
861
        }
862 863 864
    }
}

865 866 867 868 869 870
void qemu_flush_coalesced_mmio_buffer(void)
{
    if (kvm_enabled())
        kvm_flush_coalesced_mmio_buffer();
}

871 872 873 874 875 876 877 878 879 880
void qemu_mutex_lock_ramlist(void)
{
    qemu_mutex_lock(&ram_list.mutex);
}

void qemu_mutex_unlock_ramlist(void)
{
    qemu_mutex_unlock(&ram_list.mutex);
}

881
#ifdef __linux__
882 883 884 885 886 887 888 889 890 891 892

#include <sys/vfs.h>

#define HUGETLBFS_MAGIC       0x958458f6

static long gethugepagesize(const char *path)
{
    struct statfs fs;
    int ret;

    do {
Y
Yoshiaki Tamura 已提交
893
        ret = statfs(path, &fs);
894 895 896
    } while (ret != 0 && errno == EINTR);

    if (ret != 0) {
Y
Yoshiaki Tamura 已提交
897 898
        perror(path);
        return 0;
899 900 901
    }

    if (fs.f_type != HUGETLBFS_MAGIC)
Y
Yoshiaki Tamura 已提交
902
        fprintf(stderr, "Warning: path not on HugeTLBFS: %s\n", path);
903 904 905 906

    return fs.f_bsize;
}

A
Alex Williamson 已提交
907 908 909
static void *file_ram_alloc(RAMBlock *block,
                            ram_addr_t memory,
                            const char *path)
910 911
{
    char *filename;
912 913
    char *sanitized_name;
    char *c;
914 915 916 917 918 919 920 921 922
    void *area;
    int fd;
#ifdef MAP_POPULATE
    int flags;
#endif
    unsigned long hpagesize;

    hpagesize = gethugepagesize(path);
    if (!hpagesize) {
Y
Yoshiaki Tamura 已提交
923
        return NULL;
924 925 926 927 928 929 930 931 932 933 934
    }

    if (memory < hpagesize) {
        return NULL;
    }

    if (kvm_enabled() && !kvm_has_sync_mmu()) {
        fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path unsupported\n");
        return NULL;
    }

935 936 937 938 939 940 941 942 943 944
    /* Make name safe to use with mkstemp by replacing '/' with '_'. */
    sanitized_name = g_strdup(block->mr->name);
    for (c = sanitized_name; *c != '\0'; c++) {
        if (*c == '/')
            *c = '_';
    }

    filename = g_strdup_printf("%s/qemu_back_mem.%s.XXXXXX", path,
                               sanitized_name);
    g_free(sanitized_name);
945 946 947

    fd = mkstemp(filename);
    if (fd < 0) {
Y
Yoshiaki Tamura 已提交
948
        perror("unable to create backing store for hugepages");
949
        g_free(filename);
Y
Yoshiaki Tamura 已提交
950
        return NULL;
951 952
    }
    unlink(filename);
953
    g_free(filename);
954 955 956 957 958 959 960 961 962 963

    memory = (memory+hpagesize-1) & ~(hpagesize-1);

    /*
     * ftruncate is not supported by hugetlbfs in older
     * hosts, so don't bother bailing out on errors.
     * If anything goes wrong with it under other filesystems,
     * mmap will fail.
     */
    if (ftruncate(fd, memory))
Y
Yoshiaki Tamura 已提交
964
        perror("ftruncate");
965 966 967 968 969 970 971 972 973 974 975 976

#ifdef MAP_POPULATE
    /* NB: MAP_POPULATE won't exhaustively alloc all phys pages in the case
     * MAP_PRIVATE is requested.  For mem_prealloc we mmap as MAP_SHARED
     * to sidestep this quirk.
     */
    flags = mem_prealloc ? MAP_POPULATE | MAP_SHARED : MAP_PRIVATE;
    area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0);
#else
    area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
#endif
    if (area == MAP_FAILED) {
Y
Yoshiaki Tamura 已提交
977 978 979
        perror("file_ram_alloc: can't mmap RAM pages");
        close(fd);
        return (NULL);
980
    }
A
Alex Williamson 已提交
981
    block->fd = fd;
982 983
    return area;
}
984 985 986 987 988 989 990 991
#else
static void *file_ram_alloc(RAMBlock *block,
                            ram_addr_t memory,
                            const char *path)
{
    fprintf(stderr, "-mem-path not supported on this host\n");
    exit(1);
}
992 993
#endif

994
static ram_addr_t find_ram_offset(ram_addr_t size)
A
Alex Williamson 已提交
995 996
{
    RAMBlock *block, *next_block;
A
Alex Williamson 已提交
997
    ram_addr_t offset = RAM_ADDR_MAX, mingap = RAM_ADDR_MAX;
A
Alex Williamson 已提交
998

999 1000
    assert(size != 0); /* it would hand out same offset multiple times */

P
Paolo Bonzini 已提交
1001
    if (QTAILQ_EMPTY(&ram_list.blocks))
A
Alex Williamson 已提交
1002 1003
        return 0;

P
Paolo Bonzini 已提交
1004
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
1005
        ram_addr_t end, next = RAM_ADDR_MAX;
A
Alex Williamson 已提交
1006 1007 1008

        end = block->offset + block->length;

P
Paolo Bonzini 已提交
1009
        QTAILQ_FOREACH(next_block, &ram_list.blocks, next) {
A
Alex Williamson 已提交
1010 1011 1012 1013 1014
            if (next_block->offset >= end) {
                next = MIN(next, next_block->offset);
            }
        }
        if (next - end >= size && next - end < mingap) {
A
Alex Williamson 已提交
1015
            offset = end;
A
Alex Williamson 已提交
1016 1017 1018
            mingap = next - end;
        }
    }
A
Alex Williamson 已提交
1019 1020 1021 1022 1023 1024 1025

    if (offset == RAM_ADDR_MAX) {
        fprintf(stderr, "Failed to find gap of requested size: %" PRIu64 "\n",
                (uint64_t)size);
        abort();
    }

A
Alex Williamson 已提交
1026 1027 1028
    return offset;
}

J
Juan Quintela 已提交
1029
ram_addr_t last_ram_offset(void)
1030 1031 1032 1033
{
    RAMBlock *block;
    ram_addr_t last = 0;

P
Paolo Bonzini 已提交
1034
    QTAILQ_FOREACH(block, &ram_list.blocks, next)
1035 1036 1037 1038 1039
        last = MAX(last, block->offset + block->length);

    return last;
}

1040 1041 1042 1043 1044
static void qemu_ram_setup_dump(void *addr, ram_addr_t size)
{
    int ret;

    /* Use MADV_DONTDUMP, if user doesn't want the guest memory in the core */
1045 1046
    if (!qemu_opt_get_bool(qemu_get_machine_opts(),
                           "dump-guest-core", true)) {
1047 1048 1049 1050 1051 1052 1053 1054 1055
        ret = qemu_madvise(addr, size, QEMU_MADV_DONTDUMP);
        if (ret) {
            perror("qemu_madvise");
            fprintf(stderr, "madvise doesn't support MADV_DONTDUMP, "
                            "but dump_guest_core=off specified\n");
        }
    }
}

1056
void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
1057 1058 1059
{
    RAMBlock *new_block, *block;

1060
    new_block = NULL;
P
Paolo Bonzini 已提交
1061
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
1062 1063 1064 1065 1066 1067 1068
        if (block->offset == addr) {
            new_block = block;
            break;
        }
    }
    assert(new_block);
    assert(!new_block->idstr[0]);
1069

1070 1071
    if (dev) {
        char *id = qdev_get_dev_path(dev);
1072 1073
        if (id) {
            snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);
1074
            g_free(id);
1075 1076 1077 1078
        }
    }
    pstrcat(new_block->idstr, sizeof(new_block->idstr), name);

1079 1080
    /* This assumes the iothread lock is taken here too.  */
    qemu_mutex_lock_ramlist();
P
Paolo Bonzini 已提交
1081
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
1082
        if (block != new_block && !strcmp(block->idstr, new_block->idstr)) {
1083 1084 1085 1086 1087
            fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",
                    new_block->idstr);
            abort();
        }
    }
1088
    qemu_mutex_unlock_ramlist();
1089 1090
}

1091 1092
static int memory_try_enable_merging(void *addr, size_t len)
{
1093
    if (!qemu_opt_get_bool(qemu_get_machine_opts(), "mem-merge", true)) {
1094 1095 1096 1097 1098 1099 1100
        /* disabled by the user */
        return 0;
    }

    return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE);
}

1101 1102 1103
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                   MemoryRegion *mr)
{
1104
    RAMBlock *block, *new_block;
1105 1106 1107

    size = TARGET_PAGE_ALIGN(size);
    new_block = g_malloc0(sizeof(*new_block));
1108
    new_block->fd = -1;
1109

1110 1111
    /* This assumes the iothread lock is taken here too.  */
    qemu_mutex_lock_ramlist();
A
Avi Kivity 已提交
1112
    new_block->mr = mr;
J
Jun Nakajima 已提交
1113
    new_block->offset = find_ram_offset(size);
1114 1115
    if (host) {
        new_block->host = host;
H
Huang Ying 已提交
1116
        new_block->flags |= RAM_PREALLOC_MASK;
1117 1118 1119 1120 1121 1122
    } else if (xen_enabled()) {
        if (mem_path) {
            fprintf(stderr, "-mem-path not supported with Xen\n");
            exit(1);
        }
        xen_ram_alloc(new_block->offset, size, mr);
1123 1124
    } else {
        if (mem_path) {
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
            if (phys_mem_alloc != qemu_anon_ram_alloc) {
                /*
                 * file_ram_alloc() needs to allocate just like
                 * phys_mem_alloc, but we haven't bothered to provide
                 * a hook there.
                 */
                fprintf(stderr,
                        "-mem-path not supported with this accelerator\n");
                exit(1);
            }
1135
            new_block->host = file_ram_alloc(new_block, size, mem_path);
1136 1137
        }
        if (!new_block->host) {
1138
            new_block->host = phys_mem_alloc(size);
1139 1140 1141 1142 1143
            if (!new_block->host) {
                fprintf(stderr, "Cannot set up guest memory '%s': %s\n",
                        new_block->mr->name, strerror(errno));
                exit(1);
            }
1144
            memory_try_enable_merging(new_block->host, size);
1145
        }
1146
    }
P
pbrook 已提交
1147 1148
    new_block->length = size;

1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
    /* Keep the list sorted from biggest to smallest block.  */
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
        if (block->length < new_block->length) {
            break;
        }
    }
    if (block) {
        QTAILQ_INSERT_BEFORE(block, new_block, next);
    } else {
        QTAILQ_INSERT_TAIL(&ram_list.blocks, new_block, next);
    }
1160
    ram_list.mru_block = NULL;
P
pbrook 已提交
1161

U
Umesh Deshpande 已提交
1162
    ram_list.version++;
1163
    qemu_mutex_unlock_ramlist();
U
Umesh Deshpande 已提交
1164

1165
    ram_list.phys_dirty = g_realloc(ram_list.phys_dirty,
A
Alex Williamson 已提交
1166
                                       last_ram_offset() >> TARGET_PAGE_BITS);
1167 1168
    memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
           0, size >> TARGET_PAGE_BITS);
J
Juan Quintela 已提交
1169
    cpu_physical_memory_set_dirty_range(new_block->offset, size, 0xff);
P
pbrook 已提交
1170

1171
    qemu_ram_setup_dump(new_block->host, size);
1172
    qemu_madvise(new_block->host, size, QEMU_MADV_HUGEPAGE);
1173
    qemu_madvise(new_block->host, size, QEMU_MADV_DONTFORK);
1174

1175 1176 1177
    if (kvm_enabled())
        kvm_setup_guest_memory(new_block->host, size);

P
pbrook 已提交
1178 1179
    return new_block->offset;
}
B
bellard 已提交
1180

1181
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr)
1182
{
1183
    return qemu_ram_alloc_from_ptr(size, NULL, mr);
1184 1185
}

1186 1187 1188 1189
void qemu_ram_free_from_ptr(ram_addr_t addr)
{
    RAMBlock *block;

1190 1191
    /* This assumes the iothread lock is taken here too.  */
    qemu_mutex_lock_ramlist();
P
Paolo Bonzini 已提交
1192
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
1193
        if (addr == block->offset) {
P
Paolo Bonzini 已提交
1194
            QTAILQ_REMOVE(&ram_list.blocks, block, next);
1195
            ram_list.mru_block = NULL;
U
Umesh Deshpande 已提交
1196
            ram_list.version++;
1197
            g_free(block);
1198
            break;
1199 1200
        }
    }
1201
    qemu_mutex_unlock_ramlist();
1202 1203
}

A
Anthony Liguori 已提交
1204
void qemu_ram_free(ram_addr_t addr)
B
bellard 已提交
1205
{
A
Alex Williamson 已提交
1206 1207
    RAMBlock *block;

1208 1209
    /* This assumes the iothread lock is taken here too.  */
    qemu_mutex_lock_ramlist();
P
Paolo Bonzini 已提交
1210
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
A
Alex Williamson 已提交
1211
        if (addr == block->offset) {
P
Paolo Bonzini 已提交
1212
            QTAILQ_REMOVE(&ram_list.blocks, block, next);
1213
            ram_list.mru_block = NULL;
U
Umesh Deshpande 已提交
1214
            ram_list.version++;
H
Huang Ying 已提交
1215 1216
            if (block->flags & RAM_PREALLOC_MASK) {
                ;
1217 1218
            } else if (xen_enabled()) {
                xen_invalidate_map_cache_entry(block->host);
1219
#ifndef _WIN32
1220 1221 1222
            } else if (block->fd >= 0) {
                munmap(block->host, block->length);
                close(block->fd);
1223
#endif
A
Alex Williamson 已提交
1224
            } else {
1225
                qemu_anon_ram_free(block->host, block->length);
A
Alex Williamson 已提交
1226
            }
1227
            g_free(block);
1228
            break;
A
Alex Williamson 已提交
1229 1230
        }
    }
1231
    qemu_mutex_unlock_ramlist();
A
Alex Williamson 已提交
1232

B
bellard 已提交
1233 1234
}

H
Huang Ying 已提交
1235 1236 1237 1238 1239 1240 1241 1242
#ifndef _WIN32
void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
{
    RAMBlock *block;
    ram_addr_t offset;
    int flags;
    void *area, *vaddr;

P
Paolo Bonzini 已提交
1243
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
H
Huang Ying 已提交
1244 1245 1246 1247 1248
        offset = addr - block->offset;
        if (offset < block->length) {
            vaddr = block->host + offset;
            if (block->flags & RAM_PREALLOC_MASK) {
                ;
1249 1250
            } else if (xen_enabled()) {
                abort();
H
Huang Ying 已提交
1251 1252 1253
            } else {
                flags = MAP_FIXED;
                munmap(vaddr, length);
1254
                if (block->fd >= 0) {
H
Huang Ying 已提交
1255
#ifdef MAP_POPULATE
1256 1257
                    flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED :
                        MAP_PRIVATE;
1258
#else
1259
                    flags |= MAP_PRIVATE;
H
Huang Ying 已提交
1260
#endif
1261 1262
                    area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
                                flags, block->fd, offset);
H
Huang Ying 已提交
1263
                } else {
1264 1265 1266 1267 1268 1269 1270
                    /*
                     * Remap needs to match alloc.  Accelerators that
                     * set phys_mem_alloc never remap.  If they did,
                     * we'd need a remap hook here.
                     */
                    assert(phys_mem_alloc == qemu_anon_ram_alloc);

H
Huang Ying 已提交
1271 1272 1273 1274 1275
                    flags |= MAP_PRIVATE | MAP_ANONYMOUS;
                    area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
                                flags, -1, 0);
                }
                if (area != vaddr) {
1276 1277
                    fprintf(stderr, "Could not remap addr: "
                            RAM_ADDR_FMT "@" RAM_ADDR_FMT "\n",
H
Huang Ying 已提交
1278 1279 1280
                            length, addr);
                    exit(1);
                }
1281
                memory_try_enable_merging(vaddr, length);
1282
                qemu_ram_setup_dump(vaddr, length);
H
Huang Ying 已提交
1283 1284 1285 1286 1287 1288 1289
            }
            return;
        }
    }
}
#endif /* !_WIN32 */

1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
/* Return a host pointer to ram allocated with qemu_ram_alloc.
   With the exception of the softmmu code in this file, this should
   only be used for local memory (e.g. video ram) that the device owns,
   and knows it isn't going to access beyond the end of the block.

   It should not be used for general purpose DMA.
   Use cpu_physical_memory_map/cpu_physical_memory_rw instead.
 */
void *qemu_get_ram_ptr(ram_addr_t addr)
{
    RAMBlock *block = qemu_get_ram_block(addr);

1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314
    if (xen_enabled()) {
        /* We need to check if the requested address is in the RAM
         * because we don't want to map the entire memory in QEMU.
         * In that case just map until the end of the page.
         */
        if (block->offset == 0) {
            return xen_map_cache(addr, 0, 0);
        } else if (block->host == NULL) {
            block->host =
                xen_map_cache(block->offset, block->length, 1);
        }
    }
    return block->host + (addr - block->offset);
1315 1316
}

1317 1318
/* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr
 * but takes a size argument */
1319
static void *qemu_ram_ptr_length(ram_addr_t addr, hwaddr *size)
1320
{
1321 1322 1323
    if (*size == 0) {
        return NULL;
    }
1324
    if (xen_enabled()) {
J
Jan Kiszka 已提交
1325
        return xen_map_cache(addr, *size, 1);
1326
    } else {
1327 1328
        RAMBlock *block;

P
Paolo Bonzini 已提交
1329
        QTAILQ_FOREACH(block, &ram_list.blocks, next) {
1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341
            if (addr - block->offset < block->length) {
                if (addr - block->offset + *size > block->length)
                    *size = block->length - addr + block->offset;
                return block->host + (addr - block->offset);
            }
        }

        fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
        abort();
    }
}

1342 1343
/* Some of the softmmu routines need to translate from a host pointer
   (typically a TLB entry) back to a ram offset.  */
1344
MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
P
pbrook 已提交
1345
{
P
pbrook 已提交
1346 1347 1348
    RAMBlock *block;
    uint8_t *host = ptr;

1349
    if (xen_enabled()) {
J
Jan Kiszka 已提交
1350
        *ram_addr = xen_ram_addr_from_mapcache(ptr);
1351
        return qemu_get_ram_block(*ram_addr)->mr;
1352 1353
    }

1354 1355 1356 1357 1358
    block = ram_list.mru_block;
    if (block && block->host && host - block->host < block->length) {
        goto found;
    }

P
Paolo Bonzini 已提交
1359
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
J
Jun Nakajima 已提交
1360 1361 1362 1363
        /* This case append when the block is not mapped. */
        if (block->host == NULL) {
            continue;
        }
A
Alex Williamson 已提交
1364
        if (host - block->host < block->length) {
1365
            goto found;
A
Alex Williamson 已提交
1366
        }
P
pbrook 已提交
1367
    }
J
Jun Nakajima 已提交
1368

1369
    return NULL;
1370 1371 1372

found:
    *ram_addr = block->offset + (host - block->host);
1373
    return block->mr;
M
Marcelo Tosatti 已提交
1374
}
A
Alex Williamson 已提交
1375

A
Avi Kivity 已提交
1376
static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
1377
                               uint64_t val, unsigned size)
1378
{
1379
    int dirty_flags;
1380
    dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
1381
    if (!(dirty_flags & CODE_DIRTY_FLAG)) {
1382
        tb_invalidate_phys_page_fast(ram_addr, size);
1383
        dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
1384
    }
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396
    switch (size) {
    case 1:
        stb_p(qemu_get_ram_ptr(ram_addr), val);
        break;
    case 2:
        stw_p(qemu_get_ram_ptr(ram_addr), val);
        break;
    case 4:
        stl_p(qemu_get_ram_ptr(ram_addr), val);
        break;
    default:
        abort();
1397
    }
B
bellard 已提交
1398
    dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
1399
    cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
B
bellard 已提交
1400 1401
    /* we remove the notdirty callback only if the code has been
       flushed */
1402 1403 1404 1405
    if (dirty_flags == 0xff) {
        CPUArchState *env = current_cpu->env_ptr;
        tlb_set_dirty(env, env->mem_io_vaddr);
    }
1406 1407
}

1408 1409 1410 1411 1412 1413
static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
                                 unsigned size, bool is_write)
{
    return is_write;
}

1414 1415
static const MemoryRegionOps notdirty_mem_ops = {
    .write = notdirty_mem_write,
1416
    .valid.accepts = notdirty_mem_accepts,
1417
    .endianness = DEVICE_NATIVE_ENDIAN,
1418 1419
};

P
pbrook 已提交
1420
/* Generate a debug exception if a watchpoint has been hit.  */
1421
static void check_watchpoint(int offset, int len_mask, int flags)
P
pbrook 已提交
1422
{
1423
    CPUArchState *env = current_cpu->env_ptr;
1424
    target_ulong pc, cs_base;
P
pbrook 已提交
1425
    target_ulong vaddr;
1426
    CPUWatchpoint *wp;
1427
    int cpu_flags;
P
pbrook 已提交
1428

1429 1430 1431 1432
    if (env->watchpoint_hit) {
        /* We re-entered the check after replacing the TB. Now raise
         * the debug interrupt so that is will trigger after the
         * current instruction. */
1433
        cpu_interrupt(ENV_GET_CPU(env), CPU_INTERRUPT_DEBUG);
1434 1435
        return;
    }
P
pbrook 已提交
1436
    vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
B
Blue Swirl 已提交
1437
    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
1438 1439
        if ((vaddr == (wp->vaddr & len_mask) ||
             (vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
1440 1441 1442
            wp->flags |= BP_WATCHPOINT_HIT;
            if (!env->watchpoint_hit) {
                env->watchpoint_hit = wp;
B
Blue Swirl 已提交
1443
                tb_check_watchpoint(env);
1444 1445
                if (wp->flags & BP_STOP_BEFORE_ACCESS) {
                    env->exception_index = EXCP_DEBUG;
1446
                    cpu_loop_exit(env);
1447 1448 1449
                } else {
                    cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);
                    tb_gen_code(env, pc, cs_base, cpu_flags, 1);
1450
                    cpu_resume_from_signal(env, NULL);
1451
                }
1452
            }
1453 1454
        } else {
            wp->flags &= ~BP_WATCHPOINT_HIT;
P
pbrook 已提交
1455 1456 1457 1458
        }
    }
}

1459 1460 1461
/* Watchpoint access routines.  Watchpoints are inserted using TLB tricks,
   so these check for a hit then pass through to the normal out-of-line
   phys routines.  */
A
Avi Kivity 已提交
1462
static uint64_t watch_mem_read(void *opaque, hwaddr addr,
1463
                               unsigned size)
1464
{
1465 1466 1467 1468 1469 1470 1471
    check_watchpoint(addr & ~TARGET_PAGE_MASK, ~(size - 1), BP_MEM_READ);
    switch (size) {
    case 1: return ldub_phys(addr);
    case 2: return lduw_phys(addr);
    case 4: return ldl_phys(addr);
    default: abort();
    }
1472 1473
}

A
Avi Kivity 已提交
1474
static void watch_mem_write(void *opaque, hwaddr addr,
1475
                            uint64_t val, unsigned size)
1476
{
1477 1478
    check_watchpoint(addr & ~TARGET_PAGE_MASK, ~(size - 1), BP_MEM_WRITE);
    switch (size) {
1479 1480 1481 1482 1483 1484 1485 1486 1487
    case 1:
        stb_phys(addr, val);
        break;
    case 2:
        stw_phys(addr, val);
        break;
    case 4:
        stl_phys(addr, val);
        break;
1488 1489
    default: abort();
    }
1490 1491
}

1492 1493 1494 1495
static const MemoryRegionOps watch_mem_ops = {
    .read = watch_mem_read,
    .write = watch_mem_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
1496 1497
};

A
Avi Kivity 已提交
1498
static uint64_t subpage_read(void *opaque, hwaddr addr,
1499
                             unsigned len)
1500
{
1501 1502
    subpage_t *subpage = opaque;
    uint8_t buf[4];
1503

1504
#if defined(DEBUG_SUBPAGE)
A
Amos Kong 已提交
1505
    printf("%s: subpage %p len %u addr " TARGET_FMT_plx "\n", __func__,
1506
           subpage, len, addr);
1507
#endif
1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518
    address_space_read(subpage->as, addr + subpage->base, buf, len);
    switch (len) {
    case 1:
        return ldub_p(buf);
    case 2:
        return lduw_p(buf);
    case 4:
        return ldl_p(buf);
    default:
        abort();
    }
1519 1520
}

A
Avi Kivity 已提交
1521
static void subpage_write(void *opaque, hwaddr addr,
1522
                          uint64_t value, unsigned len)
1523
{
1524 1525 1526
    subpage_t *subpage = opaque;
    uint8_t buf[4];

1527
#if defined(DEBUG_SUBPAGE)
A
Amos Kong 已提交
1528
    printf("%s: subpage %p len %u addr " TARGET_FMT_plx
1529 1530
           " value %"PRIx64"\n",
           __func__, subpage, len, addr, value);
1531
#endif
1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545
    switch (len) {
    case 1:
        stb_p(buf, value);
        break;
    case 2:
        stw_p(buf, value);
        break;
    case 4:
        stl_p(buf, value);
        break;
    default:
        abort();
    }
    address_space_write(subpage->as, addr + subpage->base, buf, len);
1546 1547
}

1548
static bool subpage_accepts(void *opaque, hwaddr addr,
A
Amos Kong 已提交
1549
                            unsigned len, bool is_write)
1550
{
1551
    subpage_t *subpage = opaque;
1552
#if defined(DEBUG_SUBPAGE)
A
Amos Kong 已提交
1553
    printf("%s: subpage %p %c len %u addr " TARGET_FMT_plx "\n",
1554
           __func__, subpage, is_write ? 'w' : 'r', len, addr);
1555 1556
#endif

1557
    return address_space_access_valid(subpage->as, addr + subpage->base,
A
Amos Kong 已提交
1558
                                      len, is_write);
1559 1560
}

1561 1562 1563
static const MemoryRegionOps subpage_ops = {
    .read = subpage_read,
    .write = subpage_write,
1564
    .valid.accepts = subpage_accepts,
1565
    .endianness = DEVICE_NATIVE_ENDIAN,
1566 1567
};

A
Anthony Liguori 已提交
1568
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
1569
                             uint16_t section)
1570 1571 1572 1573 1574 1575 1576 1577
{
    int idx, eidx;

    if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE)
        return -1;
    idx = SUBPAGE_IDX(start);
    eidx = SUBPAGE_IDX(end);
#if defined(DEBUG_SUBPAGE)
A
Amos Kong 已提交
1578 1579
    printf("%s: %p start %08x end %08x idx %08x eidx %08x section %d\n",
           __func__, mmio, start, end, idx, eidx, section);
1580 1581
#endif
    for (; idx <= eidx; idx++) {
1582
        mmio->sub_section[idx] = section;
1583 1584 1585 1586 1587
    }

    return 0;
}

1588
static subpage_t *subpage_init(AddressSpace *as, hwaddr base)
1589
{
A
Anthony Liguori 已提交
1590
    subpage_t *mmio;
1591

1592
    mmio = g_malloc0(sizeof(subpage_t));
1593

1594
    mmio->as = as;
1595
    mmio->base = base;
1596
    memory_region_init_io(&mmio->iomem, NULL, &subpage_ops, mmio,
1597
                          "subpage", TARGET_PAGE_SIZE);
A
Avi Kivity 已提交
1598
    mmio->iomem.subpage = true;
1599
#if defined(DEBUG_SUBPAGE)
A
Amos Kong 已提交
1600 1601
    printf("%s: %p base " TARGET_FMT_plx " len %08x\n", __func__,
           mmio, base, TARGET_PAGE_SIZE);
1602
#endif
1603
    subpage_register(mmio, 0, TARGET_PAGE_SIZE-1, PHYS_SECTION_UNASSIGNED);
1604 1605 1606 1607

    return mmio;
}

1608 1609 1610 1611 1612 1613
static uint16_t dummy_section(MemoryRegion *mr)
{
    MemoryRegionSection section = {
        .mr = mr,
        .offset_within_address_space = 0,
        .offset_within_region = 0,
1614
        .size = int128_2_64(),
1615 1616 1617 1618 1619
    };

    return phys_section_add(&section);
}

A
Avi Kivity 已提交
1620
MemoryRegion *iotlb_to_region(hwaddr index)
1621
{
1622
    return address_space_memory.dispatch->sections[index & ~TARGET_PAGE_MASK].mr;
1623 1624
}

A
Avi Kivity 已提交
1625 1626
static void io_mem_init(void)
{
1627 1628
    memory_region_init_io(&io_mem_rom, NULL, &unassigned_mem_ops, NULL, "rom", UINT64_MAX);
    memory_region_init_io(&io_mem_unassigned, NULL, &unassigned_mem_ops, NULL,
1629
                          "unassigned", UINT64_MAX);
1630
    memory_region_init_io(&io_mem_notdirty, NULL, &notdirty_mem_ops, NULL,
1631
                          "notdirty", UINT64_MAX);
1632
    memory_region_init_io(&io_mem_watch, NULL, &watch_mem_ops, NULL,
1633
                          "watch", UINT64_MAX);
A
Avi Kivity 已提交
1634 1635
}

A
Avi Kivity 已提交
1636
static void mem_begin(MemoryListener *listener)
1637 1638 1639 1640 1641 1642 1643 1644 1645 1646
{
    AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
    AddressSpaceDispatch *d = g_new(AddressSpaceDispatch, 1);

    d->phys_map  = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .is_leaf = 0 };
    d->as = as;
    as->next_dispatch = d;
}

static void mem_commit(MemoryListener *listener)
A
Avi Kivity 已提交
1647
{
1648
    AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
1649 1650 1651 1652 1653
    AddressSpaceDispatch *cur = as->dispatch;
    AddressSpaceDispatch *next = as->next_dispatch;

    next->nodes = next_map.nodes;
    next->sections = next_map.sections;
A
Avi Kivity 已提交
1654

1655 1656
    as->dispatch = next;
    g_free(cur);
A
Avi Kivity 已提交
1657 1658
}

1659 1660
static void core_begin(MemoryListener *listener)
{
1661 1662
    uint16_t n;

P
Paolo Bonzini 已提交
1663 1664 1665
    prev_map = g_new(PhysPageMap, 1);
    *prev_map = next_map;

1666
    memset(&next_map, 0, sizeof(next_map));
1667 1668 1669 1670 1671 1672 1673 1674
    n = dummy_section(&io_mem_unassigned);
    assert(n == PHYS_SECTION_UNASSIGNED);
    n = dummy_section(&io_mem_notdirty);
    assert(n == PHYS_SECTION_NOTDIRTY);
    n = dummy_section(&io_mem_rom);
    assert(n == PHYS_SECTION_ROM);
    n = dummy_section(&io_mem_watch);
    assert(n == PHYS_SECTION_WATCH);
1675 1676
}

1677 1678 1679 1680 1681
/* This listener's commit run after the other AddressSpaceDispatch listeners'.
 * All AddressSpaceDispatch instances have switched to the next map.
 */
static void core_commit(MemoryListener *listener)
{
P
Paolo Bonzini 已提交
1682
    phys_sections_free(prev_map);
1683 1684
}

1685
static void tcg_commit(MemoryListener *listener)
1686
{
1687
    CPUState *cpu;
1688 1689 1690 1691

    /* since each CPU stores ram addresses in its TLB cache, we must
       reset the modified entries */
    /* XXX: slow ! */
A
Andreas Färber 已提交
1692
    CPU_FOREACH(cpu) {
1693 1694
        CPUArchState *env = cpu->env_ptr;

1695 1696
        tlb_flush(env, 1);
    }
1697 1698
}

1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709
static void core_log_global_start(MemoryListener *listener)
{
    cpu_physical_memory_set_dirty_tracking(1);
}

static void core_log_global_stop(MemoryListener *listener)
{
    cpu_physical_memory_set_dirty_tracking(0);
}

static MemoryListener core_memory_listener = {
1710
    .begin = core_begin,
1711
    .commit = core_commit,
1712 1713
    .log_global_start = core_log_global_start,
    .log_global_stop = core_log_global_stop,
A
Avi Kivity 已提交
1714
    .priority = 1,
1715 1716
};

1717 1718 1719 1720
static MemoryListener tcg_memory_listener = {
    .commit = tcg_commit,
};

A
Avi Kivity 已提交
1721 1722
void address_space_init_dispatch(AddressSpace *as)
{
1723
    as->dispatch = NULL;
1724
    as->dispatch_listener = (MemoryListener) {
A
Avi Kivity 已提交
1725
        .begin = mem_begin,
1726
        .commit = mem_commit,
A
Avi Kivity 已提交
1727 1728 1729 1730
        .region_add = mem_add,
        .region_nop = mem_add,
        .priority = 0,
    };
1731
    memory_listener_register(&as->dispatch_listener, as);
A
Avi Kivity 已提交
1732 1733
}

A
Avi Kivity 已提交
1734 1735 1736 1737
void address_space_destroy_dispatch(AddressSpace *as)
{
    AddressSpaceDispatch *d = as->dispatch;

1738
    memory_listener_unregister(&as->dispatch_listener);
A
Avi Kivity 已提交
1739 1740 1741 1742
    g_free(d);
    as->dispatch = NULL;
}

A
Avi Kivity 已提交
1743 1744
static void memory_map_init(void)
{
1745
    system_memory = g_malloc(sizeof(*system_memory));
1746
    memory_region_init(system_memory, NULL, "system", INT64_MAX);
1747
    address_space_init(&address_space_memory, system_memory, "memory");
1748

1749
    system_io = g_malloc(sizeof(*system_io));
1750 1751
    memory_region_init_io(system_io, NULL, &unassigned_io_ops, NULL, "io",
                          65536);
1752
    address_space_init(&address_space_io, system_io, "I/O");
1753

1754
    memory_listener_register(&core_memory_listener, &address_space_memory);
1755 1756 1757
    if (tcg_enabled()) {
        memory_listener_register(&tcg_memory_listener, &address_space_memory);
    }
A
Avi Kivity 已提交
1758 1759 1760 1761 1762 1763 1764
}

MemoryRegion *get_system_memory(void)
{
    return system_memory;
}

1765 1766 1767 1768 1769
MemoryRegion *get_system_io(void)
{
    return system_io;
}

1770 1771
#endif /* !defined(CONFIG_USER_ONLY) */

B
bellard 已提交
1772 1773
/* physical memory access (slow version, mainly for debug) */
#if defined(CONFIG_USER_ONLY)
1774
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
P
Paul Brook 已提交
1775
                        uint8_t *buf, int len, int is_write)
B
bellard 已提交
1776 1777 1778
{
    int l, flags;
    target_ulong page;
1779
    void * p;
B
bellard 已提交
1780 1781 1782 1783 1784 1785 1786 1787

    while (len > 0) {
        page = addr & TARGET_PAGE_MASK;
        l = (page + TARGET_PAGE_SIZE) - addr;
        if (l > len)
            l = len;
        flags = page_get_flags(page);
        if (!(flags & PAGE_VALID))
P
Paul Brook 已提交
1788
            return -1;
B
bellard 已提交
1789 1790
        if (is_write) {
            if (!(flags & PAGE_WRITE))
P
Paul Brook 已提交
1791
                return -1;
1792
            /* XXX: this code should not depend on lock_user */
A
aurel32 已提交
1793
            if (!(p = lock_user(VERIFY_WRITE, addr, l, 0)))
P
Paul Brook 已提交
1794
                return -1;
A
aurel32 已提交
1795 1796
            memcpy(p, buf, l);
            unlock_user(p, addr, l);
B
bellard 已提交
1797 1798
        } else {
            if (!(flags & PAGE_READ))
P
Paul Brook 已提交
1799
                return -1;
1800
            /* XXX: this code should not depend on lock_user */
A
aurel32 已提交
1801
            if (!(p = lock_user(VERIFY_READ, addr, l, 1)))
P
Paul Brook 已提交
1802
                return -1;
A
aurel32 已提交
1803
            memcpy(buf, p, l);
A
aurel32 已提交
1804
            unlock_user(p, addr, 0);
B
bellard 已提交
1805 1806 1807 1808 1809
        }
        len -= l;
        buf += l;
        addr += l;
    }
P
Paul Brook 已提交
1810
    return 0;
B
bellard 已提交
1811
}
B
bellard 已提交
1812

B
bellard 已提交
1813
#else
1814

A
Avi Kivity 已提交
1815 1816
static void invalidate_and_set_dirty(hwaddr addr,
                                     hwaddr length)
1817 1818 1819 1820 1821 1822 1823
{
    if (!cpu_physical_memory_is_dirty(addr)) {
        /* invalidate code */
        tb_invalidate_phys_page_range(addr, addr + length, 0);
        /* set dirty bit */
        cpu_physical_memory_set_dirty_flags(addr, (0xff & ~CODE_DIRTY_FLAG));
    }
1824
    xen_modified_memory(addr, length);
1825 1826
}

1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
    if (memory_region_is_ram(mr)) {
        return !(is_write && mr->readonly);
    }
    if (memory_region_is_romd(mr)) {
        return !is_write;
    }

    return false;
}

1839
static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
1840
{
1841
    unsigned access_size_max = mr->ops->valid.max_access_size;
1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854

    /* Regions are assumed to support 1-4 byte accesses unless
       otherwise specified.  */
    if (access_size_max == 0) {
        access_size_max = 4;
    }

    /* Bound the maximum access by the alignment of the address.  */
    if (!mr->ops->impl.unaligned) {
        unsigned align_size_max = addr & -addr;
        if (align_size_max != 0 && align_size_max < access_size_max) {
            access_size_max = align_size_max;
        }
1855
    }
1856 1857 1858 1859

    /* Don't attempt accesses larger than the maximum.  */
    if (l > access_size_max) {
        l = access_size_max;
1860
    }
1861 1862 1863
    if (l & (l - 1)) {
        l = 1 << (qemu_fls(l) - 1);
    }
1864 1865

    return l;
1866 1867
}

1868
bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
A
Avi Kivity 已提交
1869
                      int len, bool is_write)
B
bellard 已提交
1870
{
1871
    hwaddr l;
B
bellard 已提交
1872
    uint8_t *ptr;
1873
    uint64_t val;
1874
    hwaddr addr1;
1875
    MemoryRegion *mr;
1876
    bool error = false;
1877

B
bellard 已提交
1878
    while (len > 0) {
1879
        l = len;
1880
        mr = address_space_translate(as, addr, &addr1, &l, is_write);
1881

B
bellard 已提交
1882
        if (is_write) {
1883 1884
            if (!memory_access_is_direct(mr, is_write)) {
                l = memory_access_size(mr, l, addr1);
1885
                /* XXX: could force current_cpu to NULL to avoid
B
bellard 已提交
1886
                   potential bugs */
1887 1888 1889 1890 1891 1892 1893
                switch (l) {
                case 8:
                    /* 64 bit write access */
                    val = ldq_p(buf);
                    error |= io_mem_write(mr, addr1, val, 8);
                    break;
                case 4:
B
bellard 已提交
1894
                    /* 32 bit write access */
B
bellard 已提交
1895
                    val = ldl_p(buf);
1896
                    error |= io_mem_write(mr, addr1, val, 4);
1897 1898
                    break;
                case 2:
B
bellard 已提交
1899
                    /* 16 bit write access */
B
bellard 已提交
1900
                    val = lduw_p(buf);
1901
                    error |= io_mem_write(mr, addr1, val, 2);
1902 1903
                    break;
                case 1:
B
bellard 已提交
1904
                    /* 8 bit write access */
B
bellard 已提交
1905
                    val = ldub_p(buf);
1906
                    error |= io_mem_write(mr, addr1, val, 1);
1907 1908 1909
                    break;
                default:
                    abort();
B
bellard 已提交
1910
                }
1911
            } else {
1912
                addr1 += memory_region_get_ram_addr(mr);
B
bellard 已提交
1913
                /* RAM case */
P
pbrook 已提交
1914
                ptr = qemu_get_ram_ptr(addr1);
B
bellard 已提交
1915
                memcpy(ptr, buf, l);
1916
                invalidate_and_set_dirty(addr1, l);
B
bellard 已提交
1917 1918
            }
        } else {
1919
            if (!memory_access_is_direct(mr, is_write)) {
B
bellard 已提交
1920
                /* I/O case */
1921
                l = memory_access_size(mr, l, addr1);
1922 1923 1924 1925 1926 1927 1928
                switch (l) {
                case 8:
                    /* 64 bit read access */
                    error |= io_mem_read(mr, addr1, &val, 8);
                    stq_p(buf, val);
                    break;
                case 4:
B
bellard 已提交
1929
                    /* 32 bit read access */
1930
                    error |= io_mem_read(mr, addr1, &val, 4);
B
bellard 已提交
1931
                    stl_p(buf, val);
1932 1933
                    break;
                case 2:
B
bellard 已提交
1934
                    /* 16 bit read access */
1935
                    error |= io_mem_read(mr, addr1, &val, 2);
B
bellard 已提交
1936
                    stw_p(buf, val);
1937 1938
                    break;
                case 1:
B
bellard 已提交
1939
                    /* 8 bit read access */
1940
                    error |= io_mem_read(mr, addr1, &val, 1);
B
bellard 已提交
1941
                    stb_p(buf, val);
1942 1943 1944
                    break;
                default:
                    abort();
B
bellard 已提交
1945 1946 1947
                }
            } else {
                /* RAM case */
1948
                ptr = qemu_get_ram_ptr(mr->ram_addr + addr1);
1949
                memcpy(buf, ptr, l);
B
bellard 已提交
1950 1951 1952 1953 1954 1955
            }
        }
        len -= l;
        buf += l;
        addr += l;
    }
1956 1957

    return error;
B
bellard 已提交
1958
}
B
bellard 已提交
1959

1960
bool address_space_write(AddressSpace *as, hwaddr addr,
A
Avi Kivity 已提交
1961 1962
                         const uint8_t *buf, int len)
{
1963
    return address_space_rw(as, addr, (uint8_t *)buf, len, true);
A
Avi Kivity 已提交
1964 1965
}

1966
bool address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len)
A
Avi Kivity 已提交
1967
{
1968
    return address_space_rw(as, addr, buf, len, false);
A
Avi Kivity 已提交
1969 1970 1971
}


A
Avi Kivity 已提交
1972
void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
A
Avi Kivity 已提交
1973 1974
                            int len, int is_write)
{
1975
    address_space_rw(&address_space_memory, addr, buf, len, is_write);
A
Avi Kivity 已提交
1976 1977
}

B
bellard 已提交
1978
/* used for ROM loading : can write in RAM and ROM */
A
Avi Kivity 已提交
1979
void cpu_physical_memory_write_rom(hwaddr addr,
B
bellard 已提交
1980 1981
                                   const uint8_t *buf, int len)
{
1982
    hwaddr l;
B
bellard 已提交
1983
    uint8_t *ptr;
1984
    hwaddr addr1;
1985
    MemoryRegion *mr;
1986

B
bellard 已提交
1987
    while (len > 0) {
1988
        l = len;
1989 1990
        mr = address_space_translate(&address_space_memory,
                                     addr, &addr1, &l, true);
1991

1992 1993
        if (!(memory_region_is_ram(mr) ||
              memory_region_is_romd(mr))) {
B
bellard 已提交
1994 1995
            /* do nothing */
        } else {
1996
            addr1 += memory_region_get_ram_addr(mr);
B
bellard 已提交
1997
            /* ROM/RAM case */
P
pbrook 已提交
1998
            ptr = qemu_get_ram_ptr(addr1);
B
bellard 已提交
1999
            memcpy(ptr, buf, l);
2000
            invalidate_and_set_dirty(addr1, l);
B
bellard 已提交
2001 2002 2003 2004 2005 2006 2007
        }
        len -= l;
        buf += l;
        addr += l;
    }
}

2008
typedef struct {
2009
    MemoryRegion *mr;
2010
    void *buffer;
A
Avi Kivity 已提交
2011 2012
    hwaddr addr;
    hwaddr len;
2013 2014 2015 2016
} BounceBuffer;

static BounceBuffer bounce;

2017 2018 2019
typedef struct MapClient {
    void *opaque;
    void (*callback)(void *opaque);
B
Blue Swirl 已提交
2020
    QLIST_ENTRY(MapClient) link;
2021 2022
} MapClient;

B
Blue Swirl 已提交
2023 2024
static QLIST_HEAD(map_client_list, MapClient) map_client_list
    = QLIST_HEAD_INITIALIZER(map_client_list);
2025 2026 2027

void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque))
{
2028
    MapClient *client = g_malloc(sizeof(*client));
2029 2030 2031

    client->opaque = opaque;
    client->callback = callback;
B
Blue Swirl 已提交
2032
    QLIST_INSERT_HEAD(&map_client_list, client, link);
2033 2034 2035
    return client;
}

B
Blue Swirl 已提交
2036
static void cpu_unregister_map_client(void *_client)
2037 2038 2039
{
    MapClient *client = (MapClient *)_client;

B
Blue Swirl 已提交
2040
    QLIST_REMOVE(client, link);
2041
    g_free(client);
2042 2043 2044 2045 2046 2047
}

static void cpu_notify_map_clients(void)
{
    MapClient *client;

B
Blue Swirl 已提交
2048 2049
    while (!QLIST_EMPTY(&map_client_list)) {
        client = QLIST_FIRST(&map_client_list);
2050
        client->callback(client->opaque);
2051
        cpu_unregister_map_client(client);
2052 2053 2054
    }
}

2055 2056
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write)
{
2057
    MemoryRegion *mr;
2058 2059 2060 2061
    hwaddr l, xlat;

    while (len > 0) {
        l = len;
2062 2063 2064 2065
        mr = address_space_translate(as, addr, &xlat, &l, is_write);
        if (!memory_access_is_direct(mr, is_write)) {
            l = memory_access_size(mr, l, addr);
            if (!memory_region_access_valid(mr, xlat, l, is_write)) {
2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
                return false;
            }
        }

        len -= l;
        addr += l;
    }
    return true;
}

2076 2077 2078 2079
/* Map a physical memory region into a host virtual address.
 * May map a subset of the requested range, given by and returned in *plen.
 * May return NULL if resources needed to perform the mapping are exhausted.
 * Use only for reads OR writes - not for read-modify-write operations.
2080 2081
 * Use cpu_register_map_client() to know when retrying the map operation is
 * likely to succeed.
2082
 */
A
Avi Kivity 已提交
2083
void *address_space_map(AddressSpace *as,
A
Avi Kivity 已提交
2084 2085
                        hwaddr addr,
                        hwaddr *plen,
A
Avi Kivity 已提交
2086
                        bool is_write)
2087
{
A
Avi Kivity 已提交
2088
    hwaddr len = *plen;
2089 2090 2091 2092
    hwaddr done = 0;
    hwaddr l, xlat, base;
    MemoryRegion *mr, *this_mr;
    ram_addr_t raddr;
2093

2094 2095 2096
    if (len == 0) {
        return NULL;
    }
2097

2098 2099 2100 2101 2102
    l = len;
    mr = address_space_translate(as, addr, &xlat, &l, is_write);
    if (!memory_access_is_direct(mr, is_write)) {
        if (bounce.buffer) {
            return NULL;
2103
        }
2104 2105 2106
        /* Avoid unbounded allocations */
        l = MIN(l, TARGET_PAGE_SIZE);
        bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l);
2107 2108
        bounce.addr = addr;
        bounce.len = l;
2109 2110 2111

        memory_region_ref(mr);
        bounce.mr = mr;
2112 2113
        if (!is_write) {
            address_space_read(as, addr, bounce.buffer, l);
2114
        }
2115

2116 2117 2118 2119 2120 2121 2122 2123
        *plen = l;
        return bounce.buffer;
    }

    base = xlat;
    raddr = memory_region_get_ram_addr(mr);

    for (;;) {
2124 2125
        len -= l;
        addr += l;
2126 2127 2128 2129 2130 2131 2132 2133 2134 2135
        done += l;
        if (len == 0) {
            break;
        }

        l = len;
        this_mr = address_space_translate(as, addr, &xlat, &l, is_write);
        if (this_mr != mr || xlat != base + done) {
            break;
        }
2136
    }
2137

2138
    memory_region_ref(mr);
2139 2140
    *plen = done;
    return qemu_ram_ptr_length(raddr + base, plen);
2141 2142
}

A
Avi Kivity 已提交
2143
/* Unmaps a memory region previously mapped by address_space_map().
2144 2145 2146
 * Will also mark the memory as dirty if is_write == 1.  access_len gives
 * the amount of memory that was actually read or written by the caller.
 */
A
Avi Kivity 已提交
2147 2148
void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
                         int is_write, hwaddr access_len)
2149 2150
{
    if (buffer != bounce.buffer) {
2151 2152 2153 2154 2155
        MemoryRegion *mr;
        ram_addr_t addr1;

        mr = qemu_ram_addr_from_host(buffer, &addr1);
        assert(mr != NULL);
2156 2157 2158 2159 2160 2161
        if (is_write) {
            while (access_len) {
                unsigned l;
                l = TARGET_PAGE_SIZE;
                if (l > access_len)
                    l = access_len;
2162
                invalidate_and_set_dirty(addr1, l);
2163 2164 2165 2166
                addr1 += l;
                access_len -= l;
            }
        }
2167
        if (xen_enabled()) {
J
Jan Kiszka 已提交
2168
            xen_invalidate_map_cache_entry(buffer);
A
Anthony PERARD 已提交
2169
        }
2170
        memory_region_unref(mr);
2171 2172 2173
        return;
    }
    if (is_write) {
A
Avi Kivity 已提交
2174
        address_space_write(as, bounce.addr, bounce.buffer, access_len);
2175
    }
2176
    qemu_vfree(bounce.buffer);
2177
    bounce.buffer = NULL;
2178
    memory_region_unref(bounce.mr);
2179
    cpu_notify_map_clients();
2180
}
B
bellard 已提交
2181

A
Avi Kivity 已提交
2182 2183
void *cpu_physical_memory_map(hwaddr addr,
                              hwaddr *plen,
A
Avi Kivity 已提交
2184 2185 2186 2187 2188
                              int is_write)
{
    return address_space_map(&address_space_memory, addr, plen, is_write);
}

A
Avi Kivity 已提交
2189 2190
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
                               int is_write, hwaddr access_len)
A
Avi Kivity 已提交
2191 2192 2193 2194
{
    return address_space_unmap(&address_space_memory, buffer, len, is_write, access_len);
}

B
bellard 已提交
2195
/* warning: addr must be aligned */
A
Avi Kivity 已提交
2196
static inline uint32_t ldl_phys_internal(hwaddr addr,
2197
                                         enum device_endian endian)
B
bellard 已提交
2198 2199
{
    uint8_t *ptr;
2200
    uint64_t val;
2201
    MemoryRegion *mr;
2202 2203
    hwaddr l = 4;
    hwaddr addr1;
B
bellard 已提交
2204

2205 2206 2207
    mr = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                 false);
    if (l < 4 || !memory_access_is_direct(mr, false)) {
B
bellard 已提交
2208
        /* I/O case */
2209
        io_mem_read(mr, addr1, &val, 4);
2210 2211 2212 2213 2214 2215 2216 2217 2218
#if defined(TARGET_WORDS_BIGENDIAN)
        if (endian == DEVICE_LITTLE_ENDIAN) {
            val = bswap32(val);
        }
#else
        if (endian == DEVICE_BIG_ENDIAN) {
            val = bswap32(val);
        }
#endif
B
bellard 已提交
2219 2220
    } else {
        /* RAM case */
2221
        ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
2222
                                & TARGET_PAGE_MASK)
2223
                               + addr1);
2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234
        switch (endian) {
        case DEVICE_LITTLE_ENDIAN:
            val = ldl_le_p(ptr);
            break;
        case DEVICE_BIG_ENDIAN:
            val = ldl_be_p(ptr);
            break;
        default:
            val = ldl_p(ptr);
            break;
        }
B
bellard 已提交
2235 2236 2237 2238
    }
    return val;
}

A
Avi Kivity 已提交
2239
uint32_t ldl_phys(hwaddr addr)
2240 2241 2242 2243
{
    return ldl_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
}

A
Avi Kivity 已提交
2244
uint32_t ldl_le_phys(hwaddr addr)
2245 2246 2247 2248
{
    return ldl_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
}

A
Avi Kivity 已提交
2249
uint32_t ldl_be_phys(hwaddr addr)
2250 2251 2252 2253
{
    return ldl_phys_internal(addr, DEVICE_BIG_ENDIAN);
}

B
bellard 已提交
2254
/* warning: addr must be aligned */
A
Avi Kivity 已提交
2255
static inline uint64_t ldq_phys_internal(hwaddr addr,
2256
                                         enum device_endian endian)
B
bellard 已提交
2257 2258 2259
{
    uint8_t *ptr;
    uint64_t val;
2260
    MemoryRegion *mr;
2261 2262
    hwaddr l = 8;
    hwaddr addr1;
B
bellard 已提交
2263

2264 2265 2266
    mr = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                 false);
    if (l < 8 || !memory_access_is_direct(mr, false)) {
B
bellard 已提交
2267
        /* I/O case */
2268
        io_mem_read(mr, addr1, &val, 8);
2269 2270 2271 2272 2273 2274 2275 2276
#if defined(TARGET_WORDS_BIGENDIAN)
        if (endian == DEVICE_LITTLE_ENDIAN) {
            val = bswap64(val);
        }
#else
        if (endian == DEVICE_BIG_ENDIAN) {
            val = bswap64(val);
        }
B
bellard 已提交
2277 2278 2279
#endif
    } else {
        /* RAM case */
2280
        ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
2281
                                & TARGET_PAGE_MASK)
2282
                               + addr1);
2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293
        switch (endian) {
        case DEVICE_LITTLE_ENDIAN:
            val = ldq_le_p(ptr);
            break;
        case DEVICE_BIG_ENDIAN:
            val = ldq_be_p(ptr);
            break;
        default:
            val = ldq_p(ptr);
            break;
        }
B
bellard 已提交
2294 2295 2296 2297
    }
    return val;
}

A
Avi Kivity 已提交
2298
uint64_t ldq_phys(hwaddr addr)
2299 2300 2301 2302
{
    return ldq_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
}

A
Avi Kivity 已提交
2303
uint64_t ldq_le_phys(hwaddr addr)
2304 2305 2306 2307
{
    return ldq_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
}

A
Avi Kivity 已提交
2308
uint64_t ldq_be_phys(hwaddr addr)
2309 2310 2311 2312
{
    return ldq_phys_internal(addr, DEVICE_BIG_ENDIAN);
}

B
bellard 已提交
2313
/* XXX: optimize */
A
Avi Kivity 已提交
2314
uint32_t ldub_phys(hwaddr addr)
B
bellard 已提交
2315 2316 2317 2318 2319 2320
{
    uint8_t val;
    cpu_physical_memory_read(addr, &val, 1);
    return val;
}

2321
/* warning: addr must be aligned */
A
Avi Kivity 已提交
2322
static inline uint32_t lduw_phys_internal(hwaddr addr,
2323
                                          enum device_endian endian)
B
bellard 已提交
2324
{
2325 2326
    uint8_t *ptr;
    uint64_t val;
2327
    MemoryRegion *mr;
2328 2329
    hwaddr l = 2;
    hwaddr addr1;
2330

2331 2332 2333
    mr = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                 false);
    if (l < 2 || !memory_access_is_direct(mr, false)) {
2334
        /* I/O case */
2335
        io_mem_read(mr, addr1, &val, 2);
2336 2337 2338 2339 2340 2341 2342 2343 2344
#if defined(TARGET_WORDS_BIGENDIAN)
        if (endian == DEVICE_LITTLE_ENDIAN) {
            val = bswap16(val);
        }
#else
        if (endian == DEVICE_BIG_ENDIAN) {
            val = bswap16(val);
        }
#endif
2345 2346
    } else {
        /* RAM case */
2347
        ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
2348
                                & TARGET_PAGE_MASK)
2349
                               + addr1);
2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360
        switch (endian) {
        case DEVICE_LITTLE_ENDIAN:
            val = lduw_le_p(ptr);
            break;
        case DEVICE_BIG_ENDIAN:
            val = lduw_be_p(ptr);
            break;
        default:
            val = lduw_p(ptr);
            break;
        }
2361 2362
    }
    return val;
B
bellard 已提交
2363 2364
}

A
Avi Kivity 已提交
2365
uint32_t lduw_phys(hwaddr addr)
2366 2367 2368 2369
{
    return lduw_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
}

A
Avi Kivity 已提交
2370
uint32_t lduw_le_phys(hwaddr addr)
2371 2372 2373 2374
{
    return lduw_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
}

A
Avi Kivity 已提交
2375
uint32_t lduw_be_phys(hwaddr addr)
2376 2377 2378 2379
{
    return lduw_phys_internal(addr, DEVICE_BIG_ENDIAN);
}

B
bellard 已提交
2380 2381 2382
/* warning: addr must be aligned. The ram page is not masked as dirty
   and the code inside is not invalidated. It is useful if the dirty
   bits are used to track modified PTEs */
A
Avi Kivity 已提交
2383
void stl_phys_notdirty(hwaddr addr, uint32_t val)
B
bellard 已提交
2384 2385
{
    uint8_t *ptr;
2386
    MemoryRegion *mr;
2387 2388
    hwaddr l = 4;
    hwaddr addr1;
B
bellard 已提交
2389

2390 2391 2392 2393
    mr = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                 true);
    if (l < 4 || !memory_access_is_direct(mr, true)) {
        io_mem_write(mr, addr1, val, 4);
B
bellard 已提交
2394
    } else {
2395
        addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
P
pbrook 已提交
2396
        ptr = qemu_get_ram_ptr(addr1);
B
bellard 已提交
2397
        stl_p(ptr, val);
A
aliguori 已提交
2398 2399 2400 2401 2402 2403

        if (unlikely(in_migration)) {
            if (!cpu_physical_memory_is_dirty(addr1)) {
                /* invalidate code */
                tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
                /* set dirty bit */
2404 2405
                cpu_physical_memory_set_dirty_flags(
                    addr1, (0xff & ~CODE_DIRTY_FLAG));
A
aliguori 已提交
2406 2407
            }
        }
B
bellard 已提交
2408 2409 2410 2411
    }
}

/* warning: addr must be aligned */
A
Avi Kivity 已提交
2412
static inline void stl_phys_internal(hwaddr addr, uint32_t val,
2413
                                     enum device_endian endian)
B
bellard 已提交
2414 2415
{
    uint8_t *ptr;
2416
    MemoryRegion *mr;
2417 2418
    hwaddr l = 4;
    hwaddr addr1;
B
bellard 已提交
2419

2420 2421 2422
    mr = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                 true);
    if (l < 4 || !memory_access_is_direct(mr, true)) {
2423 2424 2425 2426 2427 2428 2429 2430 2431
#if defined(TARGET_WORDS_BIGENDIAN)
        if (endian == DEVICE_LITTLE_ENDIAN) {
            val = bswap32(val);
        }
#else
        if (endian == DEVICE_BIG_ENDIAN) {
            val = bswap32(val);
        }
#endif
2432
        io_mem_write(mr, addr1, val, 4);
B
bellard 已提交
2433 2434
    } else {
        /* RAM case */
2435
        addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
P
pbrook 已提交
2436
        ptr = qemu_get_ram_ptr(addr1);
2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447
        switch (endian) {
        case DEVICE_LITTLE_ENDIAN:
            stl_le_p(ptr, val);
            break;
        case DEVICE_BIG_ENDIAN:
            stl_be_p(ptr, val);
            break;
        default:
            stl_p(ptr, val);
            break;
        }
2448
        invalidate_and_set_dirty(addr1, 4);
B
bellard 已提交
2449 2450 2451
    }
}

A
Avi Kivity 已提交
2452
void stl_phys(hwaddr addr, uint32_t val)
2453 2454 2455 2456
{
    stl_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN);
}

A
Avi Kivity 已提交
2457
void stl_le_phys(hwaddr addr, uint32_t val)
2458 2459 2460 2461
{
    stl_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN);
}

A
Avi Kivity 已提交
2462
void stl_be_phys(hwaddr addr, uint32_t val)
2463 2464 2465 2466
{
    stl_phys_internal(addr, val, DEVICE_BIG_ENDIAN);
}

B
bellard 已提交
2467
/* XXX: optimize */
A
Avi Kivity 已提交
2468
void stb_phys(hwaddr addr, uint32_t val)
B
bellard 已提交
2469 2470 2471 2472 2473
{
    uint8_t v = val;
    cpu_physical_memory_write(addr, &v, 1);
}

2474
/* warning: addr must be aligned */
A
Avi Kivity 已提交
2475
static inline void stw_phys_internal(hwaddr addr, uint32_t val,
2476
                                     enum device_endian endian)
B
bellard 已提交
2477
{
2478
    uint8_t *ptr;
2479
    MemoryRegion *mr;
2480 2481
    hwaddr l = 2;
    hwaddr addr1;
2482

2483 2484 2485
    mr = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                 true);
    if (l < 2 || !memory_access_is_direct(mr, true)) {
2486 2487 2488 2489 2490 2491 2492 2493 2494
#if defined(TARGET_WORDS_BIGENDIAN)
        if (endian == DEVICE_LITTLE_ENDIAN) {
            val = bswap16(val);
        }
#else
        if (endian == DEVICE_BIG_ENDIAN) {
            val = bswap16(val);
        }
#endif
2495
        io_mem_write(mr, addr1, val, 2);
2496 2497
    } else {
        /* RAM case */
2498
        addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
2499
        ptr = qemu_get_ram_ptr(addr1);
2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510
        switch (endian) {
        case DEVICE_LITTLE_ENDIAN:
            stw_le_p(ptr, val);
            break;
        case DEVICE_BIG_ENDIAN:
            stw_be_p(ptr, val);
            break;
        default:
            stw_p(ptr, val);
            break;
        }
2511
        invalidate_and_set_dirty(addr1, 2);
2512
    }
B
bellard 已提交
2513 2514
}

A
Avi Kivity 已提交
2515
void stw_phys(hwaddr addr, uint32_t val)
2516 2517 2518 2519
{
    stw_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN);
}

A
Avi Kivity 已提交
2520
void stw_le_phys(hwaddr addr, uint32_t val)
2521 2522 2523 2524
{
    stw_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN);
}

A
Avi Kivity 已提交
2525
void stw_be_phys(hwaddr addr, uint32_t val)
2526 2527 2528 2529
{
    stw_phys_internal(addr, val, DEVICE_BIG_ENDIAN);
}

B
bellard 已提交
2530
/* XXX: optimize */
A
Avi Kivity 已提交
2531
void stq_phys(hwaddr addr, uint64_t val)
B
bellard 已提交
2532 2533
{
    val = tswap64(val);
2534
    cpu_physical_memory_write(addr, &val, 8);
B
bellard 已提交
2535 2536
}

A
Avi Kivity 已提交
2537
void stq_le_phys(hwaddr addr, uint64_t val)
2538 2539 2540 2541 2542
{
    val = cpu_to_le64(val);
    cpu_physical_memory_write(addr, &val, 8);
}

A
Avi Kivity 已提交
2543
void stq_be_phys(hwaddr addr, uint64_t val)
2544 2545 2546 2547 2548
{
    val = cpu_to_be64(val);
    cpu_physical_memory_write(addr, &val, 8);
}

2549
/* virtual memory access for debug (includes writing to ROM) */
2550
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
2551
                        uint8_t *buf, int len, int is_write)
B
bellard 已提交
2552 2553
{
    int l;
A
Avi Kivity 已提交
2554
    hwaddr phys_addr;
2555
    target_ulong page;
B
bellard 已提交
2556 2557 2558

    while (len > 0) {
        page = addr & TARGET_PAGE_MASK;
2559
        phys_addr = cpu_get_phys_page_debug(cpu, page);
B
bellard 已提交
2560 2561 2562 2563 2564 2565
        /* if no physical page mapped, return an error */
        if (phys_addr == -1)
            return -1;
        l = (page + TARGET_PAGE_SIZE) - addr;
        if (l > len)
            l = len;
2566 2567 2568 2569 2570
        phys_addr += (addr & ~TARGET_PAGE_MASK);
        if (is_write)
            cpu_physical_memory_write_rom(phys_addr, buf, l);
        else
            cpu_physical_memory_rw(phys_addr, buf, l, is_write);
B
bellard 已提交
2571 2572 2573 2574 2575 2576
        len -= l;
        buf += l;
        addr += l;
    }
    return 0;
}
P
Paul Brook 已提交
2577
#endif
B
bellard 已提交
2578

2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596
#if !defined(CONFIG_USER_ONLY)

/*
 * A helper function for the _utterly broken_ virtio device model to find out if
 * it's running on a big endian machine. Don't do this at home kids!
 */
bool virtio_is_big_endian(void);
bool virtio_is_big_endian(void)
{
#if defined(TARGET_WORDS_BIGENDIAN)
    return true;
#else
    return false;
#endif
}

#endif

2597
#ifndef CONFIG_USER_ONLY
A
Avi Kivity 已提交
2598
bool cpu_physical_memory_is_io(hwaddr phys_addr)
2599
{
2600
    MemoryRegion*mr;
2601
    hwaddr l = 1;
2602

2603 2604
    mr = address_space_translate(&address_space_memory,
                                 phys_addr, &phys_addr, &l, false);
2605

2606 2607
    return !(memory_region_is_ram(mr) ||
             memory_region_is_romd(mr));
2608
}
2609 2610 2611 2612 2613 2614 2615 2616 2617

void qemu_ram_foreach_block(RAMBlockIterFunc func, void *opaque)
{
    RAMBlock *block;

    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
        func(block->host, block->offset, block->length, opaque);
    }
}
2618
#endif