summaryrefslogtreecommitdiff
path: root/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'memory.c')
-rw-r--r--memory.c79
1 files changed, 54 insertions, 25 deletions
diff --git a/memory.c b/memory.c
index 5cb8f4a8b2..47b005a558 100644
--- a/memory.c
+++ b/memory.c
@@ -152,7 +152,7 @@ static bool memory_listener_match(MemoryListener *listener,
.mr = (fr)->mr, \
.address_space = (as), \
.offset_within_region = (fr)->offset_in_region, \
- .size = int128_get64((fr)->addr.size), \
+ .size = (fr)->addr.size, \
.offset_within_address_space = int128_get64((fr)->addr.start), \
.readonly = (fr)->readonly, \
}))
@@ -282,7 +282,7 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
&& r1->readonly == r2->readonly;
}
-/* Attempt to simplify a view by merging ajacent ranges */
+/* Attempt to simplify a view by merging adjacent ranges */
static void flatview_simplify(FlatView *view)
{
unsigned i, j;
@@ -556,6 +556,11 @@ static void render_memory_region(FlatView *view,
base = clip.start;
remain = clip.size;
+ fr.mr = mr;
+ fr.dirty_log_mask = mr->dirty_log_mask;
+ fr.romd_mode = mr->romd_mode;
+ fr.readonly = readonly;
+
/* Render the region itself into any gaps left by the current view. */
for (i = 0; i < view->nr && int128_nz(remain); ++i) {
if (int128_ge(base, addrrange_end(view->ranges[i].addr))) {
@@ -564,12 +569,8 @@ static void render_memory_region(FlatView *view,
if (int128_lt(base, view->ranges[i].addr.start)) {
now = int128_min(remain,
int128_sub(view->ranges[i].addr.start, base));
- fr.mr = mr;
fr.offset_in_region = offset_in_region;
fr.addr = addrrange_make(base, now);
- fr.dirty_log_mask = mr->dirty_log_mask;
- fr.romd_mode = mr->romd_mode;
- fr.readonly = readonly;
flatview_insert(view, i, &fr);
++i;
int128_addto(&base, now);
@@ -584,12 +585,8 @@ static void render_memory_region(FlatView *view,
int128_subfrom(&remain, now);
}
if (int128_nz(remain)) {
- fr.mr = mr;
fr.offset_in_region = offset_in_region;
fr.addr = addrrange_make(base, remain);
- fr.dirty_log_mask = mr->dirty_log_mask;
- fr.romd_mode = mr->romd_mode;
- fr.readonly = readonly;
flatview_insert(view, i, &fr);
}
}
@@ -634,7 +631,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
section = (MemoryRegionSection) {
.address_space = as,
.offset_within_address_space = int128_get64(fd->addr.start),
- .size = int128_get64(fd->addr.size),
+ .size = fd->addr.size,
};
MEMORY_LISTENER_CALL(eventfd_del, Forward, &section,
fd->match_data, fd->data, fd->e);
@@ -647,7 +644,7 @@ static void address_space_add_del_ioeventfds(AddressSpace *as,
section = (MemoryRegionSection) {
.address_space = as,
.offset_within_address_space = int128_get64(fd->addr.start),
- .size = int128_get64(fd->addr.size),
+ .size = fd->addr.size,
};
MEMORY_LISTENER_CALL(eventfd_add, Reverse, &section,
fd->match_data, fd->data, fd->e);
@@ -719,7 +716,7 @@ static void address_space_update_topology_pass(AddressSpace *as,
|| int128_lt(frold->addr.start, frnew->addr.start)
|| (int128_eq(frold->addr.start, frnew->addr.start)
&& !flatrange_equal(frold, frnew)))) {
- /* In old, but (not in new, or in new but attributes changed). */
+ /* In old but not in new, or in both but attributes changed. */
if (!adding) {
MEMORY_LISTENER_UPDATE_REGION(frold, as, Reverse, region_del);
@@ -727,7 +724,7 @@ static void address_space_update_topology_pass(AddressSpace *as,
++iold;
} else if (frold && frnew && flatrange_equal(frold, frnew)) {
- /* In both (logging may have changed) */
+ /* In both and unchanged (except logging may have changed) */
if (adding) {
MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_nop);
@@ -824,6 +821,7 @@ void memory_region_init(MemoryRegion *mr,
{
mr->ops = &unassigned_mem_ops;
mr->opaque = NULL;
+ mr->iommu_ops = NULL;
mr->parent = NULL;
mr->size = int128_make64(size);
if (size == UINT64_MAX) {
@@ -1063,6 +1061,17 @@ void memory_region_init_rom_device(MemoryRegion *mr,
mr->ram_addr = qemu_ram_alloc(size, mr);
}
+void memory_region_init_iommu(MemoryRegion *mr,
+ const MemoryRegionIOMMUOps *ops,
+ const char *name,
+ uint64_t size)
+{
+ memory_region_init(mr, name, size);
+ mr->iommu_ops = ops,
+ mr->terminates = true; /* then re-forwards */
+ notifier_list_init(&mr->iommu_notify);
+}
+
void memory_region_init_reservation(MemoryRegion *mr,
const char *name,
uint64_t size)
@@ -1108,6 +1117,28 @@ bool memory_region_is_rom(MemoryRegion *mr)
return mr->ram && mr->readonly;
}
+bool memory_region_is_iommu(MemoryRegion *mr)
+{
+ return mr->iommu_ops;
+}
+
+void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n)
+{
+ notifier_list_add(&mr->iommu_notify, n);
+}
+
+void memory_region_unregister_iommu_notifier(Notifier *n)
+{
+ notifier_remove(n);
+}
+
+void memory_region_notify_iommu(MemoryRegion *mr,
+ IOMMUTLBEntry entry)
+{
+ assert(memory_region_is_iommu(mr));
+ notifier_list_notify(&mr->iommu_notify, &entry);
+}
+
void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
{
uint8_t mask = 1 << client;
@@ -1215,7 +1246,7 @@ static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
section = (MemoryRegionSection) {
.address_space = as,
.offset_within_address_space = int128_get64(fr->addr.start),
- .size = int128_get64(fr->addr.size),
+ .size = fr->addr.size,
};
MEMORY_LISTENER_CALL(coalesced_mmio_del, Reverse, &section,
@@ -1506,7 +1537,7 @@ static FlatRange *address_space_lookup(AddressSpace *as, AddrRange addr)
MemoryRegionSection memory_region_find(MemoryRegion *mr,
hwaddr addr, uint64_t size)
{
- MemoryRegionSection ret = { .mr = NULL, .size = 0 };
+ MemoryRegionSection ret = { .mr = NULL };
MemoryRegion *root;
AddressSpace *as;
AddrRange range;
@@ -1536,7 +1567,7 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
ret.offset_within_region = fr->offset_in_region;
ret.offset_within_region += int128_get64(int128_sub(range.start,
fr->addr.start));
- ret.size = int128_get64(range.size);
+ ret.size = range.size;
ret.offset_within_address_space = int128_get64(range.start);
ret.readonly = fr->readonly;
return ret;
@@ -1584,7 +1615,7 @@ static void listener_add_address_space(MemoryListener *listener,
.mr = fr->mr,
.address_space = as,
.offset_within_region = fr->offset_in_region,
- .size = int128_get64(fr->addr.size),
+ .size = fr->addr.size,
.offset_within_address_space = int128_get64(fr->addr.start),
.readonly = fr->readonly,
};
@@ -1623,7 +1654,7 @@ void memory_listener_unregister(MemoryListener *listener)
QTAILQ_REMOVE(&memory_listeners, listener, link);
}
-void address_space_init(AddressSpace *as, MemoryRegion *root)
+void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
{
memory_region_transaction_begin();
as->root = root;
@@ -1632,7 +1663,7 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
as->ioeventfd_nb = 0;
as->ioeventfds = NULL;
QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
- as->name = NULL;
+ as->name = g_strdup(name ? name : "anonymous");
address_space_init_dispatch(as);
memory_region_update_pending |= root->enabled;
memory_region_transaction_commit();
@@ -1647,6 +1678,7 @@ void address_space_destroy(AddressSpace *as)
QTAILQ_REMOVE(&address_spaces, as, address_spaces_link);
address_space_destroy_dispatch(as);
flatview_destroy(as->current_map);
+ g_free(as->name);
g_free(as->current_map);
g_free(as->ioeventfds);
}
@@ -1712,7 +1744,7 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
"-" TARGET_FMT_plx "\n",
base + mr->addr,
base + mr->addr
- + (hwaddr)int128_get64(mr->size) - 1,
+ + (hwaddr)int128_get64(int128_sub(mr->size, int128_make64(1))),
mr->priority,
mr->romd_mode ? 'R' : '-',
!mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
@@ -1727,7 +1759,7 @@ static void mtree_print_mr(fprintf_function mon_printf, void *f,
TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %c%c): %s\n",
base + mr->addr,
base + mr->addr
- + (hwaddr)int128_get64(mr->size) - 1,
+ + (hwaddr)int128_get64(int128_sub(mr->size, int128_make64(1))),
mr->priority,
mr->romd_mode ? 'R' : '-',
!mr->readonly && !(mr->rom_device && mr->romd_mode) ? 'W'
@@ -1773,9 +1805,6 @@ void mtree_info(fprintf_function mon_printf, void *f)
QTAILQ_INIT(&ml_head);
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
- if (!as->name) {
- continue;
- }
mon_printf(f, "%s\n", as->name);
mtree_print_mr(mon_printf, f, as->root, 0, 0, &ml_head);
}