exec.c 71.6 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
    tb_invalidate_phys_addr(cpu_get_phys_page_debug(cpu, pc) |
413
            (pc & ~TARGET_PAGE_MASK));
414
}
B
bellard 已提交
415
#endif
416
#endif /* TARGET_HAS_ICE */
B
bellard 已提交
417

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

{
}

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

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

    wp->vaddr = addr;
447
    wp->len_mask = len_mask;
448 449
    wp->flags = flags;

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

    tlb_flush_page(env, addr);
457 458 459 460

    if (watchpoint)
        *watchpoint = wp;
    return 0;
461 462
}

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

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

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

485 486
    tlb_flush_page(env, watchpoint->vaddr);

487
    g_free(watchpoint);
488 489 490
}

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

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

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

509
    bp = g_malloc(sizeof(*bp));
B
bellard 已提交
510

511 512 513
    bp->pc = pc;
    bp->flags = flags;

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

521
    breakpoint_invalidate(ENV_GET_CPU(env), pc);
522

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

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

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

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

556
    breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc);
557

558
    g_free(breakpoint);
559 560 561 562
#endif
}

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

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

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

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

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

627
#if !defined(CONFIG_USER_ONLY)
P
Paolo Bonzini 已提交
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
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 已提交
651 652 653
static void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t end,
                                      uintptr_t length)
{
P
Paolo Bonzini 已提交
654 655
    RAMBlock *block;
    ram_addr_t start1;
J
Juan Quintela 已提交
656

P
Paolo Bonzini 已提交
657 658 659 660
    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 已提交
661 662
}

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

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

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

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

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

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

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

    /* 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)) {
719
                iotlb = PHYS_SECTION_WATCH + paddr;
B
Blue Swirl 已提交
720 721 722 723 724 725 726 727
                *address |= TLB_MMIO;
                break;
            }
        }
    }

    return iotlb;
}
728 729
#endif /* defined(CONFIG_USER_ONLY) */

730
#if !defined(CONFIG_USER_ONLY)
731

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

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

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

748 749
static uint16_t phys_section_add(MemoryRegionSection *section)
{
750 751 752 753
    /* 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.
     */
754
    assert(next_map.sections_nb < TARGET_PAGE_SIZE);
755

756 757 758 759 760
    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);
761
    }
762
    next_map.sections[next_map.sections_nb] = *section;
P
Paolo Bonzini 已提交
763
    memory_region_ref(section->mr);
764
    return next_map.sections_nb++;
765 766
}

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

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

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

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

802
    assert(existing->mr->subpage || existing->mr == &io_mem_unassigned);
803

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


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

826 827
    assert(num_pages);
    phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
828 829
}

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

837 838 839 840
    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;

841
        now.size = int128_min(int128_make64(left), now.size);
A
Avi Kivity 已提交
842
        register_subpage(d, &now);
843
    } else {
844
        now.size = int128_zero();
845
    }
846 847 848 849
    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);
850
        now = remain;
851
        if (int128_lt(remain.size, page_size)) {
852
            register_subpage(d, &now);
853
        } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
854
            now.size = page_size;
A
Avi Kivity 已提交
855
            register_subpage(d, &now);
856
        } else {
857
            now.size = int128_and(now.size, int128_neg(page_size));
A
Avi Kivity 已提交
858
            register_multipage(d, &now);
859
        }
860 861 862
    }
}

863 864 865 866 867 868
void qemu_flush_coalesced_mmio_buffer(void)
{
    if (kvm_enabled())
        kvm_flush_coalesced_mmio_buffer();
}

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

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

879
#ifdef __linux__
880 881 882 883 884 885 886 887 888 889 890

#include <sys/vfs.h>

#define HUGETLBFS_MAGIC       0x958458f6

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

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

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

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

    return fs.f_bsize;
}

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

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

    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;
    }

933 934 935 936 937 938 939 940 941 942
    /* 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);
943 944 945

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

    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 已提交
962
        perror("ftruncate");
963 964 965 966 967 968 969 970 971 972 973 974

#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 已提交
975 976 977
        perror("file_ram_alloc: can't mmap RAM pages");
        close(fd);
        return (NULL);
978
    }
A
Alex Williamson 已提交
979
    block->fd = fd;
980 981
    return area;
}
982 983 984 985 986 987 988 989
#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);
}
990 991
#endif

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

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

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

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

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

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

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

A
Alex Williamson 已提交
1024 1025 1026
    return offset;
}

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

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

    return last;
}

1038 1039 1040 1041 1042
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 */
1043 1044
    if (!qemu_opt_get_bool(qemu_get_machine_opts(),
                           "dump-guest-core", true)) {
1045 1046 1047 1048 1049 1050 1051 1052 1053
        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");
        }
    }
}

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

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

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

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

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

    return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE);
}

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

    size = TARGET_PAGE_ALIGN(size);
    new_block = g_malloc0(sizeof(*new_block));
1106
    new_block->fd = -1;
1107

1108 1109
    /* This assumes the iothread lock is taken here too.  */
    qemu_mutex_lock_ramlist();
A
Avi Kivity 已提交
1110
    new_block->mr = mr;
J
Jun Nakajima 已提交
1111
    new_block->offset = find_ram_offset(size);
1112 1113
    if (host) {
        new_block->host = host;
H
Huang Ying 已提交
1114
        new_block->flags |= RAM_PREALLOC_MASK;
1115 1116 1117 1118 1119 1120
    } 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);
1121 1122
    } else {
        if (mem_path) {
1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
            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);
            }
1133
            new_block->host = file_ram_alloc(new_block, size, mem_path);
1134 1135
        }
        if (!new_block->host) {
1136
            new_block->host = phys_mem_alloc(size);
1137 1138 1139 1140 1141
            if (!new_block->host) {
                fprintf(stderr, "Cannot set up guest memory '%s': %s\n",
                        new_block->mr->name, strerror(errno));
                exit(1);
            }
1142
            memory_try_enable_merging(new_block->host, size);
1143
        }
1144
    }
P
pbrook 已提交
1145 1146
    new_block->length = size;

1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157
    /* 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);
    }
1158
    ram_list.mru_block = NULL;
P
pbrook 已提交
1159

U
Umesh Deshpande 已提交
1160
    ram_list.version++;
1161
    qemu_mutex_unlock_ramlist();
U
Umesh Deshpande 已提交
1162

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

1169
    qemu_ram_setup_dump(new_block->host, size);
1170
    qemu_madvise(new_block->host, size, QEMU_MADV_HUGEPAGE);
1171
    qemu_madvise(new_block->host, size, QEMU_MADV_DONTFORK);
1172

1173 1174 1175
    if (kvm_enabled())
        kvm_setup_guest_memory(new_block->host, size);

P
pbrook 已提交
1176 1177
    return new_block->offset;
}
B
bellard 已提交
1178

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

1184 1185 1186 1187
void qemu_ram_free_from_ptr(ram_addr_t addr)
{
    RAMBlock *block;

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

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

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

B
bellard 已提交
1231 1232
}

H
Huang Ying 已提交
1233 1234 1235 1236 1237 1238 1239 1240
#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 已提交
1241
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
H
Huang Ying 已提交
1242 1243 1244 1245 1246
        offset = addr - block->offset;
        if (offset < block->length) {
            vaddr = block->host + offset;
            if (block->flags & RAM_PREALLOC_MASK) {
                ;
1247 1248
            } else if (xen_enabled()) {
                abort();
H
Huang Ying 已提交
1249 1250 1251
            } else {
                flags = MAP_FIXED;
                munmap(vaddr, length);
1252
                if (block->fd >= 0) {
H
Huang Ying 已提交
1253
#ifdef MAP_POPULATE
1254 1255
                    flags |= mem_prealloc ? MAP_POPULATE | MAP_SHARED :
                        MAP_PRIVATE;
1256
#else
1257
                    flags |= MAP_PRIVATE;
H
Huang Ying 已提交
1258
#endif
1259 1260
                    area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
                                flags, block->fd, offset);
H
Huang Ying 已提交
1261
                } else {
1262 1263 1264 1265 1266 1267 1268
                    /*
                     * 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 已提交
1269 1270 1271 1272 1273
                    flags |= MAP_PRIVATE | MAP_ANONYMOUS;
                    area = mmap(vaddr, length, PROT_READ | PROT_WRITE,
                                flags, -1, 0);
                }
                if (area != vaddr) {
1274 1275
                    fprintf(stderr, "Could not remap addr: "
                            RAM_ADDR_FMT "@" RAM_ADDR_FMT "\n",
H
Huang Ying 已提交
1276 1277 1278
                            length, addr);
                    exit(1);
                }
1279
                memory_try_enable_merging(vaddr, length);
1280
                qemu_ram_setup_dump(vaddr, length);
H
Huang Ying 已提交
1281 1282 1283 1284 1285 1286 1287
            }
            return;
        }
    }
}
#endif /* !_WIN32 */

1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
/* 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);

1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
    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);
1313 1314
}

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

P
Paolo Bonzini 已提交
1327
        QTAILQ_FOREACH(block, &ram_list.blocks, next) {
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339
            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();
    }
}

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

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

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

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

1367
    return NULL;
1368 1369 1370

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

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

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

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

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

1427 1428 1429 1430
    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. */
1431
        cpu_interrupt(ENV_GET_CPU(env), CPU_INTERRUPT_DEBUG);
1432 1433
        return;
    }
P
pbrook 已提交
1434
    vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
B
Blue Swirl 已提交
1435
    QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
1436 1437
        if ((vaddr == (wp->vaddr & len_mask) ||
             (vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
1438 1439 1440
            wp->flags |= BP_WATCHPOINT_HIT;
            if (!env->watchpoint_hit) {
                env->watchpoint_hit = wp;
B
Blue Swirl 已提交
1441
                tb_check_watchpoint(env);
1442 1443
                if (wp->flags & BP_STOP_BEFORE_ACCESS) {
                    env->exception_index = EXCP_DEBUG;
1444
                    cpu_loop_exit(env);
1445 1446 1447
                } else {
                    cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);
                    tb_gen_code(env, pc, cs_base, cpu_flags, 1);
1448
                    cpu_resume_from_signal(env, NULL);
1449
                }
1450
            }
1451 1452
        } else {
            wp->flags &= ~BP_WATCHPOINT_HIT;
P
pbrook 已提交
1453 1454 1455 1456
        }
    }
}

1457 1458 1459
/* 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 已提交
1460
static uint64_t watch_mem_read(void *opaque, hwaddr addr,
1461
                               unsigned size)
1462
{
1463 1464 1465 1466 1467 1468 1469
    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();
    }
1470 1471
}

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

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

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

1502
#if defined(DEBUG_SUBPAGE)
A
Amos Kong 已提交
1503
    printf("%s: subpage %p len %u addr " TARGET_FMT_plx "\n", __func__,
1504
           subpage, len, addr);
1505
#endif
1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516
    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();
    }
1517 1518
}

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

1525
#if defined(DEBUG_SUBPAGE)
A
Amos Kong 已提交
1526
    printf("%s: subpage %p len %u addr " TARGET_FMT_plx
1527 1528
           " value %"PRIx64"\n",
           __func__, subpage, len, addr, value);
1529
#endif
1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543
    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);
1544 1545
}

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

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

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

A
Anthony Liguori 已提交
1566
static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
1567
                             uint16_t section)
1568 1569 1570 1571 1572 1573 1574 1575
{
    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 已提交
1576 1577
    printf("%s: %p start %08x end %08x idx %08x eidx %08x section %d\n",
           __func__, mmio, start, end, idx, eidx, section);
1578 1579
#endif
    for (; idx <= eidx; idx++) {
1580
        mmio->sub_section[idx] = section;
1581 1582 1583 1584 1585
    }

    return 0;
}

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

1590
    mmio = g_malloc0(sizeof(subpage_t));
1591

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

    return mmio;
}

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

    return phys_section_add(&section);
}

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

A
Avi Kivity 已提交
1623 1624
static void io_mem_init(void)
{
1625 1626
    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,
1627
                          "unassigned", UINT64_MAX);
1628
    memory_region_init_io(&io_mem_notdirty, NULL, &notdirty_mem_ops, NULL,
1629
                          "notdirty", UINT64_MAX);
1630
    memory_region_init_io(&io_mem_watch, NULL, &watch_mem_ops, NULL,
1631
                          "watch", UINT64_MAX);
A
Avi Kivity 已提交
1632 1633
}

A
Avi Kivity 已提交
1634
static void mem_begin(MemoryListener *listener)
1635 1636 1637 1638 1639 1640 1641 1642 1643 1644
{
    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 已提交
1645
{
1646
    AddressSpace *as = container_of(listener, AddressSpace, dispatch_listener);
1647 1648 1649 1650 1651
    AddressSpaceDispatch *cur = as->dispatch;
    AddressSpaceDispatch *next = as->next_dispatch;

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

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

1657 1658
static void core_begin(MemoryListener *listener)
{
1659 1660
    uint16_t n;

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

1664
    memset(&next_map, 0, sizeof(next_map));
1665 1666 1667 1668 1669 1670 1671 1672
    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);
1673 1674
}

1675 1676 1677 1678 1679
/* 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 已提交
1680
    phys_sections_free(prev_map);
1681 1682
}

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

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

1693 1694
        tlb_flush(env, 1);
    }
1695 1696
}

1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707
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 = {
1708
    .begin = core_begin,
1709
    .commit = core_commit,
1710 1711
    .log_global_start = core_log_global_start,
    .log_global_stop = core_log_global_stop,
A
Avi Kivity 已提交
1712
    .priority = 1,
1713 1714
};

1715 1716 1717 1718
static MemoryListener tcg_memory_listener = {
    .commit = tcg_commit,
};

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

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

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

A
Avi Kivity 已提交
1741 1742
static void memory_map_init(void)
{
1743
    system_memory = g_malloc(sizeof(*system_memory));
1744 1745 1746 1747 1748 1749

    assert(TARGET_PHYS_ADDR_SPACE_BITS <= 64);

    memory_region_init(system_memory, NULL, "system",
                       TARGET_PHYS_ADDR_SPACE_BITS == 64 ?
                       UINT64_MAX : (0x1ULL << TARGET_PHYS_ADDR_SPACE_BITS));
1750
    address_space_init(&address_space_memory, system_memory, "memory");
1751

1752
    system_io = g_malloc(sizeof(*system_io));
1753 1754
    memory_region_init_io(system_io, NULL, &unassigned_io_ops, NULL, "io",
                          65536);
1755
    address_space_init(&address_space_io, system_io, "I/O");
1756

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

MemoryRegion *get_system_memory(void)
{
    return system_memory;
}

1768 1769 1770 1771 1772
MemoryRegion *get_system_io(void)
{
    return system_io;
}

1773 1774
#endif /* !defined(CONFIG_USER_ONLY) */

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

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

B
bellard 已提交
1816
#else
1817

A
Avi Kivity 已提交
1818 1819
static void invalidate_and_set_dirty(hwaddr addr,
                                     hwaddr length)
1820 1821 1822 1823 1824 1825 1826
{
    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));
    }
1827
    xen_modified_memory(addr, length);
1828 1829
}

1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841
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;
}

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

    /* 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;
        }
1858
    }
1859 1860 1861 1862

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

    return l;
1869 1870
}

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

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

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

    return error;
B
bellard 已提交
1961
}
B
bellard 已提交
1962

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

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


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

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

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

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

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

static BounceBuffer bounce;

2020 2021 2022
typedef struct MapClient {
    void *opaque;
    void (*callback)(void *opaque);
B
Blue Swirl 已提交
2023
    QLIST_ENTRY(MapClient) link;
2024 2025
} MapClient;

B
Blue Swirl 已提交
2026 2027
static QLIST_HEAD(map_client_list, MapClient) map_client_list
    = QLIST_HEAD_INITIALIZER(map_client_list);
2028 2029 2030

void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque))
{
2031
    MapClient *client = g_malloc(sizeof(*client));
2032 2033 2034

    client->opaque = opaque;
    client->callback = callback;
B
Blue Swirl 已提交
2035
    QLIST_INSERT_HEAD(&map_client_list, client, link);
2036 2037 2038
    return client;
}

B
Blue Swirl 已提交
2039
static void cpu_unregister_map_client(void *_client)
2040 2041 2042
{
    MapClient *client = (MapClient *)_client;

B
Blue Swirl 已提交
2043
    QLIST_REMOVE(client, link);
2044
    g_free(client);
2045 2046 2047 2048 2049 2050
}

static void cpu_notify_map_clients(void)
{
    MapClient *client;

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

2058 2059
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write)
{
2060
    MemoryRegion *mr;
2061 2062 2063 2064
    hwaddr l, xlat;

    while (len > 0) {
        l = len;
2065 2066 2067 2068
        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)) {
2069 2070 2071 2072 2073 2074 2075 2076 2077 2078
                return false;
            }
        }

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

2079 2080 2081 2082
/* 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.
2083 2084
 * Use cpu_register_map_client() to know when retrying the map operation is
 * likely to succeed.
2085
 */
A
Avi Kivity 已提交
2086
void *address_space_map(AddressSpace *as,
A
Avi Kivity 已提交
2087 2088
                        hwaddr addr,
                        hwaddr *plen,
A
Avi Kivity 已提交
2089
                        bool is_write)
2090
{
A
Avi Kivity 已提交
2091
    hwaddr len = *plen;
2092 2093 2094 2095
    hwaddr done = 0;
    hwaddr l, xlat, base;
    MemoryRegion *mr, *this_mr;
    ram_addr_t raddr;
2096

2097 2098 2099
    if (len == 0) {
        return NULL;
    }
2100

2101 2102 2103 2104 2105
    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;
2106
        }
2107 2108 2109
        /* Avoid unbounded allocations */
        l = MIN(l, TARGET_PAGE_SIZE);
        bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l);
2110 2111
        bounce.addr = addr;
        bounce.len = l;
2112 2113 2114

        memory_region_ref(mr);
        bounce.mr = mr;
2115 2116
        if (!is_write) {
            address_space_read(as, addr, bounce.buffer, l);
2117
        }
2118

2119 2120 2121 2122 2123 2124 2125 2126
        *plen = l;
        return bounce.buffer;
    }

    base = xlat;
    raddr = memory_region_get_ram_addr(mr);

    for (;;) {
2127 2128
        len -= l;
        addr += l;
2129 2130 2131 2132 2133 2134 2135 2136 2137 2138
        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;
        }
2139
    }
2140

2141
    memory_region_ref(mr);
2142 2143
    *plen = done;
    return qemu_ram_ptr_length(raddr + base, plen);
2144 2145
}

A
Avi Kivity 已提交
2146
/* Unmaps a memory region previously mapped by address_space_map().
2147 2148 2149
 * 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 已提交
2150 2151
void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
                         int is_write, hwaddr access_len)
2152 2153
{
    if (buffer != bounce.buffer) {
2154 2155 2156 2157 2158
        MemoryRegion *mr;
        ram_addr_t addr1;

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

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

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

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

2208 2209 2210
    mr = address_space_translate(&address_space_memory, addr, &addr1, &l,
                                 false);
    if (l < 4 || !memory_access_is_direct(mr, false)) {
B
bellard 已提交
2211
        /* I/O case */
2212
        io_mem_read(mr, addr1, &val, 4);
2213 2214 2215 2216 2217 2218 2219 2220 2221
#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 已提交
2222 2223
    } else {
        /* RAM case */
2224
        ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
2225
                                & TARGET_PAGE_MASK)
2226
                               + addr1);
2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237
        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 已提交
2238 2239 2240 2241
    }
    return val;
}

A
Avi Kivity 已提交
2242
uint32_t ldl_phys(hwaddr addr)
2243 2244 2245 2246
{
    return ldl_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
}

A
Avi Kivity 已提交
2247
uint32_t ldl_le_phys(hwaddr addr)
2248 2249 2250 2251
{
    return ldl_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
}

A
Avi Kivity 已提交
2252
uint32_t ldl_be_phys(hwaddr addr)
2253 2254 2255 2256
{
    return ldl_phys_internal(addr, DEVICE_BIG_ENDIAN);
}

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

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

A
Avi Kivity 已提交
2301
uint64_t ldq_phys(hwaddr addr)
2302 2303 2304 2305
{
    return ldq_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
}

A
Avi Kivity 已提交
2306
uint64_t ldq_le_phys(hwaddr addr)
2307 2308 2309 2310
{
    return ldq_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
}

A
Avi Kivity 已提交
2311
uint64_t ldq_be_phys(hwaddr addr)
2312 2313 2314 2315
{
    return ldq_phys_internal(addr, DEVICE_BIG_ENDIAN);
}

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

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

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

A
Avi Kivity 已提交
2368
uint32_t lduw_phys(hwaddr addr)
2369 2370 2371 2372
{
    return lduw_phys_internal(addr, DEVICE_NATIVE_ENDIAN);
}

A
Avi Kivity 已提交
2373
uint32_t lduw_le_phys(hwaddr addr)
2374 2375 2376 2377
{
    return lduw_phys_internal(addr, DEVICE_LITTLE_ENDIAN);
}

A
Avi Kivity 已提交
2378
uint32_t lduw_be_phys(hwaddr addr)
2379 2380 2381 2382
{
    return lduw_phys_internal(addr, DEVICE_BIG_ENDIAN);
}

B
bellard 已提交
2383 2384 2385
/* 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 已提交
2386
void stl_phys_notdirty(hwaddr addr, uint32_t val)
B
bellard 已提交
2387 2388
{
    uint8_t *ptr;
2389
    MemoryRegion *mr;
2390 2391
    hwaddr l = 4;
    hwaddr addr1;
B
bellard 已提交
2392

2393 2394 2395 2396
    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 已提交
2397
    } else {
2398
        addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
P
pbrook 已提交
2399
        ptr = qemu_get_ram_ptr(addr1);
B
bellard 已提交
2400
        stl_p(ptr, val);
A
aliguori 已提交
2401 2402 2403 2404 2405 2406

        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 */
2407 2408
                cpu_physical_memory_set_dirty_flags(
                    addr1, (0xff & ~CODE_DIRTY_FLAG));
A
aliguori 已提交
2409 2410
            }
        }
B
bellard 已提交
2411 2412 2413 2414
    }
}

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

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

A
Avi Kivity 已提交
2455
void stl_phys(hwaddr addr, uint32_t val)
2456 2457 2458 2459
{
    stl_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN);
}

A
Avi Kivity 已提交
2460
void stl_le_phys(hwaddr addr, uint32_t val)
2461 2462 2463 2464
{
    stl_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN);
}

A
Avi Kivity 已提交
2465
void stl_be_phys(hwaddr addr, uint32_t val)
2466 2467 2468 2469
{
    stl_phys_internal(addr, val, DEVICE_BIG_ENDIAN);
}

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

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

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

A
Avi Kivity 已提交
2518
void stw_phys(hwaddr addr, uint32_t val)
2519 2520 2521 2522
{
    stw_phys_internal(addr, val, DEVICE_NATIVE_ENDIAN);
}

A
Avi Kivity 已提交
2523
void stw_le_phys(hwaddr addr, uint32_t val)
2524 2525 2526 2527
{
    stw_phys_internal(addr, val, DEVICE_LITTLE_ENDIAN);
}

A
Avi Kivity 已提交
2528
void stw_be_phys(hwaddr addr, uint32_t val)
2529 2530 2531 2532
{
    stw_phys_internal(addr, val, DEVICE_BIG_ENDIAN);
}

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

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

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

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

    while (len > 0) {
        page = addr & TARGET_PAGE_MASK;
2562
        phys_addr = cpu_get_phys_page_debug(cpu, page);
B
bellard 已提交
2563 2564 2565 2566 2567 2568
        /* 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;
2569 2570 2571 2572 2573
        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 已提交
2574 2575 2576 2577 2578 2579
        len -= l;
        buf += l;
        addr += l;
    }
    return 0;
}
P
Paul Brook 已提交
2580
#endif
B
bellard 已提交
2581

2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599
#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

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

2606 2607
    mr = address_space_translate(&address_space_memory,
                                 phys_addr, &phys_addr, &l, false);
2608

2609 2610
    return !(memory_region_is_ram(mr) ||
             memory_region_is_romd(mr));
2611
}
2612 2613 2614 2615 2616 2617 2618 2619 2620

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);
    }
}
2621
#endif