* [Qemu-devel] [PATCH 0/5] Remove cpu_register_io_memory
@ 2012-03-08 17:20 Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 1/5] memory: make phys_page_find() return an unadjusted section Avi Kivity
` (4 more replies)
0 siblings, 5 replies; 15+ messages in thread
From: Avi Kivity @ 2012-03-08 17:20 UTC (permalink / raw)
To: qemu-devel
The current code allows us direct lookup from physical address (or TLB entry)
to a MemoryRegion, yet we still dispatch accesses via the ram_addr returned
by cpu_register_io_memory(). This is clumsy, so remove this extra indirection.
Avi Kivity (5):
memory: make phys_page_find() return an unadjusted section
memory: store section indices in iotlb instead of io indices
exec: fix code tlb entry misused as iotlb in get_page_addr_code()
memory: dispatch directly via MemoryRegion
memory: get rid of cpu_register_io_memory()
cpu-all.h | 8 -
exec-all.h | 9 +-
exec-obsolete.h | 3 -
exec.c | 362 ++++++++++++++++++++--------------------------------
memory.c | 13 +-
softmmu_template.h | 40 +++---
6 files changed, 168 insertions(+), 267 deletions(-)
--
1.7.9
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 1/5] memory: make phys_page_find() return an unadjusted section
2012-03-08 17:20 [Qemu-devel] [PATCH 0/5] Remove cpu_register_io_memory Avi Kivity
@ 2012-03-08 17:20 ` Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 2/5] memory: store section indices in iotlb instead of io indices Avi Kivity
` (3 subsequent siblings)
4 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-03-08 17:20 UTC (permalink / raw)
To: qemu-devel
We'd like to store the section index in the iotlb, so we can't
adjust it before returning. Return an unadjusted section and
instead introduce section_addr(), which does the adjustment later.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
exec.c | 218 ++++++++++++++++++++++++++++++----------------------------------
1 files changed, 102 insertions(+), 116 deletions(-)
diff --git a/exec.c b/exec.c
index 1e5bbd6..1fb0158 100644
--- a/exec.c
+++ b/exec.c
@@ -480,13 +480,11 @@ static void phys_page_set(target_phys_addr_t index, target_phys_addr_t nb,
phys_page_set_level(&phys_map, &index, &nb, leaf, P_L2_LEVELS - 1);
}
-static MemoryRegionSection phys_page_find(target_phys_addr_t index)
+static MemoryRegionSection *phys_page_find(target_phys_addr_t index)
{
PhysPageEntry lp = phys_map;
PhysPageEntry *p;
int i;
- MemoryRegionSection section;
- target_phys_addr_t delta;
uint16_t s_index = phys_section_unassigned;
for (i = P_L2_LEVELS - 1; i >= 0 && !lp.is_leaf; i--) {
@@ -499,15 +497,15 @@ static MemoryRegionSection phys_page_find(target_phys_addr_t index)
s_index = lp.ptr;
not_found:
- section = phys_sections[s_index];
- index <<= TARGET_PAGE_BITS;
- assert(section.offset_within_address_space <= index
- && index <= section.offset_within_address_space + section.size-1);
- delta = index - section.offset_within_address_space;
- section.offset_within_address_space += delta;
- section.offset_within_region += delta;
- section.size -= delta;
- return section;
+ return &phys_sections[s_index];
+}
+
+static target_phys_addr_t section_addr(MemoryRegionSection *section,
+ target_phys_addr_t addr)
+{
+ addr -= section->offset_within_address_space;
+ addr += section->offset_within_region;
+ return addr;
}
static void tlb_protect_code(ram_addr_t ram_addr);
@@ -1468,17 +1466,16 @@ static void breakpoint_invalidate(CPUState *env, target_ulong pc)
{
target_phys_addr_t addr;
ram_addr_t ram_addr;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
addr = cpu_get_phys_page_debug(env, pc);
section = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!(memory_region_is_ram(section.mr)
- || (section.mr->rom_device && section.mr->readable))) {
+ if (!(memory_region_is_ram(section->mr)
+ || (section->mr->rom_device && section->mr->readable))) {
return;
}
- ram_addr = (memory_region_get_ram_addr(section.mr)
- + section.offset_within_region) & TARGET_PAGE_MASK;
- ram_addr |= (pc & ~TARGET_PAGE_MASK);
+ ram_addr = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
+ + section_addr(section, addr);
tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
}
#endif
@@ -2181,7 +2178,7 @@ void tlb_set_page(CPUState *env, target_ulong vaddr,
target_phys_addr_t paddr, int prot,
int mmu_idx, target_ulong size)
{
- MemoryRegionSection section;
+ MemoryRegionSection *section;
unsigned int index;
target_ulong address;
target_ulong code_address;
@@ -2202,21 +2199,21 @@ void tlb_set_page(CPUState *env, target_ulong vaddr,
#endif
address = vaddr;
- if (!is_ram_rom_romd(§ion)) {
+ if (!is_ram_rom_romd(section)) {
/* IO memory case (romd handled later) */
address |= TLB_MMIO;
}
- if (is_ram_rom_romd(§ion)) {
- addend = (unsigned long)(memory_region_get_ram_ptr(section.mr)
- + section.offset_within_region);
+ if (is_ram_rom_romd(section)) {
+ addend = (unsigned long)memory_region_get_ram_ptr(section->mr)
+ + section_addr(section, paddr);
} else {
addend = 0;
}
- if (is_ram_rom(§ion)) {
+ if (is_ram_rom(section)) {
/* Normal RAM. */
- iotlb = (memory_region_get_ram_addr(section.mr)
- + section.offset_within_region) & TARGET_PAGE_MASK;
- if (!section.readonly)
+ iotlb = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
+ + section_addr(section, paddr);
+ if (!section->readonly)
iotlb |= io_mem_notdirty.ram_addr;
else
iotlb |= io_mem_rom.ram_addr;
@@ -2227,8 +2224,8 @@ void tlb_set_page(CPUState *env, target_ulong vaddr,
and avoid full address decoding in every device.
We can't use the high bits of pd for this because
IO_MEM_ROMD uses these as a ram address. */
- iotlb = memory_region_get_ram_addr(section.mr) & ~TARGET_PAGE_MASK;
- iotlb += section.offset_within_region;
+ iotlb = memory_region_get_ram_addr(section->mr) & ~TARGET_PAGE_MASK;
+ iotlb += section_addr(section, paddr);
}
code_address = address;
@@ -2261,14 +2258,14 @@ void tlb_set_page(CPUState *env, target_ulong vaddr,
te->addr_code = -1;
}
if (prot & PAGE_WRITE) {
- if ((memory_region_is_ram(section.mr) && section.readonly)
- || is_romd(§ion)) {
+ if ((memory_region_is_ram(section->mr) && section->readonly)
+ || is_romd(section)) {
/* Write access calls the I/O callback. */
te->addr_write = address | TLB_MMIO;
- } else if (memory_region_is_ram(section.mr)
+ } else if (memory_region_is_ram(section->mr)
&& !cpu_physical_memory_is_dirty(
- section.mr->ram_addr
- + section.offset_within_region)) {
+ section->mr->ram_addr
+ + section_addr(section, paddr))) {
te->addr_write = address | TLB_NOTDIRTY;
} else {
te->addr_write = address;
@@ -2631,22 +2628,22 @@ static void register_subpage(MemoryRegionSection *section)
subpage_t *subpage;
target_phys_addr_t base = section->offset_within_address_space
& TARGET_PAGE_MASK;
- MemoryRegionSection existing = phys_page_find(base >> TARGET_PAGE_BITS);
+ MemoryRegionSection *existing = phys_page_find(base >> TARGET_PAGE_BITS);
MemoryRegionSection subsection = {
.offset_within_address_space = base,
.size = TARGET_PAGE_SIZE,
};
target_phys_addr_t start, end;
- assert(existing.mr->subpage || existing.mr == &io_mem_unassigned);
+ assert(existing->mr->subpage || existing->mr == &io_mem_unassigned);
- if (!(existing.mr->subpage)) {
+ if (!(existing->mr->subpage)) {
subpage = subpage_init(base);
subsection.mr = &subpage->iomem;
phys_page_set(base >> TARGET_PAGE_BITS, 1,
phys_section_add(&subsection));
} else {
- subpage = container_of(existing.mr, subpage_t, iomem);
+ subpage = container_of(existing->mr, subpage_t, iomem);
}
start = section->offset_within_address_space & ~TARGET_PAGE_MASK;
end = start + section->size;
@@ -3830,7 +3827,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
uint8_t *ptr;
uint32_t val;
target_phys_addr_t page;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
while (len > 0) {
page = addr & TARGET_PAGE_MASK;
@@ -3840,12 +3837,11 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
section = phys_page_find(page >> TARGET_PAGE_BITS);
if (is_write) {
- if (!memory_region_is_ram(section.mr)) {
+ if (!memory_region_is_ram(section->mr)) {
target_phys_addr_t addr1;
- io_index = memory_region_get_ram_addr(section.mr)
+ io_index = memory_region_get_ram_addr(section->mr)
& (IO_MEM_NB_ENTRIES - 1);
- addr1 = (addr & ~TARGET_PAGE_MASK)
- + section.offset_within_region;
+ addr1 = section_addr(section, addr);
/* XXX: could force cpu_single_env to NULL to avoid
potential bugs */
if (l >= 4 && ((addr1 & 3) == 0)) {
@@ -3864,11 +3860,10 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
io_mem_write(io_index, addr1, val, 1);
l = 1;
}
- } else if (!section.readonly) {
+ } else if (!section->readonly) {
ram_addr_t addr1;
- addr1 = (memory_region_get_ram_addr(section.mr)
- + section.offset_within_region)
- | (addr & ~TARGET_PAGE_MASK);
+ addr1 = memory_region_get_ram_addr(section->mr)
+ + section_addr(section, addr);
/* RAM case */
ptr = qemu_get_ram_ptr(addr1);
memcpy(ptr, buf, l);
@@ -3882,13 +3877,12 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
qemu_put_ram_ptr(ptr);
}
} else {
- if (!is_ram_rom_romd(§ion)) {
+ if (!is_ram_rom_romd(section)) {
target_phys_addr_t addr1;
/* I/O case */
- io_index = memory_region_get_ram_addr(section.mr)
+ io_index = memory_region_get_ram_addr(section->mr)
& (IO_MEM_NB_ENTRIES - 1);
- addr1 = (addr & ~TARGET_PAGE_MASK)
- + section.offset_within_region;
+ addr1 = section_addr(section, addr);
if (l >= 4 && ((addr1 & 3) == 0)) {
/* 32 bit read access */
val = io_mem_read(io_index, addr1, 4);
@@ -3907,9 +3901,9 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
}
} else {
/* RAM case */
- ptr = qemu_get_ram_ptr(section.mr->ram_addr
- + section.offset_within_region);
- memcpy(buf, ptr + (addr & ~TARGET_PAGE_MASK), l);
+ ptr = qemu_get_ram_ptr(section->mr->ram_addr)
+ + section_addr(section, addr);
+ memcpy(buf, ptr, l);
qemu_put_ram_ptr(ptr);
}
}
@@ -3926,7 +3920,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
int l;
uint8_t *ptr;
target_phys_addr_t page;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
while (len > 0) {
page = addr & TARGET_PAGE_MASK;
@@ -3935,13 +3929,12 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
l = len;
section = phys_page_find(page >> TARGET_PAGE_BITS);
- if (!is_ram_rom_romd(§ion)) {
+ if (!is_ram_rom_romd(section)) {
/* do nothing */
} else {
unsigned long addr1;
- addr1 = (memory_region_get_ram_addr(section.mr)
- + section.offset_within_region)
- + (addr & ~TARGET_PAGE_MASK);
+ addr1 = memory_region_get_ram_addr(section->mr)
+ + section_addr(section, addr);
/* ROM/RAM case */
ptr = qemu_get_ram_ptr(addr1);
memcpy(ptr, buf, l);
@@ -4014,7 +4007,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
target_phys_addr_t todo = 0;
int l;
target_phys_addr_t page;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
ram_addr_t raddr = RAM_ADDR_MAX;
ram_addr_t rlen;
void *ret;
@@ -4026,7 +4019,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
l = len;
section = phys_page_find(page >> TARGET_PAGE_BITS);
- if (!(memory_region_is_ram(section.mr) && !section.readonly)) {
+ if (!(memory_region_is_ram(section->mr) && !section->readonly)) {
if (todo || bounce.buffer) {
break;
}
@@ -4041,9 +4034,8 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
return bounce.buffer;
}
if (!todo) {
- raddr = memory_region_get_ram_addr(section.mr)
- + section.offset_within_region
- + (addr & ~TARGET_PAGE_MASK);
+ raddr = memory_region_get_ram_addr(section->mr)
+ + section_addr(section, addr);
}
len -= l;
@@ -4102,15 +4094,15 @@ static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
int io_index;
uint8_t *ptr;
uint32_t val;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!is_ram_rom_romd(§ion)) {
+ if (!is_ram_rom_romd(section)) {
/* I/O case */
- io_index = memory_region_get_ram_addr(section.mr)
+ io_index = memory_region_get_ram_addr(section->mr)
& (IO_MEM_NB_ENTRIES - 1);
- addr = (addr & ~TARGET_PAGE_MASK) + section.offset_within_region;
+ addr = section_addr(section, addr);
val = io_mem_read(io_index, addr, 4);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
@@ -4123,10 +4115,9 @@ static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
#endif
} else {
/* RAM case */
- ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section.mr)
+ ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
& TARGET_PAGE_MASK)
- + section.offset_within_region) +
- (addr & ~TARGET_PAGE_MASK);
+ + section_addr(section, addr));
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
val = ldl_le_p(ptr);
@@ -4164,15 +4155,15 @@ static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
int io_index;
uint8_t *ptr;
uint64_t val;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!is_ram_rom_romd(§ion)) {
+ if (!is_ram_rom_romd(section)) {
/* I/O case */
- io_index = memory_region_get_ram_addr(section.mr)
+ io_index = memory_region_get_ram_addr(section->mr)
& (IO_MEM_NB_ENTRIES - 1);
- addr = (addr & ~TARGET_PAGE_MASK) + section.offset_within_region;
+ addr = section_addr(section, addr);
/* XXX This is broken when device endian != cpu endian.
Fix and add "endian" variable check */
@@ -4185,10 +4176,9 @@ static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
#endif
} else {
/* RAM case */
- ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section.mr)
+ ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
& TARGET_PAGE_MASK)
- + section.offset_within_region)
- + (addr & ~TARGET_PAGE_MASK);
+ + section_addr(section, addr));
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
val = ldq_le_p(ptr);
@@ -4234,15 +4224,15 @@ static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
int io_index;
uint8_t *ptr;
uint64_t val;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!is_ram_rom_romd(§ion)) {
+ if (!is_ram_rom_romd(section)) {
/* I/O case */
- io_index = memory_region_get_ram_addr(section.mr)
+ io_index = memory_region_get_ram_addr(section->mr)
& (IO_MEM_NB_ENTRIES - 1);
- addr = (addr & ~TARGET_PAGE_MASK) + section.offset_within_region;
+ addr = section_addr(section, addr);
val = io_mem_read(io_index, addr, 2);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
@@ -4255,10 +4245,9 @@ static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
#endif
} else {
/* RAM case */
- ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section.mr)
+ ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
& TARGET_PAGE_MASK)
- + section.offset_within_region)
- + (addr & ~TARGET_PAGE_MASK);
+ + section_addr(section, addr));
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
val = lduw_le_p(ptr);
@@ -4296,23 +4285,22 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
{
int io_index;
uint8_t *ptr;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!memory_region_is_ram(section.mr) || section.readonly) {
- if (memory_region_is_ram(section.mr)) {
+ if (!memory_region_is_ram(section->mr) || section->readonly) {
+ if (memory_region_is_ram(section->mr)) {
io_index = io_mem_rom.ram_addr;
} else {
- io_index = memory_region_get_ram_addr(section.mr);
+ io_index = memory_region_get_ram_addr(section->mr);
}
- addr = (addr & ~TARGET_PAGE_MASK) + section.offset_within_region;
+ addr = section_addr(section, addr);
io_mem_write(io_index, addr, val, 4);
} else {
- unsigned long addr1 = (memory_region_get_ram_addr(section.mr)
+ unsigned long addr1 = (memory_region_get_ram_addr(section->mr)
& TARGET_PAGE_MASK)
- + section.offset_within_region
- + (addr & ~TARGET_PAGE_MASK);
+ + section_addr(section, addr);
ptr = qemu_get_ram_ptr(addr1);
stl_p(ptr, val);
@@ -4332,18 +4320,18 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
{
int io_index;
uint8_t *ptr;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!memory_region_is_ram(section.mr) || section.readonly) {
- if (memory_region_is_ram(section.mr)) {
+ if (!memory_region_is_ram(section->mr) || section->readonly) {
+ if (memory_region_is_ram(section->mr)) {
io_index = io_mem_rom.ram_addr;
} else {
- io_index = memory_region_get_ram_addr(section.mr)
+ io_index = memory_region_get_ram_addr(section->mr)
& (IO_MEM_NB_ENTRIES - 1);
}
- addr = (addr & ~TARGET_PAGE_MASK) + section.offset_within_region;
+ addr = section_addr(section, addr);
#ifdef TARGET_WORDS_BIGENDIAN
io_mem_write(io_index, addr, val >> 32, 4);
io_mem_write(io_index, addr + 4, (uint32_t)val, 4);
@@ -4352,10 +4340,9 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
io_mem_write(io_index, addr + 4, val >> 32, 4);
#endif
} else {
- ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section.mr)
+ ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
& TARGET_PAGE_MASK)
- + section.offset_within_region)
- + (addr & ~TARGET_PAGE_MASK);
+ + section_addr(section, addr));
stq_p(ptr, val);
}
}
@@ -4366,18 +4353,18 @@ static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
{
int io_index;
uint8_t *ptr;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!memory_region_is_ram(section.mr) || section.readonly) {
- if (memory_region_is_ram(section.mr)) {
+ if (!memory_region_is_ram(section->mr) || section->readonly) {
+ if (memory_region_is_ram(section->mr)) {
io_index = io_mem_rom.ram_addr;
} else {
- io_index = memory_region_get_ram_addr(section.mr)
+ io_index = memory_region_get_ram_addr(section->mr)
& (IO_MEM_NB_ENTRIES - 1);
}
- addr = (addr & ~TARGET_PAGE_MASK) + section.offset_within_region;
+ addr = section_addr(section, addr);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap32(val);
@@ -4390,9 +4377,8 @@ static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
io_mem_write(io_index, addr, val, 4);
} else {
unsigned long addr1;
- addr1 = (memory_region_get_ram_addr(section.mr) & TARGET_PAGE_MASK)
- + section.offset_within_region
- + (addr & ~TARGET_PAGE_MASK);
+ addr1 = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
+ + section_addr(section, addr);
/* RAM case */
ptr = qemu_get_ram_ptr(addr1);
switch (endian) {
@@ -4444,18 +4430,18 @@ static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
{
int io_index;
uint8_t *ptr;
- MemoryRegionSection section;
+ MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
- if (!memory_region_is_ram(section.mr) || section.readonly) {
- if (memory_region_is_ram(section.mr)) {
+ if (!memory_region_is_ram(section->mr) || section->readonly) {
+ if (memory_region_is_ram(section->mr)) {
io_index = io_mem_rom.ram_addr;
} else {
- io_index = memory_region_get_ram_addr(section.mr)
+ io_index = memory_region_get_ram_addr(section->mr)
& (IO_MEM_NB_ENTRIES - 1);
}
- addr = (addr & ~TARGET_PAGE_MASK) + section.offset_within_region;
+ addr = section_addr(section, addr);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap16(val);
@@ -4468,8 +4454,8 @@ static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
io_mem_write(io_index, addr, val, 2);
} else {
unsigned long addr1;
- addr1 = (memory_region_get_ram_addr(section.mr) & TARGET_PAGE_MASK)
- + section.offset_within_region + (addr & ~TARGET_PAGE_MASK);
+ addr1 = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
+ + section_addr(section, addr);
/* RAM case */
ptr = qemu_get_ram_ptr(addr1);
switch (endian) {
--
1.7.9
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 2/5] memory: store section indices in iotlb instead of io indices
2012-03-08 17:20 [Qemu-devel] [PATCH 0/5] Remove cpu_register_io_memory Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 1/5] memory: make phys_page_find() return an unadjusted section Avi Kivity
@ 2012-03-08 17:20 ` Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 3/5] exec: fix code tlb entry misused as iotlb in get_page_addr_code() Avi Kivity
` (2 subsequent siblings)
4 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-03-08 17:20 UTC (permalink / raw)
To: qemu-devel
A step towards eliminating io indices.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
exec-all.h | 1 +
exec.c | 23 +++++++++++++++++++----
softmmu_template.h | 8 ++++----
3 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/exec-all.h b/exec-all.h
index 51d01f2..3ffe9dd 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -299,6 +299,7 @@ extern void *tci_tb_ptr;
#if !defined(CONFIG_USER_ONLY)
+target_phys_addr_t section_to_ioaddr(target_phys_addr_t section_io_addr);
uint64_t io_mem_read(int index, target_phys_addr_t addr, unsigned size);
void io_mem_write(int index, target_phys_addr_t addr, uint64_t value,
unsigned size);
diff --git a/exec.c b/exec.c
index 1fb0158..a35eb4f 100644
--- a/exec.c
+++ b/exec.c
@@ -191,6 +191,9 @@
static MemoryRegionSection *phys_sections;
static unsigned phys_sections_nb, phys_sections_nb_alloc;
static uint16_t phys_section_unassigned;
+static uint16_t phys_section_notdirty;
+static uint16_t phys_section_rom;
+static uint16_t phys_section_watch;
struct PhysPageEntry {
uint16_t is_leaf : 1;
@@ -2214,9 +2217,9 @@ void tlb_set_page(CPUState *env, target_ulong vaddr,
iotlb = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
+ section_addr(section, paddr);
if (!section->readonly)
- iotlb |= io_mem_notdirty.ram_addr;
+ iotlb |= phys_section_notdirty;
else
- iotlb |= io_mem_rom.ram_addr;
+ iotlb |= phys_section_rom;
} else {
/* IO handlers are currently passed a physical address.
It would be nice to pass an offset from the base address
@@ -2224,7 +2227,7 @@ void tlb_set_page(CPUState *env, target_ulong vaddr,
and avoid full address decoding in every device.
We can't use the high bits of pd for this because
IO_MEM_ROMD uses these as a ram address. */
- iotlb = memory_region_get_ram_addr(section->mr) & ~TARGET_PAGE_MASK;
+ iotlb = section - phys_sections;
iotlb += section_addr(section, paddr);
}
@@ -2235,7 +2238,7 @@ void tlb_set_page(CPUState *env, target_ulong vaddr,
if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
/* Avoid trapping reads of pages with a write breakpoint. */
if ((prot & PAGE_WRITE) || (wp->flags & BP_MEM_READ)) {
- iotlb = io_mem_watch.ram_addr + paddr;
+ iotlb = phys_section_watch + paddr;
address |= TLB_MMIO;
break;
}
@@ -3559,6 +3562,15 @@ static uint16_t dummy_section(MemoryRegion *mr)
return phys_section_add(§ion);
}
+target_phys_addr_t section_to_ioaddr(target_phys_addr_t section_io_addr)
+{
+ MemoryRegionSection *section;
+
+ section = &phys_sections[section_io_addr & ~TARGET_PAGE_MASK];
+ return (section_io_addr & TARGET_PAGE_MASK)
+ | (section->mr->ram_addr & ~TARGET_PAGE_MASK);
+}
+
static void io_mem_init(void)
{
int i;
@@ -3586,6 +3598,9 @@ static void core_begin(MemoryListener *listener)
phys_sections_clear();
phys_map.ptr = PHYS_MAP_NODE_NIL;
phys_section_unassigned = dummy_section(&io_mem_unassigned);
+ phys_section_notdirty = dummy_section(&io_mem_notdirty);
+ phys_section_rom = dummy_section(&io_mem_rom);
+ phys_section_watch = dummy_section(&io_mem_watch);
}
static void core_commit(MemoryListener *listener)
diff --git a/softmmu_template.h b/softmmu_template.h
index 97020f8..7c7e15b 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -110,7 +110,7 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
retaddr = GETPC();
- ioaddr = env->iotlb[mmu_idx][index];
+ ioaddr = section_to_ioaddr(env->iotlb[mmu_idx][index]);
res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
/* slow unaligned access (it spans two pages or IO) */
@@ -164,7 +164,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
/* IO access */
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
- ioaddr = env->iotlb[mmu_idx][index];
+ ioaddr = section_to_ioaddr(env->iotlb[mmu_idx][index]);
res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
@@ -251,7 +251,7 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
retaddr = GETPC();
- ioaddr = env->iotlb[mmu_idx][index];
+ ioaddr = section_to_ioaddr(env->iotlb[mmu_idx][index]);
glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
@@ -303,7 +303,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
/* IO access */
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
- ioaddr = env->iotlb[mmu_idx][index];
+ ioaddr = section_to_ioaddr(env->iotlb[mmu_idx][index]);
glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
--
1.7.9
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 3/5] exec: fix code tlb entry misused as iotlb in get_page_addr_code()
2012-03-08 17:20 [Qemu-devel] [PATCH 0/5] Remove cpu_register_io_memory Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 1/5] memory: make phys_page_find() return an unadjusted section Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 2/5] memory: store section indices in iotlb instead of io indices Avi Kivity
@ 2012-03-08 17:20 ` Avi Kivity
2012-03-15 19:23 ` jcmvbkbc
2012-03-08 17:20 ` [Qemu-devel] [PATCH 4/5] memory: dispatch directly via MemoryRegion Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 5/5] memory: get rid of cpu_register_io_memory() Avi Kivity
4 siblings, 1 reply; 15+ messages in thread
From: Avi Kivity @ 2012-03-08 17:20 UTC (permalink / raw)
To: qemu-devel
get_page_addr_code() reads a code tlb entry, but interprets it as an
iotlb entry. This works by accident since the low bits of a RAM code
tlb entry are clear, and match a RAM iotlb entry. This accident is
about to unhappen, so fix the code to use an iotlb entry (using the
code entry with TLB_MMIO may fail if the page is a watchpoint).
Signed-off-by: Avi Kivity <avi@redhat.com>
---
exec.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/exec.c b/exec.c
index a35eb4f..f26d1b0 100644
--- a/exec.c
+++ b/exec.c
@@ -4685,7 +4685,7 @@ tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
(addr & TARGET_PAGE_MASK))) {
ldub_code(addr);
}
- pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK;
+ pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
if (pd != io_mem_ram.ram_addr && pd != io_mem_rom.ram_addr
&& !io_mem_region[pd]->rom_device) {
#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
--
1.7.9
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 4/5] memory: dispatch directly via MemoryRegion
2012-03-08 17:20 [Qemu-devel] [PATCH 0/5] Remove cpu_register_io_memory Avi Kivity
` (2 preceding siblings ...)
2012-03-08 17:20 ` [Qemu-devel] [PATCH 3/5] exec: fix code tlb entry misused as iotlb in get_page_addr_code() Avi Kivity
@ 2012-03-08 17:20 ` Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 5/5] memory: get rid of cpu_register_io_memory() Avi Kivity
4 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-03-08 17:20 UTC (permalink / raw)
To: qemu-devel
Instead of indirecting via io_mem_region, dispatch directly
through the MemoryRegion obtained from the iotlb or phys_page_find().
Signed-off-by: Avi Kivity <avi@redhat.com>
---
exec-all.h | 9 +++--
exec.c | 102 ++++++++++++++++++---------------------------------
memory.c | 8 ++--
softmmu_template.h | 48 ++++++++++++------------
4 files changed, 69 insertions(+), 98 deletions(-)
diff --git a/exec-all.h b/exec-all.h
index 3ffe9dd..4e8c7f5 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -299,10 +299,11 @@ extern void *tci_tb_ptr;
#if !defined(CONFIG_USER_ONLY)
-target_phys_addr_t section_to_ioaddr(target_phys_addr_t section_io_addr);
-uint64_t io_mem_read(int index, target_phys_addr_t addr, unsigned size);
-void io_mem_write(int index, target_phys_addr_t addr, uint64_t value,
- unsigned size);
+struct MemoryRegion *iotlb_to_region(target_phys_addr_t index);
+uint64_t io_mem_read(struct MemoryRegion *mr, target_phys_addr_t addr,
+ unsigned size);
+void io_mem_write(struct MemoryRegion *mr, target_phys_addr_t addr,
+ uint64_t value, unsigned size);
extern struct MemoryRegion *io_mem_region[IO_MEM_NB_ENTRIES];
void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx,
diff --git a/exec.c b/exec.c
index f26d1b0..6e14048 100644
--- a/exec.c
+++ b/exec.c
@@ -3399,7 +3399,7 @@ static uint64_t subpage_read(void *opaque, target_phys_addr_t addr,
addr += mmio->base;
addr -= section->offset_within_address_space;
addr += section->offset_within_region;
- return io_mem_read(section->mr->ram_addr, addr, len);
+ return io_mem_read(section->mr, addr, len);
}
static void subpage_write(void *opaque, target_phys_addr_t addr,
@@ -3418,7 +3418,7 @@ static void subpage_write(void *opaque, target_phys_addr_t addr,
addr += mmio->base;
addr -= section->offset_within_address_space;
addr += section->offset_within_region;
- io_mem_write(section->mr->ram_addr, addr, value, len);
+ io_mem_write(section->mr, addr, value, len);
}
static const MemoryRegionOps subpage_ops = {
@@ -3562,13 +3562,9 @@ static uint16_t dummy_section(MemoryRegion *mr)
return phys_section_add(§ion);
}
-target_phys_addr_t section_to_ioaddr(target_phys_addr_t section_io_addr)
+MemoryRegion *iotlb_to_region(target_phys_addr_t index)
{
- MemoryRegionSection *section;
-
- section = &phys_sections[section_io_addr & ~TARGET_PAGE_MASK];
- return (section_io_addr & TARGET_PAGE_MASK)
- | (section->mr->ram_addr & ~TARGET_PAGE_MASK);
+ return phys_sections[index & ~TARGET_PAGE_MASK].mr;
}
static void io_mem_init(void)
@@ -3838,7 +3834,7 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
int len, int is_write)
{
- int l, io_index;
+ int l;
uint8_t *ptr;
uint32_t val;
target_phys_addr_t page;
@@ -3854,25 +3850,23 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
if (is_write) {
if (!memory_region_is_ram(section->mr)) {
target_phys_addr_t addr1;
- io_index = memory_region_get_ram_addr(section->mr)
- & (IO_MEM_NB_ENTRIES - 1);
addr1 = section_addr(section, addr);
/* XXX: could force cpu_single_env to NULL to avoid
potential bugs */
if (l >= 4 && ((addr1 & 3) == 0)) {
/* 32 bit write access */
val = ldl_p(buf);
- io_mem_write(io_index, addr1, val, 4);
+ io_mem_write(section->mr, addr1, val, 4);
l = 4;
} else if (l >= 2 && ((addr1 & 1) == 0)) {
/* 16 bit write access */
val = lduw_p(buf);
- io_mem_write(io_index, addr1, val, 2);
+ io_mem_write(section->mr, addr1, val, 2);
l = 2;
} else {
/* 8 bit write access */
val = ldub_p(buf);
- io_mem_write(io_index, addr1, val, 1);
+ io_mem_write(section->mr, addr1, val, 1);
l = 1;
}
} else if (!section->readonly) {
@@ -3895,22 +3889,20 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
if (!is_ram_rom_romd(section)) {
target_phys_addr_t addr1;
/* I/O case */
- io_index = memory_region_get_ram_addr(section->mr)
- & (IO_MEM_NB_ENTRIES - 1);
addr1 = section_addr(section, addr);
if (l >= 4 && ((addr1 & 3) == 0)) {
/* 32 bit read access */
- val = io_mem_read(io_index, addr1, 4);
+ val = io_mem_read(section->mr, addr1, 4);
stl_p(buf, val);
l = 4;
} else if (l >= 2 && ((addr1 & 1) == 0)) {
/* 16 bit read access */
- val = io_mem_read(io_index, addr1, 2);
+ val = io_mem_read(section->mr, addr1, 2);
stw_p(buf, val);
l = 2;
} else {
/* 8 bit read access */
- val = io_mem_read(io_index, addr1, 1);
+ val = io_mem_read(section->mr, addr1, 1);
stb_p(buf, val);
l = 1;
}
@@ -4106,7 +4098,6 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
enum device_endian endian)
{
- int io_index;
uint8_t *ptr;
uint32_t val;
MemoryRegionSection *section;
@@ -4115,10 +4106,8 @@ static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
if (!is_ram_rom_romd(section)) {
/* I/O case */
- io_index = memory_region_get_ram_addr(section->mr)
- & (IO_MEM_NB_ENTRIES - 1);
addr = section_addr(section, addr);
- val = io_mem_read(io_index, addr, 4);
+ val = io_mem_read(section->mr, addr, 4);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap32(val);
@@ -4167,7 +4156,6 @@ uint32_t ldl_be_phys(target_phys_addr_t addr)
static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
enum device_endian endian)
{
- int io_index;
uint8_t *ptr;
uint64_t val;
MemoryRegionSection *section;
@@ -4176,18 +4164,16 @@ static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
if (!is_ram_rom_romd(section)) {
/* I/O case */
- io_index = memory_region_get_ram_addr(section->mr)
- & (IO_MEM_NB_ENTRIES - 1);
addr = section_addr(section, addr);
/* XXX This is broken when device endian != cpu endian.
Fix and add "endian" variable check */
#ifdef TARGET_WORDS_BIGENDIAN
- val = io_mem_read(io_index, addr, 4) << 32;
- val |= io_mem_read(io_index, addr + 4, 4);
+ val = io_mem_read(section->mr, addr, 4) << 32;
+ val |= io_mem_read(section->mr, addr + 4, 4);
#else
- val = io_mem_read(io_index, addr, 4);
- val |= io_mem_read(io_index, addr + 4, 4) << 32;
+ val = io_mem_read(section->mr, addr, 4);
+ val |= io_mem_read(section->mr, addr + 4, 4) << 32;
#endif
} else {
/* RAM case */
@@ -4236,7 +4222,6 @@ uint32_t ldub_phys(target_phys_addr_t addr)
static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
enum device_endian endian)
{
- int io_index;
uint8_t *ptr;
uint64_t val;
MemoryRegionSection *section;
@@ -4245,10 +4230,8 @@ static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
if (!is_ram_rom_romd(section)) {
/* I/O case */
- io_index = memory_region_get_ram_addr(section->mr)
- & (IO_MEM_NB_ENTRIES - 1);
addr = section_addr(section, addr);
- val = io_mem_read(io_index, addr, 2);
+ val = io_mem_read(section->mr, addr, 2);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap16(val);
@@ -4298,20 +4281,17 @@ uint32_t lduw_be_phys(target_phys_addr_t addr)
bits are used to track modified PTEs */
void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
{
- int io_index;
uint8_t *ptr;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
if (!memory_region_is_ram(section->mr) || section->readonly) {
+ addr = section_addr(section, addr);
if (memory_region_is_ram(section->mr)) {
- io_index = io_mem_rom.ram_addr;
- } else {
- io_index = memory_region_get_ram_addr(section->mr);
+ section = &phys_sections[phys_section_rom];
}
- addr = section_addr(section, addr);
- io_mem_write(io_index, addr, val, 4);
+ io_mem_write(section->mr, addr, val, 4);
} else {
unsigned long addr1 = (memory_region_get_ram_addr(section->mr)
& TARGET_PAGE_MASK)
@@ -4333,26 +4313,22 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
{
- int io_index;
uint8_t *ptr;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
if (!memory_region_is_ram(section->mr) || section->readonly) {
+ addr = section_addr(section, addr);
if (memory_region_is_ram(section->mr)) {
- io_index = io_mem_rom.ram_addr;
- } else {
- io_index = memory_region_get_ram_addr(section->mr)
- & (IO_MEM_NB_ENTRIES - 1);
+ section = &phys_sections[phys_section_rom];
}
- addr = section_addr(section, addr);
#ifdef TARGET_WORDS_BIGENDIAN
- io_mem_write(io_index, addr, val >> 32, 4);
- io_mem_write(io_index, addr + 4, (uint32_t)val, 4);
+ io_mem_write(section->mr, addr, val >> 32, 4);
+ io_mem_write(section->mr, addr + 4, (uint32_t)val, 4);
#else
- io_mem_write(io_index, addr, (uint32_t)val, 4);
- io_mem_write(io_index, addr + 4, val >> 32, 4);
+ io_mem_write(section->mr, addr, (uint32_t)val, 4);
+ io_mem_write(section->mr, addr + 4, val >> 32, 4);
#endif
} else {
ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)
@@ -4366,20 +4342,16 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
enum device_endian endian)
{
- int io_index;
uint8_t *ptr;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
if (!memory_region_is_ram(section->mr) || section->readonly) {
+ addr = section_addr(section, addr);
if (memory_region_is_ram(section->mr)) {
- io_index = io_mem_rom.ram_addr;
- } else {
- io_index = memory_region_get_ram_addr(section->mr)
- & (IO_MEM_NB_ENTRIES - 1);
+ section = &phys_sections[phys_section_rom];
}
- addr = section_addr(section, addr);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap32(val);
@@ -4389,7 +4361,7 @@ static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
val = bswap32(val);
}
#endif
- io_mem_write(io_index, addr, val, 4);
+ io_mem_write(section->mr, addr, val, 4);
} else {
unsigned long addr1;
addr1 = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
@@ -4443,20 +4415,16 @@ void stb_phys(target_phys_addr_t addr, uint32_t val)
static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
enum device_endian endian)
{
- int io_index;
uint8_t *ptr;
MemoryRegionSection *section;
section = phys_page_find(addr >> TARGET_PAGE_BITS);
if (!memory_region_is_ram(section->mr) || section->readonly) {
+ addr = section_addr(section, addr);
if (memory_region_is_ram(section->mr)) {
- io_index = io_mem_rom.ram_addr;
- } else {
- io_index = memory_region_get_ram_addr(section->mr)
- & (IO_MEM_NB_ENTRIES - 1);
+ section = &phys_sections[phys_section_rom];
}
- addr = section_addr(section, addr);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap16(val);
@@ -4466,7 +4434,7 @@ static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
val = bswap16(val);
}
#endif
- io_mem_write(io_index, addr, val, 2);
+ io_mem_write(section->mr, addr, val, 2);
} else {
unsigned long addr1;
addr1 = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK)
@@ -4678,6 +4646,7 @@ tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
{
int mmu_idx, page_index, pd;
void *p;
+ MemoryRegion *mr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = cpu_mmu_index(env1);
@@ -4686,8 +4655,9 @@ tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
ldub_code(addr);
}
pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
- if (pd != io_mem_ram.ram_addr && pd != io_mem_rom.ram_addr
- && !io_mem_region[pd]->rom_device) {
+ mr = iotlb_to_region(pd);
+ if (mr != &io_mem_ram && mr != &io_mem_rom
+ && mr != &io_mem_notdirty && !mr->rom_device) {
#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
cpu_unassigned_access(env1, addr, 0, 1, 0, 4);
#else
diff --git a/memory.c b/memory.c
index 4c3dc49..bc76f55 100644
--- a/memory.c
+++ b/memory.c
@@ -1501,15 +1501,15 @@ void set_system_io_map(MemoryRegion *mr)
memory_region_update_topology(NULL);
}
-uint64_t io_mem_read(int io_index, target_phys_addr_t addr, unsigned size)
+uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
{
- return memory_region_dispatch_read(io_mem_region[io_index], addr, size);
+ return memory_region_dispatch_read(mr, addr, size);
}
-void io_mem_write(int io_index, target_phys_addr_t addr,
+void io_mem_write(MemoryRegion *mr, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
- memory_region_dispatch_write(io_mem_region[io_index], addr, val, size);
+ memory_region_dispatch_write(mr, addr, val, size);
}
typedef struct MemoryRegionList MemoryRegionList;
diff --git a/softmmu_template.h b/softmmu_template.h
index 7c7e15b..e395020 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -62,27 +62,27 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
void *retaddr)
{
DATA_TYPE res;
- int index;
- index = physaddr & (IO_MEM_NB_ENTRIES - 1);
+ MemoryRegion *mr = iotlb_to_region(physaddr);
+
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
env->mem_io_pc = (unsigned long)retaddr;
- if (index != io_mem_ram.ram_addr && index != io_mem_rom.ram_addr
- && index != io_mem_unassigned.ram_addr
- && index != io_mem_notdirty.ram_addr
+ if (mr != &io_mem_ram && mr != &io_mem_rom
+ && mr != &io_mem_unassigned
+ && mr != &io_mem_notdirty
&& !can_do_io(env)) {
cpu_io_recompile(env, retaddr);
}
env->mem_io_vaddr = addr;
#if SHIFT <= 2
- res = io_mem_read(index, physaddr, 1 << SHIFT);
+ res = io_mem_read(mr, physaddr, 1 << SHIFT);
#else
#ifdef TARGET_WORDS_BIGENDIAN
- res = io_mem_read(index, physaddr, 4) << 32;
- res |= io_mem_read(index, physaddr + 4, 4);
+ res = io_mem_read(mr, physaddr, 4) << 32;
+ res |= io_mem_read(mr, physaddr + 4, 4);
#else
- res = io_mem_read(index, physaddr, 4);
- res |= io_mem_read(index, physaddr + 4, 4) << 32;
+ res = io_mem_read(mr, physaddr, 4);
+ res |= io_mem_read(mr, physaddr + 4, 4) << 32;
#endif
#endif /* SHIFT > 2 */
return res;
@@ -110,7 +110,7 @@ DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
retaddr = GETPC();
- ioaddr = section_to_ioaddr(env->iotlb[mmu_idx][index]);
+ ioaddr = env->iotlb[mmu_idx][index];
res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
/* slow unaligned access (it spans two pages or IO) */
@@ -164,7 +164,7 @@ static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
/* IO access */
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
- ioaddr = section_to_ioaddr(env->iotlb[mmu_idx][index]);
+ ioaddr = env->iotlb[mmu_idx][index];
res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
@@ -207,12 +207,12 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
target_ulong addr,
void *retaddr)
{
- int index;
- index = physaddr & (IO_MEM_NB_ENTRIES - 1);
+ MemoryRegion *mr = iotlb_to_region(physaddr);
+
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
- if (index != io_mem_ram.ram_addr && index != io_mem_rom.ram_addr
- && index != io_mem_unassigned.ram_addr
- && index != io_mem_notdirty.ram_addr
+ if (mr != &io_mem_ram && mr != &io_mem_rom
+ && mr != &io_mem_unassigned
+ && mr != &io_mem_notdirty
&& !can_do_io(env)) {
cpu_io_recompile(env, retaddr);
}
@@ -220,14 +220,14 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
env->mem_io_vaddr = addr;
env->mem_io_pc = (unsigned long)retaddr;
#if SHIFT <= 2
- io_mem_write(index, physaddr, val, 1 << SHIFT);
+ io_mem_write(mr, physaddr, val, 1 << SHIFT);
#else
#ifdef TARGET_WORDS_BIGENDIAN
- io_mem_write(index, physaddr, (val >> 32), 4);
- io_mem_write(index, physaddr + 4, (uint32_t)val, 4);
+ io_mem_write(mr, physaddr, (val >> 32), 4);
+ io_mem_write(mr, physaddr + 4, (uint32_t)val, 4);
#else
- io_mem_write(index, physaddr, (uint32_t)val, 4);
- io_mem_write(index, physaddr + 4, val >> 32, 4);
+ io_mem_write(mr, physaddr, (uint32_t)val, 4);
+ io_mem_write(mr, physaddr + 4, val >> 32, 4);
#endif
#endif /* SHIFT > 2 */
}
@@ -251,7 +251,7 @@ void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
retaddr = GETPC();
- ioaddr = section_to_ioaddr(env->iotlb[mmu_idx][index]);
+ ioaddr = env->iotlb[mmu_idx][index];
glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
@@ -303,7 +303,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
/* IO access */
if ((addr & (DATA_SIZE - 1)) != 0)
goto do_unaligned_access;
- ioaddr = section_to_ioaddr(env->iotlb[mmu_idx][index]);
+ ioaddr = env->iotlb[mmu_idx][index];
glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
} else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
do_unaligned_access:
--
1.7.9
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 5/5] memory: get rid of cpu_register_io_memory()
2012-03-08 17:20 [Qemu-devel] [PATCH 0/5] Remove cpu_register_io_memory Avi Kivity
` (3 preceding siblings ...)
2012-03-08 17:20 ` [Qemu-devel] [PATCH 4/5] memory: dispatch directly via MemoryRegion Avi Kivity
@ 2012-03-08 17:20 ` Avi Kivity
2012-03-19 4:52 ` TeLeMan
4 siblings, 1 reply; 15+ messages in thread
From: Avi Kivity @ 2012-03-08 17:20 UTC (permalink / raw)
To: qemu-devel
The return value of cpu_register_io_memory() is no longer used anywhere, so
we can remove it and all associated data and code.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
cpu-all.h | 8 -------
exec-all.h | 1 -
exec-obsolete.h | 3 --
exec.c | 57 -------------------------------------------------------
memory.c | 5 +---
5 files changed, 1 insertions(+), 73 deletions(-)
diff --git a/cpu-all.h b/cpu-all.h
index 80e6d42..b87f2ce 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -498,14 +498,6 @@ extern RAMList ram_list;
extern const char *mem_path;
extern int mem_prealloc;
-/* physical memory access */
-
-/* MMIO pages are identified by a combination of an IO device index and
- 3 flags. The ROMD code stores the page ram offset in iotlb entry,
- so only a limited number of ids are avaiable. */
-
-#define IO_MEM_NB_ENTRIES (1 << TARGET_PAGE_BITS)
-
/* Flags stored in the low bits of the TLB virtual address. These are
defined so that fast path ram access is all zeros. */
/* Zero if TLB entry is valid. */
diff --git a/exec-all.h b/exec-all.h
index 4e8c7f5..3ec60a2 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -304,7 +304,6 @@ uint64_t io_mem_read(struct MemoryRegion *mr, target_phys_addr_t addr,
unsigned size);
void io_mem_write(struct MemoryRegion *mr, target_phys_addr_t addr,
uint64_t value, unsigned size);
-extern struct MemoryRegion *io_mem_region[IO_MEM_NB_ENTRIES];
void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx,
void *retaddr);
diff --git a/exec-obsolete.h b/exec-obsolete.h
index 4dbe476..792c831 100644
--- a/exec-obsolete.h
+++ b/exec-obsolete.h
@@ -32,9 +32,6 @@ void qemu_ram_free(ram_addr_t addr);
void qemu_ram_free_from_ptr(ram_addr_t addr);
struct MemoryRegion;
-int cpu_register_io_memory(MemoryRegion *mr);
-void cpu_unregister_io_memory(int table_address);
-
struct MemoryRegionSection;
void cpu_register_physical_memory_log(struct MemoryRegionSection *section,
bool readonly);
diff --git a/exec.c b/exec.c
index 6e14048..0c86bce 100644
--- a/exec.c
+++ b/exec.c
@@ -214,9 +214,6 @@ struct PhysPageEntry {
static void io_mem_init(void);
static void memory_map_init(void);
-/* io memory support */
-MemoryRegion *io_mem_region[IO_MEM_NB_ENTRIES];
-static char io_mem_used[IO_MEM_NB_ENTRIES];
static MemoryRegion io_mem_watch;
#endif
@@ -3503,53 +3500,6 @@ static subpage_t *subpage_init(target_phys_addr_t base)
return mmio;
}
-static int get_free_io_mem_idx(void)
-{
- int i;
-
- for (i = 0; i<IO_MEM_NB_ENTRIES; i++)
- if (!io_mem_used[i]) {
- io_mem_used[i] = 1;
- return i;
- }
- fprintf(stderr, "RAN out out io_mem_idx, max %d !\n", IO_MEM_NB_ENTRIES);
- return -1;
-}
-
-/* mem_read and mem_write are arrays of functions containing the
- function to access byte (index 0), word (index 1) and dword (index
- 2). Functions can be omitted with a NULL function pointer.
- If io_index is non zero, the corresponding io zone is
- modified. If it is zero, a new io zone is allocated. The return
- value can be used with cpu_register_physical_memory(). (-1) is
- returned if error. */
-static int cpu_register_io_memory_fixed(int io_index, MemoryRegion *mr)
-{
- if (io_index <= 0) {
- io_index = get_free_io_mem_idx();
- if (io_index == -1)
- return io_index;
- } else {
- if (io_index >= IO_MEM_NB_ENTRIES)
- return -1;
- }
-
- io_mem_region[io_index] = mr;
-
- return io_index;
-}
-
-int cpu_register_io_memory(MemoryRegion *mr)
-{
- return cpu_register_io_memory_fixed(0, mr);
-}
-
-void cpu_unregister_io_memory(int io_index)
-{
- io_mem_region[io_index] = NULL;
- io_mem_used[io_index] = 0;
-}
-
static uint16_t dummy_section(MemoryRegion *mr)
{
MemoryRegionSection section = {
@@ -3569,11 +3519,7 @@ MemoryRegion *iotlb_to_region(target_phys_addr_t index)
static void io_mem_init(void)
{
- int i;
-
- /* Must be first: */
memory_region_init_io(&io_mem_ram, &error_mem_ops, NULL, "ram", UINT64_MAX);
- assert(io_mem_ram.ram_addr == 0);
memory_region_init_io(&io_mem_rom, &rom_mem_ops, NULL, "rom", UINT64_MAX);
memory_region_init_io(&io_mem_unassigned, &unassigned_mem_ops, NULL,
"unassigned", UINT64_MAX);
@@ -3581,9 +3527,6 @@ static void io_mem_init(void)
"notdirty", UINT64_MAX);
memory_region_init_io(&io_mem_subpage_ram, &subpage_ram_ops, NULL,
"subpage-ram", UINT64_MAX);
- for (i=0; i<5; i++)
- io_mem_used[i] = 1;
-
memory_region_init_io(&io_mem_watch, &watch_mem_ops, NULL,
"watch", UINT64_MAX);
}
diff --git a/memory.c b/memory.c
index bc76f55..22b0352 100644
--- a/memory.c
+++ b/memory.c
@@ -781,13 +781,11 @@ static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
static void memory_region_destructor_iomem(MemoryRegion *mr)
{
- cpu_unregister_io_memory(mr->ram_addr);
}
static void memory_region_destructor_rom_device(MemoryRegion *mr)
{
qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
- cpu_unregister_io_memory(mr->ram_addr & ~TARGET_PAGE_MASK);
}
static bool memory_region_wrong_endianness(MemoryRegion *mr)
@@ -942,7 +940,7 @@ void memory_region_init_io(MemoryRegion *mr,
mr->opaque = opaque;
mr->terminates = true;
mr->destructor = memory_region_destructor_iomem;
- mr->ram_addr = cpu_register_io_memory(mr);
+ mr->ram_addr = ~(ram_addr_t)0;
}
void memory_region_init_ram(MemoryRegion *mr,
@@ -992,7 +990,6 @@ void memory_region_init_rom_device(MemoryRegion *mr,
mr->rom_device = true;
mr->destructor = memory_region_destructor_rom_device;
mr->ram_addr = qemu_ram_alloc(size, mr);
- mr->ram_addr |= cpu_register_io_memory(mr);
}
static uint64_t invalid_read(void *opaque, target_phys_addr_t addr,
--
1.7.9
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 3/5] exec: fix code tlb entry misused as iotlb in get_page_addr_code()
2012-03-08 17:20 ` [Qemu-devel] [PATCH 3/5] exec: fix code tlb entry misused as iotlb in get_page_addr_code() Avi Kivity
@ 2012-03-15 19:23 ` jcmvbkbc
2012-03-18 10:26 ` Avi Kivity
0 siblings, 1 reply; 15+ messages in thread
From: jcmvbkbc @ 2012-03-15 19:23 UTC (permalink / raw)
To: Avi Kivity; +Cc: qemu-devel
Hi.
> get_page_addr_code() reads a code tlb entry, but interprets it as an
> iotlb entry. This works by accident since the low bits of a RAM code
> tlb entry are clear, and match a RAM iotlb entry. This accident is
> about to unhappen, so fix the code to use an iotlb entry (using the
> code entry with TLB_MMIO may fail if the page is a watchpoint).
>
> Signed-off-by: Avi Kivity<avi@redhat.com>
> ---
> exec.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/exec.c b/exec.c
> index a35eb4f..f26d1b0 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -4685,7 +4685,7 @@ tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
> (addr& TARGET_PAGE_MASK))) {
> ldub_code(addr);
> }
> - pd = env1->tlb_table[mmu_idx][page_index].addr_code& ~TARGET_PAGE_MASK;
> + pd = env1->iotlb[mmu_idx][page_index]& ~TARGET_PAGE_MASK;
> if (pd != io_mem_ram.ram_addr&& pd != io_mem_rom.ram_addr
> && !io_mem_region[pd]->rom_device) {
> #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
With this patch xtensa debug option unit test causes qemu abort with the message
qemu: fatal: Trying to execute code outside RAM or ROM at 0xd000088c
This happens immediately after a watchpoint setup for a data breakpoint at the same memory page where the currently
executed code is located. Any idea on how to fix it?
(gdb) bt
#0 cpu_abort (env=0x55555626a310, fmt=0x55555573f540 "Trying to execute code outside RAM or ROM at 0x%08x\n") at
/home/dumb/ws/m/awt/emu/xtensa/qemu/exec.c:1848
#1 0x00005555556c1657 in get_page_addr_code (env1=0x55555626a310, addr=0xd000088c) at
/home/dumb/ws/m/awt/emu/xtensa/qemu/exec.c:4694
#2 0x00005555556b3441 in tb_find_slow (env=0x55555626a310, pc=0xd000088c, cs_base=0x0, flags=0x0) at
/home/dumb/ws/m/awt/emu/xtensa/qemu/cpu-exec.c:95
#3 0x00005555556b36ac in tb_find_fast (env=0x55555626a310) at /home/dumb/ws/m/awt/emu/xtensa/qemu/cpu-exec.c:151
#4 0x00005555556b3a2d in cpu_xtensa_exec (env=0x55555626a310) at /home/dumb/ws/m/awt/emu/xtensa/qemu/cpu-exec.c:534
#5 0x00005555556b6380 in tcg_cpu_exec (env=0x55555626a310) at /home/dumb/ws/m/awt/emu/xtensa/qemu/cpus.c:1022
#6 0x00005555556b6498 in tcg_exec_all () at /home/dumb/ws/m/awt/emu/xtensa/qemu/cpus.c:1054
#7 0x00005555556b5a30 in qemu_tcg_cpu_thread_fn (arg=0x55555626a310) at /home/dumb/ws/m/awt/emu/xtensa/qemu/cpus.c:772
#8 0x00007ffff62e0d90 in start_thread () from /lib64/libpthread.so.0
#9 0x00007ffff6011f5d in clone () from /lib64/libc.so.6
Memory maps are the following:
(qemu) info mtree
memory
00000000-fffffffe (prio 0, RW): system
00000000-07ffffff (prio 0, RW): xtensa.sram
fe000000-fe000fff (prio 0, RW): xtensa.rom
(qemu) info tlb
ITLB:
Way 5 (128 MB)
Vaddr Paddr ASID Attr RWX
---------- ---------- ---- ---- ---
0xd0000000 0x00000000 0x01 0x07 RWX
0xd8000000 0x00000000 0x01 0x03 RWX
Way 6 (256 MB)
Vaddr Paddr ASID Attr RWX
---------- ---------- ---- ---- ---
0xe0000000 0xf0000000 0x01 0x07 RWX
0xf0000000 0xf0000000 0x01 0x03 RWX
DTLB:
Way 5 (128 MB)
Vaddr Paddr ASID Attr RWX
---------- ---------- ---- ---- ---
0xd0000000 0x00000000 0x01 0x07 RWX
0xd8000000 0x00000000 0x01 0x03 RWX
Way 6 (256 MB)
Vaddr Paddr ASID Attr RWX
---------- ---------- ---- ---- ---
0xe0000000 0xf0000000 0x01 0x07 RWX
0xf0000000 0xf0000000 0x01 0x03 RWX
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 3/5] exec: fix code tlb entry misused as iotlb in get_page_addr_code()
2012-03-15 19:23 ` jcmvbkbc
@ 2012-03-18 10:26 ` Avi Kivity
2012-03-18 11:07 ` Max Filippov
0 siblings, 1 reply; 15+ messages in thread
From: Avi Kivity @ 2012-03-18 10:26 UTC (permalink / raw)
To: jcmvbkbc; +Cc: qemu-devel
On 03/15/2012 09:23 PM, jcmvbkbc wrote:
> Hi.
>
>> get_page_addr_code() reads a code tlb entry, but interprets it as an
>> iotlb entry. This works by accident since the low bits of a RAM code
>> tlb entry are clear, and match a RAM iotlb entry. This accident is
>> about to unhappen, so fix the code to use an iotlb entry (using the
>> code entry with TLB_MMIO may fail if the page is a watchpoint).
>>
>> Signed-off-by: Avi Kivity<avi@redhat.com>
>> ---
>> exec.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/exec.c b/exec.c
>> index a35eb4f..f26d1b0 100644
>> --- a/exec.c
>> +++ b/exec.c
>> @@ -4685,7 +4685,7 @@ tb_page_addr_t get_page_addr_code(CPUState
>> *env1, target_ulong addr)
>> (addr& TARGET_PAGE_MASK))) {
>> ldub_code(addr);
>> }
>> - pd = env1->tlb_table[mmu_idx][page_index].addr_code&
>> ~TARGET_PAGE_MASK;
>> + pd = env1->iotlb[mmu_idx][page_index]& ~TARGET_PAGE_MASK;
>> if (pd != io_mem_ram.ram_addr&& pd != io_mem_rom.ram_addr
>> && !io_mem_region[pd]->rom_device) {
>> #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) ||
>> defined(TARGET_SPARC)
>
> With this patch xtensa debug option unit test causes qemu abort with
> the message
>
> qemu: fatal: Trying to execute code outside RAM or ROM at 0xd000088c
>
> This happens immediately after a watchpoint setup for a data
> breakpoint at the same memory page where the currently
> executed code is located. Any idea on how to fix it?
Can you provide details on how to reproduce this?
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 3/5] exec: fix code tlb entry misused as iotlb in get_page_addr_code()
2012-03-18 10:26 ` Avi Kivity
@ 2012-03-18 11:07 ` Max Filippov
2012-03-18 16:33 ` Avi Kivity
0 siblings, 1 reply; 15+ messages in thread
From: Max Filippov @ 2012-03-18 11:07 UTC (permalink / raw)
To: Avi Kivity; +Cc: qemu-devel
>>> get_page_addr_code() reads a code tlb entry, but interprets it as an
>>> iotlb entry. This works by accident since the low bits of a RAM code
>>> tlb entry are clear, and match a RAM iotlb entry. This accident is
>>> about to unhappen, so fix the code to use an iotlb entry (using the
>>> code entry with TLB_MMIO may fail if the page is a watchpoint).
>>>
>>> Signed-off-by: Avi Kivity<avi@redhat.com>
>>> ---
>>> exec.c | 2 +-
>>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/exec.c b/exec.c
>>> index a35eb4f..f26d1b0 100644
>>> --- a/exec.c
>>> +++ b/exec.c
>>> @@ -4685,7 +4685,7 @@ tb_page_addr_t get_page_addr_code(CPUState
>>> *env1, target_ulong addr)
>>> (addr& TARGET_PAGE_MASK))) {
>>> ldub_code(addr);
>>> }
>>> - pd = env1->tlb_table[mmu_idx][page_index].addr_code&
>>> ~TARGET_PAGE_MASK;
>>> + pd = env1->iotlb[mmu_idx][page_index]& ~TARGET_PAGE_MASK;
>>> if (pd != io_mem_ram.ram_addr&& pd != io_mem_rom.ram_addr
>>> && !io_mem_region[pd]->rom_device) {
>>> #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) ||
>>> defined(TARGET_SPARC)
>>
>> With this patch xtensa debug option unit test causes qemu abort with
>> the message
>>
>> qemu: fatal: Trying to execute code outside RAM or ROM at 0xd000088c
>>
>> This happens immediately after a watchpoint setup for a data
>> breakpoint at the same memory page where the currently
>> executed code is located. Any idea on how to fix it?
>
> Can you provide details on how to reproduce this?
It may be reproduced by running test_break.tst unit test:
qemu-system-xtensa -M sim -cpu dc232b -nographic -semihosting -kernel
./test_break.tst
Compiled test binary is here:
http://jcmvbkbc.spb.ru/~dumb/ws/osll/qemu-xtensa/20120318/test_break.tst
--
Thanks.
-- Max
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 3/5] exec: fix code tlb entry misused as iotlb in get_page_addr_code()
2012-03-18 11:07 ` Max Filippov
@ 2012-03-18 16:33 ` Avi Kivity
2012-03-18 16:45 ` Max Filippov
0 siblings, 1 reply; 15+ messages in thread
From: Avi Kivity @ 2012-03-18 16:33 UTC (permalink / raw)
To: Max Filippov; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 2054 bytes --]
On 03/18/2012 01:07 PM, Max Filippov wrote:
> >>> get_page_addr_code() reads a code tlb entry, but interprets it as an
> >>> iotlb entry. This works by accident since the low bits of a RAM code
> >>> tlb entry are clear, and match a RAM iotlb entry. This accident is
> >>> about to unhappen, so fix the code to use an iotlb entry (using the
> >>> code entry with TLB_MMIO may fail if the page is a watchpoint).
> >>>
> >>> Signed-off-by: Avi Kivity<avi@redhat.com>
> >>> ---
> >>> exec.c | 2 +-
> >>> 1 files changed, 1 insertions(+), 1 deletions(-)
> >>>
> >>> diff --git a/exec.c b/exec.c
> >>> index a35eb4f..f26d1b0 100644
> >>> --- a/exec.c
> >>> +++ b/exec.c
> >>> @@ -4685,7 +4685,7 @@ tb_page_addr_t get_page_addr_code(CPUState
> >>> *env1, target_ulong addr)
> >>> (addr& TARGET_PAGE_MASK))) {
> >>> ldub_code(addr);
> >>> }
> >>> - pd = env1->tlb_table[mmu_idx][page_index].addr_code&
> >>> ~TARGET_PAGE_MASK;
> >>> + pd = env1->iotlb[mmu_idx][page_index]& ~TARGET_PAGE_MASK;
> >>> if (pd != io_mem_ram.ram_addr&& pd != io_mem_rom.ram_addr
> >>> && !io_mem_region[pd]->rom_device) {
> >>> #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) ||
> >>> defined(TARGET_SPARC)
> >>
> >> With this patch xtensa debug option unit test causes qemu abort with
> >> the message
> >>
> >> qemu: fatal: Trying to execute code outside RAM or ROM at 0xd000088c
> >>
> >> This happens immediately after a watchpoint setup for a data
> >> breakpoint at the same memory page where the currently
> >> executed code is located. Any idea on how to fix it?
> >
> > Can you provide details on how to reproduce this?
>
> It may be reproduced by running test_break.tst unit test:
>
> qemu-system-xtensa -M sim -cpu dc232b -nographic -semihosting -kernel
> ./test_break.tst
>
> Compiled test binary is here:
> http://jcmvbkbc.spb.ru/~dumb/ws/osll/qemu-xtensa/20120318/test_break.tst
>
Thanks. Please try out the attached patch.
--
error compiling committee.c: too many arguments to function
[-- Attachment #2: 0001-memory-check-for-watchpoints-when-getting-code-ram_a.patch --]
[-- Type: text/x-patch, Size: 1159 bytes --]
>From a7b99c89dfe9784a94af86df344d4ef893c15ee4 Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi@redhat.com>
Date: Sun, 18 Mar 2012 18:31:13 +0200
Subject: [PATCH] memory: check for watchpoints when getting code ram_addr
The code to get the ram_addr from a (tlb entry, vaddr) pair
checks that the resulting memory is not MMIO, but neglects to
check whether the region is hidden by a watchpoint page.
Add the missing check.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
exec.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/exec.c b/exec.c
index d8b089e..405e277 100644
--- a/exec.c
+++ b/exec.c
@@ -4605,7 +4605,8 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(pd);
if (mr != &io_mem_ram && mr != &io_mem_rom
- && mr != &io_mem_notdirty && !mr->rom_device) {
+ && mr != &io_mem_notdirty && !mr->rom_device
+ && mr != &io_mem_watch) {
#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
cpu_unassigned_access(env1, addr, 0, 1, 0, 4);
#else
--
1.7.9
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 3/5] exec: fix code tlb entry misused as iotlb in get_page_addr_code()
2012-03-18 16:33 ` Avi Kivity
@ 2012-03-18 16:45 ` Max Filippov
0 siblings, 0 replies; 15+ messages in thread
From: Max Filippov @ 2012-03-18 16:45 UTC (permalink / raw)
To: Avi Kivity; +Cc: qemu-devel
>> >>> get_page_addr_code() reads a code tlb entry, but interprets it as an
>> >>> iotlb entry. This works by accident since the low bits of a RAM code
>> >>> tlb entry are clear, and match a RAM iotlb entry. This accident is
>> >>> about to unhappen, so fix the code to use an iotlb entry (using the
>> >>> code entry with TLB_MMIO may fail if the page is a watchpoint).
>> >>>
>> >>> Signed-off-by: Avi Kivity<avi@redhat.com>
>> >>> ---
>> >>> exec.c | 2 +-
>> >>> 1 files changed, 1 insertions(+), 1 deletions(-)
>> >>>
>> >>> diff --git a/exec.c b/exec.c
>> >>> index a35eb4f..f26d1b0 100644
>> >>> --- a/exec.c
>> >>> +++ b/exec.c
>> >>> @@ -4685,7 +4685,7 @@ tb_page_addr_t get_page_addr_code(CPUState
>> >>> *env1, target_ulong addr)
>> >>> (addr& TARGET_PAGE_MASK))) {
>> >>> ldub_code(addr);
>> >>> }
>> >>> - pd = env1->tlb_table[mmu_idx][page_index].addr_code&
>> >>> ~TARGET_PAGE_MASK;
>> >>> + pd = env1->iotlb[mmu_idx][page_index]& ~TARGET_PAGE_MASK;
>> >>> if (pd != io_mem_ram.ram_addr&& pd != io_mem_rom.ram_addr
>> >>> && !io_mem_region[pd]->rom_device) {
>> >>> #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) ||
>> >>> defined(TARGET_SPARC)
>> >>
>> >> With this patch xtensa debug option unit test causes qemu abort with
>> >> the message
>> >>
>> >> qemu: fatal: Trying to execute code outside RAM or ROM at 0xd000088c
>> >>
>> >> This happens immediately after a watchpoint setup for a data
>> >> breakpoint at the same memory page where the currently
>> >> executed code is located. Any idea on how to fix it?
>> >
>> > Can you provide details on how to reproduce this?
>>
>> It may be reproduced by running test_break.tst unit test:
>>
>> qemu-system-xtensa -M sim -cpu dc232b -nographic -semihosting -kernel
>> ./test_break.tst
>>
>> Compiled test binary is here:
>> http://jcmvbkbc.spb.ru/~dumb/ws/osll/qemu-xtensa/20120318/test_break.tst
>>
>
> Thanks. Please try out the attached patch.
Thanks, with this patch it works.
-- Max
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 5/5] memory: get rid of cpu_register_io_memory()
2012-03-08 17:20 ` [Qemu-devel] [PATCH 5/5] memory: get rid of cpu_register_io_memory() Avi Kivity
@ 2012-03-19 4:52 ` TeLeMan
2012-03-19 9:16 ` Avi Kivity
0 siblings, 1 reply; 15+ messages in thread
From: TeLeMan @ 2012-03-19 4:52 UTC (permalink / raw)
To: Avi Kivity; +Cc: qemu-devel
On Fri, Mar 9, 2012 at 01:20, Avi Kivity <avi@redhat.com> wrote:
> The return value of cpu_register_io_memory() is no longer used anywhere, so
> we can remove it and all associated data and code.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
> cpu-all.h | 8 -------
> exec-all.h | 1 -
> exec-obsolete.h | 3 --
> exec.c | 57 -------------------------------------------------------
> memory.c | 5 +---
> 5 files changed, 1 insertions(+), 73 deletions(-)
>
> diff --git a/cpu-all.h b/cpu-all.h
> index 80e6d42..b87f2ce 100644
> --- a/cpu-all.h
> +++ b/cpu-all.h
> @@ -498,14 +498,6 @@ extern RAMList ram_list;
> extern const char *mem_path;
> extern int mem_prealloc;
>
> -/* physical memory access */
> -
> -/* MMIO pages are identified by a combination of an IO device index and
> - 3 flags. The ROMD code stores the page ram offset in iotlb entry,
> - so only a limited number of ids are avaiable. */
> -
> -#define IO_MEM_NB_ENTRIES (1 << TARGET_PAGE_BITS)
> -
> /* Flags stored in the low bits of the TLB virtual address. These are
> defined so that fast path ram access is all zeros. */
> /* Zero if TLB entry is valid. */
> diff --git a/exec-all.h b/exec-all.h
> index 4e8c7f5..3ec60a2 100644
> --- a/exec-all.h
> +++ b/exec-all.h
> @@ -304,7 +304,6 @@ uint64_t io_mem_read(struct MemoryRegion *mr, target_phys_addr_t addr,
> unsigned size);
> void io_mem_write(struct MemoryRegion *mr, target_phys_addr_t addr,
> uint64_t value, unsigned size);
> -extern struct MemoryRegion *io_mem_region[IO_MEM_NB_ENTRIES];
>
> void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx,
> void *retaddr);
> diff --git a/exec-obsolete.h b/exec-obsolete.h
> index 4dbe476..792c831 100644
> --- a/exec-obsolete.h
> +++ b/exec-obsolete.h
> @@ -32,9 +32,6 @@ void qemu_ram_free(ram_addr_t addr);
> void qemu_ram_free_from_ptr(ram_addr_t addr);
>
> struct MemoryRegion;
> -int cpu_register_io_memory(MemoryRegion *mr);
> -void cpu_unregister_io_memory(int table_address);
> -
> struct MemoryRegionSection;
> void cpu_register_physical_memory_log(struct MemoryRegionSection *section,
> bool readonly);
> diff --git a/exec.c b/exec.c
> index 6e14048..0c86bce 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -214,9 +214,6 @@ struct PhysPageEntry {
> static void io_mem_init(void);
> static void memory_map_init(void);
>
> -/* io memory support */
> -MemoryRegion *io_mem_region[IO_MEM_NB_ENTRIES];
> -static char io_mem_used[IO_MEM_NB_ENTRIES];
> static MemoryRegion io_mem_watch;
> #endif
>
> @@ -3503,53 +3500,6 @@ static subpage_t *subpage_init(target_phys_addr_t base)
> return mmio;
> }
>
> -static int get_free_io_mem_idx(void)
> -{
> - int i;
> -
> - for (i = 0; i<IO_MEM_NB_ENTRIES; i++)
> - if (!io_mem_used[i]) {
> - io_mem_used[i] = 1;
> - return i;
> - }
> - fprintf(stderr, "RAN out out io_mem_idx, max %d !\n", IO_MEM_NB_ENTRIES);
> - return -1;
> -}
> -
> -/* mem_read and mem_write are arrays of functions containing the
> - function to access byte (index 0), word (index 1) and dword (index
> - 2). Functions can be omitted with a NULL function pointer.
> - If io_index is non zero, the corresponding io zone is
> - modified. If it is zero, a new io zone is allocated. The return
> - value can be used with cpu_register_physical_memory(). (-1) is
> - returned if error. */
> -static int cpu_register_io_memory_fixed(int io_index, MemoryRegion *mr)
> -{
> - if (io_index <= 0) {
> - io_index = get_free_io_mem_idx();
> - if (io_index == -1)
> - return io_index;
> - } else {
> - if (io_index >= IO_MEM_NB_ENTRIES)
> - return -1;
> - }
> -
> - io_mem_region[io_index] = mr;
> -
> - return io_index;
> -}
> -
> -int cpu_register_io_memory(MemoryRegion *mr)
> -{
> - return cpu_register_io_memory_fixed(0, mr);
> -}
> -
> -void cpu_unregister_io_memory(int io_index)
> -{
> - io_mem_region[io_index] = NULL;
> - io_mem_used[io_index] = 0;
> -}
> -
> static uint16_t dummy_section(MemoryRegion *mr)
> {
> MemoryRegionSection section = {
> @@ -3569,11 +3519,7 @@ MemoryRegion *iotlb_to_region(target_phys_addr_t index)
>
> static void io_mem_init(void)
> {
> - int i;
> -
> - /* Must be first: */
> memory_region_init_io(&io_mem_ram, &error_mem_ops, NULL, "ram", UINT64_MAX);
> - assert(io_mem_ram.ram_addr == 0);
> memory_region_init_io(&io_mem_rom, &rom_mem_ops, NULL, "rom", UINT64_MAX);
> memory_region_init_io(&io_mem_unassigned, &unassigned_mem_ops, NULL,
> "unassigned", UINT64_MAX);
> @@ -3581,9 +3527,6 @@ static void io_mem_init(void)
> "notdirty", UINT64_MAX);
> memory_region_init_io(&io_mem_subpage_ram, &subpage_ram_ops, NULL,
> "subpage-ram", UINT64_MAX);
> - for (i=0; i<5; i++)
> - io_mem_used[i] = 1;
> -
> memory_region_init_io(&io_mem_watch, &watch_mem_ops, NULL,
> "watch", UINT64_MAX);
> }
> diff --git a/memory.c b/memory.c
> index bc76f55..22b0352 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -781,13 +781,11 @@ static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
>
> static void memory_region_destructor_iomem(MemoryRegion *mr)
> {
> - cpu_unregister_io_memory(mr->ram_addr);
> }
>
> static void memory_region_destructor_rom_device(MemoryRegion *mr)
> {
> qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
> - cpu_unregister_io_memory(mr->ram_addr & ~TARGET_PAGE_MASK);
> }
>
> static bool memory_region_wrong_endianness(MemoryRegion *mr)
> @@ -942,7 +940,7 @@ void memory_region_init_io(MemoryRegion *mr,
> mr->opaque = opaque;
> mr->terminates = true;
> mr->destructor = memory_region_destructor_iomem;
> - mr->ram_addr = cpu_register_io_memory(mr);
> + mr->ram_addr = ~(ram_addr_t)0;
Why not 0 but -1?
> }
>
> void memory_region_init_ram(MemoryRegion *mr,
> @@ -992,7 +990,6 @@ void memory_region_init_rom_device(MemoryRegion *mr,
> mr->rom_device = true;
> mr->destructor = memory_region_destructor_rom_device;
> mr->ram_addr = qemu_ram_alloc(size, mr);
> - mr->ram_addr |= cpu_register_io_memory(mr);
> }
>
> static uint64_t invalid_read(void *opaque, target_phys_addr_t addr,
> --
> 1.7.9
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 5/5] memory: get rid of cpu_register_io_memory()
2012-03-19 4:52 ` TeLeMan
@ 2012-03-19 9:16 ` Avi Kivity
2012-03-19 10:37 ` TeLeMan
0 siblings, 1 reply; 15+ messages in thread
From: Avi Kivity @ 2012-03-19 9:16 UTC (permalink / raw)
To: TeLeMan; +Cc: qemu-devel
On 03/19/2012 06:52 AM, TeLeMan wrote:
> > static bool memory_region_wrong_endianness(MemoryRegion *mr)
> > @@ -942,7 +940,7 @@ void memory_region_init_io(MemoryRegion *mr,
> > mr->opaque = opaque;
> > mr->terminates = true;
> > mr->destructor = memory_region_destructor_iomem;
> > - mr->ram_addr = cpu_register_io_memory(mr);
> > + mr->ram_addr = ~(ram_addr_t)0;
> Why not 0 but -1?
>
To catch bugs. In fact it triggered bugs (not the ones I wanted though).
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 5/5] memory: get rid of cpu_register_io_memory()
2012-03-19 9:16 ` Avi Kivity
@ 2012-03-19 10:37 ` TeLeMan
2012-03-19 10:48 ` Avi Kivity
0 siblings, 1 reply; 15+ messages in thread
From: TeLeMan @ 2012-03-19 10:37 UTC (permalink / raw)
To: Avi Kivity; +Cc: qemu-devel
On Mon, Mar 19, 2012 at 17:16, Avi Kivity <avi@redhat.com> wrote:
> On 03/19/2012 06:52 AM, TeLeMan wrote:
>> > static bool memory_region_wrong_endianness(MemoryRegion *mr)
>> > @@ -942,7 +940,7 @@ void memory_region_init_io(MemoryRegion *mr,
>> > mr->opaque = opaque;
>> > mr->terminates = true;
>> > mr->destructor = memory_region_destructor_iomem;
>> > - mr->ram_addr = cpu_register_io_memory(mr);
>> > + mr->ram_addr = ~(ram_addr_t)0;
>> Why not 0 but -1?
>>
>
> To catch bugs. In fact it triggered bugs (not the ones I wanted though).
There may be BSOD on the guest windows xp after applying this patch.
>
> --
> error compiling committee.c: too many arguments to function
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 5/5] memory: get rid of cpu_register_io_memory()
2012-03-19 10:37 ` TeLeMan
@ 2012-03-19 10:48 ` Avi Kivity
0 siblings, 0 replies; 15+ messages in thread
From: Avi Kivity @ 2012-03-19 10:48 UTC (permalink / raw)
To: TeLeMan; +Cc: qemu-devel
On 03/19/2012 12:37 PM, TeLeMan wrote:
> On Mon, Mar 19, 2012 at 17:16, Avi Kivity <avi@redhat.com> wrote:
> > On 03/19/2012 06:52 AM, TeLeMan wrote:
> >> > static bool memory_region_wrong_endianness(MemoryRegion *mr)
> >> > @@ -942,7 +940,7 @@ void memory_region_init_io(MemoryRegion *mr,
> >> > mr->opaque = opaque;
> >> > mr->terminates = true;
> >> > mr->destructor = memory_region_destructor_iomem;
> >> > - mr->ram_addr = cpu_register_io_memory(mr);
> >> > + mr->ram_addr = ~(ram_addr_t)0;
> >> Why not 0 but -1?
> >>
> >
> > To catch bugs. In fact it triggered bugs (not the ones I wanted though).
> There may be BSOD on the guest windows xp after applying this patch.
>
May? Where?
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2012-03-19 10:48 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-08 17:20 [Qemu-devel] [PATCH 0/5] Remove cpu_register_io_memory Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 1/5] memory: make phys_page_find() return an unadjusted section Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 2/5] memory: store section indices in iotlb instead of io indices Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 3/5] exec: fix code tlb entry misused as iotlb in get_page_addr_code() Avi Kivity
2012-03-15 19:23 ` jcmvbkbc
2012-03-18 10:26 ` Avi Kivity
2012-03-18 11:07 ` Max Filippov
2012-03-18 16:33 ` Avi Kivity
2012-03-18 16:45 ` Max Filippov
2012-03-08 17:20 ` [Qemu-devel] [PATCH 4/5] memory: dispatch directly via MemoryRegion Avi Kivity
2012-03-08 17:20 ` [Qemu-devel] [PATCH 5/5] memory: get rid of cpu_register_io_memory() Avi Kivity
2012-03-19 4:52 ` TeLeMan
2012-03-19 9:16 ` Avi Kivity
2012-03-19 10:37 ` TeLeMan
2012-03-19 10:48 ` Avi Kivity
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).