diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index b03556a..9199f40 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -607,6 +607,7 @@ static TLBEntry* dtlb2_refill(uint32_t guest_va, int is_write) if (reg_desc->type & RT_MMIO) { // MMIO region tlb_entry->flags = flags | TLBFlags::PAGE_IO; tlb_entry->reg_desc = reg_desc; + tlb_entry->reg_va_offs = (phys_addr - reg_desc->start) - guest_va; } else { // memory region backed by host memory tlb_entry->flags = flags | TLBFlags::PAGE_MEM; tlb_entry->host_va_offs_r = (int64_t)reg_desc->mem_ptr - guest_va + @@ -1042,10 +1043,10 @@ inline T mmu_read_vmem(uint32_t guest_va) { return ( ((T)tlb2_entry->reg_desc->devobj->read(tlb2_entry->reg_desc->start, - guest_va - tlb2_entry->reg_desc->start, + static_cast(tlb2_entry->reg_va_offs + guest_va), 4) << 32) | tlb2_entry->reg_desc->devobj->read(tlb2_entry->reg_desc->start, - guest_va + 4 - tlb2_entry->reg_desc->start, + static_cast(tlb2_entry->reg_va_offs + guest_va) + 4, 4) ); } @@ -1053,7 +1054,7 @@ inline T mmu_read_vmem(uint32_t guest_va) else { return ( tlb2_entry->reg_desc->devobj->read(tlb2_entry->reg_desc->start, - guest_va - tlb2_entry->reg_desc->start, + static_cast(tlb2_entry->reg_va_offs + guest_va), sizeof(T)) ); } @@ -1167,16 +1168,16 @@ inline void mmu_write_vmem(uint32_t guest_va, T value) } { tlb2_entry->reg_desc->devobj->write(tlb2_entry->reg_desc->start, - guest_va - tlb2_entry->reg_desc->start, + static_cast(tlb2_entry->reg_va_offs + guest_va), value >> 32, 4); tlb2_entry->reg_desc->devobj->write(tlb2_entry->reg_desc->start, - guest_va + 4 - tlb2_entry->reg_desc->start, + static_cast(tlb2_entry->reg_va_offs + guest_va) + 4, (uint32_t)value, 4); } } else { tlb2_entry->reg_desc->devobj->write(tlb2_entry->reg_desc->start, - guest_va - tlb2_entry->reg_desc->start, + static_cast(tlb2_entry->reg_va_offs + guest_va), value, sizeof(T)); } return; @@ -1686,7 +1687,7 @@ static inline uint64_t tlb_translate_addr(uint32_t guest_va) tlb1_entry->host_va_offs_r = tlb2_entry->host_va_offs_r; return tlb1_entry->host_va_offs_r + guest_va; } else { // an attempt to access a memory-mapped device - return guest_va - tlb2_entry->reg_desc->start; + return tlb2_entry->reg_va_offs + guest_va; } } } diff --git a/cpu/ppc/ppcmmu.h b/cpu/ppc/ppcmmu.h index 914a9b7..9f270e4 100644 --- a/cpu/ppc/ppcmmu.h +++ b/cpu/ppc/ppcmmu.h @@ -82,11 +82,15 @@ typedef struct TLBEntry { uint16_t flags; uint16_t lru_bits; union { - int64_t host_va_offs_r; - AddressMapEntry* reg_desc; + struct { + int64_t host_va_offs_r; + int64_t host_va_offs_w; + }; + struct { + AddressMapEntry* reg_desc; + int64_t reg_va_offs; + }; }; - int64_t host_va_offs_w; - int64_t unused; } TLBEntry; enum TLBFlags : uint16_t {