memory: move mmio access to functions
Currently mmio access goes directly to the io_mem_{read,write} arrays.
In preparation for eliminating them, add indirection via a function.
Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
			
			
This commit is contained in:
		
							parent
							
								
									f1f6e3b86e
								
							
						
					
					
						commit
						acbbec5d43
					
				| 
						 | 
				
			
			@ -299,8 +299,11 @@ extern void *tci_tb_ptr;
 | 
			
		|||
 | 
			
		||||
#if !defined(CONFIG_USER_ONLY)
 | 
			
		||||
 | 
			
		||||
extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
 | 
			
		||||
extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
 | 
			
		||||
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);
 | 
			
		||||
extern CPUWriteMemoryFunc *_io_mem_write[IO_MEM_NB_ENTRIES][4];
 | 
			
		||||
extern CPUReadMemoryFunc *_io_mem_read[IO_MEM_NB_ENTRIES][4];
 | 
			
		||||
extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
 | 
			
		||||
 | 
			
		||||
void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										54
									
								
								exec.c
								
								
								
								
							
							
						
						
									
										54
									
								
								exec.c
								
								
								
								
							| 
						 | 
				
			
			@ -205,8 +205,8 @@ static void io_mem_init(void);
 | 
			
		|||
static void memory_map_init(void);
 | 
			
		||||
 | 
			
		||||
/* io memory support */
 | 
			
		||||
CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
 | 
			
		||||
CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
 | 
			
		||||
CPUWriteMemoryFunc *_io_mem_write[IO_MEM_NB_ENTRIES][4];
 | 
			
		||||
CPUReadMemoryFunc *_io_mem_read[IO_MEM_NB_ENTRIES][4];
 | 
			
		||||
void *io_mem_opaque[IO_MEM_NB_ENTRIES];
 | 
			
		||||
static char io_mem_used[IO_MEM_NB_ENTRIES];
 | 
			
		||||
static int io_mem_watch;
 | 
			
		||||
