exec: introduce memory_access_is_direct

After the previous patches, this is a common test for all read/write
functions.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2013-05-24 12:29:54 +02:00
parent d17d45e95f
commit 2bbfa05d20
1 changed files with 22 additions and 17 deletions

39
exec.c
View File

@ -1856,6 +1856,18 @@ static void invalidate_and_set_dirty(hwaddr addr,
xen_modified_memory(addr, length); xen_modified_memory(addr, length);
} }
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
if (memory_region_is_ram(mr)) {
return !(is_write && mr->readonly);
}
if (memory_region_is_romd(mr)) {
return !is_write;
}
return false;
}
void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf, void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
int len, bool is_write) int len, bool is_write)
{ {
@ -1870,7 +1882,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
section = address_space_translate(as, addr, &addr1, &l, is_write); section = address_space_translate(as, addr, &addr1, &l, is_write);
if (is_write) { if (is_write) {
if (!memory_region_is_ram(section->mr)) { if (!memory_access_is_direct(section->mr, is_write)) {
/* XXX: could force cpu_single_env to NULL to avoid /* XXX: could force cpu_single_env to NULL to avoid
potential bugs */ potential bugs */
if (l >= 4 && ((addr1 & 3) == 0)) { if (l >= 4 && ((addr1 & 3) == 0)) {
@ -1889,7 +1901,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
io_mem_write(section->mr, addr1, val, 1); io_mem_write(section->mr, addr1, val, 1);
l = 1; l = 1;
} }
} else if (!section->readonly) { } else {
addr1 += memory_region_get_ram_addr(section->mr); addr1 += memory_region_get_ram_addr(section->mr);
/* RAM case */ /* RAM case */
ptr = qemu_get_ram_ptr(addr1); ptr = qemu_get_ram_ptr(addr1);
@ -1897,8 +1909,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
invalidate_and_set_dirty(addr1, l); invalidate_and_set_dirty(addr1, l);
} }
} else { } else {
if (!(memory_region_is_ram(section->mr) || if (!memory_access_is_direct(section->mr, is_write)) {
memory_region_is_romd(section->mr))) {
/* I/O case */ /* I/O case */
if (l >= 4 && ((addr1 & 3) == 0)) { if (l >= 4 && ((addr1 & 3) == 0)) {
/* 32 bit read access */ /* 32 bit read access */
@ -2053,7 +2064,7 @@ void *address_space_map(AddressSpace *as,
l = len; l = len;
section = address_space_translate(as, addr, &xlat, &l, is_write); section = address_space_translate(as, addr, &xlat, &l, is_write);
if (!(memory_region_is_ram(section->mr) && !section->readonly)) { if (!memory_access_is_direct(section->mr, is_write)) {
if (todo || bounce.buffer) { if (todo || bounce.buffer) {
break; break;
} }
@ -2143,9 +2154,7 @@ static inline uint32_t ldl_phys_internal(hwaddr addr,
section = address_space_translate(&address_space_memory, addr, &addr1, &l, section = address_space_translate(&address_space_memory, addr, &addr1, &l,
false); false);
if (l < 4 || if (l < 4 || !memory_access_is_direct(section->mr, false)) {
!(memory_region_is_ram(section->mr) ||
memory_region_is_romd(section->mr))) {
/* I/O case */ /* I/O case */
val = io_mem_read(section->mr, addr1, 4); val = io_mem_read(section->mr, addr1, 4);
#if defined(TARGET_WORDS_BIGENDIAN) #if defined(TARGET_WORDS_BIGENDIAN)
@ -2204,9 +2213,7 @@ static inline uint64_t ldq_phys_internal(hwaddr addr,
section = address_space_translate(&address_space_memory, addr, &addr1, &l, section = address_space_translate(&address_space_memory, addr, &addr1, &l,
false); false);
if (l < 8 || if (l < 8 || !memory_access_is_direct(section->mr, false)) {
!(memory_region_is_ram(section->mr) ||
memory_region_is_romd(section->mr))) {
/* I/O case */ /* I/O case */
/* XXX This is broken when device endian != cpu endian. /* XXX This is broken when device endian != cpu endian.
@ -2273,9 +2280,7 @@ static inline uint32_t lduw_phys_internal(hwaddr addr,
section = address_space_translate(&address_space_memory, addr, &addr1, &l, section = address_space_translate(&address_space_memory, addr, &addr1, &l,
false); false);
if (l < 2 || if (l < 2 || !memory_access_is_direct(section->mr, false)) {
!(memory_region_is_ram(section->mr) ||
memory_region_is_romd(section->mr))) {
/* I/O case */ /* I/O case */
val = io_mem_read(section->mr, addr1, 2); val = io_mem_read(section->mr, addr1, 2);
#if defined(TARGET_WORDS_BIGENDIAN) #if defined(TARGET_WORDS_BIGENDIAN)
@ -2334,7 +2339,7 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val)
section = address_space_translate(&address_space_memory, addr, &addr1, &l, section = address_space_translate(&address_space_memory, addr, &addr1, &l,
true); true);
if (l < 4 || !memory_region_is_ram(section->mr) || section->readonly) { if (l < 4 || !memory_access_is_direct(section->mr, true)) {
io_mem_write(section->mr, addr1, val, 4); io_mem_write(section->mr, addr1, val, 4);
} else { } else {
addr1 += memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK; addr1 += memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK;
@ -2364,7 +2369,7 @@ static inline void stl_phys_internal(hwaddr addr, uint32_t val,
section = address_space_translate(&address_space_memory, addr, &addr1, &l, section = address_space_translate(&address_space_memory, addr, &addr1, &l,
true); true);
if (l < 4 || !memory_region_is_ram(section->mr) || section->readonly) { if (l < 4 || !memory_access_is_direct(section->mr, true)) {
#if defined(TARGET_WORDS_BIGENDIAN) #if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) { if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap32(val); val = bswap32(val);
@ -2427,7 +2432,7 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val,
section = address_space_translate(&address_space_memory, addr, &addr1, &l, section = address_space_translate(&address_space_memory, addr, &addr1, &l,
true); true);
if (l < 2 || !memory_region_is_ram(section->mr) || section->readonly) { if (l < 2 || !memory_access_is_direct(section->mr, true)) {
#if defined(TARGET_WORDS_BIGENDIAN) #if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) { if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap16(val); val = bswap16(val);