|
@@ -777,13 +777,16 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
|
|
|
target_ulong addr, uintptr_t retaddr, int size)
|
|
|
{
|
|
|
CPUState *cpu = ENV_GET_CPU(env);
|
|
|
- hwaddr physaddr = iotlbentry->addr;
|
|
|
- MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
|
|
|
+ hwaddr mr_offset;
|
|
|
+ MemoryRegionSection *section;
|
|
|
+ MemoryRegion *mr;
|
|
|
uint64_t val;
|
|
|
bool locked = false;
|
|
|
MemTxResult r;
|
|
|
|
|
|
- physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
|
|
|
+ section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
|
|
|
+ mr = section->mr;
|
|
|
+ mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
|
|
|
cpu->mem_io_pc = retaddr;
|
|
|
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
|
|
|
cpu_io_recompile(cpu, retaddr);
|
|
@@ -795,9 +798,13 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
|
|
|
qemu_mutex_lock_iothread();
|
|
|
locked = true;
|
|
|
}
|
|
|
- r = memory_region_dispatch_read(mr, physaddr,
|
|
|
+ r = memory_region_dispatch_read(mr, mr_offset,
|
|
|
&val, size, iotlbentry->attrs);
|
|
|
if (r != MEMTX_OK) {
|
|
|
+ hwaddr physaddr = mr_offset +
|
|
|
+ section->offset_within_address_space -
|
|
|
+ section->offset_within_region;
|
|
|
+
|
|
|
cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_LOAD,
|
|
|
mmu_idx, iotlbentry->attrs, r, retaddr);
|
|
|
}
|
|
@@ -814,12 +821,15 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
|
|
|
uintptr_t retaddr, int size)
|
|
|
{
|
|
|
CPUState *cpu = ENV_GET_CPU(env);
|
|
|
- hwaddr physaddr = iotlbentry->addr;
|
|
|
- MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
|
|
|
+ hwaddr mr_offset;
|
|
|
+ MemoryRegionSection *section;
|
|
|
+ MemoryRegion *mr;
|
|
|
bool locked = false;
|
|
|
MemTxResult r;
|
|
|
|
|
|
- physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
|
|
|
+ section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
|
|
|
+ mr = section->mr;
|
|
|
+ mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
|
|
|
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu->can_do_io) {
|
|
|
cpu_io_recompile(cpu, retaddr);
|
|
|
}
|
|
@@ -830,9 +840,13 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
|
|
|
qemu_mutex_lock_iothread();
|
|
|
locked = true;
|
|
|
}
|
|
|
- r = memory_region_dispatch_write(mr, physaddr,
|
|
|
+ r = memory_region_dispatch_write(mr, mr_offset,
|
|
|
val, size, iotlbentry->attrs);
|
|
|
if (r != MEMTX_OK) {
|
|
|
+ hwaddr physaddr = mr_offset +
|
|
|
+ section->offset_within_address_space -
|
|
|
+ section->offset_within_region;
|
|
|
+
|
|
|
cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE,
|
|
|
mmu_idx, iotlbentry->attrs, r, retaddr);
|
|
|
}
|
|
@@ -880,12 +894,13 @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
|
|
|
*/
|
|
|
tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
|
|
|
{
|
|
|
- int mmu_idx, index, pd;
|
|
|
+ int mmu_idx, index;
|
|
|
void *p;
|
|
|
MemoryRegion *mr;
|
|
|
+ MemoryRegionSection *section;
|
|
|
CPUState *cpu = ENV_GET_CPU(env);
|
|
|
CPUIOTLBEntry *iotlbentry;
|
|
|
- hwaddr physaddr;
|
|
|
+ hwaddr physaddr, mr_offset;
|
|
|
|
|
|
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
|
|
mmu_idx = cpu_mmu_index(env, true);
|
|
@@ -896,8 +911,8 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
|
|
|
}
|
|
|
}
|
|
|
iotlbentry = &env->iotlb[mmu_idx][index];
|
|
|
- pd = iotlbentry->addr & ~TARGET_PAGE_MASK;
|
|
|
- mr = iotlb_to_region(cpu, pd, iotlbentry->attrs);
|
|
|
+ section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
|
|
|
+ mr = section->mr;
|
|
|
if (memory_region_is_unassigned(mr)) {
|
|
|
qemu_mutex_lock_iothread();
|
|
|
if (memory_region_request_mmio_ptr(mr, addr)) {
|
|
@@ -918,7 +933,10 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
|
|
|
* and use the MemTXResult it produced). However it is the
|
|
|
* simplest place we have currently available for the check.
|
|
|
*/
|
|
|
- physaddr = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
|
|
|
+ mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
|
|
|
+ physaddr = mr_offset +
|
|
|
+ section->offset_within_address_space -
|
|
|
+ section->offset_within_region;
|
|
|
cpu_transaction_failed(cpu, physaddr, addr, 0, MMU_INST_FETCH, mmu_idx,
|
|
|
iotlbentry->attrs, MEMTX_DECODE_ERROR, 0);
|
|
|
|