Statistics
| Branch: | Revision:

root / memory.c @ e36c8766

History | View | Annotate | Download (51 kB)

1 093bc2cd Avi Kivity
/*
2 093bc2cd Avi Kivity
 * Physical memory management
3 093bc2cd Avi Kivity
 *
4 093bc2cd Avi Kivity
 * Copyright 2011 Red Hat, Inc. and/or its affiliates
5 093bc2cd Avi Kivity
 *
6 093bc2cd Avi Kivity
 * Authors:
7 093bc2cd Avi Kivity
 *  Avi Kivity <avi@redhat.com>
8 093bc2cd Avi Kivity
 *
9 093bc2cd Avi Kivity
 * This work is licensed under the terms of the GNU GPL, version 2.  See
10 093bc2cd Avi Kivity
 * the COPYING file in the top-level directory.
11 093bc2cd Avi Kivity
 *
12 6b620ca3 Paolo Bonzini
 * Contributions after 2012-01-13 are licensed under the terms of the
13 6b620ca3 Paolo Bonzini
 * GNU GPL, version 2 or (at your option) any later version.
14 093bc2cd Avi Kivity
 */
15 093bc2cd Avi Kivity
16 093bc2cd Avi Kivity
#include "memory.h"
17 1c0ffa58 Avi Kivity
#include "exec-memory.h"
18 658b2224 Avi Kivity
#include "ioport.h"
19 74901c3b Avi Kivity
#include "bitops.h"
20 3e9d69e7 Avi Kivity
#include "kvm.h"
21 093bc2cd Avi Kivity
#include <assert.h>
22 093bc2cd Avi Kivity
23 67d95c15 Avi Kivity
#define WANT_EXEC_OBSOLETE
24 67d95c15 Avi Kivity
#include "exec-obsolete.h"
25 67d95c15 Avi Kivity
26 4ef4db86 Avi Kivity
unsigned memory_region_transaction_depth = 0;
27 e87c099f Avi Kivity
static bool memory_region_update_pending = false;
28 7664e80c Avi Kivity
static bool global_dirty_log = false;
29 7664e80c Avi Kivity
30 72e22d2f Avi Kivity
static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
31 72e22d2f Avi Kivity
    = QTAILQ_HEAD_INITIALIZER(memory_listeners);
32 4ef4db86 Avi Kivity
33 093bc2cd Avi Kivity
typedef struct AddrRange AddrRange;
34 093bc2cd Avi Kivity
35 8417cebf Avi Kivity
/*
36 8417cebf Avi Kivity
 * Note using signed integers limits us to physical addresses at most
37 8417cebf Avi Kivity
 * 63 bits wide.  They are needed for negative offsetting in aliases
38 8417cebf Avi Kivity
 * (large MemoryRegion::alias_offset).
39 8417cebf Avi Kivity
 */
40 093bc2cd Avi Kivity
struct AddrRange {
41 08dafab4 Avi Kivity
    Int128 start;
42 08dafab4 Avi Kivity
    Int128 size;
43 093bc2cd Avi Kivity
};
44 093bc2cd Avi Kivity
45 08dafab4 Avi Kivity
static AddrRange addrrange_make(Int128 start, Int128 size)
46 093bc2cd Avi Kivity
{
47 093bc2cd Avi Kivity
    return (AddrRange) { start, size };
48 093bc2cd Avi Kivity
}
49 093bc2cd Avi Kivity
50 093bc2cd Avi Kivity
static bool addrrange_equal(AddrRange r1, AddrRange r2)
51 093bc2cd Avi Kivity
{
52 08dafab4 Avi Kivity
    return int128_eq(r1.start, r2.start) && int128_eq(r1.size, r2.size);
53 093bc2cd Avi Kivity
}
54 093bc2cd Avi Kivity
55 08dafab4 Avi Kivity
static Int128 addrrange_end(AddrRange r)
56 093bc2cd Avi Kivity
{
57 08dafab4 Avi Kivity
    return int128_add(r.start, r.size);
58 093bc2cd Avi Kivity
}
59 093bc2cd Avi Kivity
60 08dafab4 Avi Kivity
static AddrRange addrrange_shift(AddrRange range, Int128 delta)
61 093bc2cd Avi Kivity
{
62 08dafab4 Avi Kivity
    int128_addto(&range.start, delta);
63 093bc2cd Avi Kivity
    return range;
64 093bc2cd Avi Kivity
}
65 093bc2cd Avi Kivity
66 08dafab4 Avi Kivity
static bool addrrange_contains(AddrRange range, Int128 addr)
67 08dafab4 Avi Kivity
{
68 08dafab4 Avi Kivity
    return int128_ge(addr, range.start)
69 08dafab4 Avi Kivity
        && int128_lt(addr, addrrange_end(range));
70 08dafab4 Avi Kivity
}
71 08dafab4 Avi Kivity
72 093bc2cd Avi Kivity
static bool addrrange_intersects(AddrRange r1, AddrRange r2)
73 093bc2cd Avi Kivity
{
74 08dafab4 Avi Kivity
    return addrrange_contains(r1, r2.start)
75 08dafab4 Avi Kivity
        || addrrange_contains(r2, r1.start);
76 093bc2cd Avi Kivity
}
77 093bc2cd Avi Kivity
78 093bc2cd Avi Kivity
static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2)
79 093bc2cd Avi Kivity
{
80 08dafab4 Avi Kivity
    Int128 start = int128_max(r1.start, r2.start);
81 08dafab4 Avi Kivity
    Int128 end = int128_min(addrrange_end(r1), addrrange_end(r2));
82 08dafab4 Avi Kivity
    return addrrange_make(start, int128_sub(end, start));
83 093bc2cd Avi Kivity
}
84 093bc2cd Avi Kivity
85 0e0d36b4 Avi Kivity
enum ListenerDirection { Forward, Reverse };
86 0e0d36b4 Avi Kivity
87 7376e582 Avi Kivity
static bool memory_listener_match(MemoryListener *listener,
88 7376e582 Avi Kivity
                                  MemoryRegionSection *section)
89 7376e582 Avi Kivity
{
90 7376e582 Avi Kivity
    return !listener->address_space_filter
91 7376e582 Avi Kivity
        || listener->address_space_filter == section->address_space;
92 7376e582 Avi Kivity
}
93 7376e582 Avi Kivity
94 7376e582 Avi Kivity
#define MEMORY_LISTENER_CALL_GLOBAL(_callback, _direction, _args...)    \
95 0e0d36b4 Avi Kivity
    do {                                                                \
96 0e0d36b4 Avi Kivity
        MemoryListener *_listener;                                      \
97 0e0d36b4 Avi Kivity
                                                                        \
98 0e0d36b4 Avi Kivity
        switch (_direction) {                                           \
99 0e0d36b4 Avi Kivity
        case Forward:                                                   \
100 0e0d36b4 Avi Kivity
            QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
101 0e0d36b4 Avi Kivity
                _listener->_callback(_listener, ##_args);               \
102 0e0d36b4 Avi Kivity
            }                                                           \
103 0e0d36b4 Avi Kivity
            break;                                                      \
104 0e0d36b4 Avi Kivity
        case Reverse:                                                   \
105 0e0d36b4 Avi Kivity
            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
106 0e0d36b4 Avi Kivity
                                   memory_listeners, link) {            \
107 0e0d36b4 Avi Kivity
                _listener->_callback(_listener, ##_args);               \
108 0e0d36b4 Avi Kivity
            }                                                           \
109 0e0d36b4 Avi Kivity
            break;                                                      \
110 0e0d36b4 Avi Kivity
        default:                                                        \
111 0e0d36b4 Avi Kivity
            abort();                                                    \
112 0e0d36b4 Avi Kivity
        }                                                               \
113 0e0d36b4 Avi Kivity
    } while (0)
114 0e0d36b4 Avi Kivity
115 7376e582 Avi Kivity
#define MEMORY_LISTENER_CALL(_callback, _direction, _section, _args...) \
116 7376e582 Avi Kivity
    do {                                                                \
117 7376e582 Avi Kivity
        MemoryListener *_listener;                                      \
118 7376e582 Avi Kivity
                                                                        \
119 7376e582 Avi Kivity
        switch (_direction) {                                           \
120 7376e582 Avi Kivity
        case Forward:                                                   \
121 7376e582 Avi Kivity
            QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
122 7376e582 Avi Kivity
                if (memory_listener_match(_listener, _section)) {       \
123 7376e582 Avi Kivity
                    _listener->_callback(_listener, _section, ##_args); \
124 7376e582 Avi Kivity
                }                                                       \
125 7376e582 Avi Kivity
            }                                                           \
126 7376e582 Avi Kivity
            break;                                                      \
127 7376e582 Avi Kivity
        case Reverse:                                                   \
128 7376e582 Avi Kivity
            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
129 7376e582 Avi Kivity
                                   memory_listeners, link) {            \
130 7376e582 Avi Kivity
                if (memory_listener_match(_listener, _section)) {       \
131 7376e582 Avi Kivity
                    _listener->_callback(_listener, _section, ##_args); \
132 7376e582 Avi Kivity
                }                                                       \
133 7376e582 Avi Kivity
            }                                                           \
134 7376e582 Avi Kivity
            break;                                                      \
135 7376e582 Avi Kivity
        default:                                                        \
136 7376e582 Avi Kivity
            abort();                                                    \
137 7376e582 Avi Kivity
        }                                                               \
138 7376e582 Avi Kivity
    } while (0)
139 7376e582 Avi Kivity
140 0e0d36b4 Avi Kivity
#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
141 7376e582 Avi Kivity
    MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) {       \
142 0e0d36b4 Avi Kivity
        .mr = (fr)->mr,                                                 \
143 0e0d36b4 Avi Kivity
        .address_space = (as)->root,                                    \
144 0e0d36b4 Avi Kivity
        .offset_within_region = (fr)->offset_in_region,                 \
145 0e0d36b4 Avi Kivity
        .size = int128_get64((fr)->addr.size),                          \
146 0e0d36b4 Avi Kivity
        .offset_within_address_space = int128_get64((fr)->addr.start),  \
147 7a8499e8 Avi Kivity
        .readonly = (fr)->readonly,                                     \
148 7376e582 Avi Kivity
              }))
149 0e0d36b4 Avi Kivity
150 093bc2cd Avi Kivity
struct CoalescedMemoryRange {
151 093bc2cd Avi Kivity
    AddrRange addr;
152 093bc2cd Avi Kivity
    QTAILQ_ENTRY(CoalescedMemoryRange) link;
153 093bc2cd Avi Kivity
};
154 093bc2cd Avi Kivity
155 3e9d69e7 Avi Kivity
struct MemoryRegionIoeventfd {
156 3e9d69e7 Avi Kivity
    AddrRange addr;
157 3e9d69e7 Avi Kivity
    bool match_data;
158 3e9d69e7 Avi Kivity
    uint64_t data;
159 753d5e14 Paolo Bonzini
    EventNotifier *e;
160 3e9d69e7 Avi Kivity
};
161 3e9d69e7 Avi Kivity
162 3e9d69e7 Avi Kivity
static bool memory_region_ioeventfd_before(MemoryRegionIoeventfd a,
163 3e9d69e7 Avi Kivity
                                           MemoryRegionIoeventfd b)
164 3e9d69e7 Avi Kivity
{
165 08dafab4 Avi Kivity
    if (int128_lt(a.addr.start, b.addr.start)) {
166 3e9d69e7 Avi Kivity
        return true;
167 08dafab4 Avi Kivity
    } else if (int128_gt(a.addr.start, b.addr.start)) {
168 3e9d69e7 Avi Kivity
        return false;
169 08dafab4 Avi Kivity
    } else if (int128_lt(a.addr.size, b.addr.size)) {
170 3e9d69e7 Avi Kivity
        return true;
171 08dafab4 Avi Kivity
    } else if (int128_gt(a.addr.size, b.addr.size)) {
172 3e9d69e7 Avi Kivity
        return false;
173 3e9d69e7 Avi Kivity
    } else if (a.match_data < b.match_data) {
174 3e9d69e7 Avi Kivity
        return true;
175 3e9d69e7 Avi Kivity
    } else  if (a.match_data > b.match_data) {
176 3e9d69e7 Avi Kivity
        return false;
177 3e9d69e7 Avi Kivity
    } else if (a.match_data) {
178 3e9d69e7 Avi Kivity
        if (a.data < b.data) {
179 3e9d69e7 Avi Kivity
            return true;
180 3e9d69e7 Avi Kivity
        } else if (a.data > b.data) {
181 3e9d69e7 Avi Kivity
            return false;
182 3e9d69e7 Avi Kivity
        }
183 3e9d69e7 Avi Kivity
    }
184 753d5e14 Paolo Bonzini
    if (a.e < b.e) {
185 3e9d69e7 Avi Kivity
        return true;
186 753d5e14 Paolo Bonzini
    } else if (a.e > b.e) {
187 3e9d69e7 Avi Kivity
        return false;
188 3e9d69e7 Avi Kivity
    }
189 3e9d69e7 Avi Kivity
    return false;
190 3e9d69e7 Avi Kivity
}
191 3e9d69e7 Avi Kivity
192 3e9d69e7 Avi Kivity
static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd a,
193 3e9d69e7 Avi Kivity
                                          MemoryRegionIoeventfd b)
194 3e9d69e7 Avi Kivity
{
195 3e9d69e7 Avi Kivity
    return !memory_region_ioeventfd_before(a, b)
196 3e9d69e7 Avi Kivity
        && !memory_region_ioeventfd_before(b, a);
197 3e9d69e7 Avi Kivity
}
198 3e9d69e7 Avi Kivity
199 093bc2cd Avi Kivity
typedef struct FlatRange FlatRange;
200 093bc2cd Avi Kivity
typedef struct FlatView FlatView;
201 093bc2cd Avi Kivity
202 093bc2cd Avi Kivity
/* Range of memory in the global map.  Addresses are absolute. */
203 093bc2cd Avi Kivity
struct FlatRange {
204 093bc2cd Avi Kivity
    MemoryRegion *mr;
205 093bc2cd Avi Kivity
    target_phys_addr_t offset_in_region;
206 093bc2cd Avi Kivity
    AddrRange addr;
207 5a583347 Avi Kivity
    uint8_t dirty_log_mask;
208 d0a9b5bc Avi Kivity
    bool readable;
209 fb1cd6f9 Avi Kivity
    bool readonly;
210 093bc2cd Avi Kivity
};
211 093bc2cd Avi Kivity
212 093bc2cd Avi Kivity
/* Flattened global view of current active memory hierarchy.  Kept in sorted
213 093bc2cd Avi Kivity
 * order.
214 093bc2cd Avi Kivity
 */
215 093bc2cd Avi Kivity
struct FlatView {
216 093bc2cd Avi Kivity
    FlatRange *ranges;
217 093bc2cd Avi Kivity
    unsigned nr;
218 093bc2cd Avi Kivity
    unsigned nr_allocated;
219 093bc2cd Avi Kivity
};
220 093bc2cd Avi Kivity
221 cc31e6e7 Avi Kivity
typedef struct AddressSpace AddressSpace;
222 cc31e6e7 Avi Kivity
typedef struct AddressSpaceOps AddressSpaceOps;
223 cc31e6e7 Avi Kivity
224 cc31e6e7 Avi Kivity
/* A system address space - I/O, memory, etc. */
225 cc31e6e7 Avi Kivity
struct AddressSpace {
226 cc31e6e7 Avi Kivity
    MemoryRegion *root;
227 cc31e6e7 Avi Kivity
    FlatView current_map;
228 3e9d69e7 Avi Kivity
    int ioeventfd_nb;
229 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd *ioeventfds;
230 cc31e6e7 Avi Kivity
};
231 cc31e6e7 Avi Kivity
232 093bc2cd Avi Kivity
#define FOR_EACH_FLAT_RANGE(var, view)          \
233 093bc2cd Avi Kivity
    for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
234 093bc2cd Avi Kivity
235 093bc2cd Avi Kivity
static bool flatrange_equal(FlatRange *a, FlatRange *b)
236 093bc2cd Avi Kivity
{
237 093bc2cd Avi Kivity
    return a->mr == b->mr
238 093bc2cd Avi Kivity
        && addrrange_equal(a->addr, b->addr)
239 d0a9b5bc Avi Kivity
        && a->offset_in_region == b->offset_in_region
240 fb1cd6f9 Avi Kivity
        && a->readable == b->readable
241 fb1cd6f9 Avi Kivity
        && a->readonly == b->readonly;
242 093bc2cd Avi Kivity
}
243 093bc2cd Avi Kivity
244 093bc2cd Avi Kivity
static void flatview_init(FlatView *view)
245 093bc2cd Avi Kivity
{
246 093bc2cd Avi Kivity
    view->ranges = NULL;
247 093bc2cd Avi Kivity
    view->nr = 0;
248 093bc2cd Avi Kivity
    view->nr_allocated = 0;
249 093bc2cd Avi Kivity
}
250 093bc2cd Avi Kivity
251 093bc2cd Avi Kivity
/* Insert a range into a given position.  Caller is responsible for maintaining
252 093bc2cd Avi Kivity
 * sorting order.
253 093bc2cd Avi Kivity
 */
254 093bc2cd Avi Kivity
static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range)
255 093bc2cd Avi Kivity
{
256 093bc2cd Avi Kivity
    if (view->nr == view->nr_allocated) {
257 093bc2cd Avi Kivity
        view->nr_allocated = MAX(2 * view->nr, 10);
258 7267c094 Anthony Liguori
        view->ranges = g_realloc(view->ranges,
259 093bc2cd Avi Kivity
                                    view->nr_allocated * sizeof(*view->ranges));
260 093bc2cd Avi Kivity
    }
261 093bc2cd Avi Kivity
    memmove(view->ranges + pos + 1, view->ranges + pos,
262 093bc2cd Avi Kivity
            (view->nr - pos) * sizeof(FlatRange));
263 093bc2cd Avi Kivity
    view->ranges[pos] = *range;
264 093bc2cd Avi Kivity
    ++view->nr;
265 093bc2cd Avi Kivity
}
266 093bc2cd Avi Kivity
267 093bc2cd Avi Kivity
static void flatview_destroy(FlatView *view)
268 093bc2cd Avi Kivity
{
269 7267c094 Anthony Liguori
    g_free(view->ranges);
270 093bc2cd Avi Kivity
}
271 093bc2cd Avi Kivity
272 3d8e6bf9 Avi Kivity
static bool can_merge(FlatRange *r1, FlatRange *r2)
273 3d8e6bf9 Avi Kivity
{
274 08dafab4 Avi Kivity
    return int128_eq(addrrange_end(r1->addr), r2->addr.start)
275 3d8e6bf9 Avi Kivity
        && r1->mr == r2->mr
276 08dafab4 Avi Kivity
        && int128_eq(int128_add(int128_make64(r1->offset_in_region),
277 08dafab4 Avi Kivity
                                r1->addr.size),
278 08dafab4 Avi Kivity
                     int128_make64(r2->offset_in_region))
279 d0a9b5bc Avi Kivity
        && r1->dirty_log_mask == r2->dirty_log_mask
280 fb1cd6f9 Avi Kivity
        && r1->readable == r2->readable
281 fb1cd6f9 Avi Kivity
        && r1->readonly == r2->readonly;
282 3d8e6bf9 Avi Kivity
}
283 3d8e6bf9 Avi Kivity
284 3d8e6bf9 Avi Kivity
/* Attempt to simplify a view by merging ajacent ranges */
285 3d8e6bf9 Avi Kivity
static void flatview_simplify(FlatView *view)
286 3d8e6bf9 Avi Kivity
{
287 3d8e6bf9 Avi Kivity
    unsigned i, j;
288 3d8e6bf9 Avi Kivity
289 3d8e6bf9 Avi Kivity
    i = 0;
290 3d8e6bf9 Avi Kivity
    while (i < view->nr) {
291 3d8e6bf9 Avi Kivity
        j = i + 1;
292 3d8e6bf9 Avi Kivity
        while (j < view->nr
293 3d8e6bf9 Avi Kivity
               && can_merge(&view->ranges[j-1], &view->ranges[j])) {
294 08dafab4 Avi Kivity
            int128_addto(&view->ranges[i].addr.size, view->ranges[j].addr.size);
295 3d8e6bf9 Avi Kivity
            ++j;
296 3d8e6bf9 Avi Kivity
        }
297 3d8e6bf9 Avi Kivity
        ++i;
298 3d8e6bf9 Avi Kivity
        memmove(&view->ranges[i], &view->ranges[j],
299 3d8e6bf9 Avi Kivity
                (view->nr - j) * sizeof(view->ranges[j]));
300 3d8e6bf9 Avi Kivity
        view->nr -= j - i;
301 3d8e6bf9 Avi Kivity
    }
302 3d8e6bf9 Avi Kivity
}
303 3d8e6bf9 Avi Kivity
304 164a4dcd Avi Kivity
static void memory_region_read_accessor(void *opaque,
305 164a4dcd Avi Kivity
                                        target_phys_addr_t addr,
306 164a4dcd Avi Kivity
                                        uint64_t *value,
307 164a4dcd Avi Kivity
                                        unsigned size,
308 164a4dcd Avi Kivity
                                        unsigned shift,
309 164a4dcd Avi Kivity
                                        uint64_t mask)
310 164a4dcd Avi Kivity
{
311 164a4dcd Avi Kivity
    MemoryRegion *mr = opaque;
312 164a4dcd Avi Kivity
    uint64_t tmp;
313 164a4dcd Avi Kivity
314 164a4dcd Avi Kivity
    tmp = mr->ops->read(mr->opaque, addr, size);
315 164a4dcd Avi Kivity
    *value |= (tmp & mask) << shift;
316 164a4dcd Avi Kivity
}
317 164a4dcd Avi Kivity
318 164a4dcd Avi Kivity
static void memory_region_write_accessor(void *opaque,
319 164a4dcd Avi Kivity
                                         target_phys_addr_t addr,
320 164a4dcd Avi Kivity
                                         uint64_t *value,
321 164a4dcd Avi Kivity
                                         unsigned size,
322 164a4dcd Avi Kivity
                                         unsigned shift,
323 164a4dcd Avi Kivity
                                         uint64_t mask)
324 164a4dcd Avi Kivity
{
325 164a4dcd Avi Kivity
    MemoryRegion *mr = opaque;
326 164a4dcd Avi Kivity
    uint64_t tmp;
327 164a4dcd Avi Kivity
328 164a4dcd Avi Kivity
    tmp = (*value >> shift) & mask;
329 164a4dcd Avi Kivity
    mr->ops->write(mr->opaque, addr, tmp, size);
330 164a4dcd Avi Kivity
}
331 164a4dcd Avi Kivity
332 164a4dcd Avi Kivity
static void access_with_adjusted_size(target_phys_addr_t addr,
333 164a4dcd Avi Kivity
                                      uint64_t *value,
334 164a4dcd Avi Kivity
                                      unsigned size,
335 164a4dcd Avi Kivity
                                      unsigned access_size_min,
336 164a4dcd Avi Kivity
                                      unsigned access_size_max,
337 164a4dcd Avi Kivity
                                      void (*access)(void *opaque,
338 164a4dcd Avi Kivity
                                                     target_phys_addr_t addr,
339 164a4dcd Avi Kivity
                                                     uint64_t *value,
340 164a4dcd Avi Kivity
                                                     unsigned size,
341 164a4dcd Avi Kivity
                                                     unsigned shift,
342 164a4dcd Avi Kivity
                                                     uint64_t mask),
343 164a4dcd Avi Kivity
                                      void *opaque)
344 164a4dcd Avi Kivity
{
345 164a4dcd Avi Kivity
    uint64_t access_mask;
346 164a4dcd Avi Kivity
    unsigned access_size;
347 164a4dcd Avi Kivity
    unsigned i;
348 164a4dcd Avi Kivity
349 164a4dcd Avi Kivity
    if (!access_size_min) {
350 164a4dcd Avi Kivity
        access_size_min = 1;
351 164a4dcd Avi Kivity
    }
352 164a4dcd Avi Kivity
    if (!access_size_max) {
353 164a4dcd Avi Kivity
        access_size_max = 4;
354 164a4dcd Avi Kivity
    }
355 164a4dcd Avi Kivity
    access_size = MAX(MIN(size, access_size_max), access_size_min);
356 164a4dcd Avi Kivity
    access_mask = -1ULL >> (64 - access_size * 8);
357 164a4dcd Avi Kivity
    for (i = 0; i < size; i += access_size) {
358 164a4dcd Avi Kivity
        /* FIXME: big-endian support */
359 164a4dcd Avi Kivity
        access(opaque, addr + i, value, access_size, i * 8, access_mask);
360 164a4dcd Avi Kivity
    }
361 164a4dcd Avi Kivity
}
362 164a4dcd Avi Kivity
363 8df8a843 Avi Kivity
static AddressSpace address_space_memory;
364 cc31e6e7 Avi Kivity
365 627a0e90 Avi Kivity
static const MemoryRegionPortio *find_portio(MemoryRegion *mr, uint64_t offset,
366 627a0e90 Avi Kivity
                                             unsigned width, bool write)
367 627a0e90 Avi Kivity
{
368 627a0e90 Avi Kivity
    const MemoryRegionPortio *mrp;
369 627a0e90 Avi Kivity
370 627a0e90 Avi Kivity
    for (mrp = mr->ops->old_portio; mrp->size; ++mrp) {
371 627a0e90 Avi Kivity
        if (offset >= mrp->offset && offset < mrp->offset + mrp->len
372 627a0e90 Avi Kivity
            && width == mrp->size
373 627a0e90 Avi Kivity
            && (write ? (bool)mrp->write : (bool)mrp->read)) {
374 627a0e90 Avi Kivity
            return mrp;
375 627a0e90 Avi Kivity
        }
376 627a0e90 Avi Kivity
    }
377 627a0e90 Avi Kivity
    return NULL;
378 627a0e90 Avi Kivity
}
379 627a0e90 Avi Kivity
380 658b2224 Avi Kivity
static void memory_region_iorange_read(IORange *iorange,
381 658b2224 Avi Kivity
                                       uint64_t offset,
382 658b2224 Avi Kivity
                                       unsigned width,
383 658b2224 Avi Kivity
                                       uint64_t *data)
384 658b2224 Avi Kivity
{
385 a2d33521 Avi Kivity
    MemoryRegionIORange *mrio
386 a2d33521 Avi Kivity
        = container_of(iorange, MemoryRegionIORange, iorange);
387 a2d33521 Avi Kivity
    MemoryRegion *mr = mrio->mr;
388 658b2224 Avi Kivity
389 a2d33521 Avi Kivity
    offset += mrio->offset;
390 627a0e90 Avi Kivity
    if (mr->ops->old_portio) {
391 a2d33521 Avi Kivity
        const MemoryRegionPortio *mrp = find_portio(mr, offset - mrio->offset,
392 a2d33521 Avi Kivity
                                                    width, false);
393 627a0e90 Avi Kivity
394 627a0e90 Avi Kivity
        *data = ((uint64_t)1 << (width * 8)) - 1;
395 627a0e90 Avi Kivity
        if (mrp) {
396 2b50aa1f Avi Kivity
            *data = mrp->read(mr->opaque, offset);
397 03808f58 Jan Kiszka
        } else if (width == 2) {
398 a2d33521 Avi Kivity
            mrp = find_portio(mr, offset - mrio->offset, 1, false);
399 03808f58 Jan Kiszka
            assert(mrp);
400 2b50aa1f Avi Kivity
            *data = mrp->read(mr->opaque, offset) |
401 2b50aa1f Avi Kivity
                    (mrp->read(mr->opaque, offset + 1) << 8);
402 627a0e90 Avi Kivity
        }
403 627a0e90 Avi Kivity
        return;
404 627a0e90 Avi Kivity
    }
405 3a130f4e Avi Kivity
    *data = 0;
406 2b50aa1f Avi Kivity
    access_with_adjusted_size(offset, data, width,
407 3a130f4e Avi Kivity
                              mr->ops->impl.min_access_size,
408 3a130f4e Avi Kivity
                              mr->ops->impl.max_access_size,
409 3a130f4e Avi Kivity
                              memory_region_read_accessor, mr);
410 658b2224 Avi Kivity
}
411 658b2224 Avi Kivity
412 658b2224 Avi Kivity
static void memory_region_iorange_write(IORange *iorange,
413 658b2224 Avi Kivity
                                        uint64_t offset,
414 658b2224 Avi Kivity
                                        unsigned width,
415 658b2224 Avi Kivity
                                        uint64_t data)
416 658b2224 Avi Kivity
{
417 a2d33521 Avi Kivity
    MemoryRegionIORange *mrio
418 a2d33521 Avi Kivity
        = container_of(iorange, MemoryRegionIORange, iorange);
419 a2d33521 Avi Kivity
    MemoryRegion *mr = mrio->mr;
420 658b2224 Avi Kivity
421 a2d33521 Avi Kivity
    offset += mrio->offset;
422 627a0e90 Avi Kivity
    if (mr->ops->old_portio) {
423 a2d33521 Avi Kivity
        const MemoryRegionPortio *mrp = find_portio(mr, offset - mrio->offset,
424 a2d33521 Avi Kivity
                                                    width, true);
425 627a0e90 Avi Kivity
426 627a0e90 Avi Kivity
        if (mrp) {
427 2b50aa1f Avi Kivity
            mrp->write(mr->opaque, offset, data);
428 03808f58 Jan Kiszka
        } else if (width == 2) {
429 a2d33521 Avi Kivity
            mrp = find_portio(mr, offset - mrio->offset, 1, false);
430 03808f58 Jan Kiszka
            assert(mrp);
431 2b50aa1f Avi Kivity
            mrp->write(mr->opaque, offset, data & 0xff);
432 2b50aa1f Avi Kivity
            mrp->write(mr->opaque, offset + 1, data >> 8);
433 627a0e90 Avi Kivity
        }
434 627a0e90 Avi Kivity
        return;
435 627a0e90 Avi Kivity
    }
436 2b50aa1f Avi Kivity
    access_with_adjusted_size(offset, &data, width,
437 3a130f4e Avi Kivity
                              mr->ops->impl.min_access_size,
438 3a130f4e Avi Kivity
                              mr->ops->impl.max_access_size,
439 3a130f4e Avi Kivity
                              memory_region_write_accessor, mr);
440 658b2224 Avi Kivity
}
441 658b2224 Avi Kivity
442 a2d33521 Avi Kivity
static void memory_region_iorange_destructor(IORange *iorange)
443 a2d33521 Avi Kivity
{
444 a2d33521 Avi Kivity
    g_free(container_of(iorange, MemoryRegionIORange, iorange));
445 a2d33521 Avi Kivity
}
446 a2d33521 Avi Kivity
447 93632747 Avi Kivity
const IORangeOps memory_region_iorange_ops = {
448 658b2224 Avi Kivity
    .read = memory_region_iorange_read,
449 658b2224 Avi Kivity
    .write = memory_region_iorange_write,
450 a2d33521 Avi Kivity
    .destructor = memory_region_iorange_destructor,
451 658b2224 Avi Kivity
};
452 658b2224 Avi Kivity
453 8df8a843 Avi Kivity
static AddressSpace address_space_io;
454 658b2224 Avi Kivity
455 e2177955 Avi Kivity
static AddressSpace *memory_region_to_address_space(MemoryRegion *mr)
456 e2177955 Avi Kivity
{
457 e2177955 Avi Kivity
    while (mr->parent) {
458 e2177955 Avi Kivity
        mr = mr->parent;
459 e2177955 Avi Kivity
    }
460 e2177955 Avi Kivity
    if (mr == address_space_memory.root) {
461 e2177955 Avi Kivity
        return &address_space_memory;
462 e2177955 Avi Kivity
    }
463 e2177955 Avi Kivity
    if (mr == address_space_io.root) {
464 e2177955 Avi Kivity
        return &address_space_io;
465 e2177955 Avi Kivity
    }
466 e2177955 Avi Kivity
    abort();
467 e2177955 Avi Kivity
}
468 e2177955 Avi Kivity
469 093bc2cd Avi Kivity
/* Render a memory region into the global view.  Ranges in @view obscure
470 093bc2cd Avi Kivity
 * ranges in @mr.
471 093bc2cd Avi Kivity
 */
472 093bc2cd Avi Kivity
static void render_memory_region(FlatView *view,
473 093bc2cd Avi Kivity
                                 MemoryRegion *mr,
474 08dafab4 Avi Kivity
                                 Int128 base,
475 fb1cd6f9 Avi Kivity
                                 AddrRange clip,
476 fb1cd6f9 Avi Kivity
                                 bool readonly)
477 093bc2cd Avi Kivity
{
478 093bc2cd Avi Kivity
    MemoryRegion *subregion;
479 093bc2cd Avi Kivity
    unsigned i;
480 093bc2cd Avi Kivity
    target_phys_addr_t offset_in_region;
481 08dafab4 Avi Kivity
    Int128 remain;
482 08dafab4 Avi Kivity
    Int128 now;
483 093bc2cd Avi Kivity
    FlatRange fr;
484 093bc2cd Avi Kivity
    AddrRange tmp;
485 093bc2cd Avi Kivity
486 6bba19ba Avi Kivity
    if (!mr->enabled) {
487 6bba19ba Avi Kivity
        return;
488 6bba19ba Avi Kivity
    }
489 6bba19ba Avi Kivity
490 08dafab4 Avi Kivity
    int128_addto(&base, int128_make64(mr->addr));
491 fb1cd6f9 Avi Kivity
    readonly |= mr->readonly;
492 093bc2cd Avi Kivity
493 093bc2cd Avi Kivity
    tmp = addrrange_make(base, mr->size);
494 093bc2cd Avi Kivity
495 093bc2cd Avi Kivity
    if (!addrrange_intersects(tmp, clip)) {
496 093bc2cd Avi Kivity
        return;
497 093bc2cd Avi Kivity
    }
498 093bc2cd Avi Kivity
499 093bc2cd Avi Kivity
    clip = addrrange_intersection(tmp, clip);
500 093bc2cd Avi Kivity
501 093bc2cd Avi Kivity
    if (mr->alias) {
502 08dafab4 Avi Kivity
        int128_subfrom(&base, int128_make64(mr->alias->addr));
503 08dafab4 Avi Kivity
        int128_subfrom(&base, int128_make64(mr->alias_offset));
504 fb1cd6f9 Avi Kivity
        render_memory_region(view, mr->alias, base, clip, readonly);
505 093bc2cd Avi Kivity
        return;
506 093bc2cd Avi Kivity
    }
507 093bc2cd Avi Kivity
508 093bc2cd Avi Kivity
    /* Render subregions in priority order. */
509 093bc2cd Avi Kivity
    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
510 fb1cd6f9 Avi Kivity
        render_memory_region(view, subregion, base, clip, readonly);
511 093bc2cd Avi Kivity
    }
512 093bc2cd Avi Kivity
513 14a3c10a Avi Kivity
    if (!mr->terminates) {
514 093bc2cd Avi Kivity
        return;
515 093bc2cd Avi Kivity
    }
516 093bc2cd Avi Kivity
517 08dafab4 Avi Kivity
    offset_in_region = int128_get64(int128_sub(clip.start, base));
518 093bc2cd Avi Kivity
    base = clip.start;
519 093bc2cd Avi Kivity
    remain = clip.size;
520 093bc2cd Avi Kivity
521 093bc2cd Avi Kivity
    /* Render the region itself into any gaps left by the current view. */
522 08dafab4 Avi Kivity
    for (i = 0; i < view->nr && int128_nz(remain); ++i) {
523 08dafab4 Avi Kivity
        if (int128_ge(base, addrrange_end(view->ranges[i].addr))) {
524 093bc2cd Avi Kivity
            continue;
525 093bc2cd Avi Kivity
        }
526 08dafab4 Avi Kivity
        if (int128_lt(base, view->ranges[i].addr.start)) {
527 08dafab4 Avi Kivity
            now = int128_min(remain,
528 08dafab4 Avi Kivity
                             int128_sub(view->ranges[i].addr.start, base));
529 093bc2cd Avi Kivity
            fr.mr = mr;
530 093bc2cd Avi Kivity
            fr.offset_in_region = offset_in_region;
531 093bc2cd Avi Kivity
            fr.addr = addrrange_make(base, now);
532 5a583347 Avi Kivity
            fr.dirty_log_mask = mr->dirty_log_mask;
533 d0a9b5bc Avi Kivity
            fr.readable = mr->readable;
534 fb1cd6f9 Avi Kivity
            fr.readonly = readonly;
535 093bc2cd Avi Kivity
            flatview_insert(view, i, &fr);
536 093bc2cd Avi Kivity
            ++i;
537 08dafab4 Avi Kivity
            int128_addto(&base, now);
538 08dafab4 Avi Kivity
            offset_in_region += int128_get64(now);
539 08dafab4 Avi Kivity
            int128_subfrom(&remain, now);
540 093bc2cd Avi Kivity
        }
541 08dafab4 Avi Kivity
        if (int128_eq(base, view->ranges[i].addr.start)) {
542 08dafab4 Avi Kivity
            now = int128_min(remain, view->ranges[i].addr.size);
543 08dafab4 Avi Kivity
            int128_addto(&base, now);
544 08dafab4 Avi Kivity
            offset_in_region += int128_get64(now);
545 08dafab4 Avi Kivity
            int128_subfrom(&remain, now);
546 093bc2cd Avi Kivity
        }
547 093bc2cd Avi Kivity
    }
548 08dafab4 Avi Kivity
    if (int128_nz(remain)) {
549 093bc2cd Avi Kivity
        fr.mr = mr;
550 093bc2cd Avi Kivity
        fr.offset_in_region = offset_in_region;
551 093bc2cd Avi Kivity
        fr.addr = addrrange_make(base, remain);
552 5a583347 Avi Kivity
        fr.dirty_log_mask = mr->dirty_log_mask;
553 d0a9b5bc Avi Kivity
        fr.readable = mr->readable;
554 fb1cd6f9 Avi Kivity
        fr.readonly = readonly;
555 093bc2cd Avi Kivity
        flatview_insert(view, i, &fr);
556 093bc2cd Avi Kivity
    }
557 093bc2cd Avi Kivity
}
558 093bc2cd Avi Kivity
559 093bc2cd Avi Kivity
/* Render a memory topology into a list of disjoint absolute ranges. */
560 093bc2cd Avi Kivity
static FlatView generate_memory_topology(MemoryRegion *mr)
561 093bc2cd Avi Kivity
{
562 093bc2cd Avi Kivity
    FlatView view;
563 093bc2cd Avi Kivity
564 093bc2cd Avi Kivity
    flatview_init(&view);
565 093bc2cd Avi Kivity
566 08dafab4 Avi Kivity
    render_memory_region(&view, mr, int128_zero(),
567 08dafab4 Avi Kivity
                         addrrange_make(int128_zero(), int128_2_64()), false);
568 3d8e6bf9 Avi Kivity
    flatview_simplify(&view);
569 093bc2cd Avi Kivity
570 093bc2cd Avi Kivity
    return view;
571 093bc2cd Avi Kivity
}
572 093bc2cd Avi Kivity
573 3e9d69e7 Avi Kivity
static void address_space_add_del_ioeventfds(AddressSpace *as,
574 3e9d69e7 Avi Kivity
                                             MemoryRegionIoeventfd *fds_new,
575 3e9d69e7 Avi Kivity
                                             unsigned fds_new_nb,
576 3e9d69e7 Avi Kivity
                                             MemoryRegionIoeventfd *fds_old,
577 3e9d69e7 Avi Kivity
                                             unsigned fds_old_nb)
