Commit 37ec01d4 authored by Avi Kivity's avatar Avi Kivity

memory: dispatch directly via MemoryRegion

Instead of indirecting via io_mem_region, dispatch directly
through the MemoryRegion obtained from the iotlb or phys_page_find().
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent ce5d64c2
......@@ -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,
......
This diff is collapsed.
......@@ -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;
......
......@@ -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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment