mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-11 05:29:43 +00:00
ppcmmu: Fix mmio read/write offset calculation.
For TLBs referencing an mmio region, calculate an offset that will translate a guest virtual address to an offset in the mmio region.
This commit is contained in:
parent
16123dea45
commit
ac64f9e30d
@ -607,6 +607,7 @@ static TLBEntry* dtlb2_refill(uint32_t guest_va, int is_write)
|
|||||||
if (reg_desc->type & RT_MMIO) { // MMIO region
|
if (reg_desc->type & RT_MMIO) { // MMIO region
|
||||||
tlb_entry->flags = flags | TLBFlags::PAGE_IO;
|
tlb_entry->flags = flags | TLBFlags::PAGE_IO;
|
||||||
tlb_entry->reg_desc = reg_desc;
|
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
|
} else { // memory region backed by host memory
|
||||||
tlb_entry->flags = flags | TLBFlags::PAGE_MEM;
|
tlb_entry->flags = flags | TLBFlags::PAGE_MEM;
|
||||||
tlb_entry->host_va_offs_r = (int64_t)reg_desc->mem_ptr - guest_va +
|
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 (
|
return (
|
||||||
((T)tlb2_entry->reg_desc->devobj->read(tlb2_entry->reg_desc->start,
|
((T)tlb2_entry->reg_desc->devobj->read(tlb2_entry->reg_desc->start,
|
||||||
guest_va - tlb2_entry->reg_desc->start,
|
static_cast<uint32_t>(tlb2_entry->reg_va_offs + guest_va),
|
||||||
4) << 32) |
|
4) << 32) |
|
||||||
tlb2_entry->reg_desc->devobj->read(tlb2_entry->reg_desc->start,
|
tlb2_entry->reg_desc->devobj->read(tlb2_entry->reg_desc->start,
|
||||||
guest_va + 4 - tlb2_entry->reg_desc->start,
|
static_cast<uint32_t>(tlb2_entry->reg_va_offs + guest_va) + 4,
|
||||||
4)
|
4)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1053,7 +1054,7 @@ inline T mmu_read_vmem(uint32_t guest_va)
|
|||||||
else {
|
else {
|
||||||
return (
|
return (
|
||||||
tlb2_entry->reg_desc->devobj->read(tlb2_entry->reg_desc->start,
|
tlb2_entry->reg_desc->devobj->read(tlb2_entry->reg_desc->start,
|
||||||
guest_va - tlb2_entry->reg_desc->start,
|
static_cast<uint32_t>(tlb2_entry->reg_va_offs + guest_va),
|
||||||
sizeof(T))
|
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,
|
tlb2_entry->reg_desc->devobj->write(tlb2_entry->reg_desc->start,
|
||||||
guest_va - tlb2_entry->reg_desc->start,
|
static_cast<uint32_t>(tlb2_entry->reg_va_offs + guest_va),
|
||||||
value >> 32, 4);
|
value >> 32, 4);
|
||||||
tlb2_entry->reg_desc->devobj->write(tlb2_entry->reg_desc->start,
|
tlb2_entry->reg_desc->devobj->write(tlb2_entry->reg_desc->start,
|
||||||
guest_va + 4 - tlb2_entry->reg_desc->start,
|
static_cast<uint32_t>(tlb2_entry->reg_va_offs + guest_va) + 4,
|
||||||
(uint32_t)value, 4);
|
(uint32_t)value, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tlb2_entry->reg_desc->devobj->write(tlb2_entry->reg_desc->start,
|
tlb2_entry->reg_desc->devobj->write(tlb2_entry->reg_desc->start,
|
||||||
guest_va - tlb2_entry->reg_desc->start,
|
static_cast<uint32_t>(tlb2_entry->reg_va_offs + guest_va),
|
||||||
value, sizeof(T));
|
value, sizeof(T));
|
||||||
}
|
}
|
||||||
return;
|
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;
|
tlb1_entry->host_va_offs_r = tlb2_entry->host_va_offs_r;
|
||||||
return tlb1_entry->host_va_offs_r + guest_va;
|
return tlb1_entry->host_va_offs_r + guest_va;
|
||||||
} else { // an attempt to access a memory-mapped device
|
} 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,11 +82,15 @@ typedef struct TLBEntry {
|
|||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
uint16_t lru_bits;
|
uint16_t lru_bits;
|
||||||
union {
|
union {
|
||||||
int64_t host_va_offs_r;
|
struct {
|
||||||
AddressMapEntry* reg_desc;
|
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;
|
} TLBEntry;
|
||||||
|
|
||||||
enum TLBFlags : uint16_t {
|
enum TLBFlags : uint16_t {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user