Statistics
| Branch: | Revision:

root / include / exec / ram_addr.h @ 5ff7fb77

History | View | Annotate | Download (4.3 kB)

1
/*
2
 * Declarations for cpu physical memory functions
3
 *
4
 * Copyright 2011 Red Hat, Inc. and/or its affiliates
5
 *
6
 * Authors:
7
 *  Avi Kivity <avi@redhat.com>
8
 *
9
 * This work is licensed under the terms of the GNU GPL, version 2 or
10
 * later.  See the COPYING file in the top-level directory.
11
 *
12
 */
13

    
14
/*
15
 * This header is for use by exec.c and memory.c ONLY.  Do not include it.
16
 * The functions declared here will be removed soon.
17
 */
18

    
19
#ifndef RAM_ADDR_H
20
#define RAM_ADDR_H
21

    
22
#ifndef CONFIG_USER_ONLY
23
#include "hw/xen/xen.h"
24

    
25
ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
26
                                   MemoryRegion *mr);
27
ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr);
28
void *qemu_get_ram_ptr(ram_addr_t addr);
29
void qemu_ram_free(ram_addr_t addr);
30
void qemu_ram_free_from_ptr(ram_addr_t addr);
31

    
32
static inline bool cpu_physical_memory_get_dirty(ram_addr_t start,
33
                                                 ram_addr_t length,
34
                                                 unsigned client)
35
{
36
    unsigned long end, page, next;
37

    
38
    assert(client < DIRTY_MEMORY_NUM);
39

    
40
    end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS;
41
    page = start >> TARGET_PAGE_BITS;
42
    next = find_next_bit(ram_list.dirty_memory[client], end, page);
43

    
44
    return next < end;
45
}
46

    
47
static inline bool cpu_physical_memory_get_dirty_flag(ram_addr_t addr,
48
                                                      unsigned client)
49
{
50
    return cpu_physical_memory_get_dirty(addr, 1, client);
51
}
52

    
53
static inline bool cpu_physical_memory_is_clean(ram_addr_t addr)
54
{
55
    bool vga = cpu_physical_memory_get_dirty_flag(addr, DIRTY_MEMORY_VGA);
56
    bool code = cpu_physical_memory_get_dirty_flag(addr, DIRTY_MEMORY_CODE);
57
    bool migration =
58
        cpu_physical_memory_get_dirty_flag(addr, DIRTY_MEMORY_MIGRATION);
59
    return !(vga && code && migration);
60
}
61

    
62
static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr,
63
                                                      unsigned client)
64
{
65
    assert(client < DIRTY_MEMORY_NUM);
66
    set_bit(addr >> TARGET_PAGE_BITS, ram_list.dirty_memory[client]);
67
}
68

    
69
static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start,
70
                                                       ram_addr_t length)
71
{
72
    unsigned long end, page;
73

    
74
    end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS;
75
    page = start >> TARGET_PAGE_BITS;
76
    bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION], page, end - page);
77
    bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_VGA], page, end - page);
78
    bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_CODE], page, end - page);
79
    xen_modified_memory(start, length);
80
}
81

    
82
static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
83
                                                          ram_addr_t start,
84
                                                          ram_addr_t pages)
85
{
86
    unsigned int i, j;
87
    unsigned long page_number, c;
88
    hwaddr addr;
89
    ram_addr_t ram_addr;
90
    unsigned int len = (pages + HOST_LONG_BITS - 1) / HOST_LONG_BITS;
91
    unsigned long hpratio = getpagesize() / TARGET_PAGE_SIZE;
92

    
93
    /*
94
     * bitmap-traveling is faster than memory-traveling (for addr...)
95
     * especially when most of the memory is not dirty.
96
     */
97
    for (i = 0; i < len; i++) {
98
        if (bitmap[i] != 0) {
99
            c = leul_to_cpu(bitmap[i]);
100
            do {
101
                j = ffsl(c) - 1;
102
                c &= ~(1ul << j);
103
                page_number = (i * HOST_LONG_BITS + j) * hpratio;
104
                addr = page_number * TARGET_PAGE_SIZE;
105
                ram_addr = start + addr;
106
                cpu_physical_memory_set_dirty_range(ram_addr,
107
                                                    TARGET_PAGE_SIZE * hpratio);
108
            } while (c != 0);
109
        }
110
    }
111
}
112

    
113
static inline void cpu_physical_memory_clear_dirty_range(ram_addr_t start,
114
                                                         ram_addr_t length,
115
                                                         unsigned client)
116
{
117
    unsigned long end, page;
118

    
119
    assert(client < DIRTY_MEMORY_NUM);
120
    end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS;
121
    page = start >> TARGET_PAGE_BITS;
122
    bitmap_clear(ram_list.dirty_memory[client], page, end - page);
123
}
124

    
125
void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t length,
126
                                     unsigned client);
127

    
128
#endif
129
#endif