static bool ioeventfd_update_pending;
static bool global_dirty_log = false;
-static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
+static QTAILQ_HEAD(, MemoryListener) memory_listeners
= QTAILQ_HEAD_INITIALIZER(memory_listeners);
static QTAILQ_HEAD(, AddressSpace) address_spaces
} \
break; \
case Reverse: \
- QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners, \
- memory_listeners, link) { \
+ QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners, link) { \
if (_listener->_callback) { \
_listener->_callback(_listener, ##_args); \
} \
#define MEMORY_LISTENER_CALL(_as, _callback, _direction, _section, _args...) \
do { \
MemoryListener *_listener; \
- struct memory_listeners_as *list = &(_as)->listeners; \
\
switch (_direction) { \
case Forward: \
- QTAILQ_FOREACH(_listener, list, link_as) { \
+ QTAILQ_FOREACH(_listener, &(_as)->listeners, link_as) { \
if (_listener->_callback) { \
_listener->_callback(_listener, _section, ##_args); \
} \
} \
break; \
case Reverse: \
- QTAILQ_FOREACH_REVERSE(_listener, list, memory_listeners_as, \
- link_as) { \
+ QTAILQ_FOREACH_REVERSE(_listener, &(_as)->listeners, link_as) { \
if (_listener->_callback) { \
_listener->_callback(_listener, _section, ##_args); \
} \
bool romd_mode;
bool readonly;
bool nonvolatile;
+ int has_coalesced_range;
};
#define FOR_EACH_FLAT_RANGE(var, view) \
fr.romd_mode = mr->romd_mode;
fr.readonly = readonly;
fr.nonvolatile = nonvolatile;
+ fr.has_coalesced_range = 0;
/* Render the region itself into any gaps left by the current view. */
for (i = 0; i < view->nr && int128_nz(remain); ++i) {
static void flat_range_coalesced_io_del(FlatRange *fr, AddressSpace *as)
{
+ if (!fr->has_coalesced_range) {
+ return;
+ }
+
+ if (--fr->has_coalesced_range > 0) {
+ return;
+ }
+
MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del,
int128_get64(fr->addr.start),
int128_get64(fr->addr.size));
CoalescedMemoryRange *cmr;
AddrRange tmp;
+ if (QTAILQ_EMPTY(&mr->coalesced)) {
+ return;
+ }
+
+ if (fr->has_coalesced_range++) {
+ return;
+ }
+
QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
tmp = addrrange_shift(cmr->addr,
int128_sub(fr->addr.start,
/* In old but not in new, or in both but attributes changed. */
if (!adding) {
+ flat_range_coalesced_io_del(frold, as);
MEMORY_LISTENER_UPDATE_REGION(frold, as, Reverse, region_del);
}
if (adding) {
MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_add);
+ flat_range_coalesced_io_add(frnew, as);
}
++inew;
uint64_t size,
void *ptr)
{
- memory_region_init_ram_ptr(mr, owner, name, size, ptr);
+ memory_region_init(mr, owner, name, size);
+ mr->ram = true;
+ mr->terminates = true;
mr->ram_device = true;
mr->ops = &ram_device_mem_ops;
mr->opaque = mr;
+ mr->destructor = memory_region_destructor_ram;
+ mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0;
+ /* qemu_ram_alloc_from_ptr cannot fail with ptr != NULL. */
+ assert(ptr != NULL);
+ mr->ram_block = qemu_ram_alloc_from_ptr(size, ptr, mr, &error_fatal);
}
void memory_region_init_alias(MemoryRegion *mr,
listener->address_space = as;
if (QTAILQ_EMPTY(&memory_listeners)
- || listener->priority >= QTAILQ_LAST(&memory_listeners,
- memory_listeners)->priority) {
+ || listener->priority >= QTAILQ_LAST(&memory_listeners)->priority) {
QTAILQ_INSERT_TAIL(&memory_listeners, listener, link);
} else {
QTAILQ_FOREACH(other, &memory_listeners, link) {
}
if (QTAILQ_EMPTY(&as->listeners)
- || listener->priority >= QTAILQ_LAST(&as->listeners,
- memory_listeners)->priority) {
+ || listener->priority >= QTAILQ_LAST(&as->listeners)->priority) {
QTAILQ_INSERT_TAIL(&as->listeners, listener, link_as);
} else {
QTAILQ_FOREACH(other, &as->listeners, link_as) {
QTAILQ_ENTRY(MemoryRegionList) mrqueue;
};
-typedef QTAILQ_HEAD(mrqueue, MemoryRegionList) MemoryRegionListHead;
+typedef QTAILQ_HEAD(, MemoryRegionList) MemoryRegionListHead;
#define MR_SIZE(size) (int128_nz(size) ? (hwaddr)int128_get64( \
int128_sub((size), int128_one())) : 0)