mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-07-10 01:34:41 -06:00
core/memory: Fix undefined behavior and optimize Luma alias path (#2202)
* core/memory: Fix undefined behavior and optimize Luma alias path * chore: clean up Luma mapping comments * style: fix clang-format formatting
This commit is contained in:
parent
f015a208e5
commit
735c63174c
@ -598,19 +598,25 @@ T MemorySystem::Read(const std::shared_ptr<PageTable>& page_table, const VAddr v
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom Luma3ds mapping
|
// Custom Luma3ds mapping (bit 31 set) Bypasses page tables for FCRAM/MMIO
|
||||||
// Is there a more efficient way to do this?
|
constexpr VAddr LUMA_ALIAS_BIT = 0x80000000u;
|
||||||
if (vaddr & (1 << 31)) {
|
|
||||||
PAddr paddr = (vaddr & ~(1 << 31));
|
if (vaddr & LUMA_ALIAS_BIT) [[unlikely]] {
|
||||||
if ((paddr & 0xF0000000) == Memory::FCRAM_PADDR) { // Check FCRAM region
|
const PAddr paddr = vaddr & ~LUMA_ALIAS_BIT;
|
||||||
|
|
||||||
|
// FCRAM (0x2xxxxxxx)
|
||||||
|
if ((paddr & 0xF0000000) == Memory::FCRAM_PADDR) {
|
||||||
ReadType value;
|
ReadType value;
|
||||||
std::memcpy(&value, GetFCRAMPointer(paddr - Memory::FCRAM_PADDR), read_size);
|
std::memcpy(&value, GetFCRAMPointer(paddr - Memory::FCRAM_PADDR), read_size);
|
||||||
return value;
|
return value;
|
||||||
} else if ((paddr & 0xF0000000) == 0x10000000 &&
|
}
|
||||||
paddr >= Memory::IO_AREA_PADDR) { // Check MMIO region
|
|
||||||
|
// MMIO (0x1xxxxxxx, >= IO_AREA_PADDR) - Strictly 32-bit
|
||||||
|
if ((paddr & 0xF0000000) == 0x10000000 && paddr >= Memory::IO_AREA_PADDR) [[unlikely]] {
|
||||||
return static_cast<ReadType>(impl->system.GPU().ReadReg(
|
return static_cast<ReadType>(impl->system.GPU().ReadReg(
|
||||||
static_cast<VAddr>(paddr) - Memory::IO_AREA_PADDR + 0x1EC00000));
|
static_cast<VAddr>(paddr) - Memory::IO_AREA_PADDR + 0x1EC00000));
|
||||||
}
|
}
|
||||||
|
// Fallthrough: Standard page table lookup
|
||||||
}
|
}
|
||||||
|
|
||||||
PageType type = page_table->attributes[vaddr >> CITRA_PAGE_BITS];
|
PageType type = page_table->attributes[vaddr >> CITRA_PAGE_BITS];
|
||||||
@ -686,21 +692,27 @@ void MemorySystem::Write(const std::shared_ptr<PageTable>& page_table, const VAd
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom Luma3ds mapping
|
// Custom Luma3ds mapping (bit 31 set) Bypasses page tables for FCRAM/MMIO
|
||||||
// Is there a more efficient way to do this?
|
constexpr VAddr LUMA_ALIAS_BIT = 0x80000000u;
|
||||||
if (vaddr & (1 << 31)) {
|
|
||||||
PAddr paddr = (vaddr & ~(1 << 31));
|
if (vaddr & LUMA_ALIAS_BIT) [[unlikely]] {
|
||||||
if ((paddr & 0xF0000000) == Memory::FCRAM_PADDR) { // Check FCRAM region
|
const PAddr paddr = vaddr & ~LUMA_ALIAS_BIT;
|
||||||
|
|
||||||
|
// FCRAM (0x2xxxxxxx)
|
||||||
|
if ((paddr & 0xF0000000) == Memory::FCRAM_PADDR) {
|
||||||
std::memcpy(GetFCRAMPointer(paddr - Memory::FCRAM_PADDR), &data, sizeof(T));
|
std::memcpy(GetFCRAMPointer(paddr - Memory::FCRAM_PADDR), &data, sizeof(T));
|
||||||
return;
|
return;
|
||||||
} else if ((paddr & 0xF0000000) == 0x10000000 &&
|
}
|
||||||
paddr >= Memory::IO_AREA_PADDR) { // Check MMIO region
|
|
||||||
|
// MMIO (0x1xxxxxxx, >= IO_AREA_PADDR) - Strictly 32-bit
|
||||||
|
if ((paddr & 0xF0000000) == 0x10000000 && paddr >= Memory::IO_AREA_PADDR) [[unlikely]] {
|
||||||
ASSERT(sizeof(data) == sizeof(u32));
|
ASSERT(sizeof(data) == sizeof(u32));
|
||||||
impl->system.GPU().WriteReg(static_cast<VAddr>(paddr) - Memory::IO_AREA_PADDR +
|
impl->system.GPU().WriteReg(static_cast<VAddr>(paddr) - Memory::IO_AREA_PADDR +
|
||||||
0x1EC00000,
|
0x1EC00000,
|
||||||
static_cast<u32>(data));
|
static_cast<u32>(data));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Fallthrough: Standard page table lookup
|
||||||
}
|
}
|
||||||
|
|
||||||
PageType type = page_table->attributes[vaddr >> CITRA_PAGE_BITS];
|
PageType type = page_table->attributes[vaddr >> CITRA_PAGE_BITS];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user