578 3e9d69e7 Avi Kivity
{
579 3e9d69e7 Avi Kivity
    unsigned iold, inew;
580 80a1ea37 Avi Kivity
    MemoryRegionIoeventfd *fd;
581 80a1ea37 Avi Kivity
    MemoryRegionSection section;
582 3e9d69e7 Avi Kivity
583 3e9d69e7 Avi Kivity
    /* Generate a symmetric difference of the old and new fd sets, adding
584 3e9d69e7 Avi Kivity
     * and deleting as necessary.
585 3e9d69e7 Avi Kivity
     */
586 3e9d69e7 Avi Kivity
587 3e9d69e7 Avi Kivity
    iold = inew = 0;
588 3e9d69e7 Avi Kivity
    while (iold < fds_old_nb || inew < fds_new_nb) {
589 3e9d69e7 Avi Kivity
        if (iold < fds_old_nb
590 3e9d69e7 Avi Kivity
            && (inew == fds_new_nb
591 3e9d69e7 Avi Kivity
                || memory_region_ioeventfd_before(fds_old[iold],
592 3e9d69e7 Avi Kivity
                                                  fds_new[inew]))) {
593 80a1ea37 Avi Kivity
            fd = &fds_old[iold];
594 80a1ea37 Avi Kivity
            section = (MemoryRegionSection) {
595 80a1ea37 Avi Kivity
                .address_space = as->root,
596 80a1ea37 Avi Kivity
                .offset_within_address_space = int128_get64(fd->addr.start),
597 80a1ea37 Avi Kivity
                .size = int128_get64(fd->addr.size),
598 80a1ea37 Avi Kivity
            };
599 80a1ea37 Avi Kivity
            MEMORY_LISTENER_CALL(eventfd_del, Forward, &section,
600 753d5e14 Paolo Bonzini
                                 fd->match_data, fd->data, fd->e);
601 3e9d69e7 Avi Kivity
            ++iold;
602 3e9d69e7 Avi Kivity
        } else if (inew < fds_new_nb
603 3e9d69e7 Avi Kivity
                   && (iold == fds_old_nb
604 3e9d69e7 Avi Kivity
                       || memory_region_ioeventfd_before(fds_new[inew],
605 3e9d69e7 Avi Kivity
                                                         fds_old[iold]))) {
606 80a1ea37 Avi Kivity
            fd = &fds_new[inew];
607 80a1ea37 Avi Kivity
            section = (MemoryRegionSection) {
608 80a1ea37 Avi Kivity
                .address_space = as->root,
609 80a1ea37 Avi Kivity
                .offset_within_address_space = int128_get64(fd->addr.start),
610 80a1ea37 Avi Kivity
                .size = int128_get64(fd->addr.size),
611 80a1ea37 Avi Kivity
            };
612 80a1ea37 Avi Kivity
            MEMORY_LISTENER_CALL(eventfd_add, Reverse, &section,
613 753d5e14 Paolo Bonzini
                                 fd->match_data, fd->data, fd->e);
614 3e9d69e7 Avi Kivity
            ++inew;
615 3e9d69e7 Avi Kivity
        } else {
616 3e9d69e7 Avi Kivity
            ++iold;
617 3e9d69e7 Avi Kivity
            ++inew;
618 3e9d69e7 Avi Kivity
        }
619 3e9d69e7 Avi Kivity
    }
620 3e9d69e7 Avi Kivity
}
621 3e9d69e7 Avi Kivity
622 3e9d69e7 Avi Kivity
static void address_space_update_ioeventfds(AddressSpace *as)
623 3e9d69e7 Avi Kivity
{
624 3e9d69e7 Avi Kivity
    FlatRange *fr;
625 3e9d69e7 Avi Kivity
    unsigned ioeventfd_nb = 0;
626 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd *ioeventfds = NULL;
627 3e9d69e7 Avi Kivity
    AddrRange tmp;
628 3e9d69e7 Avi Kivity
    unsigned i;
629 3e9d69e7 Avi Kivity
630 3e9d69e7 Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, &as->current_map) {
631 3e9d69e7 Avi Kivity
        for (i = 0; i < fr->mr->ioeventfd_nb; ++i) {
632 3e9d69e7 Avi Kivity
            tmp = addrrange_shift(fr->mr->ioeventfds[i].addr,
633 08dafab4 Avi Kivity
                                  int128_sub(fr->addr.start,
634 08dafab4 Avi Kivity
                                             int128_make64(fr->offset_in_region)));
635 3e9d69e7 Avi Kivity
            if (addrrange_intersects(fr->addr, tmp)) {
636 3e9d69e7 Avi Kivity
                ++ioeventfd_nb;
637 7267c094 Anthony Liguori
                ioeventfds = g_realloc(ioeventfds,
638 3e9d69e7 Avi Kivity
                                          ioeventfd_nb * sizeof(*ioeventfds));
639 3e9d69e7 Avi Kivity
                ioeventfds[ioeventfd_nb-1] = fr->mr->ioeventfds[i];
640 3e9d69e7 Avi Kivity
                ioeventfds[ioeventfd_nb-1].addr = tmp;
641 3e9d69e7 Avi Kivity
            }
642 3e9d69e7 Avi Kivity
        }
643 3e9d69e7 Avi Kivity
    }
644 3e9d69e7 Avi Kivity
645 3e9d69e7 Avi Kivity
    address_space_add_del_ioeventfds(as, ioeventfds, ioeventfd_nb,
646 3e9d69e7 Avi Kivity
                                     as->ioeventfds, as->ioeventfd_nb);
647 3e9d69e7 Avi Kivity
648 7267c094 Anthony Liguori
    g_free(as->ioeventfds);
649 3e9d69e7 Avi Kivity
    as->ioeventfds = ioeventfds;
650 3e9d69e7 Avi Kivity
    as->ioeventfd_nb = ioeventfd_nb;
651 3e9d69e7 Avi Kivity
}
652 3e9d69e7 Avi Kivity
653 b8af1afb Avi Kivity
static void address_space_update_topology_pass(AddressSpace *as,
654 b8af1afb Avi Kivity
                                               FlatView old_view,
655 b8af1afb Avi Kivity
                                               FlatView new_view,
656 b8af1afb Avi Kivity
                                               bool adding)
657 093bc2cd Avi Kivity
{
658 093bc2cd Avi Kivity
    unsigned iold, inew;
659 093bc2cd Avi Kivity
    FlatRange *frold, *frnew;
660 093bc2cd Avi Kivity
661 093bc2cd Avi Kivity
    /* Generate a symmetric difference of the old and new memory maps.
662 093bc2cd Avi Kivity
     * Kill ranges in the old map, and instantiate ranges in the new map.
663 093bc2cd Avi Kivity
     */
664 093bc2cd Avi Kivity
    iold = inew = 0;
665 093bc2cd Avi Kivity
    while (iold < old_view.nr || inew < new_view.nr) {
666 093bc2cd Avi Kivity
        if (iold < old_view.nr) {
667 093bc2cd Avi Kivity
            frold = &old_view.ranges[iold];
668 093bc2cd Avi Kivity
        } else {
669 093bc2cd Avi Kivity
            frold = NULL;
670 093bc2cd Avi Kivity
        }
671 093bc2cd Avi Kivity
        if (inew < new_view.nr) {
672 093bc2cd Avi Kivity
            frnew = &new_view.ranges[inew];
673 093bc2cd Avi Kivity
        } else {
674 093bc2cd Avi Kivity
            frnew = NULL;
675 093bc2cd Avi Kivity
        }
676 093bc2cd Avi Kivity
677 093bc2cd Avi Kivity
        if (frold
678 093bc2cd Avi Kivity
            && (!frnew
679 08dafab4 Avi Kivity
                || int128_lt(frold->addr.start, frnew->addr.start)
680 08dafab4 Avi Kivity
                || (int128_eq(frold->addr.start, frnew->addr.start)
681 093bc2cd Avi Kivity
                    && !flatrange_equal(frold, frnew)))) {
682 093bc2cd Avi Kivity
            /* In old, but (not in new, or in new but attributes changed). */
683 093bc2cd Avi Kivity
684 b8af1afb Avi Kivity
            if (!adding) {
685 72e22d2f Avi Kivity
                MEMORY_LISTENER_UPDATE_REGION(frold, as, Reverse, region_del);
686 b8af1afb Avi Kivity
            }
687 b8af1afb Avi Kivity
688 093bc2cd Avi Kivity
            ++iold;
689 093bc2cd Avi Kivity
        } else if (frold && frnew && flatrange_equal(frold, frnew)) {
690 093bc2cd Avi Kivity
            /* In both (logging may have changed) */
691 093bc2cd Avi Kivity
692 b8af1afb Avi Kivity
            if (adding) {
693 50c1e149 Avi Kivity
                MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_nop);
694 b8af1afb Avi Kivity
                if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
695 72e22d2f Avi Kivity
                    MEMORY_LISTENER_UPDATE_REGION(frnew, as, Reverse, log_stop);
696 b8af1afb Avi Kivity
                } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
697 72e22d2f Avi Kivity
                    MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, log_start);
698 b8af1afb Avi Kivity
                }
699 5a583347 Avi Kivity
            }
700 5a583347 Avi Kivity
701 093bc2cd Avi Kivity
            ++iold;
702 093bc2cd Avi Kivity
            ++inew;
703 093bc2cd Avi Kivity
        } else {
704 093bc2cd Avi Kivity
            /* In new */
705 093bc2cd Avi Kivity
706 b8af1afb Avi Kivity
            if (adding) {
707 72e22d2f Avi Kivity
                MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_add);
708 b8af1afb Avi Kivity
            }
709 b8af1afb Avi Kivity
710 093bc2cd Avi Kivity
            ++inew;
711 093bc2cd Avi Kivity
        }
712 093bc2cd Avi Kivity
    }
713 b8af1afb Avi Kivity
}
714 b8af1afb Avi Kivity
715 b8af1afb Avi Kivity
716 b8af1afb Avi Kivity
static void address_space_update_topology(AddressSpace *as)
717 b8af1afb Avi Kivity
{
718 b8af1afb Avi Kivity
    FlatView old_view = as->current_map;
719 b8af1afb Avi Kivity
    FlatView new_view = generate_memory_topology(as->root);
720 b8af1afb Avi Kivity
721 b8af1afb Avi Kivity
    address_space_update_topology_pass(as, old_view, new_view, false);
722 b8af1afb Avi Kivity
    address_space_update_topology_pass(as, old_view, new_view, true);
723 b8af1afb Avi Kivity
724 cc31e6e7 Avi Kivity
    as->current_map = new_view;
725 093bc2cd Avi Kivity
    flatview_destroy(&old_view);
726 3e9d69e7 Avi Kivity
    address_space_update_ioeventfds(as);
727 093bc2cd Avi Kivity
}
728 093bc2cd Avi Kivity
729 6bba19ba Avi Kivity
static void memory_region_update_topology(MemoryRegion *mr)
730 cc31e6e7 Avi Kivity
{
731 4ef4db86 Avi Kivity
    if (memory_region_transaction_depth) {
732 e87c099f Avi Kivity
        memory_region_update_pending |= !mr || mr->enabled;
733 4ef4db86 Avi Kivity
        return;
734 4ef4db86 Avi Kivity
    }
735 4ef4db86 Avi Kivity
736 6bba19ba Avi Kivity
    if (mr && !mr->enabled) {
737 6bba19ba Avi Kivity
        return;
738 6bba19ba Avi Kivity
    }
739 6bba19ba Avi Kivity
740 50c1e149 Avi Kivity
    MEMORY_LISTENER_CALL_GLOBAL(begin, Forward);
741 50c1e149 Avi Kivity
742 658b2224 Avi Kivity
    if (address_space_memory.root) {
743 658b2224 Avi Kivity
        address_space_update_topology(&address_space_memory);
744 658b2224 Avi Kivity
    }
745 658b2224 Avi Kivity
    if (address_space_io.root) {
746 658b2224 Avi Kivity
        address_space_update_topology(&address_space_io);
747 658b2224 Avi Kivity
    }
748 e87c099f Avi Kivity
749 50c1e149 Avi Kivity
    MEMORY_LISTENER_CALL_GLOBAL(commit, Forward);
750 50c1e149 Avi Kivity
751 e87c099f Avi Kivity
    memory_region_update_pending = false;
752 cc31e6e7 Avi Kivity
}
753 cc31e6e7 Avi Kivity
754 4ef4db86 Avi Kivity
void memory_region_transaction_begin(void)
755 4ef4db86 Avi Kivity
{
756 4ef4db86 Avi Kivity
    ++memory_region_transaction_depth;
757 4ef4db86 Avi Kivity
}
758 4ef4db86 Avi Kivity
759 4ef4db86 Avi Kivity
void memory_region_transaction_commit(void)
760 4ef4db86 Avi Kivity
{
761 4ef4db86 Avi Kivity
    assert(memory_region_transaction_depth);
762 4ef4db86 Avi Kivity
    --memory_region_transaction_depth;
763 e87c099f Avi Kivity
    if (!memory_region_transaction_depth && memory_region_update_pending) {
764 e87c099f Avi Kivity
        memory_region_update_topology(NULL);
765 e87c099f Avi Kivity
    }
766 4ef4db86 Avi Kivity
}
767 4ef4db86 Avi Kivity
768 545e92e0 Avi Kivity
static void memory_region_destructor_none(MemoryRegion *mr)
769 545e92e0 Avi Kivity
{
770 545e92e0 Avi Kivity
}
771 545e92e0 Avi Kivity
772 545e92e0 Avi Kivity
static void memory_region_destructor_ram(MemoryRegion *mr)
773 545e92e0 Avi Kivity
{
774 545e92e0 Avi Kivity
    qemu_ram_free(mr->ram_addr);
775 545e92e0 Avi Kivity
}
776 545e92e0 Avi Kivity
777 545e92e0 Avi Kivity
static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
778 545e92e0 Avi Kivity
{
779 545e92e0 Avi Kivity
    qemu_ram_free_from_ptr(mr->ram_addr);
780 545e92e0 Avi Kivity
}
781 545e92e0 Avi Kivity
782 545e92e0 Avi Kivity
static void memory_region_destructor_iomem(MemoryRegion *mr)
783 545e92e0 Avi Kivity
{
784 545e92e0 Avi Kivity
}
785 545e92e0 Avi Kivity
786 d0a9b5bc Avi Kivity
static void memory_region_destructor_rom_device(MemoryRegion *mr)
787 d0a9b5bc Avi Kivity
{
788 d0a9b5bc Avi Kivity
    qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
789 d0a9b5bc Avi Kivity
}
790 d0a9b5bc Avi Kivity
791 be675c97 Avi Kivity
static bool memory_region_wrong_endianness(MemoryRegion *mr)
792 be675c97 Avi Kivity
{
793 2c3579ab Andreas Fรคrber
#ifdef TARGET_WORDS_BIGENDIAN
794 be675c97 Avi Kivity
    return mr->ops->endianness == DEVICE_LITTLE_ENDIAN;
795 be675c97 Avi Kivity
#else
796 be675c97 Avi Kivity
    return mr->ops->endianness == DEVICE_BIG_ENDIAN;
797 be675c97 Avi Kivity
#endif
798 be675c97 Avi Kivity
}
799 be675c97 Avi Kivity
800 093bc2cd Avi Kivity
void memory_region_init(MemoryRegion *mr,
801 093bc2cd Avi Kivity
                        const char *name,
802 093bc2cd Avi Kivity
                        uint64_t size)
803 093bc2cd Avi Kivity
{
804 093bc2cd Avi Kivity
    mr->ops = NULL;
805 093bc2cd Avi Kivity
    mr->parent = NULL;
806 08dafab4 Avi Kivity
    mr->size = int128_make64(size);
807 08dafab4 Avi Kivity
    if (size == UINT64_MAX) {
808 08dafab4 Avi Kivity
        mr->size = int128_2_64();
809 08dafab4 Avi Kivity
    }
810 093bc2cd Avi Kivity
    mr->addr = 0;
811 b3b00c78 Avi Kivity
    mr->subpage = false;
812 6bba19ba Avi Kivity
    mr->enabled = true;
813 14a3c10a Avi Kivity
    mr->terminates = false;
814 8ea9252a Avi Kivity
    mr->ram = false;
815 d0a9b5bc Avi Kivity
    mr->readable = true;
816 fb1cd6f9 Avi Kivity
    mr->readonly = false;
817 75c578dc Avi Kivity
    mr->rom_device = false;
818 545e92e0 Avi Kivity
    mr->destructor = memory_region_destructor_none;
819 093bc2cd Avi Kivity
    mr->priority = 0;
820 093bc2cd Avi Kivity
    mr->may_overlap = false;
821 093bc2cd Avi Kivity
    mr->alias = NULL;
822 093bc2cd Avi Kivity
    QTAILQ_INIT(&mr->subregions);
823 093bc2cd Avi Kivity
    memset(&mr->subregions_link, 0, sizeof mr->subregions_link);
824 093bc2cd Avi Kivity
    QTAILQ_INIT(&mr->coalesced);
825 7267c094 Anthony Liguori
    mr->name = g_strdup(name);
826 5a583347 Avi Kivity
    mr->dirty_log_mask = 0;
827 3e9d69e7 Avi Kivity
    mr->ioeventfd_nb = 0;
828 3e9d69e7 Avi Kivity
    mr->ioeventfds = NULL;
829 093bc2cd Avi Kivity
}
830 093bc2cd Avi Kivity
831 093bc2cd Avi Kivity
static bool memory_region_access_valid(MemoryRegion *mr,
832 093bc2cd Avi Kivity
                                       target_phys_addr_t addr,
833 897fa7cf Avi Kivity
                                       unsigned size,
834 897fa7cf Avi Kivity
                                       bool is_write)
835 093bc2cd Avi Kivity
{
836 897fa7cf Avi Kivity
    if (mr->ops->valid.accepts
837 897fa7cf Avi Kivity
        && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write)) {
838 897fa7cf Avi Kivity
        return false;
839 897fa7cf Avi Kivity
    }
840 897fa7cf Avi Kivity
841 093bc2cd Avi Kivity
    if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
842 093bc2cd Avi Kivity
        return false;
843 093bc2cd Avi Kivity
    }
844 093bc2cd Avi Kivity
845 093bc2cd Avi Kivity
    /* Treat zero as compatibility all valid */
846 093bc2cd Avi Kivity
    if (!mr->ops->valid.max_access_size) {
847 093bc2cd Avi Kivity
        return true;
848 093bc2cd Avi Kivity
    }
849 093bc2cd Avi Kivity
850 093bc2cd Avi Kivity
    if (size > mr->ops->valid.max_access_size
851 093bc2cd Avi Kivity
        || size < mr->ops->valid.min_access_size) {
852 093bc2cd Avi Kivity
        return false;
853 093bc2cd Avi Kivity
    }
854 093bc2cd Avi Kivity
    return true;
855 093bc2cd Avi Kivity
}
856 093bc2cd Avi Kivity
857 a621f38d Avi Kivity
static uint64_t memory_region_dispatch_read1(MemoryRegion *mr,
858 a621f38d Avi Kivity
                                             target_phys_addr_t addr,
859 a621f38d Avi Kivity
                                             unsigned size)
860 093bc2cd Avi Kivity
{
861 164a4dcd Avi Kivity
    uint64_t data = 0;
862 093bc2cd Avi Kivity
863 897fa7cf Avi Kivity
    if (!memory_region_access_valid(mr, addr, size, false)) {
864 093bc2cd Avi Kivity
        return -1U; /* FIXME: better signalling */
865 093bc2cd Avi Kivity
    }
866 093bc2cd Avi Kivity
867 74901c3b Avi Kivity
    if (!mr->ops->read) {
868 74901c3b Avi Kivity
        return mr->ops->old_mmio.read[bitops_ffsl(size)](mr->opaque, addr);
869 74901c3b Avi Kivity
    }
870 74901c3b Avi Kivity
871 093bc2cd Avi Kivity
    /* FIXME: support unaligned access */
872 2b50aa1f Avi Kivity
    access_with_adjusted_size(addr, &data, size,
873 164a4dcd Avi Kivity
                              mr->ops->impl.min_access_size,
874 164a4dcd Avi Kivity
                              mr->ops->impl.max_access_size,
875 164a4dcd Avi Kivity
                              memory_region_read_accessor, mr);
876 093bc2cd Avi Kivity
877 093bc2cd Avi Kivity
    return data;
878 093bc2cd Avi Kivity
}
879 093bc2cd Avi Kivity
880 a621f38d Avi Kivity
static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size)
881 093bc2cd Avi Kivity
{
882 a621f38d Avi Kivity
    if (memory_region_wrong_endianness(mr)) {
883 a621f38d Avi Kivity
        switch (size) {
884 a621f38d Avi Kivity
        case 1:
885 a621f38d Avi Kivity
            break;
886 a621f38d Avi Kivity
        case 2:
887 a621f38d Avi Kivity
            *data = bswap16(*data);
888 a621f38d Avi Kivity
            break;
889 a621f38d Avi Kivity
        case 4:
890 a621f38d Avi Kivity
            *data = bswap32(*data);
891 1470a0cd Andreas Fรคrber
            break;
892 a621f38d Avi Kivity
        default:
893 a621f38d Avi Kivity
            abort();
894 a621f38d Avi Kivity
        }
895 a621f38d Avi Kivity
    }
896 a621f38d Avi Kivity
}
897 a621f38d Avi Kivity
898 a621f38d Avi Kivity
static uint64_t memory_region_dispatch_read(MemoryRegion *mr,
899 a621f38d Avi Kivity
                                            target_phys_addr_t addr,
900 a621f38d Avi Kivity
                                            unsigned size)
901 a621f38d Avi Kivity
{
902 a621f38d Avi Kivity
    uint64_t ret;
903 a621f38d Avi Kivity
904 a621f38d Avi Kivity
    ret = memory_region_dispatch_read1(mr, addr, size);
905 a621f38d Avi Kivity
    adjust_endianness(mr, &ret, size);
906 a621f38d Avi Kivity
    return ret;
907 a621f38d Avi Kivity
}
908 093bc2cd Avi Kivity
909 a621f38d Avi Kivity
static void memory_region_dispatch_write(MemoryRegion *mr,
910 a621f38d Avi Kivity
                                         target_phys_addr_t addr,
911 a621f38d Avi Kivity
                                         uint64_t data,
912 a621f38d Avi Kivity
                                         unsigned size)
913 a621f38d Avi Kivity
{
914 897fa7cf Avi Kivity
    if (!memory_region_access_valid(mr, addr, size, true)) {
915 093bc2cd Avi Kivity
        return; /* FIXME: better signalling */
916 093bc2cd Avi Kivity
    }
917 093bc2cd Avi Kivity
918 a621f38d Avi Kivity
    adjust_endianness(mr, &data, size);
919 a621f38d Avi Kivity
920 74901c3b Avi Kivity
    if (!mr->ops->write) {
921 74901c3b Avi Kivity
        mr->ops->old_mmio.write[bitops_ffsl(size)](mr->opaque, addr, data);
922 74901c3b Avi Kivity
        return;
923 74901c3b Avi Kivity
    }
924 74901c3b Avi Kivity
925 093bc2cd Avi Kivity
    /* FIXME: support unaligned access */
926 2b50aa1f Avi Kivity
    access_with_adjusted_size(addr, &data, size,
927 164a4dcd Avi Kivity
                              mr->ops->impl.min_access_size,
928 164a4dcd Avi Kivity
                              mr->ops->impl.max_access_size,
929 164a4dcd Avi Kivity
                              memory_region_write_accessor, mr);
930 093bc2cd Avi Kivity
}
931 093bc2cd Avi Kivity
932 093bc2cd Avi Kivity
void memory_region_init_io(MemoryRegion *mr,
933 093bc2cd Avi Kivity
                           const MemoryRegionOps *ops,
934 093bc2cd Avi Kivity
                           void *opaque,
935 093bc2cd Avi Kivity
                           const char *name,
936 093bc2cd Avi Kivity
                           uint64_t size)
937 093bc2cd Avi Kivity
{
938 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
939 093bc2cd Avi Kivity
    mr->ops = ops;
940 093bc2cd Avi Kivity
    mr->opaque = opaque;
941 14a3c10a Avi Kivity
    mr->terminates = true;
942 26a83ad0 Avi Kivity
    mr->destructor = memory_region_destructor_iomem;
943 97161e17 Avi Kivity
    mr->ram_addr = ~(ram_addr_t)0;
944 093bc2cd Avi Kivity
}
945 093bc2cd Avi Kivity
946 093bc2cd Avi Kivity
void memory_region_init_ram(MemoryRegion *mr,
947 093bc2cd Avi Kivity
                            const char *name,
948 093bc2cd Avi Kivity
                            uint64_t size)
949 093bc2cd Avi Kivity
{
950 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
951 8ea9252a Avi Kivity
    mr->ram = true;
952 14a3c10a Avi Kivity
    mr->terminates = true;
953 545e92e0 Avi Kivity
    mr->destructor = memory_region_destructor_ram;
954 c5705a77 Avi Kivity
    mr->ram_addr = qemu_ram_alloc(size, mr);
955 093bc2cd Avi Kivity
}
956 093bc2cd Avi Kivity
957 093bc2cd Avi Kivity
void memory_region_init_ram_ptr(MemoryRegion *mr,
958 093bc2cd Avi Kivity
                                const char *name,
959 093bc2cd Avi Kivity
                                uint64_t size,
960 093bc2cd Avi Kivity
                                void *ptr)
961 093bc2cd Avi Kivity
{
962 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
963 8ea9252a Avi Kivity
    mr->ram = true;
964 14a3c10a Avi Kivity
    mr->terminates = true;
965 545e92e0 Avi Kivity
    mr->destructor = memory_region_destructor_ram_from_ptr;
966 c5705a77 Avi Kivity
    mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr);
967 093bc2cd Avi Kivity
}
968 093bc2cd Avi Kivity
969 093bc2cd Avi Kivity
void memory_region_init_alias(MemoryRegion *mr,
970 093bc2cd Avi Kivity
                              const char *name,
971 093bc2cd Avi Kivity
                              MemoryRegion *orig,
972 093bc2cd Avi Kivity
                              target_phys_addr_t offset,
973 093bc2cd Avi Kivity
                              uint64_t size)
974 093bc2cd Avi Kivity
{
975 093bc2cd Avi Kivity
    memory_region_init(mr, name, size);
976 093bc2cd Avi Kivity
    mr->alias = orig;
977 093bc2cd Avi Kivity
    mr->alias_offset = offset;
978 093bc2cd Avi Kivity
}
979 093bc2cd Avi Kivity
980 d0a9b5bc Avi Kivity
void memory_region_init_rom_device(MemoryRegion *mr,
981 d0a9b5bc Avi Kivity
                                   const MemoryRegionOps *ops,
982 75f5941c Avi Kivity
                                   void *opaque,
983 d0a9b5bc Avi Kivity
                                   const char *name,
984 d0a9b5bc Avi Kivity
                                   uint64_t size)
985 d0a9b5bc Avi Kivity
{
986 d0a9b5bc Avi Kivity
    memory_region_init(mr, name, size);
987 7bc2b9cd Avi Kivity
    mr->ops = ops;
988 75f5941c Avi Kivity
    mr->opaque = opaque;
989 d0a9b5bc Avi Kivity
    mr->terminates = true;
990 75c578dc Avi Kivity
    mr->rom_device = true;
991 d0a9b5bc Avi Kivity
    mr->destructor = memory_region_destructor_rom_device;
992 c5705a77 Avi Kivity
    mr->ram_addr = qemu_ram_alloc(size, mr);
993 d0a9b5bc Avi Kivity
}
994 d0a9b5bc Avi Kivity
995 1660e72d Jan Kiszka
static uint64_t invalid_read(void *opaque, target_phys_addr_t addr,
996 1660e72d Jan Kiszka
                             unsigned size)
997 1660e72d Jan Kiszka
{
998 1660e72d Jan Kiszka
    MemoryRegion *mr = opaque;
999 1660e72d Jan Kiszka
1000 1660e72d Jan Kiszka
    if (!mr->warning_printed) {
1001 1660e72d Jan Kiszka
        fprintf(stderr, "Invalid read from memory region %s\n", mr->name);
1002 1660e72d Jan Kiszka
        mr->warning_printed = true;
1003 1660e72d Jan Kiszka
    }
1004 1660e72d Jan Kiszka
    return -1U;
1005 1660e72d Jan Kiszka
}
1006 1660e72d Jan Kiszka
1007 1660e72d Jan Kiszka
static void invalid_write(void *opaque, target_phys_addr_t addr, uint64_t data,
1008 1660e72d Jan Kiszka
                          unsigned size)
1009 1660e72d Jan Kiszka
{
1010 1660e72d Jan Kiszka
    MemoryRegion *mr = opaque;
1011 1660e72d Jan Kiszka
1012 1660e72d Jan Kiszka
    if (!mr->warning_printed) {
1013 1660e72d Jan Kiszka
        fprintf(stderr, "Invalid write to memory region %s\n", mr->name);
1014 1660e72d Jan Kiszka
        mr->warning_printed = true;
1015 1660e72d Jan Kiszka
    }
1016 1660e72d Jan Kiszka
}
1017 1660e72d Jan Kiszka
1018 1660e72d Jan Kiszka
static const MemoryRegionOps reservation_ops = {
1019 1660e72d Jan Kiszka
    .read = invalid_read,
1020 1660e72d Jan Kiszka
    .write = invalid_write,
1021 1660e72d Jan Kiszka
    .endianness = DEVICE_NATIVE_ENDIAN,
1022 1660e72d Jan Kiszka
};
1023 1660e72d Jan Kiszka
1024 1660e72d Jan Kiszka
void memory_region_init_reservation(MemoryRegion *mr,
1025 1660e72d Jan Kiszka
                                    const char *name,
1026 1660e72d Jan Kiszka
                                    uint64_t size)
1027 1660e72d Jan Kiszka
{
1028 1660e72d Jan Kiszka
    memory_region_init_io(mr, &reservation_ops, mr, name, size);
1029 1660e72d Jan Kiszka
}
1030 1660e72d Jan Kiszka
1031 093bc2cd Avi Kivity
void memory_region_destroy(MemoryRegion *mr)
1032 093bc2cd Avi Kivity
{
1033 093bc2cd Avi Kivity
    assert(QTAILQ_EMPTY(&mr->subregions));
1034 545e92e0 Avi Kivity
    mr->destructor(mr);
1035 093bc2cd Avi Kivity
    memory_region_clear_coalescing(mr);
1036 7267c094 Anthony Liguori
    g_free((char *)mr->name);
1037 7267c094 Anthony Liguori
    g_free(mr->ioeventfds);
1038 093bc2cd Avi Kivity
}
1039 093bc2cd Avi Kivity
1040 093bc2cd Avi Kivity
uint64_t memory_region_size(MemoryRegion *mr)
1041 093bc2cd Avi Kivity
{
1042 08dafab4 Avi Kivity
    if (int128_eq(mr->size, int128_2_64())) {
1043 08dafab4 Avi Kivity
        return UINT64_MAX;
1044 08dafab4 Avi Kivity
    }
1045 08dafab4 Avi Kivity
    return int128_get64(mr->size);
1046 093bc2cd Avi Kivity
}
1047 093bc2cd Avi Kivity
1048 8991c79b Avi Kivity
const char *memory_region_name(MemoryRegion *mr)
1049 8991c79b Avi Kivity
{
1050 8991c79b Avi Kivity
    return mr->name;
1051 8991c79b Avi Kivity
}
1052 8991c79b Avi Kivity
1053 8ea9252a Avi Kivity
bool memory_region_is_ram(MemoryRegion *mr)
1054 8ea9252a Avi Kivity
{
1055 8ea9252a Avi Kivity
    return mr->ram;
1056 8ea9252a Avi Kivity
}
1057 8ea9252a Avi Kivity
1058 55043ba3 Avi Kivity
bool memory_region_is_logging(MemoryRegion *mr)
1059 55043ba3 Avi Kivity
{
1060 55043ba3 Avi Kivity
    return mr->dirty_log_mask;
1061 55043ba3 Avi Kivity
}
1062 55043ba3 Avi Kivity
1063 ce7923da Avi Kivity
bool memory_region_is_rom(MemoryRegion *mr)
1064 ce7923da Avi Kivity
{
1065 ce7923da Avi Kivity
    return mr->ram && mr->readonly;
1066 ce7923da Avi Kivity
}
1067 ce7923da Avi Kivity
1068 093bc2cd Avi Kivity
void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
1069 093bc2cd Avi Kivity
{
1070 5a583347 Avi Kivity
    uint8_t mask = 1 << client;
1071 5a583347 Avi Kivity
1072 5a583347 Avi Kivity
    mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
1073 6bba19ba Avi Kivity
    memory_region_update_topology(mr);
1074 093bc2cd Avi Kivity
}
1075 093bc2cd Avi Kivity
1076 093bc2cd Avi Kivity
bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr,
1077 cd7a45c9 Blue Swirl
                             target_phys_addr_t size, unsigned client)
1078 093bc2cd Avi Kivity
{
1079 14a3c10a Avi Kivity
    assert(mr->terminates);
1080 cd7a45c9 Blue Swirl
    return cpu_physical_memory_get_dirty(mr->ram_addr + addr, size,
1081 cd7a45c9 Blue Swirl
                                         1 << client);
1082 093bc2cd Avi Kivity
}
1083 093bc2cd Avi Kivity
1084 fd4aa979 Blue Swirl
void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr,
1085 fd4aa979 Blue Swirl
                             target_phys_addr_t size)
1086 093bc2cd Avi Kivity
{
1087 14a3c10a Avi Kivity
    assert(mr->terminates);
1088 fd4aa979 Blue Swirl
    return cpu_physical_memory_set_dirty_range(mr->ram_addr + addr, size, -1);
1089 093bc2cd Avi Kivity
}
1090 093bc2cd Avi Kivity
1091 093bc2cd Avi Kivity
void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
1092 093bc2cd Avi Kivity
{
1093 5a583347 Avi Kivity
    FlatRange *fr;
1094 5a583347 Avi Kivity
1095 cc31e6e7 Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
1096 5a583347 Avi Kivity
        if (fr->mr == mr) {
1097 72e22d2f Avi Kivity
            MEMORY_LISTENER_UPDATE_REGION(fr, &address_space_memory,
1098 72e22d2f Avi Kivity
                                          Forward, log_sync);
1099 5a583347 Avi Kivity
        }
1100 5a583347 Avi Kivity
    }
1101 093bc2cd Avi Kivity
}
1102 093bc2cd Avi Kivity
1103 093bc2cd Avi Kivity
void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
1104 093bc2cd Avi Kivity
{
1105 fb1cd6f9 Avi Kivity
    if (mr->readonly != readonly) {
1106 fb1cd6f9 Avi Kivity
        mr->readonly = readonly;
1107 6bba19ba Avi Kivity
        memory_region_update_topology(mr);
1108 fb1cd6f9 Avi Kivity
    }
1109 093bc2cd Avi Kivity
}
1110 093bc2cd Avi Kivity
1111 d0a9b5bc Avi Kivity
void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
1112 d0a9b5bc Avi Kivity
{
1113 d0a9b5bc Avi Kivity
    if (mr->readable != readable) {
1114 d0a9b5bc Avi Kivity
        mr->readable = readable;
1115 6bba19ba Avi Kivity
        memory_region_update_topology(mr);
1116 d0a9b5bc Avi Kivity
    }
1117 d0a9b5bc Avi Kivity
}
1118 d0a9b5bc Avi Kivity
1119 093bc2cd Avi Kivity
void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
1120 093bc2cd Avi Kivity
                               target_phys_addr_t size, unsigned client)
1121 093bc2cd Avi Kivity
{
1122 14a3c10a Avi Kivity
    assert(mr->terminates);
1123 5a583347 Avi Kivity
    cpu_physical_memory_reset_dirty(mr->ram_addr + addr,
1124 5a583347 Avi Kivity
                                    mr->ram_addr + addr + size,
1125 5a583347 Avi Kivity
                                    1 << client);
1126 093bc2cd Avi Kivity
}
1127 093bc2cd Avi Kivity
1128 093bc2cd Avi Kivity
void *memory_region_get_ram_ptr(MemoryRegion *mr)
1129 093bc2cd Avi Kivity
{
1130 093bc2cd Avi Kivity
    if (mr->alias) {
1131 093bc2cd Avi Kivity
        return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
1132 093bc2cd Avi Kivity
    }
1133 093bc2cd Avi Kivity
1134 14a3c10a Avi Kivity
    assert(mr->terminates);
1135 093bc2cd Avi Kivity
1136 021d26d1 Jan Kiszka
    return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
1137 093bc2cd Avi Kivity
}
1138 093bc2cd Avi Kivity
1139 093bc2cd Avi Kivity
static void memory_region_update_coalesced_range(MemoryRegion *mr)
1140 093bc2cd Avi Kivity
{
1141 093bc2cd Avi Kivity
    FlatRange *fr;
1142 093bc2cd Avi Kivity
    CoalescedMemoryRange *cmr;
1143 093bc2cd Avi Kivity
    AddrRange tmp;
1144 093bc2cd Avi Kivity
1145 cc31e6e7 Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, &address_space_memory.current_map) {
1146 093bc2cd Avi Kivity
        if (fr->mr == mr) {
1147 08dafab4 Avi Kivity
            qemu_unregister_coalesced_mmio(int128_get64(fr->addr.start),
1148 08dafab4 Avi Kivity
                                           int128_get64(fr->addr.size));
1149 093bc2cd Avi Kivity
            QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
1150 093bc2cd Avi Kivity
                tmp = addrrange_shift(cmr->addr,
1151 08dafab4 Avi Kivity
                                      int128_sub(fr->addr.start,
1152 08dafab4 Avi Kivity
                                                 int128_make64(fr->offset_in_region)));
1153 093bc2cd Avi Kivity
                if (!addrrange_intersects(tmp, fr->addr)) {
1154 093bc2cd Avi Kivity
                    continue;
1155 093bc2cd Avi Kivity
                }
1156 093bc2cd Avi Kivity
                tmp = addrrange_intersection(tmp, fr->addr);
1157 08dafab4 Avi Kivity
                qemu_register_coalesced_mmio(int128_get64(tmp.start),
1158 08dafab4 Avi Kivity
                                             int128_get64(tmp.size));
1159 093bc2cd Avi Kivity
            }
1160 093bc2cd Avi Kivity
        }
1161 093bc2cd Avi Kivity
    }
1162 093bc2cd Avi Kivity
}
1163 093bc2cd Avi Kivity
1164 093bc2cd Avi Kivity
void memory_region_set_coalescing(MemoryRegion *mr)
1165 093bc2cd Avi Kivity
{
1166 093bc2cd Avi Kivity
    memory_region_clear_coalescing(mr);
1167 08dafab4 Avi Kivity
    memory_region_add_coalescing(mr, 0, int128_get64(mr->size));
1168 093bc2cd Avi Kivity
}
1169 093bc2cd Avi Kivity
1170 093bc2cd Avi Kivity
void memory_region_add_coalescing(MemoryRegion *mr,
1171 093bc2cd Avi Kivity
                                  target_phys_addr_t offset,
1172 093bc2cd Avi Kivity
                                  uint64_t size)
1173 093bc2cd Avi Kivity
{
1174 7267c094 Anthony Liguori
    CoalescedMemoryRange *cmr = g_malloc(sizeof(*cmr));
1175 093bc2cd Avi Kivity
1176 08dafab4 Avi Kivity
    cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size));
1177 093bc2cd Avi Kivity
    QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
1178 093bc2cd Avi Kivity
    memory_region_update_coalesced_range(mr);
1179 093bc2cd Avi Kivity
}
1180 093bc2cd Avi Kivity
1181 093bc2cd Avi Kivity
void memory_region_clear_coalescing(MemoryRegion *mr)
1182 093bc2cd Avi Kivity
{
1183 093bc2cd Avi Kivity
    CoalescedMemoryRange *cmr;
1184 093bc2cd Avi Kivity
1185 093bc2cd Avi Kivity
    while (!QTAILQ_EMPTY(&mr->coalesced)) {
1186 093bc2cd Avi Kivity
        cmr = QTAILQ_FIRST(&mr->coalesced);
1187 093bc2cd Avi Kivity
        QTAILQ_REMOVE(&mr->coalesced, cmr, link);
1188 7267c094 Anthony Liguori
        g_free(cmr);
1189 093bc2cd Avi Kivity
    }
1190 093bc2cd Avi Kivity
    memory_region_update_coalesced_range(mr);
1191 093bc2cd Avi Kivity
}
1192 093bc2cd Avi Kivity
1193 3e9d69e7 Avi Kivity
void memory_region_add_eventfd(MemoryRegion *mr,
1194 3e9d69e7 Avi Kivity
                               target_phys_addr_t addr,
1195 3e9d69e7 Avi Kivity
                               unsigned size,
1196 3e9d69e7 Avi Kivity
                               bool match_data,
1197 3e9d69e7 Avi Kivity
                               uint64_t data,
1198 753d5e14 Paolo Bonzini
                               EventNotifier *e)
1199 3e9d69e7 Avi Kivity
{
1200 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd mrfd = {
1201 08dafab4 Avi Kivity
        .addr.start = int128_make64(addr),
1202 08dafab4 Avi Kivity
        .addr.size = int128_make64(size),
1203 3e9d69e7 Avi Kivity
        .match_data = match_data,
1204 3e9d69e7 Avi Kivity
        .data = data,
1205 753d5e14 Paolo Bonzini
        .e = e,
1206 3e9d69e7 Avi Kivity
    };
1207 3e9d69e7 Avi Kivity
    unsigned i;
1208 3e9d69e7 Avi Kivity
1209 3e9d69e7 Avi Kivity
    for (i = 0; i < mr->ioeventfd_nb; ++i) {
1210 3e9d69e7 Avi Kivity
        if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) {
1211 3e9d69e7 Avi Kivity
            break;
1212 3e9d69e7 Avi Kivity
        }
1213 3e9d69e7 Avi Kivity
    }
1214 3e9d69e7 Avi Kivity
    ++mr->ioeventfd_nb;
1215 7267c094 Anthony Liguori
    mr->ioeventfds = g_realloc(mr->ioeventfds,
1216 3e9d69e7 Avi Kivity
                                  sizeof(*mr->ioeventfds) * mr->ioeventfd_nb);
1217 3e9d69e7 Avi Kivity
    memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i],
1218 3e9d69e7 Avi Kivity
            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i));
1219 3e9d69e7 Avi Kivity
    mr->ioeventfds[i] = mrfd;
1220 6bba19ba Avi Kivity
    memory_region_update_topology(mr);
1221 3e9d69e7 Avi Kivity
}
1222 3e9d69e7 Avi Kivity
1223 3e9d69e7 Avi Kivity
void memory_region_del_eventfd(MemoryRegion *mr,
1224 3e9d69e7 Avi Kivity
                               target_phys_addr_t addr,
1225 3e9d69e7 Avi Kivity
                               unsigned size,
1226 3e9d69e7 Avi Kivity
                               bool match_data,
1227 3e9d69e7 Avi Kivity
                               uint64_t data,
1228 753d5e14 Paolo Bonzini
                               EventNotifier *e)
1229 3e9d69e7 Avi Kivity
{
1230 3e9d69e7 Avi Kivity
    MemoryRegionIoeventfd mrfd = {
1231 08dafab4 Avi Kivity
        .addr.start = int128_make64(addr),
1232 08dafab4 Avi Kivity
        .addr.size = int128_make64(size),
1233 3e9d69e7 Avi Kivity
        .match_data = match_data,
1234 3e9d69e7 Avi Kivity
        .data = data,
1235 753d5e14 Paolo Bonzini
        .e = e,
1236 3e9d69e7 Avi Kivity
    };
1237 3e9d69e7 Avi Kivity
    unsigned i;
1238 3e9d69e7 Avi Kivity
1239 3e9d69e7 Avi Kivity
    for (i = 0; i < mr->ioeventfd_nb; ++i) {
1240 3e9d69e7 Avi Kivity
        if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) {
1241 3e9d69e7 Avi Kivity
            break;
1242 3e9d69e7 Avi Kivity
        }
1243 3e9d69e7 Avi Kivity
    }
1244 3e9d69e7 Avi Kivity
    assert(i != mr->ioeventfd_nb);
1245 3e9d69e7 Avi Kivity
    memmove(&mr->ioeventfds[i], &mr->ioeventfds[i+1],
1246 3e9d69e7 Avi Kivity
            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb - (i+1)));
1247 3e9d69e7 Avi Kivity
    --mr->ioeventfd_nb;
1248 7267c094 Anthony Liguori
    mr->ioeventfds = g_realloc(mr->ioeventfds,
1249 3e9d69e7 Avi Kivity
                                  sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);
1250 6bba19ba Avi Kivity
    memory_region_update_topology(mr);
1251 3e9d69e7 Avi Kivity
}
1252 3e9d69e7 Avi Kivity
1253 093bc2cd Avi Kivity
static void memory_region_add_subregion_common(MemoryRegion *mr,
1254 093bc2cd Avi Kivity
                                               target_phys_addr_t offset,
1255 093bc2cd Avi Kivity
                                               MemoryRegion *subregion)
1256 093bc2cd Avi Kivity
{
1257 093bc2cd Avi Kivity
    MemoryRegion *other;
1258 093bc2cd Avi Kivity
1259 093bc2cd Avi Kivity
    assert(!subregion->parent);
1260 093bc2cd Avi Kivity
    subregion->parent = mr;
1261 093bc2cd Avi Kivity
    subregion->addr = offset;
1262 093bc2cd Avi Kivity
    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
1263 093bc2cd Avi Kivity
        if (subregion->may_overlap || other->may_overlap) {
1264 093bc2cd Avi Kivity
            continue;
1265 093bc2cd Avi Kivity
        }
1266 08dafab4 Avi Kivity
        if (int128_gt(int128_make64(offset),
1267 08dafab4 Avi Kivity
                      int128_add(int128_make64(other->addr), other->size))
1268 08dafab4 Avi Kivity
            || int128_le(int128_add(int128_make64(offset), subregion->size),
1269 08dafab4 Avi Kivity
                         int128_make64(other->addr))) {
1270 093bc2cd Avi Kivity
            continue;
1271 093bc2cd Avi Kivity
        }
1272 a5e1cbc8 Anthony Liguori
#if 0
1273 860329b2 Michael Walle
        printf("warning: subregion collision %llx/%llx (%s) "
1274 860329b2 Michael Walle
               "vs %llx/%llx (%s)\n",
1275 093bc2cd Avi Kivity
               (unsigned long long)offset,
1276 08dafab4 Avi Kivity
               (unsigned long long)int128_get64(subregion->size),
1277 860329b2 Michael Walle
               subregion->name,
1278 860329b2 Michael Walle
               (unsigned long long)other->addr,
1279 08dafab4 Avi Kivity
               (unsigned long long)int128_get64(other->size),
1280 860329b2 Michael Walle
               other->name);
1281 a5e1cbc8 Anthony Liguori
#endif
1282 093bc2cd Avi Kivity
    }
1283 093bc2cd Avi Kivity
    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
1284 093bc2cd Avi Kivity
        if (subregion->priority >= other->priority) {
1285 093bc2cd Avi Kivity
            QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
1286 093bc2cd Avi Kivity
            goto done;
1287 093bc2cd Avi Kivity
        }
1288 093bc2cd Avi Kivity
    }
1289 093bc2cd Avi Kivity
    QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link);
1290 093bc2cd Avi Kivity
done:
1291 6bba19ba Avi Kivity
    memory_region_update_topology(mr);
1292 093bc2cd Avi Kivity
}
1293 093bc2cd Avi Kivity
1294 093bc2cd Avi Kivity
1295 093bc2cd Avi Kivity
void memory_region_add_subregion(MemoryRegion *mr,
1296 093bc2cd Avi Kivity
                                 target_phys_addr_t offset,
1297 093bc2cd Avi Kivity
                                 MemoryRegion *subregion)
1298 093bc2cd Avi Kivity
{
1299 093bc2cd Avi Kivity
    subregion->may_overlap = false;
1300 093bc2cd Avi Kivity
    subregion->priority = 0;
1301 093bc2cd Avi Kivity
    memory_region_add_subregion_common(mr, offset, subregion);
1302 093bc2cd Avi Kivity
}
1303 093bc2cd Avi Kivity
1304 093bc2cd Avi Kivity
void memory_region_add_subregion_overlap(MemoryRegion *mr,
1305 093bc2cd Avi Kivity
                                         target_phys_addr_t offset,
1306 093bc2cd Avi Kivity
                                         MemoryRegion *subregion,
1307 093bc2cd Avi Kivity
                                         unsigned priority)
1308 093bc2cd Avi Kivity
{
1309 093bc2cd Avi Kivity
    subregion->may_overlap = true;
1310 093bc2cd Avi Kivity
    subregion->priority = priority;
1311 093bc2cd Avi Kivity
    memory_region_add_subregion_common(mr, offset, subregion);
1312 093bc2cd Avi Kivity
}
1313 093bc2cd Avi Kivity
1314 093bc2cd Avi Kivity
void memory_region_del_subregion(MemoryRegion *mr,
1315 093bc2cd Avi Kivity
                                 MemoryRegion *subregion)
1316 093bc2cd Avi Kivity
{
1317 093bc2cd Avi Kivity
    assert(subregion->parent == mr);
1318 093bc2cd Avi Kivity
    subregion->parent = NULL;
1319 093bc2cd Avi Kivity
    QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
1320 6bba19ba Avi Kivity
    memory_region_update_topology(mr);
1321 6bba19ba Avi Kivity
}
1322 6bba19ba Avi Kivity
1323 6bba19ba Avi Kivity
void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
1324 6bba19ba Avi Kivity
{
1325 6bba19ba Avi Kivity
    if (enabled == mr->enabled) {
1326 6bba19ba Avi Kivity
        return;
1327 6bba19ba Avi Kivity
    }
1328 6bba19ba Avi Kivity
    mr->enabled = enabled;
1329 6bba19ba Avi Kivity
    memory_region_update_topology(NULL);
1330 093bc2cd Avi Kivity
}
1331 1c0ffa58 Avi Kivity
1332 2282e1af Avi Kivity
void memory_region_set_address(MemoryRegion *mr, target_phys_addr_t addr)
1333 2282e1af Avi Kivity
{
1334 2282e1af Avi Kivity
    MemoryRegion *parent = mr->parent;
1335 2282e1af Avi Kivity
    unsigned priority = mr->priority;
1336 2282e1af Avi Kivity
    bool may_overlap = mr->may_overlap;
1337 2282e1af Avi Kivity
1338 2282e1af Avi Kivity
    if (addr == mr->addr || !parent) {
1339 2282e1af Avi Kivity
        mr->addr = addr;
1340 2282e1af Avi Kivity
        return;
1341 2282e1af Avi Kivity
    }
1342 2282e1af Avi Kivity
1343 2282e1af Avi Kivity
    memory_region_transaction_begin();
1344 2282e1af Avi Kivity
    memory_region_del_subregion(parent, mr);
1345 2282e1af Avi Kivity
    if (may_overlap) {
1346 2282e1af Avi Kivity
        memory_region_add_subregion_overlap(parent, addr, mr, priority);
1347 2282e1af Avi Kivity
    } else {
1348 2282e1af Avi Kivity
        memory_region_add_subregion(parent, addr, mr);
1349 2282e1af Avi Kivity
    }
1350 2282e1af Avi Kivity
    memory_region_transaction_commit();
1351 2282e1af Avi Kivity
}
1352 2282e1af Avi Kivity
1353 4703359e Avi Kivity
void memory_region_set_alias_offset(MemoryRegion *mr, target_phys_addr_t offset)
1354 4703359e Avi Kivity
{
1355 4703359e Avi Kivity
    target_phys_addr_t old_offset = mr->alias_offset;
1356 4703359e Avi Kivity
1357 4703359e Avi Kivity
    assert(mr->alias);
1358 4703359e Avi Kivity
    mr->alias_offset = offset;
1359 4703359e Avi Kivity
1360 4703359e Avi Kivity
    if (offset == old_offset || !mr->parent) {
1361 4703359e Avi Kivity
        return;
1362 4703359e Avi Kivity
    }
1363 4703359e Avi Kivity
1364 4703359e Avi Kivity
    memory_region_update_topology(mr);
1365 4703359e Avi Kivity
}
1366 4703359e Avi Kivity
1367 e34911c4 Avi Kivity
ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
1368 e34911c4 Avi Kivity
{
1369 e34911c4 Avi Kivity
    return mr->ram_addr;
1370 e34911c4 Avi Kivity
}
1371 e34911c4 Avi Kivity
1372 e2177955 Avi Kivity
static int cmp_flatrange_addr(const void *addr_, const void *fr_)
1373 e2177955 Avi Kivity
{
1374 e2177955 Avi Kivity
    const AddrRange *addr = addr_;
1375 e2177955 Avi Kivity
    const FlatRange *fr = fr_;
1376 e2177955 Avi Kivity
1377 e2177955 Avi Kivity
    if (int128_le(addrrange_end(*addr), fr->addr.start)) {
1378 e2177955 Avi Kivity
        return -1;
1379 e2177955 Avi Kivity
    } else if (int128_ge(addr->start, addrrange_end(fr->addr))) {
1380 e2177955 Avi Kivity
        return 1;
1381 e2177955 Avi Kivity
    }
1382 e2177955 Avi Kivity
    return 0;
1383 e2177955 Avi Kivity
}
1384 e2177955 Avi Kivity
1385 e2177955 Avi Kivity
static FlatRange *address_space_lookup(AddressSpace *as, AddrRange addr)
1386 e2177955 Avi Kivity
{
1387 e2177955 Avi Kivity
    return bsearch(&addr, as->current_map.ranges, as->current_map.nr,
1388 e2177955 Avi Kivity
                   sizeof(FlatRange), cmp_flatrange_addr);
1389 e2177955 Avi Kivity
}
1390 e2177955 Avi Kivity
1391 e2177955 Avi Kivity
MemoryRegionSection memory_region_find(MemoryRegion *address_space,
1392 e2177955 Avi Kivity
                                       target_phys_addr_t addr, uint64_t size)
1393 e2177955 Avi Kivity
{
1394 e2177955 Avi Kivity
    AddressSpace *as = memory_region_to_address_space(address_space);
1395 e2177955 Avi Kivity
    AddrRange range = addrrange_make(int128_make64(addr),
1396 e2177955 Avi Kivity
                                     int128_make64(size));
1397 e2177955 Avi Kivity
    FlatRange *fr = address_space_lookup(as, range);
1398 e2177955 Avi Kivity
    MemoryRegionSection ret = { .mr = NULL, .size = 0 };
1399 e2177955 Avi Kivity
1400 e2177955 Avi Kivity
    if (!fr) {
1401 e2177955 Avi Kivity
        return ret;
1402 e2177955 Avi Kivity
    }
1403 e2177955 Avi Kivity
1404 e2177955 Avi Kivity
    while (fr > as->current_map.ranges
1405 e2177955 Avi Kivity
           && addrrange_intersects(fr[-1].addr, range)) {
1406 e2177955 Avi Kivity
        --fr;
1407 e2177955 Avi Kivity
    }
1408 e2177955 Avi Kivity
1409 e2177955 Avi Kivity
    ret.mr = fr->mr;
1410 e2177955 Avi Kivity
    range = addrrange_intersection(range, fr->addr);
1411 e2177955 Avi Kivity
    ret.offset_within_region = fr->offset_in_region;
1412 e2177955 Avi Kivity
    ret.offset_within_region += int128_get64(int128_sub(range.start,
1413 e2177955 Avi Kivity
                                                        fr->addr.start));
1414 e2177955 Avi Kivity
    ret.size = int128_get64(range.size);
1415 e2177955 Avi Kivity
    ret.offset_within_address_space = int128_get64(range.start);
1416 7a8499e8 Avi Kivity
    ret.readonly = fr->readonly;
1417 e2177955 Avi Kivity
    return ret;
1418 e2177955 Avi Kivity
}
1419 e2177955 Avi Kivity
1420 86e775c6 Avi Kivity
void memory_global_sync_dirty_bitmap(MemoryRegion *address_space)
1421 86e775c6 Avi Kivity
{
1422 7664e80c Avi Kivity
    AddressSpace *as = memory_region_to_address_space(address_space);
1423 7664e80c Avi Kivity
    FlatRange *fr;
1424 7664e80c Avi Kivity
1425 7664e80c Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, &as->current_map) {
1426 72e22d2f Avi Kivity
        MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync);
1427 7664e80c Avi Kivity
    }
1428 7664e80c Avi Kivity
}
1429 7664e80c Avi Kivity
1430 7664e80c Avi Kivity
void memory_global_dirty_log_start(void)
1431 7664e80c Avi Kivity
{
1432 7664e80c Avi Kivity
    global_dirty_log = true;
1433 7376e582 Avi Kivity
    MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward);
1434 7664e80c Avi Kivity
}
1435 7664e80c Avi Kivity
1436 7664e80c Avi Kivity
void memory_global_dirty_log_stop(void)
1437 7664e80c Avi Kivity
{
1438 7664e80c Avi Kivity
    global_dirty_log = false;
1439 7376e582 Avi Kivity
    MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse);
1440 7664e80c Avi Kivity
}
1441 7664e80c Avi Kivity
1442 7664e80c Avi Kivity
static void listener_add_address_space(MemoryListener *listener,
1443 7664e80c Avi Kivity
                                       AddressSpace *as)
1444 7664e80c Avi Kivity
{
1445 7664e80c Avi Kivity
    FlatRange *fr;
1446 7664e80c Avi Kivity
1447 221b3a3f Julien Grall
    if (listener->address_space_filter
1448 221b3a3f Julien Grall
        && listener->address_space_filter != as->root) {
1449 221b3a3f Julien Grall
        return;
1450 221b3a3f Julien Grall
    }
1451 221b3a3f Julien Grall
1452 7664e80c Avi Kivity
    if (global_dirty_log) {
1453 7664e80c Avi Kivity
        listener->log_global_start(listener);
1454 7664e80c Avi Kivity
    }
1455 7664e80c Avi Kivity
    FOR_EACH_FLAT_RANGE(fr, &as->current_map) {
1456 7664e80c Avi Kivity
        MemoryRegionSection section = {
1457 7664e80c Avi Kivity
            .mr = fr->mr,
1458 7664e80c Avi Kivity
            .address_space = as->root,
1459 7664e80c Avi Kivity
            .offset_within_region = fr->offset_in_region,
1460 7664e80c Avi Kivity
            .size = int128_get64(fr->addr.size),
1461 7664e80c Avi Kivity
            .offset_within_address_space = int128_get64(fr->addr.start),
1462 7a8499e8 Avi Kivity
            .readonly = fr->readonly,
1463 7664e80c Avi Kivity
        };
1464 7664e80c Avi Kivity
        listener->region_add(listener, &section);
1465 7664e80c Avi Kivity
    }
1466 7664e80c Avi Kivity
}
1467 7664e80c Avi Kivity
1468 7376e582 Avi Kivity
void memory_listener_register(MemoryListener *listener, MemoryRegion *filter)
1469 7664e80c Avi Kivity
{
1470 72e22d2f Avi Kivity
    MemoryListener *other = NULL;
1471 72e22d2f Avi Kivity
1472 7376e582 Avi Kivity
    listener->address_space_filter = filter;
1473 72e22d2f Avi Kivity
    if (QTAILQ_EMPTY(&memory_listeners)
1474 72e22d2f Avi Kivity
        || listener->priority >= QTAILQ_LAST(&memory_listeners,
1475 72e22d2f Avi Kivity
                                             memory_listeners)->priority) {
1476 72e22d2f Avi Kivity
        QTAILQ_INSERT_TAIL(&memory_listeners, listener, link);
1477 72e22d2f Avi Kivity
    } else {
1478 72e22d2f Avi Kivity
        QTAILQ_FOREACH(other, &memory_listeners, link) {
1479 72e22d2f Avi Kivity
            if (listener->priority < other->priority) {
1480 72e22d2f Avi Kivity
                break;
1481 72e22d2f Avi Kivity
            }
1482 72e22d2f Avi Kivity
        }
1483 72e22d2f Avi Kivity
        QTAILQ_INSERT_BEFORE(other, listener, link);
1484 72e22d2f Avi Kivity
    }
1485 7664e80c Avi Kivity
    listener_add_address_space(listener, &address_space_memory);
1486 7664e80c Avi Kivity
    listener_add_address_space(listener, &address_space_io);
1487 7664e80c Avi Kivity
}
1488 7664e80c Avi Kivity
1489 7664e80c Avi Kivity
void memory_listener_unregister(MemoryListener *listener)
1490 7664e80c Avi Kivity
{
1491 72e22d2f Avi Kivity
    QTAILQ_REMOVE(&memory_listeners, listener, link);
1492 86e775c6 Avi Kivity
}
1493 e2177955 Avi Kivity
1494 1c0ffa58 Avi Kivity
void set_system_memory_map(MemoryRegion *mr)
1495 1c0ffa58 Avi Kivity
{
1496 cc31e6e7 Avi Kivity
    address_space_memory.root = mr;
1497 6bba19ba Avi Kivity
    memory_region_update_topology(NULL);
1498 1c0ffa58 Avi Kivity
}
1499 658b2224 Avi Kivity
1500 658b2224 Avi Kivity
void set_system_io_map(MemoryRegion *mr)
1501 658b2224 Avi Kivity
{
1502 658b2224 Avi Kivity
    address_space_io.root = mr;
1503 6bba19ba Avi Kivity
    memory_region_update_topology(NULL);
1504 658b2224 Avi Kivity
}
1505 314e2987 Blue Swirl
1506 37ec01d4 Avi Kivity
uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
1507 acbbec5d Avi Kivity
{
1508 37ec01d4 Avi Kivity
    return memory_region_dispatch_read(mr, addr, size);
1509 acbbec5d Avi Kivity
}
1510 acbbec5d Avi Kivity
1511 37ec01d4 Avi Kivity
void io_mem_write(MemoryRegion *mr, target_phys_addr_t addr,
1512 acbbec5d Avi Kivity
                  uint64_t val, unsigned size)
1513 acbbec5d Avi Kivity
{
1514 37ec01d4 Avi Kivity
    memory_region_dispatch_write(mr, addr, val, size);
1515 acbbec5d Avi Kivity
}
1516 acbbec5d Avi Kivity
1517 314e2987 Blue Swirl
typedef struct MemoryRegionList MemoryRegionList;
1518 314e2987 Blue Swirl
1519 314e2987 Blue Swirl
struct MemoryRegionList {
1520 314e2987 Blue Swirl
    const MemoryRegion *mr;
1521 314e2987 Blue Swirl
    bool printed;
1522 314e2987 Blue Swirl
    QTAILQ_ENTRY(MemoryRegionList) queue;
1523 314e2987 Blue Swirl
};
1524 314e2987 Blue Swirl
1525 314e2987 Blue Swirl
typedef QTAILQ_HEAD(queue, MemoryRegionList) MemoryRegionListHead;
1526 314e2987 Blue Swirl
1527 314e2987 Blue Swirl
static void mtree_print_mr(fprintf_function mon_printf, void *f,
1528 314e2987 Blue Swirl
                           const MemoryRegion *mr, unsigned int level,
1529 314e2987 Blue Swirl
                           target_phys_addr_t base,
1530 9479c57a Jan Kiszka
                           MemoryRegionListHead *alias_print_queue)
1531 314e2987 Blue Swirl
{
1532 9479c57a Jan Kiszka
    MemoryRegionList *new_ml, *ml, *next_ml;
1533 9479c57a Jan Kiszka
    MemoryRegionListHead submr_print_queue;
1534 314e2987 Blue Swirl
    const MemoryRegion *submr;
1535 314e2987 Blue Swirl
    unsigned int i;
1536 314e2987 Blue Swirl
1537 314e2987 Blue Swirl
    if (!mr) {
1538 314e2987 Blue Swirl
        return;
1539 314e2987 Blue Swirl
    }
1540 314e2987 Blue Swirl
1541 314e2987 Blue Swirl
    for (i = 0; i < level; i++) {
1542 314e2987 Blue Swirl
        mon_printf(f, "  ");
1543 314e2987 Blue Swirl
    }
1544 314e2987 Blue Swirl
1545 314e2987 Blue Swirl
    if (mr->alias) {
1546 314e2987 Blue Swirl
        MemoryRegionList *ml;
1547 314e2987 Blue Swirl
        bool found = false;
1548 314e2987 Blue Swirl
1549 314e2987 Blue Swirl
        /* check if the alias is already in the queue */
1550 9479c57a Jan Kiszka
        QTAILQ_FOREACH(ml, alias_print_queue, queue) {
1551 314e2987 Blue Swirl
            if (ml->mr == mr->alias && !ml->printed) {
1552 314e2987 Blue Swirl
                found = true;
1553 314e2987 Blue Swirl
            }
1554 314e2987 Blue Swirl
        }
1555 314e2987 Blue Swirl
1556 314e2987 Blue Swirl
        if (!found) {
1557 314e2987 Blue Swirl
            ml = g_new(MemoryRegionList, 1);
1558 314e2987 Blue Swirl
            ml->mr = mr->alias;
1559 314e2987 Blue Swirl
            ml->printed = false;
1560 9479c57a Jan Kiszka
            QTAILQ_INSERT_TAIL(alias_print_queue, ml, queue);
1561 314e2987 Blue Swirl
        }
1562 4896d74b Jan Kiszka
        mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx
1563 4896d74b Jan Kiszka
                   " (prio %d, %c%c): alias %s @%s " TARGET_FMT_plx
1564 4896d74b Jan Kiszka
                   "-" TARGET_FMT_plx "\n",
1565 314e2987 Blue Swirl
                   base + mr->addr,
1566 08dafab4 Avi Kivity
                   base + mr->addr
1567 08dafab4 Avi Kivity
                   + (target_phys_addr_t)int128_get64(mr->size) - 1,
1568 4b474ba7 Jan Kiszka
                   mr->priority,
1569 4896d74b Jan Kiszka
                   mr->readable ? 'R' : '-',
1570 4896d74b Jan Kiszka
                   !mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
1571 4896d74b Jan Kiszka
                                                                      : '-',
1572 314e2987 Blue Swirl
                   mr->name,
1573 314e2987 Blue Swirl
                   mr->alias->name,
1574 314e2987 Blue Swirl
                   mr->alias_offset,
1575 08dafab4 Avi Kivity
                   mr->alias_offset
1576 08dafab4 Avi Kivity
                   + (target_phys_addr_t)int128_get64(mr->size) - 1);
1577 314e2987 Blue Swirl
    } else {
1578 4896d74b Jan Kiszka
        mon_printf(f,
1579 4896d74b Jan Kiszka
                   TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %c%c): %s\n",
1580 314e2987 Blue Swirl
                   base + mr->addr,
1581 08dafab4 Avi Kivity
                   base + mr->addr
1582 08dafab4 Avi Kivity
                   + (target_phys_addr_t)int128_get64(mr->size) - 1,
1583 4b474ba7 Jan Kiszka
                   mr->priority,
1584 4896d74b Jan Kiszka
                   mr->readable ? 'R' : '-',
1585 4896d74b Jan Kiszka
                   !mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
1586 4896d74b Jan Kiszka
                                                                      : '-',
1587 314e2987 Blue Swirl
                   mr->name);
1588 314e2987 Blue Swirl
    }
1589 9479c57a Jan Kiszka
1590 9479c57a Jan Kiszka
    QTAILQ_INIT(&submr_print_queue);
1591 9479c57a Jan Kiszka
1592 314e2987 Blue Swirl
    QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {
1593 9479c57a Jan Kiszka
        new_ml = g_new(MemoryRegionList, 1);
1594 9479c57a Jan Kiszka
        new_ml->mr = submr;
1595 9479c57a Jan Kiszka
        QTAILQ_FOREACH(ml, &submr_print_queue, queue) {
1596 9479c57a Jan Kiszka
            if (new_ml->mr->addr < ml->mr->addr ||
1597 9479c57a Jan Kiszka
                (new_ml->mr->addr == ml->mr->addr &&
1598 9479c57a Jan Kiszka
                 new_ml->mr->priority > ml->mr->priority)) {
1599 9479c57a Jan Kiszka
                QTAILQ_INSERT_BEFORE(ml, new_ml, queue);
1600 9479c57a Jan Kiszka
                new_ml = NULL;
1601 9479c57a Jan Kiszka
                break;
1602 9479c57a Jan Kiszka
            }
1603 9479c57a Jan Kiszka
        }
1604 9479c57a Jan Kiszka
        if (new_ml) {
1605 9479c57a Jan Kiszka
            QTAILQ_INSERT_TAIL(&submr_print_queue, new_ml, queue);
1606 9479c57a Jan Kiszka
        }
1607 9479c57a Jan Kiszka
    }
1608 9479c57a Jan Kiszka
1609 9479c57a Jan Kiszka
    QTAILQ_FOREACH(ml, &submr_print_queue, queue) {
1610 9479c57a Jan Kiszka
        mtree_print_mr(mon_printf, f, ml->mr, level + 1, base + mr->addr,
1611 9479c57a Jan Kiszka
                       alias_print_queue);
1612 9479c57a Jan Kiszka
    }
1613 9479c57a Jan Kiszka
1614 88365e47 Avi Kivity
    QTAILQ_FOREACH_SAFE(ml, &submr_print_queue, queue, next_ml) {
1615 9479c57a Jan Kiszka
        g_free(ml);
1616 314e2987 Blue Swirl
    }
1617 314e2987 Blue Swirl
}
1618 314e2987 Blue Swirl
1619 314e2987 Blue Swirl
void mtree_info(fprintf_function mon_printf, void *f)
1620 314e2987 Blue Swirl
{
1621 314e2987 Blue Swirl
    MemoryRegionListHead ml_head;
1622 314e2987 Blue Swirl
    MemoryRegionList *ml, *ml2;
1623 314e2987 Blue Swirl
1624 314e2987 Blue Swirl
    QTAILQ_INIT(&ml_head);
1625 314e2987 Blue Swirl
1626 314e2987 Blue Swirl
    mon_printf(f, "memory\n");
1627 314e2987 Blue Swirl
    mtree_print_mr(mon_printf, f, address_space_memory.root, 0, 0, &ml_head);
1628 314e2987 Blue Swirl
1629 b9f9be88 Blue Swirl
    if (address_space_io.root &&
1630 b9f9be88 Blue Swirl
        !QTAILQ_EMPTY(&address_space_io.root->subregions)) {
1631 b9f9be88 Blue Swirl
        mon_printf(f, "I/O\n");
1632 b9f9be88 Blue Swirl
        mtree_print_mr(mon_printf, f, address_space_io.root, 0, 0, &ml_head);
1633 b9f9be88 Blue Swirl
    }
1634 b9f9be88 Blue Swirl
1635 b9f9be88 Blue Swirl
    mon_printf(f, "aliases\n");
1636 314e2987 Blue Swirl
    /* print aliased regions */
1637 314e2987 Blue Swirl
    QTAILQ_FOREACH(ml, &ml_head, queue) {
1638 314e2987 Blue Swirl
        if (!ml->printed) {
1639 314e2987 Blue Swirl
            mon_printf(f, "%s\n", ml->mr->name);
1640 314e2987 Blue Swirl
            mtree_print_mr(mon_printf, f, ml->mr, 0, 0, &ml_head);
1641 314e2987 Blue Swirl
        }
1642 314e2987 Blue Swirl
    }
1643 314e2987 Blue Swirl
1644 314e2987 Blue Swirl
    QTAILQ_FOREACH_SAFE(ml, &ml_head, queue, ml2) {
1645 88365e47 Avi Kivity
        g_free(ml);
1646 314e2987 Blue Swirl
    }
1647 314e2987 Blue Swirl
}