diff options
Diffstat (limited to 'memory.c')
-rw-r--r-- | memory.c | 142 |
1 files changed, 88 insertions, 54 deletions
@@ -183,7 +183,7 @@ static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range) { if (view->nr == view->nr_allocated) { view->nr_allocated = MAX(2 * view->nr, 10); - view->ranges = qemu_realloc(view->ranges, + view->ranges = g_realloc(view->ranges, view->nr_allocated * sizeof(*view->ranges)); } memmove(view->ranges + pos + 1, view->ranges + pos, @@ -194,7 +194,7 @@ static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range) static void flatview_destroy(FlatView *view) { - qemu_free(view->ranges); + g_free(view->ranges); } static bool can_merge(FlatRange *r1, FlatRange *r2) @@ -226,6 +226,65 @@ static void flatview_simplify(FlatView *view) } } +static void memory_region_read_accessor(void *opaque, + target_phys_addr_t addr, + uint64_t *value, + unsigned size, + unsigned shift, + uint64_t mask) +{ + MemoryRegion *mr = opaque; + uint64_t tmp; + + tmp = mr->ops->read(mr->opaque, addr, size); + *value |= (tmp & mask) << shift; +} + +static void memory_region_write_accessor(void *opaque, + target_phys_addr_t addr, + uint64_t *value, + unsigned size, + unsigned shift, + uint64_t mask) +{ + MemoryRegion *mr = opaque; + uint64_t tmp; + + tmp = (*value >> shift) & mask; + mr->ops->write(mr->opaque, addr, tmp, size); +} + +static void access_with_adjusted_size(target_phys_addr_t addr, + uint64_t *value, + unsigned size, + unsigned access_size_min, + unsigned access_size_max, + void (*access)(void *opaque, + target_phys_addr_t addr, + uint64_t *value, + unsigned size, + unsigned shift, + uint64_t mask), + void *opaque) +{ + uint64_t access_mask; + unsigned access_size; + unsigned i; + + if (!access_size_min) { + access_size_min = 1; + } + if (!access_size_max) { + access_size_max = 4; + } + access_size = MAX(MIN(size, access_size_max), access_size_min); + access_mask = -1ULL >> (64 - access_size * 8); + for (i = 0; i < size; i += access_size) { + /* FIXME: big-endian support */ + access(opaque, addr + i, value, access_size, i * 8, access_mask); + } +} + static void memory_region_prepare_ram_addr(MemoryRegion *mr); static void as_memory_range_add(AddressSpace *as, FlatRange *fr) @@ -341,7 +400,11 @@ static void memory_region_iorange_read(IORange *iorange, } return; } - *data = mr->ops->read(mr->opaque, offset, width); + *data = 0; + access_with_adjusted_size(offset, data, width, + mr->ops->impl.min_access_size, + mr->ops->impl.max_access_size, + memory_region_read_accessor, mr); } static void memory_region_iorange_write(IORange *iorange, @@ -359,7 +422,10 @@ static void memory_region_iorange_write(IORange *iorange, } return; } - mr->ops->write(mr->opaque, offset, data, width); + access_with_adjusted_size(offset, &data, width, + mr->ops->impl.min_access_size, + mr->ops->impl.max_access_size, + memory_region_write_accessor, mr); } static const IORangeOps memory_region_iorange_ops = { @@ -553,7 +619,7 @@ static void address_space_update_ioeventfds(AddressSpace *as) fr->addr.start - fr->offset_in_region); if (addrrange_intersects(fr->addr, tmp)) { ++ioeventfd_nb; - ioeventfds = qemu_realloc(ioeventfds, + ioeventfds = g_realloc(ioeventfds, ioeventfd_nb * sizeof(*ioeventfds)); ioeventfds[ioeventfd_nb-1] = fr->mr->ioeventfds[i]; ioeventfds[ioeventfd_nb-1].addr = tmp; @@ -564,7 +630,7 @@ static void address_space_update_ioeventfds(AddressSpace *as) address_space_add_del_ioeventfds(as, ioeventfds, ioeventfd_nb, as->ioeventfds, as->ioeventfd_nb); - qemu_free(as->ioeventfds); + g_free(as->ioeventfds); as->ioeventfds = ioeventfds; as->ioeventfd_nb = ioeventfd_nb; } @@ -713,7 +779,7 @@ void memory_region_init(MemoryRegion *mr, QTAILQ_INIT(&mr->subregions); memset(&mr->subregions_link, 0, sizeof mr->subregions_link); QTAILQ_INIT(&mr->coalesced); - mr->name = qemu_strdup(name); + mr->name = g_strdup(name); mr->dirty_log_mask = 0; mr->ioeventfd_nb = 0; mr->ioeventfds = NULL; @@ -744,10 +810,7 @@ static uint32_t memory_region_read_thunk_n(void *_mr, unsigned size) { MemoryRegion *mr = _mr; - unsigned access_size, access_size_min, access_size_max; - uint64_t access_mask; - uint32_t data = 0, tmp; - unsigned i; + uint64_t data = 0; if (!memory_region_access_valid(mr, addr, size)) { return -1U; /* FIXME: better signalling */ @@ -758,23 +821,10 @@ static uint32_t memory_region_read_thunk_n(void *_mr, } /* FIXME: support unaligned access */ - - access_size_min = mr->ops->impl.min_access_size; - if (!access_size_min) { - access_size_min = 1; - } - access_size_max = mr->ops->impl.max_access_size; - if (!access_size_max) { - access_size_max = 4; - } - access_size = MAX(MIN(size, access_size_max), access_size_min); - access_mask = -1ULL >> (64 - access_size * 8); - addr += mr->offset; - for (i = 0; i < size; i += access_size) { - /* FIXME: big-endian support */ - tmp = mr->ops->read(mr->opaque, addr + i, access_size); - data |= (tmp & access_mask) << (i * 8); - } + access_with_adjusted_size(addr + mr->offset, &data, size, + mr->ops->impl.min_access_size, + mr->ops->impl.max_access_size, + memory_region_read_accessor, mr); return data; } @@ -785,9 +835,6 @@ static void memory_region_write_thunk_n(void *_mr, uint64_t data) { MemoryRegion *mr = _mr; - unsigned access_size, access_size_min, access_size_max; - uint64_t access_mask; - unsigned i; if (!memory_region_access_valid(mr, addr, size)) { return; /* FIXME: better signalling */ @@ -799,23 +846,10 @@ static void memory_region_write_thunk_n(void *_mr, } /* FIXME: support unaligned access */ - - access_size_min = mr->ops->impl.min_access_size; - if (!access_size_min) { - access_size_min = 1; - } - access_size_max = mr->ops->impl.max_access_size; - if (!access_size_max) { - access_size_max = 4; - } - access_size = MAX(MIN(size, access_size_max), access_size_min); - access_mask = -1ULL >> (64 - access_size * 8); - addr += mr->offset; - for (i = 0; i < size; i += access_size) { - /* FIXME: big-endian support */ - mr->ops->write(mr->opaque, addr + i, (data >> (i * 8)) & access_mask, - access_size); - } + access_with_adjusted_size(addr + mr->offset, &data, size, + mr->ops->impl.min_access_size, + mr->ops->impl.max_access_size, + memory_region_write_accessor, mr); } static uint32_t memory_region_read_thunk_b(void *mr, target_phys_addr_t addr) @@ -949,8 +983,8 @@ void memory_region_destroy(MemoryRegion *mr) assert(QTAILQ_EMPTY(&mr->subregions)); mr->destructor(mr); memory_region_clear_coalescing(mr); - qemu_free((char *)mr->name); - qemu_free(mr->ioeventfds); + g_free((char *)mr->name); + g_free(mr->ioeventfds); } uint64_t memory_region_size(MemoryRegion *mr) @@ -1061,7 +1095,7 @@ void memory_region_add_coalescing(MemoryRegion *mr, target_phys_addr_t offset, uint64_t size) { - CoalescedMemoryRange *cmr = qemu_malloc(sizeof(*cmr)); + CoalescedMemoryRange *cmr = g_malloc(sizeof(*cmr)); cmr->addr = addrrange_make(offset, size); QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link); @@ -1075,7 +1109,7 @@ void memory_region_clear_coalescing(MemoryRegion *mr) while (!QTAILQ_EMPTY(&mr->coalesced)) { cmr = QTAILQ_FIRST(&mr->coalesced); QTAILQ_REMOVE(&mr->coalesced, cmr, link); - qemu_free(cmr); + g_free(cmr); } memory_region_update_coalesced_range(mr); } @@ -1102,7 +1136,7 @@ void memory_region_add_eventfd(MemoryRegion *mr, } } ++mr->ioeventfd_nb; - mr->ioeventfds = qemu_realloc(mr->ioeventfds, + mr->ioeventfds = g_realloc(mr->ioeventfds, sizeof(*mr->ioeventfds) * mr->ioeventfd_nb); memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i], sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i)); @@ -1135,7 +1169,7 @@ void memory_region_del_eventfd(MemoryRegion *mr, memmove(&mr->ioeventfds[i], &mr->ioeventfds[i+1], sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb - (i+1))); --mr->ioeventfd_nb; - mr->ioeventfds = qemu_realloc(mr->ioeventfds, + mr->ioeventfds = g_realloc(mr->ioeventfds, sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1); memory_region_update_topology(); } |