| 
						 | 
				
			
			@ -3350,7 +3350,7 @@ static inline uint32_t subpage_readlen (subpage_t *mmio,
 | 
			
		|||
 | 
			
		||||
    addr += mmio->region_offset[idx];
 | 
			
		||||
    idx = mmio->sub_io_index[idx];
 | 
			
		||||
    return io_mem_read[idx][len](io_mem_opaque[idx], addr);
 | 
			
		||||
    return io_mem_read(idx, addr, 1 <<len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
 | 
			
		||||
| 
						 | 
				
			
			@ -3364,7 +3364,7 @@ static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
 | 
			
		|||
 | 
			
		||||
    addr += mmio->region_offset[idx];
 | 
			
		||||
    idx = mmio->sub_io_index[idx];
 | 
			
		||||
    io_mem_write[idx][len](io_mem_opaque[idx], addr, value);
 | 
			
		||||
    io_mem_write(idx, addr, value, 1 << len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr)
 | 
			
		||||
| 
						 | 
				
			
			@ -3553,11 +3553,11 @@ static int cpu_register_io_memory_fixed(int io_index,
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < 3; ++i) {
 | 
			
		||||
        io_mem_read[io_index][i]
 | 
			
		||||
        _io_mem_read[io_index][i]
 | 
			
		||||
            = (mem_read[i] ? mem_read[i] : unassigned_mem_read[i]);
 | 
			
		||||
    }
 | 
			
		||||
    for (i = 0; i < 3; ++i) {
 | 
			
		||||
        io_mem_write[io_index][i]
 | 
			
		||||
        _io_mem_write[io_index][i]
 | 
			
		||||
            = (mem_write[i] ? mem_write[i] : unassigned_mem_write[i]);
 | 
			
		||||
    }
 | 
			
		||||
    io_mem_opaque[io_index] = opaque;
 | 
			
		||||
| 
						 | 
				
			
			@ -3578,8 +3578,8 @@ void cpu_unregister_io_memory(int io_table_address)
 | 
			
		|||
    int io_index = io_table_address >> IO_MEM_SHIFT;
 | 
			
		||||
 | 
			
		||||
    for (i=0;i < 3; i++) {
 | 
			
		||||
        io_mem_read[io_index][i] = unassigned_mem_read[i];
 | 
			
		||||
        io_mem_write[io_index][i] = unassigned_mem_write[i];
 | 
			
		||||
        _io_mem_read[io_index][i] = unassigned_mem_read[i];
 | 
			
		||||
        _io_mem_write[io_index][i] = unassigned_mem_write[i];
 | 
			
		||||
    }
 | 
			
		||||
    io_mem_opaque[io_index] = NULL;
 | 
			
		||||
    io_mem_used[io_index] = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -3697,17 +3697,17 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
 | 
			
		|||
                if (l >= 4 && ((addr1 & 3) == 0)) {
 | 
			
		||||
                    /* 32 bit write access */
 | 
			
		||||
                    val = ldl_p(buf);
 | 
			
		||||
                    io_mem_write[io_index][2](io_mem_opaque[io_index], addr1, val);
 | 
			
		||||
                    io_mem_write(io_index, 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][1](io_mem_opaque[io_index], addr1, val);
 | 
			
		||||
                    io_mem_write(io_index, addr1, val, 2);
 | 
			
		||||
                    l = 2;
 | 
			
		||||
                } else {
 | 
			
		||||
                    /* 8 bit write access */
 | 
			
		||||
                    val = ldub_p(buf);
 | 
			
		||||
                    io_mem_write[io_index][0](io_mem_opaque[io_index], addr1, val);
 | 
			
		||||
                    io_mem_write(io_index, addr1, val, 1);
 | 
			
		||||
                    l = 1;
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -3734,17 +3734,17 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
 | 
			
		|||
                addr1 = (addr & ~TARGET_PAGE_MASK) + p.region_offset;
 | 
			
		||||
                if (l >= 4 && ((addr1 & 3) == 0)) {
 | 
			
		||||
                    /* 32 bit read access */
 | 
			
		||||
                    val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr1);
 | 
			
		||||
                    val = io_mem_read(io_index, 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][1](io_mem_opaque[io_index], addr1);
 | 
			
		||||
                    val = io_mem_read(io_index, addr1, 2);
 | 
			
		||||
                    stw_p(buf, val);
 | 
			
		||||
                    l = 2;
 | 
			
		||||
                } else {
 | 
			
		||||
                    /* 8 bit read access */
 | 
			
		||||
                    val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr1);
 | 
			
		||||
                    val = io_mem_read(io_index, addr1, 1);
 | 
			
		||||
                    stb_p(buf, val);
 | 
			
		||||
                    l = 1;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -3957,7 +3957,7 @@ static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,
 | 
			
		|||
        /* I/O case */
 | 
			
		||||
        io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
 | 
			
		||||
        addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset;
 | 
			
		||||
        val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
 | 
			
		||||
        val = io_mem_read(io_index, addr, 4);
 | 
			
		||||
#if defined(TARGET_WORDS_BIGENDIAN)
 | 
			
		||||
        if (endian == DEVICE_LITTLE_ENDIAN) {
 | 
			
		||||
            val = bswap32(val);
 | 
			
		||||
| 
						 | 
				
			
			@ -4023,11 +4023,11 @@ static inline uint64_t ldq_phys_internal(target_phys_addr_t addr,
 | 
			
		|||
        /* XXX This is broken when device endian != cpu endian.
 | 
			
		||||
               Fix and add "endian" variable check */
 | 
			
		||||
#ifdef TARGET_WORDS_BIGENDIAN
 | 
			
		||||
        val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32;
 | 
			
		||||
        val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4);
 | 
			
		||||
        val = io_mem_read(io_index, addr, 4) << 32;
 | 
			
		||||
        val |= io_mem_read(io_index, addr + 4, 4);
 | 
			
		||||
#else
 | 
			
		||||
        val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
 | 
			
		||||
        val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32;
 | 
			
		||||
        val = io_mem_read(io_index, addr, 4);
 | 
			
		||||
        val |= io_mem_read(io_index, addr + 4, 4) << 32;
 | 
			
		||||
#endif
 | 
			
		||||
    } else {
 | 
			
		||||
        /* RAM case */
 | 
			
		||||
| 
						 | 
				
			
			@ -4089,7 +4089,7 @@ static inline uint32_t lduw_phys_internal(target_phys_addr_t addr,
 | 
			
		|||
        /* I/O case */
 | 
			
		||||
        io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
 | 
			
		||||
        addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset;
 | 
			
		||||
        val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
 | 
			
		||||
        val = io_mem_read(io_index, addr, 2);
 | 
			
		||||
#if defined(TARGET_WORDS_BIGENDIAN)
 | 
			
		||||
        if (endian == DEVICE_LITTLE_ENDIAN) {
 | 
			
		||||
            val = bswap16(val);
 | 
			
		||||
| 
						 | 
				
			
			@ -4149,7 +4149,7 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
 | 
			
		|||
    if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
 | 
			
		||||
        io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
 | 
			
		||||
        addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset;
 | 
			
		||||
        io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
 | 
			
		||||
        io_mem_write(io_index, addr, val, 4);
 | 
			
		||||
    } else {
 | 
			
		||||
        unsigned long addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
 | 
			
		||||
        ptr = qemu_get_ram_ptr(addr1);
 | 
			
		||||
| 
						 | 
				
			
			@ -4181,11 +4181,11 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
 | 
			
		|||
        io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
 | 
			
		||||
        addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset;
 | 
			
		||||
#ifdef TARGET_WORDS_BIGENDIAN
 | 
			
		||||
        io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val >> 32);
 | 
			
		||||
        io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val);
 | 
			
		||||
        io_mem_write(io_index, addr, val >> 32, 4);
 | 
			
		||||
        io_mem_write(io_index, addr + 4, (uint32_t)val, 4);
 | 
			
		||||
#else
 | 
			
		||||
        io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
 | 
			
		||||
        io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val >> 32);
 | 
			
		||||
        io_mem_write(io_index, addr, (uint32_t)val, 4);
 | 
			
		||||
        io_mem_write(io_index, addr + 4, val >> 32, 4);
 | 
			
		||||
#endif
 | 
			
		||||
    } else {
 | 
			
		||||
        ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) +
 | 
			
		||||
| 
						 | 
				
			
			@ -4218,7 +4218,7 @@ static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
 | 
			
		|||
            val = bswap32(val);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
 | 
			
		||||
        io_mem_write(io_index, addr, val, 4);
 | 
			
		||||
    } else {
 | 
			
		||||
        unsigned long addr1;
 | 
			
		||||
        addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
 | 
			
		||||
| 
						 | 
				
			
			@ -4291,7 +4291,7 @@ static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
 | 
			
		|||
            val = bswap16(val);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
 | 
			
		||||
        io_mem_write(io_index, addr, val, 2);
 | 
			
		||||
    } else {
 | 
			
		||||
        unsigned long addr1;
 | 
			
		||||
        addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								memory.c
								
								
								
								
							
							
						
						
									
										13
									
								
								memory.c
								
								
								
								
							| 
						 | 
				
			
			@ -1580,6 +1580,19 @@ 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)
 | 
			
		||||
{
 | 
			
		||||
    return _io_mem_read[io_index][bitops_ffsl(size)](io_mem_opaque[io_index],
 | 
			
		||||
                                                     addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void io_mem_write(int io_index, target_phys_addr_t addr,
 | 
			
		||||
                  uint64_t val, unsigned size)
 | 
			
		||||
{
 | 
			
		||||
    _io_mem_write[io_index][bitops_ffsl(size)](io_mem_opaque[io_index],
 | 
			
		||||
                                               addr, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct MemoryRegionList MemoryRegionList;
 | 
			
		||||
 | 
			
		||||
struct MemoryRegionList {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,14 +72,14 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
 | 
			
		|||
 | 
			
		||||
    env->mem_io_vaddr = addr;
 | 
			
		||||
#if SHIFT <= 2
 | 
			
		||||
    res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr);
 | 
			
		||||
    res = io_mem_read(index, physaddr, 1 << SHIFT);
 | 
			
		||||
#else
 | 
			
		||||
#ifdef TARGET_WORDS_BIGENDIAN
 | 
			
		||||
    res = (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr) << 32;
 | 
			
		||||
    res |= io_mem_read[index][2](io_mem_opaque[index], physaddr + 4);
 | 
			
		||||
    res = io_mem_read(index, physaddr, 4) << 32;
 | 
			
		||||
    res |= io_mem_read(index, physaddr + 4, 4);
 | 
			
		||||
#else
 | 
			
		||||
    res = io_mem_read[index][2](io_mem_opaque[index], physaddr);
 | 
			
		||||
    res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
 | 
			
		||||
    res = io_mem_read(index, physaddr, 4);
 | 
			
		||||
    res |= io_mem_read(index, physaddr + 4, 4) << 32;
 | 
			
		||||
#endif
 | 
			
		||||
#endif /* SHIFT > 2 */
 | 
			
		||||
    return res;
 | 
			
		||||
| 
						 | 
				
			
			@ -215,14 +215,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][SHIFT](io_mem_opaque[index], physaddr, val);
 | 
			
		||||
    io_mem_write(index, physaddr, val, 1 << SHIFT);
 | 
			
		||||
#else
 | 
			
		||||
#ifdef TARGET_WORDS_BIGENDIAN
 | 
			
		||||
    io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32);
 | 
			
		||||
    io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val);
 | 
			
		||||
    io_mem_write(index, physaddr, (val >> 32), 4);
 | 
			
		||||
    io_mem_write(index, physaddr + 4, (uint32_t)val, 4);
 | 
			
		||||
#else
 | 
			
		||||
    io_mem_write[index][2](io_mem_opaque[index], physaddr, val);
 | 
			
		||||
    io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
 | 
			
		||||
    io_mem_write(index, physaddr, (uint32_t)val, 4);
 | 
			
		||||
    io_mem_write(index, physaddr + 4, val >> 32, 4);
 | 
			
		||||
#endif
 | 
			
		||||
#endif /* SHIFT > 2 */
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue