qemu/memory.c
<<
>>
Prefs
   1/*
   2 * Physical memory management
   3 *
   4 * Copyright 2011 Red Hat, Inc. and/or its affiliates
   5 *
   6 * Authors:
   7 *  Avi Kivity <avi@redhat.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2.  See
  10 * the COPYING file in the top-level directory.
  11 *
  12 * Contributions after 2012-01-13 are licensed under the terms of the
  13 * GNU GPL, version 2 or (at your option) any later version.
  14 */
  15
  16#include "exec/memory.h"
  17#include "exec/address-spaces.h"
  18#include "exec/ioport.h"
  19#include "qapi/visitor.h"
  20#include "qemu/bitops.h"
  21#include "qom/object.h"
  22#include "trace.h"
  23#include <assert.h>
  24
  25#include "exec/memory-internal.h"
  26#include "exec/ram_addr.h"
  27#include "sysemu/sysemu.h"
  28
  29//#define DEBUG_UNASSIGNED
  30
  31static unsigned memory_region_transaction_depth;
  32static bool memory_region_update_pending;
  33static bool ioeventfd_update_pending;
  34static bool global_dirty_log = false;
  35
  36/* flat_view_mutex is taken around reading as->current_map; the critical
  37 * section is extremely short, so I'm using a single mutex for every AS.
  38 * We could also RCU for the read-side.
  39 *
  40 * The BQL is taken around transaction commits, hence both locks are taken
  41 * while writing to as->current_map (with the BQL taken outside).
  42 */
  43static QemuMutex flat_view_mutex;
  44
  45static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
  46    = QTAILQ_HEAD_INITIALIZER(memory_listeners);
  47
  48static QTAILQ_HEAD(, AddressSpace) address_spaces
  49    = QTAILQ_HEAD_INITIALIZER(address_spaces);
  50
  51static void memory_init(void)
  52{
  53    qemu_mutex_init(&flat_view_mutex);
  54}
  55
  56typedef struct AddrRange AddrRange;
  57
  58/*
  59 * Note that signed integers are needed for negative offsetting in aliases
  60 * (large MemoryRegion::alias_offset).
  61 */
  62struct AddrRange {
  63    Int128 start;
  64    Int128 size;
  65};
  66
  67static AddrRange addrrange_make(Int128 start, Int128 size)
  68{
  69    return (AddrRange) { start, size };
  70}
  71
  72static bool addrrange_equal(AddrRange r1, AddrRange r2)
  73{
  74    return int128_eq(r1.start, r2.start) && int128_eq(r1.size, r2.size);
  75}
  76
  77static Int128 addrrange_end(AddrRange r)
  78{
  79    return int128_add(r.start, r.size);
  80}
  81
  82static AddrRange addrrange_shift(AddrRange range, Int128 delta)
  83{
  84    int128_addto(&range.start, delta);
  85    return range;
  86}
  87
  88static bool addrrange_contains(AddrRange range, Int128 addr)
  89{
  90    return int128_ge(addr, range.start)
  91        && int128_lt(addr, addrrange_end(range));
  92}
  93
  94static bool addrrange_intersects(AddrRange r1, AddrRange r2)
  95{
  96    return addrrange_contains(r1, r2.start)
  97        || addrrange_contains(r2, r1.start);
  98}
  99
 100static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2)
 101{
 102    Int128 start = int128_max(r1.start, r2.start);
 103    Int128 end = int128_min(addrrange_end(r1), addrrange_end(r2));
 104    return addrrange_make(start, int128_sub(end, start));
 105}
 106
 107enum ListenerDirection { Forward, Reverse };
 108
 109static bool memory_listener_match(MemoryListener *listener,
 110                                  MemoryRegionSection *section)
 111{
 112    return !listener->address_space_filter
 113        || listener->address_space_filter == section->address_space;
 114}
 115
 116#define MEMORY_LISTENER_CALL_GLOBAL(_callback, _direction, _args...)    \
 117    do {                                                                \
 118        MemoryListener *_listener;                                      \
 119                                                                        \
 120        switch (_direction) {                                           \
 121        case Forward:                                                   \
 122            QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
 123                if (_listener->_callback) {                             \
 124                    _listener->_callback(_listener, ##_args);           \
 125                }                                                       \
 126            }                                                           \
 127            break;                                                      \
 128        case Reverse:                                                   \
 129            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
 130                                   memory_listeners, link) {            \
 131                if (_listener->_callback) {                             \
 132                    _listener->_callback(_listener, ##_args);           \
 133                }                                                       \
 134            }                                                           \
 135            break;                                                      \
 136        default:                                                        \
 137            abort();                                                    \
 138        }                                                               \
 139    } while (0)
 140
 141#define MEMORY_LISTENER_CALL(_callback, _direction, _section, _args...) \
 142    do {                                                                \
 143        MemoryListener *_listener;                                      \
 144                                                                        \
 145        switch (_direction) {                                           \
 146        case Forward:                                                   \
 147            QTAILQ_FOREACH(_listener, &memory_listeners, link) {        \
 148                if (_listener->_callback                                \
 149                    && memory_listener_match(_listener, _section)) {    \
 150                    _listener->_callback(_listener, _section, ##_args); \
 151                }                                                       \
 152            }                                                           \
 153            break;                                                      \
 154        case Reverse:                                                   \
 155            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
 156                                   memory_listeners, link) {            \
 157                if (_listener->_callback                                \
 158                    && memory_listener_match(_listener, _section)) {    \
 159                    _listener->_callback(_listener, _section, ##_args); \
 160                }                                                       \
 161            }                                                           \
 162            break;                                                      \
 163        default:                                                        \
 164            abort();                                                    \
 165        }                                                               \
 166    } while (0)
 167
 168/* No need to ref/unref .mr, the FlatRange keeps it alive.  */
 169#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback)            \
 170    MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) {       \
 171        .mr = (fr)->mr,                                                 \
 172        .address_space = (as),                                          \
 173        .offset_within_region = (fr)->offset_in_region,                 \
 174        .size = (fr)->addr.size,                                        \
 175        .offset_within_address_space = int128_get64((fr)->addr.start),  \
 176        .readonly = (fr)->readonly,                                     \
 177              }))
 178
 179struct CoalescedMemoryRange {
 180    AddrRange addr;
 181    QTAILQ_ENTRY(CoalescedMemoryRange) link;
 182};
 183
 184struct MemoryRegionIoeventfd {
 185    AddrRange addr;
 186    bool match_data;
 187    uint64_t data;
 188    EventNotifier *e;
 189};
 190
 191static bool memory_region_ioeventfd_before(MemoryRegionIoeventfd a,
 192                                           MemoryRegionIoeventfd b)
 193{
 194    if (int128_lt(a.addr.start, b.addr.start)) {
 195        return true;
 196    } else if (int128_gt(a.addr.start, b.addr.start)) {
 197        return false;
 198    } else if (int128_lt(a.addr.size, b.addr.size)) {
 199        return true;
 200    } else if (int128_gt(a.addr.size, b.addr.size)) {
 201        return false;
 202    } else if (a.match_data < b.match_data) {
 203        return true;
 204    } else  if (a.match_data > b.match_data) {
 205        return false;
 206    } else if (a.match_data) {
 207        if (a.data < b.data) {
 208            return true;
 209        } else if (a.data > b.data) {
 210            return false;
 211        }
 212    }
 213    if (a.e < b.e) {
 214        return true;
 215    } else if (a.e > b.e) {
 216        return false;
 217    }
 218    return false;
 219}
 220
 221static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd a,
 222                                          MemoryRegionIoeventfd b)
 223{
 224    return !memory_region_ioeventfd_before(a, b)
 225        && !memory_region_ioeventfd_before(b, a);
 226}
 227
 228typedef struct FlatRange FlatRange;
 229typedef struct FlatView FlatView;
 230
 231/* Range of memory in the global map.  Addresses are absolute. */
 232struct FlatRange {
 233    MemoryRegion *mr;
 234    hwaddr offset_in_region;
 235    AddrRange addr;
 236    uint8_t dirty_log_mask;
 237    bool romd_mode;
 238    bool readonly;
 239};
 240
 241/* Flattened global view of current active memory hierarchy.  Kept in sorted
 242 * order.
 243 */
 244struct FlatView {
 245    unsigned ref;
 246    FlatRange *ranges;
 247    unsigned nr;
 248    unsigned nr_allocated;
 249};
 250
 251typedef struct AddressSpaceOps AddressSpaceOps;
 252
 253#define FOR_EACH_FLAT_RANGE(var, view)          \
 254    for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var)
 255
 256static bool flatrange_equal(FlatRange *a, FlatRange *b)
 257{
 258    return a->mr == b->mr
 259        && addrrange_equal(a->addr, b->addr)
 260        && a->offset_in_region == b->offset_in_region
 261        && a->romd_mode == b->romd_mode
 262        && a->readonly == b->readonly;
 263}
 264
 265static void flatview_init(FlatView *view)
 266{
 267    view->ref = 1;
 268    view->ranges = NULL;
 269    view->nr = 0;
 270    view->nr_allocated = 0;
 271}
 272
 273/* Insert a range into a given position.  Caller is responsible for maintaining
 274 * sorting order.
 275 */
 276static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range)
 277{
 278    if (view->nr == view->nr_allocated) {
 279        view->nr_allocated = MAX(2 * view->nr, 10);
 280        view->ranges = g_realloc(view->ranges,
 281                                    view->nr_allocated * sizeof(*view->ranges));
 282    }
 283    memmove(view->ranges + pos + 1, view->ranges + pos,
 284            (view->nr - pos) * sizeof(FlatRange));
 285    view->ranges[pos] = *range;
 286    memory_region_ref(range->mr);
 287    ++view->nr;
 288}
 289
 290static void flatview_destroy(FlatView *view)
 291{
 292    int i;
 293
 294    for (i = 0; i < view->nr; i++) {
 295        memory_region_unref(view->ranges[i].mr);
 296    }
 297    g_free(view->ranges);
 298    g_free(view);
 299}
 300
 301static void flatview_ref(FlatView *view)
 302{
 303    atomic_inc(&view->ref);
 304}
 305
 306static void flatview_unref(FlatView *view)
 307{
 308    if (atomic_fetch_dec(&view->ref) == 1) {
 309        flatview_destroy(view);
 310    }
 311}
 312
 313static bool can_merge(FlatRange *r1, FlatRange *r2)
 314{
 315    return int128_eq(addrrange_end(r1->addr), r2->addr.start)
 316        && r1->mr == r2->mr
 317        && int128_eq(int128_add(int128_make64(r1->offset_in_region),
 318                                r1->addr.size),
 319                     int128_make64(r2->offset_in_region))
 320        && r1->dirty_log_mask == r2->dirty_log_mask
 321        && r1->romd_mode == r2->romd_mode
 322        && r1->readonly == r2->readonly;
 323}
 324
 325/* Attempt to simplify a view by merging adjacent ranges */
 326static void flatview_simplify(FlatView *view)
 327{
 328    unsigned i, j;
 329
 330    i = 0;
 331    while (i < view->nr) {
 332        j = i + 1;
 333        while (j < view->nr
 334               && can_merge(&view->ranges[j-1], &view->ranges[j])) {
 335            int128_addto(&view->ranges[i].addr.size, view->ranges[j].addr.size);
 336            ++j;
 337        }
 338        ++i;
 339        memmove(&view->ranges[i], &view->ranges[j],
 340                (view->nr - j) * sizeof(view->ranges[j]));
 341        view->nr -= j - i;
 342    }
 343}
 344
 345static bool memory_region_big_endian(MemoryRegion *mr)
 346{
 347#ifdef TARGET_WORDS_BIGENDIAN
 348    return mr->ops->endianness != DEVICE_LITTLE_ENDIAN;
 349#else
 350    return mr->ops->endianness == DEVICE_BIG_ENDIAN;
 351#endif
 352}
 353
 354static bool memory_region_wrong_endianness(MemoryRegion *mr)
 355{
 356#ifdef TARGET_WORDS_BIGENDIAN
 357    return mr->ops->endianness == DEVICE_LITTLE_ENDIAN;
 358#else
 359    return mr->ops->endianness == DEVICE_BIG_ENDIAN;
 360#endif
 361}
 362
 363static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size)
 364{
 365    if (memory_region_wrong_endianness(mr)) {
 366        switch (size) {
 367        case 1:
 368            break;
 369        case 2:
 370            *data = bswap16(*data);
 371            break;
 372        case 4:
 373            *data = bswap32(*data);
 374            break;
 375        case 8:
 376            *data = bswap64(*data);
 377            break;
 378        default:
 379            abort();
 380        }
 381    }
 382}
 383
 384static void memory_region_oldmmio_read_accessor(MemoryRegion *mr,
 385                                                hwaddr addr,
 386                                                uint64_t *value,
 387                                                unsigned size,
 388                                                unsigned shift,
 389                                                uint64_t mask)
 390{
 391    uint64_t tmp;
 392
 393    tmp = mr->ops->old_mmio.read[ctz32(size)](mr->opaque, addr);
 394    trace_memory_region_ops_read(mr, addr, tmp, size);
 395    *value |= (tmp & mask) << shift;
 396}
 397
 398static void memory_region_read_accessor(MemoryRegion *mr,
 399                                        hwaddr addr,
 400                                        uint64_t *value,
 401                                        unsigned size,
 402                                        unsigned shift,
 403                                        uint64_t mask)
 404{
 405    uint64_t tmp;
 406
 407    if (mr->flush_coalesced_mmio) {
 408        qemu_flush_coalesced_mmio_buffer();
 409    }
 410    tmp = mr->ops->read(mr->opaque, addr, size);
 411    trace_memory_region_ops_read(mr, addr, tmp, size);
 412    *value |= (tmp & mask) << shift;
 413}
 414
 415static void memory_region_oldmmio_write_accessor(MemoryRegion *mr,
 416                                                 hwaddr addr,
 417                                                 uint64_t *value,
 418                                                 unsigned size,
 419                                                 unsigned shift,
 420                                                 uint64_t mask)
 421{
 422    uint64_t tmp;
 423
 424    tmp = (*value >> shift) & mask;
 425    trace_memory_region_ops_write(mr, addr, tmp, size);
 426    mr->ops->old_mmio.write[ctz32(size)](mr->opaque, addr, tmp);
 427}
 428
 429static void memory_region_write_accessor(MemoryRegion *mr,
 430                                         hwaddr addr,
 431                                         uint64_t *value,
 432                                         unsigned size,
 433                                         unsigned shift,
 434                                         uint64_t mask)
 435{
 436    uint64_t tmp;
 437
 438    if (mr->flush_coalesced_mmio) {
 439        qemu_flush_coalesced_mmio_buffer();
 440    }
 441    tmp = (*value >> shift) & mask;
 442    trace_memory_region_ops_write(mr, addr, tmp, size);
 443    mr->ops->write(mr->opaque, addr, tmp, size);
 444}
 445
 446static void access_with_adjusted_size(hwaddr addr,
 447                                      uint64_t *value,
 448                                      unsigned size,
 449                                      unsigned access_size_min,
 450                                      unsigned access_size_max,
 451                                      void (*access)(MemoryRegion *mr,
 452                                                     hwaddr addr,
 453                                                     uint64_t *value,
 454                                                     unsigned size,
 455                                                     unsigned shift,
 456                                                     uint64_t mask),
 457                                      MemoryRegion *mr)
 458{
 459    uint64_t access_mask;
 460    unsigned access_size;
 461    unsigned i;
 462
 463    if (!access_size_min) {
 464        access_size_min = 1;
 465    }
 466    if (!access_size_max) {
 467        access_size_max = 4;
 468    }
 469
 470    /* FIXME: support unaligned access? */
 471    access_size = MAX(MIN(size, access_size_max), access_size_min);
 472    access_mask = -1ULL >> (64 - access_size * 8);
 473    if (memory_region_big_endian(mr)) {
 474        for (i = 0; i < size; i += access_size) {
 475            access(mr, addr + i, value, access_size,
 476                   (size - access_size - i) * 8, access_mask);
 477        }
 478    } else {
 479        for (i = 0; i < size; i += access_size) {
 480            access(mr, addr + i, value, access_size, i * 8, access_mask);
 481        }
 482    }
 483}
 484
 485static AddressSpace *memory_region_to_address_space(MemoryRegion *mr)
 486{
 487    AddressSpace *as;
 488
 489    while (mr->container) {
 490        mr = mr->container;
 491    }
 492    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
 493        if (mr == as->root) {
 494            return as;
 495        }
 496    }
 497    return NULL;
 498}
 499
 500/* Render a memory region into the global view.  Ranges in @view obscure
 501 * ranges in @mr.
 502 */
 503static void render_memory_region(FlatView *view,
 504                                 MemoryRegion *mr,
 505                                 Int128 base,
 506                                 AddrRange clip,
 507                                 bool readonly)
 508{
 509    MemoryRegion *subregion;
 510    unsigned i;
 511    hwaddr offset_in_region;
 512    Int128 remain;
 513    Int128 now;
 514    FlatRange fr;
 515    AddrRange tmp;
 516
 517    if (!mr->enabled) {
 518        return;
 519    }
 520
 521    int128_addto(&base, int128_make64(mr->addr));
 522    readonly |= mr->readonly;
 523
 524    tmp = addrrange_make(base, mr->size);
 525
 526    if (!addrrange_intersects(tmp, clip)) {
 527        return;
 528    }
 529
 530    clip = addrrange_intersection(tmp, clip);
 531
 532    if (mr->alias) {
 533        int128_subfrom(&base, int128_make64(mr->alias->addr));
 534        int128_subfrom(&base, int128_make64(mr->alias_offset));
 535        render_memory_region(view, mr->alias, base, clip, readonly);
 536        return;
 537    }
 538
 539    /* Render subregions in priority order. */
 540    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {
 541        render_memory_region(view, subregion, base, clip, readonly);
 542    }
 543
 544    if (!mr->terminates) {
 545        return;
 546    }
 547
 548    offset_in_region = int128_get64(int128_sub(clip.start, base));
 549    base = clip.start;
 550    remain = clip.size;
 551
 552    fr.mr = mr;
 553    fr.dirty_log_mask = mr->dirty_log_mask;
 554    fr.romd_mode = mr->romd_mode;
 555    fr.readonly = readonly;
 556
 557    /* Render the region itself into any gaps left by the current view. */
 558    for (i = 0; i < view->nr && int128_nz(remain); ++i) {
 559        if (int128_ge(base, addrrange_end(view->ranges[i].addr))) {
 560            continue;
 561        }
 562        if (int128_lt(base, view->ranges[i].addr.start)) {
 563            now = int128_min(remain,
 564                             int128_sub(view->ranges[i].addr.start, base));
 565            fr.offset_in_region = offset_in_region;
 566            fr.addr = addrrange_make(base, now);
 567            flatview_insert(view, i, &fr);
 568            ++i;
 569            int128_addto(&base, now);
 570            offset_in_region += int128_get64(now);
 571            int128_subfrom(&remain, now);
 572        }
 573        now = int128_sub(int128_min(int128_add(base, remain),
 574                                    addrrange_end(view->ranges[i].addr)),
 575                         base);
 576        int128_addto(&base, now);
 577        offset_in_region += int128_get64(now);
 578        int128_subfrom(&remain, now);
 579    }
 580    if (int128_nz(remain)) {
 581        fr.offset_in_region = offset_in_region;
 582        fr.addr = addrrange_make(base, remain);
 583        flatview_insert(view, i, &fr);
 584    }
 585}
 586
 587/* Render a memory topology into a list of disjoint absolute ranges. */
 588static FlatView *generate_memory_topology(MemoryRegion *mr)
 589{
 590    FlatView *view;
 591
 592    view = g_new(FlatView, 1);
 593    flatview_init(view);
 594
 595    if (mr) {
 596        render_memory_region(view, mr, int128_zero(),
 597                             addrrange_make(int128_zero(), int128_2_64()), false);
 598    }
 599    flatview_simplify(view);
 600
 601    return view;
 602}
 603
 604static void address_space_add_del_ioeventfds(AddressSpace *as,
 605                                             MemoryRegionIoeventfd *fds_new,
 606                                             unsigned fds_new_nb,
 607                                             MemoryRegionIoeventfd *fds_old,
 608                                             unsigned fds_old_nb)
 609{
 610    unsigned iold, inew;
 611    MemoryRegionIoeventfd *fd;
 612    MemoryRegionSection section;
 613
 614    /* Generate a symmetric difference of the old and new fd sets, adding
 615     * and deleting as necessary.
 616     */
 617
 618    iold = inew = 0;
 619    while (iold < fds_old_nb || inew < fds_new_nb) {
 620        if (iold < fds_old_nb
 621            && (inew == fds_new_nb
 622                || memory_region_ioeventfd_before(fds_old[iold],
 623                                                  fds_new[inew]))) {
 624            fd = &fds_old[iold];
 625            section = (MemoryRegionSection) {
 626                .address_space = as,
 627                .offset_within_address_space = int128_get64(fd->addr.start),
 628                .size = fd->addr.size,
 629            };
 630            MEMORY_LISTENER_CALL(eventfd_del, Forward, &section,
 631                                 fd->match_data, fd->data, fd->e);
 632            ++iold;
 633        } else if (inew < fds_new_nb
 634                   && (iold == fds_old_nb
 635                       || memory_region_ioeventfd_before(fds_new[inew],
 636                                                         fds_old[iold]))) {
 637            fd = &fds_new[inew];
 638            section = (MemoryRegionSection) {
 639                .address_space = as,
 640                .offset_within_address_space = int128_get64(fd->addr.start),
 641                .size = fd->addr.size,
 642            };
 643            MEMORY_LISTENER_CALL(eventfd_add, Reverse, &section,
 644                                 fd->match_data, fd->data, fd->e);
 645            ++inew;
 646        } else {
 647            ++iold;
 648            ++inew;
 649        }
 650    }
 651}
 652
 653static FlatView *address_space_get_flatview(AddressSpace *as)
 654{
 655    FlatView *view;
 656
 657    qemu_mutex_lock(&flat_view_mutex);
 658    view = as->current_map;
 659    flatview_ref(view);
 660    qemu_mutex_unlock(&flat_view_mutex);
 661    return view;
 662}
 663
 664static void address_space_update_ioeventfds(AddressSpace *as)
 665{
 666    FlatView *view;
 667    FlatRange *fr;
 668    unsigned ioeventfd_nb = 0;
 669    MemoryRegionIoeventfd *ioeventfds = NULL;
 670    AddrRange tmp;
 671    unsigned i;
 672
 673    view = address_space_get_flatview(as);
 674    FOR_EACH_FLAT_RANGE(fr, view) {
 675        for (i = 0; i < fr->mr->ioeventfd_nb; ++i) {
 676            tmp = addrrange_shift(fr->mr->ioeventfds[i].addr,
 677                                  int128_sub(fr->addr.start,
 678                                             int128_make64(fr->offset_in_region)));
 679            if (addrrange_intersects(fr->addr, tmp)) {
 680                ++ioeventfd_nb;
 681                ioeventfds = g_realloc(ioeventfds,
 682                                          ioeventfd_nb * sizeof(*ioeventfds));
 683                ioeventfds[ioeventfd_nb-1] = fr->mr->ioeventfds[i];
 684                ioeventfds[ioeventfd_nb-1].addr = tmp;
 685            }
 686        }
 687    }
 688
 689    address_space_add_del_ioeventfds(as, ioeventfds, ioeventfd_nb,
 690                                     as->ioeventfds, as->ioeventfd_nb);
 691
 692    g_free(as->ioeventfds);
 693    as->ioeventfds = ioeventfds;
 694    as->ioeventfd_nb = ioeventfd_nb;
 695    flatview_unref(view);
 696}
 697
 698static void address_space_update_topology_pass(AddressSpace *as,
 699                                               const FlatView *old_view,
 700                                               const FlatView *new_view,
 701                                               bool adding)
 702{
 703    unsigned iold, inew;
 704    FlatRange *frold, *frnew;
 705
 706    /* Generate a symmetric difference of the old and new memory maps.
 707     * Kill ranges in the old map, and instantiate ranges in the new map.
 708     */
 709    iold = inew = 0;
 710    while (iold < old_view->nr || inew < new_view->nr) {
 711        if (iold < old_view->nr) {
 712            frold = &old_view->ranges[iold];
 713        } else {
 714            frold = NULL;
 715        }
 716        if (inew < new_view->nr) {
 717            frnew = &new_view->ranges[inew];
 718        } else {
 719            frnew = NULL;
 720        }
 721
 722        if (frold
 723            && (!frnew
 724                || int128_lt(frold->addr.start, frnew->addr.start)
 725                || (int128_eq(frold->addr.start, frnew->addr.start)
 726                    && !flatrange_equal(frold, frnew)))) {
 727            /* In old but not in new, or in both but attributes changed. */
 728
 729            if (!adding) {
 730                MEMORY_LISTENER_UPDATE_REGION(frold, as, Reverse, region_del);
 731            }
 732
 733            ++iold;
 734        } else if (frold && frnew && flatrange_equal(frold, frnew)) {
 735            /* In both and unchanged (except logging may have changed) */
 736
 737            if (adding) {
 738                MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_nop);
 739                if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
 740                    MEMORY_LISTENER_UPDATE_REGION(frnew, as, Reverse, log_stop);
 741                } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
 742                    MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, log_start);
 743                }
 744            }
 745
 746            ++iold;
 747            ++inew;
 748        } else {
 749            /* In new */
 750
 751            if (adding) {
 752                MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_add);
 753            }
 754
 755            ++inew;
 756        }
 757    }
 758}
 759
 760
 761static void address_space_update_topology(AddressSpace *as)
 762{
 763    FlatView *old_view = address_space_get_flatview(as);
 764    FlatView *new_view = generate_memory_topology(as->root);
 765
 766    address_space_update_topology_pass(as, old_view, new_view, false);
 767    address_space_update_topology_pass(as, old_view, new_view, true);
 768
 769    qemu_mutex_lock(&flat_view_mutex);
 770    flatview_unref(as->current_map);
 771    as->current_map = new_view;
 772    qemu_mutex_unlock(&flat_view_mutex);
 773
 774    /* Note that all the old MemoryRegions are still alive up to this
 775     * point.  This relieves most MemoryListeners from the need to
 776     * ref/unref the MemoryRegions they get---unless they use them
 777     * outside the iothread mutex, in which case precise reference
 778     * counting is necessary.
 779     */
 780    flatview_unref(old_view);
 781
 782    address_space_update_ioeventfds(as);
 783}
 784
 785void memory_region_transaction_begin(void)
 786{
 787    qemu_flush_coalesced_mmio_buffer();
 788    ++memory_region_transaction_depth;
 789}
 790
 791static void memory_region_clear_pending(void)
 792{
 793    memory_region_update_pending = false;
 794    ioeventfd_update_pending = false;
 795}
 796
 797void memory_region_transaction_commit(void)
 798{
 799    AddressSpace *as;
 800
 801    assert(memory_region_transaction_depth);
 802    --memory_region_transaction_depth;
 803    if (!memory_region_transaction_depth) {
 804        if (memory_region_update_pending) {
 805            MEMORY_LISTENER_CALL_GLOBAL(begin, Forward);
 806
 807            QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
 808                address_space_update_topology(as);
 809            }
 810
 811            MEMORY_LISTENER_CALL_GLOBAL(commit, Forward);
 812        } else if (ioeventfd_update_pending) {
 813            QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
 814                address_space_update_ioeventfds(as);
 815            }
 816        }
 817        memory_region_clear_pending();
 818   }
 819}
 820
 821static void memory_region_destructor_none(MemoryRegion *mr)
 822{
 823}
 824
 825static void memory_region_destructor_ram(MemoryRegion *mr)
 826{
 827    qemu_ram_free(mr->ram_addr);
 828}
 829
 830static void memory_region_destructor_alias(MemoryRegion *mr)
 831{
 832    memory_region_unref(mr->alias);
 833}
 834
 835static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
 836{
 837    qemu_ram_free_from_ptr(mr->ram_addr);
 838}
 839
 840static void memory_region_destructor_rom_device(MemoryRegion *mr)
 841{
 842    qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
 843}
 844
 845static bool memory_region_need_escape(char c)
 846{
 847    return c == '/' || c == '[' || c == '\\' || c == ']';
 848}
 849
 850static char *memory_region_escape_name(const char *name)
 851{
 852    const char *p;
 853    char *escaped, *q;
 854    uint8_t c;
 855    size_t bytes = 0;
 856
 857    for (p = name; *p; p++) {
 858        bytes += memory_region_need_escape(*p) ? 4 : 1;
 859    }
 860    if (bytes == p - name) {
 861       return g_memdup(name, bytes + 1);
 862    }
 863
 864    escaped = g_malloc(bytes + 1);
 865    for (p = name, q = escaped; *p; p++) {
 866        c = *p;
 867        if (unlikely(memory_region_need_escape(c))) {
 868            *q++ = '\\';
 869            *q++ = 'x';
 870            *q++ = "0123456789abcdef"[c >> 4];
 871            c = "0123456789abcdef"[c & 15];
 872        }
 873        *q++ = c;
 874    }
 875    *q = 0;
 876    return escaped;
 877}
 878
 879void memory_region_init(MemoryRegion *mr,
 880                        Object *owner,
 881                        const char *name,
 882                        uint64_t size)
 883{
 884    if (!owner) {
 885        owner = qdev_get_machine();
 886    }
 887
 888    object_initialize(mr, sizeof(*mr), TYPE_MEMORY_REGION);
 889    mr->size = int128_make64(size);
 890    if (size == UINT64_MAX) {
 891        mr->size = int128_2_64();
 892    }
 893    mr->name = g_strdup(name);
 894
 895    if (name) {
 896        char *escaped_name = memory_region_escape_name(name);
 897        char *name_array = g_strdup_printf("%s[*]", escaped_name);
 898        object_property_add_child(owner, name_array, OBJECT(mr), &error_abort);
 899        object_unref(OBJECT(mr));
 900        g_free(name_array);
 901        g_free(escaped_name);
 902    }
 903}
 904
 905static void memory_region_get_addr(Object *obj, Visitor *v, void *opaque,
 906                                   const char *name, Error **errp)
 907{
 908    MemoryRegion *mr = MEMORY_REGION(obj);
 909    uint64_t value = mr->addr;
 910
 911    visit_type_uint64(v, &value, name, errp);
 912}
 913
 914static void memory_region_get_container(Object *obj, Visitor *v, void *opaque,
 915                                        const char *name, Error **errp)
 916{
 917    MemoryRegion *mr = MEMORY_REGION(obj);
 918    gchar *path = (gchar *)"";
 919
 920    if (mr->container) {
 921        path = object_get_canonical_path(OBJECT(mr->container));
 922    }
 923    visit_type_str(v, &path, name, errp);
 924    if (mr->container) {
 925        g_free(path);
 926    }
 927}
 928
 929static Object *memory_region_resolve_container(Object *obj, void *opaque,
 930                                               const char *part)
 931{
 932    MemoryRegion *mr = MEMORY_REGION(obj);
 933
 934    return OBJECT(mr->container);
 935}
 936
 937static void memory_region_get_priority(Object *obj, Visitor *v, void *opaque,
 938                                       const char *name, Error **errp)
 939{
 940    MemoryRegion *mr = MEMORY_REGION(obj);
 941    int32_t value = mr->priority;
 942
 943    visit_type_int32(v, &value, name, errp);
 944}
 945
 946static bool memory_region_get_may_overlap(Object *obj, Error **errp)
 947{
 948    MemoryRegion *mr = MEMORY_REGION(obj);
 949
 950    return mr->may_overlap;
 951}
 952
 953static void memory_region_get_size(Object *obj, Visitor *v, void *opaque,
 954                                   const char *name, Error **errp)
 955{
 956    MemoryRegion *mr = MEMORY_REGION(obj);
 957    uint64_t value = memory_region_size(mr);
 958
 959    visit_type_uint64(v, &value, name, errp);
 960}
 961
 962static void memory_region_initfn(Object *obj)
 963{
 964    MemoryRegion *mr = MEMORY_REGION(obj);
 965    ObjectProperty *op;
 966
 967    mr->ops = &unassigned_mem_ops;
 968    mr->enabled = true;
 969    mr->romd_mode = true;
 970    mr->destructor = memory_region_destructor_none;
 971    QTAILQ_INIT(&mr->subregions);
 972    QTAILQ_INIT(&mr->coalesced);
 973
 974    op = object_property_add(OBJECT(mr), "container",
 975                             "link<" TYPE_MEMORY_REGION ">",
 976                             memory_region_get_container,
 977                             NULL, /* memory_region_set_container */
 978                             NULL, NULL, &error_abort);
 979    op->resolve = memory_region_resolve_container;
 980
 981    object_property_add(OBJECT(mr), "addr", "uint64",
 982                        memory_region_get_addr,
 983                        NULL, /* memory_region_set_addr */
 984                        NULL, NULL, &error_abort);
 985    object_property_add(OBJECT(mr), "priority", "uint32",
 986                        memory_region_get_priority,
 987                        NULL, /* memory_region_set_priority */
 988                        NULL, NULL, &error_abort);
 989    object_property_add_bool(OBJECT(mr), "may-overlap",
 990                             memory_region_get_may_overlap,
 991                             NULL, /* memory_region_set_may_overlap */
 992                             &error_abort);
 993    object_property_add(OBJECT(mr), "size", "uint64",
 994                        memory_region_get_size,
 995                        NULL, /* memory_region_set_size, */
 996                        NULL, NULL, &error_abort);
 997}
 998
 999static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
1000                                    unsigned size)
1001{
1002#ifdef DEBUG_UNASSIGNED
1003    printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
1004#endif
1005    if (current_cpu != NULL) {
1006        cpu_unassigned_access(current_cpu, addr, false, false, 0, size);
1007    }
1008    return 0;
1009}
1010
1011static void unassigned_mem_write(void *opaque, hwaddr addr,
1012                                 uint64_t val, unsigned size)
1013{
1014#ifdef DEBUG_UNASSIGNED
1015    printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
1016#endif
1017    if (current_cpu != NULL) {
1018        cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
1019    }
1020}
1021
1022static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
1023                                   unsigned size, bool is_write)
1024{
1025    return false;
1026}
1027
1028const MemoryRegionOps unassigned_mem_ops = {
1029    .valid.accepts = unassigned_mem_accepts,
1030    .endianness = DEVICE_NATIVE_ENDIAN,
1031};
1032
1033bool memory_region_access_valid(MemoryRegion *mr,
1034                                hwaddr addr,
1035                                unsigned size,
1036                                bool is_write)
1037{
1038    int access_size_min, access_size_max;
1039    int access_size, i;
1040
1041    if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
1042        return false;
1043    }
1044
1045    if (!mr->ops->valid.accepts) {
1046        return true;
1047    }
1048
1049    access_size_min = mr->ops->valid.min_access_size;
1050    if (!mr->ops->valid.min_access_size) {
1051        access_size_min = 1;
1052    }
1053
1054    access_size_max = mr->ops->valid.max_access_size;
1055    if (!mr->ops->valid.max_access_size) {
1056        access_size_max = 4;
1057    }
1058
1059    access_size = MAX(MIN(size, access_size_max), access_size_min);
1060    for (i = 0; i < size; i += access_size) {
1061        if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
1062                                    is_write)) {
1063            return false;
1064        }
1065    }
1066
1067    return true;
1068}
1069
1070static uint64_t memory_region_dispatch_read1(MemoryRegion *mr,
1071                                             hwaddr addr,
1072                                             unsigned size)
1073{
1074    uint64_t data = 0;
1075
1076    if (mr->ops->read) {
1077        access_with_adjusted_size(addr, &data, size,
1078                                  mr->ops->impl.min_access_size,
1079                                  mr->ops->impl.max_access_size,
1080                                  memory_region_read_accessor, mr);
1081    } else {
1082        access_with_adjusted_size(addr, &data, size, 1, 4,
1083                                  memory_region_oldmmio_read_accessor, mr);
1084    }
1085
1086    return data;
1087}
1088
1089static bool memory_region_dispatch_read(MemoryRegion *mr,
1090                                        hwaddr addr,
1091                                        uint64_t *pval,
1092                                        unsigned size)
1093{
1094    if (!memory_region_access_valid(mr, addr, size, false)) {
1095        *pval = unassigned_mem_read(mr, addr, size);
1096        return true;
1097    }
1098
1099    *pval = memory_region_dispatch_read1(mr, addr, size);
1100    adjust_endianness(mr, pval, size);
1101    return false;
1102}
1103
1104static bool memory_region_dispatch_write(MemoryRegion *mr,
1105                                         hwaddr addr,
1106                                         uint64_t data,
1107                                         unsigned size)
1108{
1109    if (!memory_region_access_valid(mr, addr, size, true)) {
1110        unassigned_mem_write(mr, addr, data, size);
1111        return true;
1112    }
1113
1114    adjust_endianness(mr, &data, size);
1115
1116    if (mr->ops->write) {
1117        access_with_adjusted_size(addr, &data, size,
1118                                  mr->ops->impl.min_access_size,
1119                                  mr->ops->impl.max_access_size,
1120                                  memory_region_write_accessor, mr);
1121    } else {
1122        access_with_adjusted_size(addr, &data, size, 1, 4,
1123                                  memory_region_oldmmio_write_accessor, mr);
1124    }
1125    return false;
1126}
1127
1128void memory_region_init_io(MemoryRegion *mr,
1129                           Object *owner,
1130                           const MemoryRegionOps *ops,
1131                           void *opaque,
1132                           const char *name,
1133                           uint64_t size)
1134{
1135    memory_region_init(mr, owner, name, size);
1136    mr->ops = ops;
1137    mr->opaque = opaque;
1138    mr->terminates = true;
1139    mr->ram_addr = ~(ram_addr_t)0;
1140}
1141
1142void memory_region_init_ram(MemoryRegion *mr,
1143                            Object *owner,
1144                            const char *name,
1145                            uint64_t size,
1146                            Error **errp)
1147{
1148    memory_region_init(mr, owner, name, size);
1149    mr->ram = true;
1150    mr->terminates = true;
1151    mr->destructor = memory_region_destructor_ram;
1152    mr->ram_addr = qemu_ram_alloc(size, mr, errp);
1153}
1154
1155#ifdef __linux__
1156void memory_region_init_ram_from_file(MemoryRegion *mr,
1157                                      struct Object *owner,
1158                                      const char *name,
1159                                      uint64_t size,
1160                                      bool share,
1161                                      const char *path,
1162                                      Error **errp)
1163{
1164    memory_region_init(mr, owner, name, size);
1165    mr->ram = true;
1166    mr->terminates = true;
1167    mr->destructor = memory_region_destructor_ram;
1168    mr->ram_addr = qemu_ram_alloc_from_file(size, mr, share, path, errp);
1169}
1170#endif
1171
1172void memory_region_init_ram_ptr(MemoryRegion *mr,
1173                                Object *owner,
1174                                const char *name,
1175                                uint64_t size,
1176                                void *ptr)
1177{
1178    memory_region_init(mr, owner, name, size);
1179    mr->ram = true;
1180    mr->terminates = true;
1181    mr->destructor = memory_region_destructor_ram_from_ptr;
1182
1183    /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL.  */
1184    assert(ptr != NULL);
1185    mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_abort);
1186}
1187
1188void memory_region_set_skip_dump(MemoryRegion *mr)
1189{
1190    mr->skip_dump = true;
1191}
1192
1193void memory_region_init_alias(MemoryRegion *mr,
1194                              Object *owner,
1195                              const char *name,
1196                              MemoryRegion *orig,
1197                              hwaddr offset,
1198                              uint64_t size)
1199{
1200    memory_region_init(mr, owner, name, size);
1201    memory_region_ref(orig);
1202    mr->destructor = memory_region_destructor_alias;
1203    mr->alias = orig;
1204    mr->alias_offset = offset;
1205}
1206
1207void memory_region_init_rom_device(MemoryRegion *mr,
1208                                   Object *owner,
1209                                   const MemoryRegionOps *ops,
1210                                   void *opaque,
1211                                   const char *name,
1212                                   uint64_t size,
1213                                   Error **errp)
1214{
1215    memory_region_init(mr, owner, name, size);
1216    mr->ops = ops;
1217    mr->opaque = opaque;
1218    mr->terminates = true;
1219    mr->rom_device = true;
1220    mr->destructor = memory_region_destructor_rom_device;
1221    mr->ram_addr = qemu_ram_alloc(size, mr, errp);
1222}
1223
1224void memory_region_init_iommu(MemoryRegion *mr,
1225                              Object *owner,
1226                              const MemoryRegionIOMMUOps *ops,
1227                              const char *name,
1228                              uint64_t size)
1229{
1230    memory_region_init(mr, owner, name, size);
1231    mr->iommu_ops = ops,
1232    mr->terminates = true;  /* then re-forwards */
1233    notifier_list_init(&mr->iommu_notify);
1234}
1235
1236void memory_region_init_reservation(MemoryRegion *mr,
1237                                    Object *owner,
1238                                    const char *name,
1239                                    uint64_t size)
1240{
1241    memory_region_init_io(mr, owner, &unassigned_mem_ops, mr, name, size);
1242}
1243
1244static void memory_region_finalize(Object *obj)
1245{
1246    MemoryRegion *mr = MEMORY_REGION(obj);
1247
1248    assert(QTAILQ_EMPTY(&mr->subregions));
1249    assert(memory_region_transaction_depth == 0);
1250    mr->destructor(mr);
1251    memory_region_clear_coalescing(mr);
1252    g_free((char *)mr->name);
1253    g_free(mr->ioeventfds);
1254}
1255
1256Object *memory_region_owner(MemoryRegion *mr)
1257{
1258    Object *obj = OBJECT(mr);
1259    return obj->parent;
1260}
1261
1262void memory_region_ref(MemoryRegion *mr)
1263{
1264    /* MMIO callbacks most likely will access data that belongs
1265     * to the owner, hence the need to ref/unref the owner whenever
1266     * the memory region is in use.
1267     *
1268     * The memory region is a child of its owner.  As long as the
1269     * owner doesn't call unparent itself on the memory region,
1270     * ref-ing the owner will also keep the memory region alive.
1271     * Memory regions without an owner are supposed to never go away,
1272     * but we still ref/unref them for debugging purposes.
1273     */
1274    Object *obj = OBJECT(mr);
1275    if (obj && obj->parent) {
1276        object_ref(obj->parent);
1277    } else {
1278        object_ref(obj);
1279    }
1280}
1281
1282void memory_region_unref(MemoryRegion *mr)
1283{
1284    Object *obj = OBJECT(mr);
1285    if (obj && obj->parent) {
1286        object_unref(obj->parent);
1287    } else {
1288        object_unref(obj);
1289    }
1290}
1291
1292uint64_t memory_region_size(MemoryRegion *mr)
1293{
1294    if (int128_eq(mr->size, int128_2_64())) {
1295        return UINT64_MAX;
1296    }
1297    return int128_get64(mr->size);
1298}
1299
1300const char *memory_region_name(const MemoryRegion *mr)
1301{
1302    if (!mr->name) {
1303        ((MemoryRegion *)mr)->name =
1304            object_get_canonical_path_component(OBJECT(mr));
1305    }
1306    return mr->name;
1307}
1308
1309bool memory_region_is_ram(MemoryRegion *mr)
1310{
1311    return mr->ram;
1312}
1313
1314bool memory_region_is_skip_dump(MemoryRegion *mr)
1315{
1316    return mr->skip_dump;
1317}
1318
1319bool memory_region_is_logging(MemoryRegion *mr)
1320{
1321    return mr->dirty_log_mask;
1322}
1323
1324bool memory_region_is_rom(MemoryRegion *mr)
1325{
1326    return mr->ram && mr->readonly;
1327}
1328
1329bool memory_region_is_iommu(MemoryRegion *mr)
1330{
1331    return mr->iommu_ops;
1332}
1333
1334void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n)
1335{
1336    notifier_list_add(&mr->iommu_notify, n);
1337}
1338
1339void memory_region_unregister_iommu_notifier(Notifier *n)
1340{
1341    notifier_remove(n);
1342}
1343
1344void memory_region_notify_iommu(MemoryRegion *mr,
1345                                IOMMUTLBEntry entry)
1346{
1347    assert(memory_region_is_iommu(mr));
1348    notifier_list_notify(&mr->iommu_notify, &entry);
1349}
1350
1351void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
1352{
1353    uint8_t mask = 1 << client;
1354
1355    memory_region_transaction_begin();
1356    mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
1357    memory_region_update_pending |= mr->enabled;
1358    memory_region_transaction_commit();
1359}
1360
1361bool memory_region_get_dirty(MemoryRegion *mr, hwaddr addr,
1362                             hwaddr size, unsigned client)
1363{
1364    assert(mr->terminates);
1365    return cpu_physical_memory_get_dirty(mr->ram_addr + addr, size, client);
1366}
1367
1368void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr,
1369                             hwaddr size)
1370{
1371    assert(mr->terminates);
1372    cpu_physical_memory_set_dirty_range(mr->ram_addr + addr, size);
1373}
1374
1375bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr,
1376                                        hwaddr size, unsigned client)
1377{
1378    bool ret;
1379    assert(mr->terminates);
1380    ret = cpu_physical_memory_get_dirty(mr->ram_addr + addr, size, client);
1381    if (ret) {
1382        cpu_physical_memory_reset_dirty(mr->ram_addr + addr, size, client);
1383    }
1384    return ret;
1385}
1386
1387
1388void memory_region_sync_dirty_bitmap(MemoryRegion *mr)
1389{
1390    AddressSpace *as;
1391    FlatRange *fr;
1392
1393    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
1394        FlatView *view = address_space_get_flatview(as);
1395        FOR_EACH_FLAT_RANGE(fr, view) {
1396            if (fr->mr == mr) {
1397                MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync);
1398            }
1399        }
1400        flatview_unref(view);
1401    }
1402}
1403
1404void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
1405{
1406    if (mr->readonly != readonly) {
1407        memory_region_transaction_begin();
1408        mr->readonly = readonly;
1409        memory_region_update_pending |= mr->enabled;
1410        memory_region_transaction_commit();
1411    }
1412}
1413
1414void memory_region_rom_device_set_romd(MemoryRegion *mr, bool romd_mode)
1415{
1416    if (mr->romd_mode != romd_mode) {
1417        memory_region_transaction_begin();
1418        mr->romd_mode = romd_mode;
1419        memory_region_update_pending |= mr->enabled;
1420        memory_region_transaction_commit();
1421    }
1422}
1423
1424void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
1425                               hwaddr size, unsigned client)
1426{
1427    assert(mr->terminates);
1428    cpu_physical_memory_reset_dirty(mr->ram_addr + addr, size, client);
1429}
1430
1431int memory_region_get_fd(MemoryRegion *mr)
1432{
1433    if (mr->alias) {
1434        return memory_region_get_fd(mr->alias);
1435    }
1436
1437    assert(mr->terminates);
1438
1439    return qemu_get_ram_fd(mr->ram_addr & TARGET_PAGE_MASK);
1440}
1441
1442void *memory_region_get_ram_ptr(MemoryRegion *mr)
1443{
1444    if (mr->alias) {
1445        return memory_region_get_ram_ptr(mr->alias) + mr->alias_offset;
1446    }
1447
1448    assert(mr->terminates);
1449
1450    return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
1451}
1452
1453static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
1454{
1455    FlatView *view;
1456    FlatRange *fr;
1457    CoalescedMemoryRange *cmr;
1458    AddrRange tmp;
1459    MemoryRegionSection section;
1460
1461    view = address_space_get_flatview(as);
1462    FOR_EACH_FLAT_RANGE(fr, view) {
1463        if (fr->mr == mr) {
1464            section = (MemoryRegionSection) {
1465                .address_space = as,
1466                .offset_within_address_space = int128_get64(fr->addr.start),
1467                .size = fr->addr.size,
1468            };
1469
1470            MEMORY_LISTENER_CALL(coalesced_mmio_del, Reverse, &section,
1471                                 int128_get64(fr->addr.start),
1472                                 int128_get64(fr->addr.size));
1473            QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
1474                tmp = addrrange_shift(cmr->addr,
1475                                      int128_sub(fr->addr.start,
1476                                                 int128_make64(fr->offset_in_region)));
1477                if (!addrrange_intersects(tmp, fr->addr)) {
1478                    continue;
1479                }
1480                tmp = addrrange_intersection(tmp, fr->addr);
1481                MEMORY_LISTENER_CALL(coalesced_mmio_add, Forward, &section,
1482                                     int128_get64(tmp.start),
1483                                     int128_get64(tmp.size));
1484            }
1485        }
1486    }
1487    flatview_unref(view);
1488}
1489
1490static void memory_region_update_coalesced_range(MemoryRegion *mr)
1491{
1492    AddressSpace *as;
1493
1494    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
1495        memory_region_update_coalesced_range_as(mr, as);
1496    }
1497}
1498
1499void memory_region_set_coalescing(MemoryRegion *mr)
1500{
1501    memory_region_clear_coalescing(mr);
1502    memory_region_add_coalescing(mr, 0, int128_get64(mr->size));
1503}
1504
1505void memory_region_add_coalescing(MemoryRegion *mr,
1506                                  hwaddr offset,
1507                                  uint64_t size)
1508{
1509    CoalescedMemoryRange *cmr = g_malloc(sizeof(*cmr));
1510
1511    cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size));
1512    QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
1513    memory_region_update_coalesced_range(mr);
1514    memory_region_set_flush_coalesced(mr);
1515}
1516
1517void memory_region_clear_coalescing(MemoryRegion *mr)
1518{
1519    CoalescedMemoryRange *cmr;
1520    bool updated = false;
1521
1522    qemu_flush_coalesced_mmio_buffer();
1523    mr->flush_coalesced_mmio = false;
1524
1525    while (!QTAILQ_EMPTY(&mr->coalesced)) {
1526        cmr = QTAILQ_FIRST(&mr->coalesced);
1527        QTAILQ_REMOVE(&mr->coalesced, cmr, link);
1528        g_free(cmr);
1529        updated = true;
1530    }
1531
1532    if (updated) {
1533        memory_region_update_coalesced_range(mr);
1534    }
1535}
1536
1537void memory_region_set_flush_coalesced(MemoryRegion *mr)
1538{
1539    mr->flush_coalesced_mmio = true;
1540}
1541
1542void memory_region_clear_flush_coalesced(MemoryRegion *mr)
1543{
1544    qemu_flush_coalesced_mmio_buffer();
1545    if (QTAILQ_EMPTY(&mr->coalesced)) {
1546        mr->flush_coalesced_mmio = false;
1547    }
1548}
1549
1550void memory_region_add_eventfd(MemoryRegion *mr,
1551                               hwaddr addr,
1552                               unsigned size,
1553                               bool match_data,
1554                               uint64_t data,
1555                               EventNotifier *e)
1556{
1557    MemoryRegionIoeventfd mrfd = {
1558        .addr.start = int128_make64(addr),
1559        .addr.size = int128_make64(size),
1560        .match_data = match_data,
1561        .data = data,
1562        .e = e,
1563    };
1564    unsigned i;
1565
1566    adjust_endianness(mr, &mrfd.data, size);
1567    memory_region_transaction_begin();
1568    for (i = 0; i < mr->ioeventfd_nb; ++i) {
1569        if (memory_region_ioeventfd_before(mrfd, mr->ioeventfds[i])) {
1570            break;
1571        }
1572    }
1573    ++mr->ioeventfd_nb;
1574    mr->ioeventfds = g_realloc(mr->ioeventfds,
1575                                  sizeof(*mr->ioeventfds) * mr->ioeventfd_nb);
1576    memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i],
1577            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i));
1578    mr->ioeventfds[i] = mrfd;
1579    ioeventfd_update_pending |= mr->enabled;
1580    memory_region_transaction_commit();
1581}
1582
1583void memory_region_del_eventfd(MemoryRegion *mr,
1584                               hwaddr addr,
1585                               unsigned size,
1586                               bool match_data,
1587                               uint64_t data,
1588                               EventNotifier *e)
1589{
1590    MemoryRegionIoeventfd mrfd = {
1591        .addr.start = int128_make64(addr),
1592        .addr.size = int128_make64(size),
1593        .match_data = match_data,
1594        .data = data,
1595        .e = e,
1596    };
1597    unsigned i;
1598
1599    adjust_endianness(mr, &mrfd.data, size);
1600    memory_region_transaction_begin();
1601    for (i = 0; i < mr->ioeventfd_nb; ++i) {
1602        if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) {
1603            break;
1604        }
1605    }
1606    assert(i != mr->ioeventfd_nb);
1607    memmove(&mr->ioeventfds[i], &mr->ioeventfds[i+1],
1608            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb - (i+1)));
1609    --mr->ioeventfd_nb;
1610    mr->ioeventfds = g_realloc(mr->ioeventfds,
1611                                  sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);
1612    ioeventfd_update_pending |= mr->enabled;
1613    memory_region_transaction_commit();
1614}
1615
1616static void memory_region_update_container_subregions(MemoryRegion *subregion)
1617{
1618    hwaddr offset = subregion->addr;
1619    MemoryRegion *mr = subregion->container;
1620    MemoryRegion *other;
1621
1622    memory_region_transaction_begin();
1623
1624    memory_region_ref(subregion);
1625    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
1626        if (subregion->may_overlap || other->may_overlap) {
1627            continue;
1628        }
1629        if (int128_ge(int128_make64(offset),
1630                      int128_add(int128_make64(other->addr), other->size))
1631            || int128_le(int128_add(int128_make64(offset), subregion->size),
1632                         int128_make64(other->addr))) {
1633            continue;
1634        }
1635#if 0
1636        printf("warning: subregion collision %llx/%llx (%s) "
1637               "vs %llx/%llx (%s)\n",
1638               (unsigned long long)offset,
1639               (unsigned long long)int128_get64(subregion->size),
1640               subregion->name,
1641               (unsigned long long)other->addr,
1642               (unsigned long long)int128_get64(other->size),
1643               other->name);
1644#endif
1645    }
1646    QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
1647        if (subregion->priority >= other->priority) {
1648            QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
1649            goto done;
1650        }
1651    }
1652    QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link);
1653done:
1654    memory_region_update_pending |= mr->enabled && subregion->enabled;
1655    memory_region_transaction_commit();
1656}
1657
1658static void memory_region_add_subregion_common(MemoryRegion *mr,
1659                                               hwaddr offset,
1660                                               MemoryRegion *subregion)
1661{
1662    assert(!subregion->container);
1663    subregion->container = mr;
1664    subregion->addr = offset;
1665    memory_region_update_container_subregions(subregion);
1666}
1667
1668void memory_region_add_subregion(MemoryRegion *mr,
1669                                 hwaddr offset,
1670                                 MemoryRegion *subregion)
1671{
1672    subregion->may_overlap = false;
1673    subregion->priority = 0;
1674    memory_region_add_subregion_common(mr, offset, subregion);
1675}
1676
1677void memory_region_add_subregion_overlap(MemoryRegion *mr,
1678                                         hwaddr offset,
1679                                         MemoryRegion *subregion,
1680                                         int priority)
1681{
1682    subregion->may_overlap = true;
1683    subregion->priority = priority;
1684    memory_region_add_subregion_common(mr, offset, subregion);
1685}
1686
1687void memory_region_del_subregion(MemoryRegion *mr,
1688                                 MemoryRegion *subregion)
1689{
1690    memory_region_transaction_begin();
1691    assert(subregion->container == mr);
1692    subregion->container = NULL;
1693    QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
1694    memory_region_unref(subregion);
1695    memory_region_update_pending |= mr->enabled && subregion->enabled;
1696    memory_region_transaction_commit();
1697}
1698
1699void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
1700{
1701    if (enabled == mr->enabled) {
1702        return;
1703    }
1704    memory_region_transaction_begin();
1705    mr->enabled = enabled;
1706    memory_region_update_pending = true;
1707    memory_region_transaction_commit();
1708}
1709
1710static void memory_region_readd_subregion(MemoryRegion *mr)
1711{
1712    MemoryRegion *container = mr->container;
1713
1714    if (container) {
1715        memory_region_transaction_begin();
1716        memory_region_ref(mr);
1717        memory_region_del_subregion(container, mr);
1718        mr->container = container;
1719        memory_region_update_container_subregions(mr);
1720        memory_region_unref(mr);
1721        memory_region_transaction_commit();
1722    }
1723}
1724
1725void memory_region_set_address(MemoryRegion *mr, hwaddr addr)
1726{
1727    if (addr != mr->addr) {
1728        mr->addr = addr;
1729        memory_region_readd_subregion(mr);
1730    }
1731}
1732
1733void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset)
1734{
1735    assert(mr->alias);
1736
1737    if (offset == mr->alias_offset) {
1738        return;
1739    }
1740
1741    memory_region_transaction_begin();
1742    mr->alias_offset = offset;
1743    memory_region_update_pending |= mr->enabled;
1744    memory_region_transaction_commit();
1745}
1746
1747ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
1748{
1749    return mr->ram_addr;
1750}
1751
1752uint64_t memory_region_get_alignment(const MemoryRegion *mr)
1753{
1754    return mr->align;
1755}
1756
1757static int cmp_flatrange_addr(const void *addr_, const void *fr_)
1758{
1759    const AddrRange *addr = addr_;
1760    const FlatRange *fr = fr_;
1761
1762    if (int128_le(addrrange_end(*addr), fr->addr.start)) {
1763        return -1;
1764    } else if (int128_ge(addr->start, addrrange_end(fr->addr))) {
1765        return 1;
1766    }
1767    return 0;
1768}
1769
1770static FlatRange *flatview_lookup(FlatView *view, AddrRange addr)
1771{
1772    return bsearch(&addr, view->ranges, view->nr,
1773                   sizeof(FlatRange), cmp_flatrange_addr);
1774}
1775
1776bool memory_region_present(MemoryRegion *container, hwaddr addr)
1777{
1778    MemoryRegion *mr = memory_region_find(container, addr, 1).mr;
1779    if (!mr || (mr == container)) {
1780        return false;
1781    }
1782    memory_region_unref(mr);
1783    return true;
1784}
1785
1786bool memory_region_is_mapped(MemoryRegion *mr)
1787{
1788    return mr->container ? true : false;
1789}
1790
1791MemoryRegionSection memory_region_find(MemoryRegion *mr,
1792                                       hwaddr addr, uint64_t size)
1793{
1794    MemoryRegionSection ret = { .mr = NULL };
1795    MemoryRegion *root;
1796    AddressSpace *as;
1797    AddrRange range;
1798    FlatView *view;
1799    FlatRange *fr;
1800
1801    addr += mr->addr;
1802    for (root = mr; root->container; ) {
1803        root = root->container;
1804        addr += root->addr;
1805    }
1806
1807    as = memory_region_to_address_space(root);
1808    if (!as) {
1809        return ret;
1810    }
1811    range = addrrange_make(int128_make64(addr), int128_make64(size));
1812
1813    view = address_space_get_flatview(as);
1814    fr = flatview_lookup(view, range);
1815    if (!fr) {
1816        flatview_unref(view);
1817        return ret;
1818    }
1819
1820    while (fr > view->ranges && addrrange_intersects(fr[-1].addr, range)) {
1821        --fr;
1822    }
1823
1824    ret.mr = fr->mr;
1825    ret.address_space = as;
1826    range = addrrange_intersection(range, fr->addr);
1827    ret.offset_within_region = fr->offset_in_region;
1828    ret.offset_within_region += int128_get64(int128_sub(range.start,
1829                                                        fr->addr.start));
1830    ret.size = range.size;
1831    ret.offset_within_address_space = int128_get64(range.start);
1832    ret.readonly = fr->readonly;
1833    memory_region_ref(ret.mr);
1834
1835    flatview_unref(view);
1836    return ret;
1837}
1838
1839void address_space_sync_dirty_bitmap(AddressSpace *as)
1840{
1841    FlatView *view;
1842    FlatRange *fr;
1843
1844    view = address_space_get_flatview(as);
1845    FOR_EACH_FLAT_RANGE(fr, view) {
1846        MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, log_sync);
1847    }
1848    flatview_unref(view);
1849}
1850
1851void memory_global_dirty_log_start(void)
1852{
1853    global_dirty_log = true;
1854    MEMORY_LISTENER_CALL_GLOBAL(log_global_start, Forward);
1855}
1856
1857void memory_global_dirty_log_stop(void)
1858{
1859    global_dirty_log = false;
1860    MEMORY_LISTENER_CALL_GLOBAL(log_global_stop, Reverse);
1861}
1862
1863static void listener_add_address_space(MemoryListener *listener,
1864                                       AddressSpace *as)
1865{
1866    FlatView *view;
1867    FlatRange *fr;
1868
1869    if (listener->address_space_filter
1870        && listener->address_space_filter != as) {
1871        return;
1872    }
1873
1874    if (global_dirty_log) {
1875        if (listener->log_global_start) {
1876            listener->log_global_start(listener);
1877        }
1878    }
1879
1880    view = address_space_get_flatview(as);
1881    FOR_EACH_FLAT_RANGE(fr, view) {
1882        MemoryRegionSection section = {
1883            .mr = fr->mr,
1884            .address_space = as,
1885            .offset_within_region = fr->offset_in_region,
1886            .size = fr->addr.size,
1887            .offset_within_address_space = int128_get64(fr->addr.start),
1888            .readonly = fr->readonly,
1889        };
1890        if (listener->region_add) {
1891            listener->region_add(listener, &section);
1892        }
1893    }
1894    flatview_unref(view);
1895}
1896
1897void memory_listener_register(MemoryListener *listener, AddressSpace *filter)
1898{
1899    MemoryListener *other = NULL;
1900    AddressSpace *as;
1901
1902    listener->address_space_filter = filter;
1903    if (QTAILQ_EMPTY(&memory_listeners)
1904        || listener->priority >= QTAILQ_LAST(&memory_listeners,
1905                                             memory_listeners)->priority) {
1906        QTAILQ_INSERT_TAIL(&memory_listeners, listener, link);
1907    } else {
1908        QTAILQ_FOREACH(other, &memory_listeners, link) {
1909            if (listener->priority < other->priority) {
1910                break;
1911            }
1912        }
1913        QTAILQ_INSERT_BEFORE(other, listener, link);
1914    }
1915
1916    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
1917        listener_add_address_space(listener, as);
1918    }
1919}
1920
1921void memory_listener_unregister(MemoryListener *listener)
1922{
1923    QTAILQ_REMOVE(&memory_listeners, listener, link);
1924}
1925
1926void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
1927{
1928    if (QTAILQ_EMPTY(&address_spaces)) {
1929        memory_init();
1930    }
1931
1932    memory_region_transaction_begin();
1933    as->root = root;
1934    as->current_map = g_new(FlatView, 1);
1935    flatview_init(as->current_map);
1936    as->ioeventfd_nb = 0;
1937    as->ioeventfds = NULL;
1938    QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
1939    as->name = g_strdup(name ? name : "anonymous");
1940    address_space_init_dispatch(as);
1941    memory_region_update_pending |= root->enabled;
1942    memory_region_transaction_commit();
1943}
1944
1945void address_space_destroy(AddressSpace *as)
1946{
1947    MemoryListener *listener;
1948
1949    /* Flush out anything from MemoryListeners listening in on this */
1950    memory_region_transaction_begin();
1951    as->root = NULL;
1952    memory_region_transaction_commit();
1953    QTAILQ_REMOVE(&address_spaces, as, address_spaces_link);
1954    address_space_destroy_dispatch(as);
1955
1956    QTAILQ_FOREACH(listener, &memory_listeners, link) {
1957        assert(listener->address_space_filter != as);
1958    }
1959
1960    flatview_unref(as->current_map);
1961    g_free(as->name);
1962    g_free(as->ioeventfds);
1963}
1964
1965bool io_mem_read(MemoryRegion *mr, hwaddr addr, uint64_t *pval, unsigned size)
1966{
1967    return memory_region_dispatch_read(mr, addr, pval, size);
1968}
1969
1970bool io_mem_write(MemoryRegion *mr, hwaddr addr,
1971                  uint64_t val, unsigned size)
1972{
1973    return memory_region_dispatch_write(mr, addr, val, size);
1974}
1975
1976typedef struct MemoryRegionList MemoryRegionList;
1977
1978struct MemoryRegionList {
1979    const MemoryRegion *mr;
1980    QTAILQ_ENTRY(MemoryRegionList) queue;
1981};
1982
1983typedef QTAILQ_HEAD(queue, MemoryRegionList) MemoryRegionListHead;
1984
1985static void mtree_print_mr(fprintf_function mon_printf, void *f,
1986                           const MemoryRegion *mr, unsigned int level,
1987                           hwaddr base,
1988                           MemoryRegionListHead *alias_print_queue)
1989{
1990    MemoryRegionList *new_ml, *ml, *next_ml;
1991    MemoryRegionListHead submr_print_queue;
1992    const MemoryRegion *submr;
1993    unsigned int i;
1994
1995    if (!mr || !mr->enabled) {
1996        return;
1997    }
1998
1999    for (i = 0; i < level; i++) {
2000        mon_printf(f, "  ");
2001    }
2002
2003    if (mr->alias) {
2004        MemoryRegionList *ml;
2005        bool found = false;
2006
2007        /* check if the alias is already in the queue */
2008        QTAILQ_FOREACH(ml, alias_print_queue, queue) {
2009            if (ml->mr == mr->alias) {
2010                found = true;
2011            }
2012        }
2013
2014        if (!found) {
2015            ml = g_new(MemoryRegionList, 1);
2016            ml->mr = mr->alias;
2017            QTAILQ_INSERT_TAIL(alias_print_queue, ml, queue);
2018        }
2019        mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx
2020                   " (prio %d, %c%c): alias %s @%s " TARGET_FMT_plx
2021                   "-" TARGET_FMT_plx "\n",
2022                   base + mr->addr,
2023                   base + mr->addr
2024                   + (int128_nz(mr->size) ?
2025                      (hwaddr)int128_get64(int128_sub(mr->size,
2026                                                      int128_one())) : 0),
2027                   mr->priority,
2028                   mr->romd_mode ? 'R' : '-',
2029                   !mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
2030                                                                       : '-',
2031                   memory_region_name(mr),
2032                   memory_region_name(mr->alias),
2033                   mr->alias_offset,
2034                   mr->alias_offset
2035                   + (int128_nz(mr->size) ?
2036                      (hwaddr)int128_get64(int128_sub(mr->size,
2037                                                      int128_one())) : 0));
2038    } else {
2039        mon_printf(f,
2040                   TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %c%c): %s\n",
2041                   base + mr->addr,
2042                   base + mr->addr
2043                   + (int128_nz(mr->size) ?
2044                      (hwaddr)int128_get64(int128_sub(mr->size,
2045                                                      int128_one())) : 0),
2046                   mr->priority,
2047                   mr->romd_mode ? 'R' : '-',
2048                   !mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
2049                                                                       : '-',
2050                   memory_region_name(mr));
2051    }
2052
2053    QTAILQ_INIT(&submr_print_queue);
2054
2055    QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {
2056        new_ml = g_new(MemoryRegionList, 1);
2057        new_ml->mr = submr;
2058        QTAILQ_FOREACH(ml, &submr_print_queue, queue) {
2059            if (new_ml->mr->addr < ml->mr->addr ||
2060                (new_ml->mr->addr == ml->mr->addr &&
2061                 new_ml->mr->priority > ml->mr->priority)) {
2062                QTAILQ_INSERT_BEFORE(ml, new_ml, queue);
2063                new_ml = NULL;
2064                break;
2065            }
2066        }
2067        if (new_ml) {
2068            QTAILQ_INSERT_TAIL(&submr_print_queue, new_ml, queue);
2069        }
2070    }
2071
2072    QTAILQ_FOREACH(ml, &submr_print_queue, queue) {
2073        mtree_print_mr(mon_printf, f, ml->mr, level + 1, base + mr->addr,
2074                       alias_print_queue);
2075    }
2076
2077    QTAILQ_FOREACH_SAFE(ml, &submr_print_queue, queue, next_ml) {
2078        g_free(ml);
2079    }
2080}
2081
2082void mtree_info(fprintf_function mon_printf, void *f)
2083{
2084    MemoryRegionListHead ml_head;
2085    MemoryRegionList *ml, *ml2;
2086    AddressSpace *as;
2087
2088    QTAILQ_INIT(&ml_head);
2089
2090    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
2091        mon_printf(f, "%s\n", as->name);
2092        mtree_print_mr(mon_printf, f, as->root, 0, 0, &ml_head);
2093    }
2094
2095    mon_printf(f, "aliases\n");
2096    /* print aliased regions */
2097    QTAILQ_FOREACH(ml, &ml_head, queue) {
2098        mon_printf(f, "%s\n", memory_region_name(ml->mr));
2099        mtree_print_mr(mon_printf, f, ml->mr, 0, 0, &ml_head);
2100    }
2101
2102    QTAILQ_FOREACH_SAFE(ml, &ml_head, queue, ml2) {
2103        g_free(ml);
2104    }
2105}
2106
2107static const TypeInfo memory_region_info = {
2108    .parent             = TYPE_OBJECT,
2109    .name               = TYPE_MEMORY_REGION,
2110    .instance_size      = sizeof(MemoryRegion),
2111    .instance_init      = memory_region_initfn,
2112    .instance_finalize  = memory_region_finalize,
2113};
2114
2115static void memory_register_types(void)
2116{
2117    type_register_static(&memory_region_info);
2118}
2119
2120type_init(memory_register_types)
2121