mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-22 05:41:04 +00:00
memory: split address_space_read and address_space_write
Rather than dispatching on is_write for every iteration, make address_space_rw call one of the two functions. The amount of duplicate logic is pretty small, and memory_access_is_direct can be tweaked so that it inlines better in the callers. Backports commit eb7eeb88628074207dd611472e712af775985e73 from qemu
This commit is contained in:
parent
077ffc3bd5
commit
0688343929
233
qemu/exec.c
233
qemu/exec.c
|
@ -328,11 +328,10 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
|
||||||
|
|
||||||
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
|
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
|
||||||
{
|
{
|
||||||
if (memory_region_is_ram(mr)) {
|
if (is_write) {
|
||||||
return !(is_write && mr->readonly);
|
return memory_region_is_ram(mr) && !mr->readonly;
|
||||||
}
|
} else {
|
||||||
if (memory_region_is_romd(mr)) {
|
return memory_region_is_ram(mr) || memory_region_is_romd(mr);
|
||||||
return !is_write;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1796,8 +1795,8 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
||||||
uint8_t *buf, int len, bool is_write)
|
const uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
hwaddr l;
|
hwaddr l;
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
|
@ -1805,119 +1804,159 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
||||||
hwaddr addr1;
|
hwaddr addr1;
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
MemTxResult result = MEMTX_OK;
|
MemTxResult result = MEMTX_OK;
|
||||||
|
// Unicorn: commented out
|
||||||
|
//bool release_lock = false;
|
||||||
|
|
||||||
|
// Unicorn: commented out
|
||||||
|
//rcu_read_lock();
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
l = len;
|
l = len;
|
||||||
|
|
||||||
mr = address_space_translate(as, addr, &addr1, &l, is_write);
|
mr = address_space_translate(as, addr, &addr1, &l, true);
|
||||||
if (!mr)
|
if (!mr)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (is_write) {
|
if (!memory_access_is_direct(mr, true)) {
|
||||||
if (!memory_access_is_direct(mr, is_write)) {
|
// Unicorn: commented out
|
||||||
l = memory_access_size(mr, l, addr1);
|
//release_lock |= prepare_mmio_access(mr);
|
||||||
/* XXX: could force current_cpu to NULL to avoid
|
l = memory_access_size(mr, l, addr1);
|
||||||
potential bugs */
|
/* XXX: could force current_cpu to NULL to avoid
|
||||||
switch (l) {
|
potential bugs */
|
||||||
case 8:
|
switch (l) {
|
||||||
/* 64 bit write access */
|
case 8:
|
||||||
val = ldq_p(buf);
|
/* 64 bit write access */
|
||||||
result |= memory_region_dispatch_write(mr, addr1, val, 8,
|
val = ldq_p(buf);
|
||||||
attrs);
|
result |= memory_region_dispatch_write(mr, addr1, val, 8,
|
||||||
break;
|
attrs);
|
||||||
case 4:
|
break;
|
||||||
/* 32 bit write access */
|
case 4:
|
||||||
val = ldl_p(buf);
|
/* 32 bit write access */
|
||||||
result |= memory_region_dispatch_write(mr, addr1, val, 4,
|
val = ldl_p(buf);
|
||||||
attrs);
|
result |= memory_region_dispatch_write(mr, addr1, val, 4,
|
||||||
|
attrs);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* 16 bit write access */
|
/* 16 bit write access */
|
||||||
val = lduw_p(buf);
|
val = lduw_p(buf);
|
||||||
result |= memory_region_dispatch_write(mr, addr1, val, 2,
|
result |= memory_region_dispatch_write(mr, addr1, val, 2,
|
||||||
attrs);
|
attrs);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* 8 bit write access */
|
/* 8 bit write access */
|
||||||
val = ldub_p(buf);
|
val = ldub_p(buf);
|
||||||
result |= memory_region_dispatch_write(mr, addr1, val, 1,
|
result |= memory_region_dispatch_write(mr, addr1, val, 1,
|
||||||
attrs);
|
attrs);
|
||||||
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
abort();
|
||||||
abort();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addr1 += memory_region_get_ram_addr(mr);
|
|
||||||
/* RAM case */
|
|
||||||
ptr = qemu_get_ram_ptr(as->uc, addr1);
|
|
||||||
memcpy(ptr, buf, l);
|
|
||||||
invalidate_and_set_dirty(mr, addr1, l);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!memory_access_is_direct(mr, is_write)) {
|
addr1 += memory_region_get_ram_addr(mr);
|
||||||
/* I/O case */
|
/* RAM case */
|
||||||
l = memory_access_size(mr, l, addr1);
|
ptr = qemu_get_ram_ptr(mr->uc, addr1);
|
||||||
|
memcpy(ptr, buf, l);
|
||||||
switch (l) {
|
invalidate_and_set_dirty(mr, addr1, l);
|
||||||
case 8:
|
|
||||||
/* 64 bit read access */
|
|
||||||
result |= memory_region_dispatch_read(mr, addr1, &val, 8,
|
|
||||||
attrs);
|
|
||||||
|
|
||||||
stq_p(buf, val);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
/* 32 bit read access */
|
|
||||||
result |= memory_region_dispatch_read(mr, addr1, &val, 4,
|
|
||||||
attrs);
|
|
||||||
|
|
||||||
stl_p(buf, val);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
/* 16 bit read access */
|
|
||||||
result |= memory_region_dispatch_read(mr, addr1, &val, 2,
|
|
||||||
attrs);
|
|
||||||
|
|
||||||
stw_p(buf, val);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* 8 bit read access */
|
|
||||||
result |= memory_region_dispatch_read(mr, addr1, &val, 1,
|
|
||||||
attrs);
|
|
||||||
|
|
||||||
stb_p(buf, val);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* RAM case */
|
|
||||||
ptr = qemu_get_ram_ptr(as->uc, mr->ram_addr + addr1);
|
|
||||||
memcpy(buf, ptr, l);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Unicorn: commented out
|
||||||
|
if (release_lock) {
|
||||||
|
qemu_mutex_unlock_iothread();
|
||||||
|
release_lock = false;
|
||||||
|
}*/
|
||||||
|
|
||||||
len -= l;
|
len -= l;
|
||||||
buf += l;
|
buf += l;
|
||||||
addr += l;
|
addr += l;
|
||||||
}
|
}
|
||||||
|
// Unicorn: commented out
|
||||||
|
//rcu_read_unlock();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
|
||||||
const uint8_t *buf, int len)
|
|
||||||
{
|
|
||||||
return address_space_rw(as, addr, attrs, (uint8_t *)buf, len, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
||||||
uint8_t *buf, int len)
|
uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
return address_space_rw(as, addr, attrs, buf, len, false);
|
hwaddr l;
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint64_t val;
|
||||||
|
hwaddr addr1;
|
||||||
|
MemoryRegion *mr;
|
||||||
|
MemTxResult result = MEMTX_OK;
|
||||||
|
// Unicorn: commented out
|
||||||
|
//bool release_lock = false;
|
||||||
|
|
||||||
|
// Unicorn: commented out
|
||||||
|
//rcu_read_lock();
|
||||||
|
while (len > 0) {
|
||||||
|
l = len;
|
||||||
|
mr = address_space_translate(as, addr, &addr1, &l, false);
|
||||||
|
|
||||||
|
if (!memory_access_is_direct(mr, false)) {
|
||||||
|
/* I/O case */
|
||||||
|
// Unicorn: commented out
|
||||||
|
//release_lock |= prepare_mmio_access(mr);
|
||||||
|
l = memory_access_size(mr, l, addr1);
|
||||||
|
switch (l) {
|
||||||
|
case 8:
|
||||||
|
/* 64 bit read access */
|
||||||
|
result |= memory_region_dispatch_read(mr, addr1, &val, 8,
|
||||||
|
attrs);
|
||||||
|
stq_p(buf, val);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
/* 32 bit read access */
|
||||||
|
result |= memory_region_dispatch_read(mr, addr1, &val, 4,
|
||||||
|
attrs);
|
||||||
|
stl_p(buf, val);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
/* 16 bit read access */
|
||||||
|
result |= memory_region_dispatch_read(mr, addr1, &val, 2,
|
||||||
|
attrs);
|
||||||
|
stw_p(buf, val);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
/* 8 bit read access */
|
||||||
|
result |= memory_region_dispatch_read(mr, addr1, &val, 1,
|
||||||
|
attrs);
|
||||||
|
stb_p(buf, val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* RAM case */
|
||||||
|
ptr = qemu_get_ram_ptr(mr->uc, mr->ram_addr + addr1);
|
||||||
|
memcpy(buf, ptr, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unicorn: Commented out
|
||||||
|
if (release_lock) {
|
||||||
|
qemu_mutex_unlock_iothread();
|
||||||
|
release_lock = false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
len -= l;
|
||||||
|
buf += l;
|
||||||
|
addr += l;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unicorn: commented out
|
||||||
|
//rcu_read_unlock();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
||||||
|
uint8_t *buf, int len, bool is_write)
|
||||||
|
{
|
||||||
|
if (is_write) {
|
||||||
|
return address_space_write(as, addr, attrs, (uint8_t *)buf, len);
|
||||||
|
} else {
|
||||||
|
return address_space_read(as, addr, attrs, (uint8_t *)buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool cpu_physical_memory_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
|
bool cpu_physical_memory_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
|
||||||
int len, int is_write)
|
int len, int is_write)
|
||||||
|
|
Loading…
Reference in a new issue