memory: extract first iteration of address_space_read and address_space_write
We want to inline the case where there is only one iteration, because then the compiler can also inline the memcpy. As a start, extract everything after the first address_space_translate call. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
eb7eeb8862
commit
a203ac702e
87
exec.c
87
exec.c
@ -2468,22 +2468,19 @@ static bool prepare_mmio_access(MemoryRegion *mr)
|
|||||||
return release_lock;
|
return release_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
/* Called within RCU critical section. */
|
||||||
const uint8_t *buf, int len)
|
static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
|
||||||
|
MemTxAttrs attrs,
|
||||||
|
const uint8_t *buf,
|
||||||
|
int len, hwaddr addr1,
|
||||||
|
hwaddr l, MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
hwaddr l;
|
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
hwaddr addr1;
|
|
||||||
MemoryRegion *mr;
|
|
||||||
MemTxResult result = MEMTX_OK;
|
MemTxResult result = MEMTX_OK;
|
||||||
bool release_lock = false;
|
bool release_lock = false;
|
||||||
|
|
||||||
rcu_read_lock();
|
for (;;) {
|
||||||
while (len > 0) {
|
|
||||||
l = len;
|
|
||||||
mr = address_space_translate(as, addr, &addr1, &l, true);
|
|
||||||
|
|
||||||
if (!memory_access_is_direct(mr, true)) {
|
if (!memory_access_is_direct(mr, true)) {
|
||||||
release_lock |= prepare_mmio_access(mr);
|
release_lock |= prepare_mmio_access(mr);
|
||||||
l = memory_access_size(mr, l, addr1);
|
l = memory_access_size(mr, l, addr1);
|
||||||
@ -2533,28 +2530,50 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
|||||||
len -= l;
|
len -= l;
|
||||||
buf += l;
|
buf += l;
|
||||||
addr += l;
|
addr += l;
|
||||||
|
|
||||||
|
if (!len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
l = len;
|
||||||
|
mr = address_space_translate(as, addr, &addr1, &l, true);
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
||||||
uint8_t *buf, int len)
|
const uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
hwaddr l;
|
hwaddr l;
|
||||||
uint8_t *ptr;
|
|
||||||
uint64_t val;
|
|
||||||
hwaddr addr1;
|
hwaddr addr1;
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
MemTxResult result = MEMTX_OK;
|
MemTxResult result = MEMTX_OK;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
rcu_read_lock();
|
||||||
|
l = len;
|
||||||
|
mr = address_space_translate(as, addr, &addr1, &l, true);
|
||||||
|
result = address_space_write_continue(as, addr, attrs, buf, len,
|
||||||
|
addr1, l, mr);
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called within RCU critical section. */
|
||||||
|
MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
|
||||||
|
MemTxAttrs attrs, uint8_t *buf,
|
||||||
|
int len, hwaddr addr1, hwaddr l,
|
||||||
|
MemoryRegion *mr)
|
||||||
|
{
|
||||||
|
uint8_t *ptr;
|
||||||
|
uint64_t val;
|
||||||
|
MemTxResult result = MEMTX_OK;
|
||||||
bool release_lock = false;
|
bool release_lock = false;
|
||||||
|
|
||||||
rcu_read_lock();
|
for (;;) {
|
||||||
while (len > 0) {
|
|
||||||
l = len;
|
|
||||||
mr = address_space_translate(as, addr, &addr1, &l, false);
|
|
||||||
|
|
||||||
if (!memory_access_is_direct(mr, false)) {
|
if (!memory_access_is_direct(mr, false)) {
|
||||||
/* I/O case */
|
/* I/O case */
|
||||||
release_lock |= prepare_mmio_access(mr);
|
release_lock |= prepare_mmio_access(mr);
|
||||||
@ -2601,8 +2620,34 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
|||||||
len -= l;
|
len -= l;
|
||||||
buf += l;
|
buf += l;
|
||||||
addr += l;
|
addr += l;
|
||||||
|
|
||||||
|
if (!len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
l = len;
|
||||||
|
mr = address_space_translate(as, addr, &addr1, &l, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
|
||||||
|
uint8_t *buf, int len)
|
||||||
|
{
|
||||||
|
hwaddr l;
|
||||||
|
hwaddr addr1;
|
||||||
|
MemoryRegion *mr;
|
||||||
|
MemTxResult result = MEMTX_OK;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
rcu_read_lock();
|
||||||
|
l = len;
|
||||||
|
mr = address_space_translate(as, addr, &addr1, &l, false);
|
||||||
|
result = address_space_read_continue(as, addr, attrs, buf, len,
|
||||||
|
addr1, l, mr);
|
||||||
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1366,6 +1366,12 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
|
|||||||
int is_write, hwaddr access_len);
|
int is_write, hwaddr access_len);
|
||||||
|
|
||||||
|
|
||||||
|
/* Internal functions, part of the implementation of address_space_read. */
|
||||||
|
MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
|
||||||
|
MemTxAttrs attrs, uint8_t *buf,
|
||||||
|
int len, hwaddr addr1, hwaddr l,
|
||||||
|
MemoryRegion *mr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user