mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-05-29 01:49:11 +12:00
Map pages properly maybe
This commit is contained in:
parent
a174aa1e6a
commit
db2608eb14
4 changed files with 91 additions and 3 deletions
|
@ -8,8 +8,12 @@
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "handles.hpp"
|
#include "handles.hpp"
|
||||||
#include "loader/ncsd.hpp"
|
#include "loader/ncsd.hpp"
|
||||||
|
#include "MemArena/memory_arena.hpp"
|
||||||
#include "services/shared_font.hpp"
|
#include "services/shared_font.hpp"
|
||||||
|
|
||||||
|
// Comment this out to disable fastmem
|
||||||
|
#define PANDA3DS_HARDWARE_FASTMEM
|
||||||
|
|
||||||
namespace PhysicalAddrs {
|
namespace PhysicalAddrs {
|
||||||
enum : u32 {
|
enum : u32 {
|
||||||
VRAM = 0x18000000,
|
VRAM = 0x18000000,
|
||||||
|
@ -100,7 +104,7 @@ class Memory {
|
||||||
u64& cpuTicks; // Reference to the CPU tick counter
|
u64& cpuTicks; // Reference to the CPU tick counter
|
||||||
using SharedMemoryBlock = KernelMemoryTypes::SharedMemoryBlock;
|
using SharedMemoryBlock = KernelMemoryTypes::SharedMemoryBlock;
|
||||||
|
|
||||||
// Our dynarmic core uses page tables for reads and writes with 4096 byte pages
|
// Our memory core uses page tables for reads and writes with 4096 byte pages
|
||||||
std::vector<uintptr_t> readTable, writeTable;
|
std::vector<uintptr_t> readTable, writeTable;
|
||||||
|
|
||||||
// This tracks our OS' memory allocations
|
// This tracks our OS' memory allocations
|
||||||
|
@ -128,6 +132,36 @@ public:
|
||||||
static constexpr u32 DSP_DATA_MEMORY_OFFSET = 256_KB;
|
static constexpr u32 DSP_DATA_MEMORY_OFFSET = 256_KB;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// We also use MMU-accelerated fastmem for fast memory emulation
|
||||||
|
// This means that we've got a 4GB memory arena which is organized the same way as the emulated 3DS' memory map
|
||||||
|
// And we can access this directly instead of calling the memory read/write functions, which would be slower
|
||||||
|
// Regions that are not mapped or can't be accelerated this way will segfault, and the caller (eg dynarmic), will
|
||||||
|
// handle this segfault and call the Slower memory read/write functions
|
||||||
|
bool useFastmem = false;
|
||||||
|
u8* fastmemArenaBase = nullptr;
|
||||||
|
static constexpr size_t FASTMEM_FCRAM_OFFSET = 0; // Offset of FCRAM in the fastmem arena
|
||||||
|
static constexpr size_t FASTMEM_DSP_RAM_OFFSET = FASTMEM_FCRAM_OFFSET + FCRAM_SIZE; // Offset of DSP RAM
|
||||||
|
|
||||||
|
#ifdef PANDA3DS_HARDWARE_FASTMEM
|
||||||
|
Common::MemoryArena arena;
|
||||||
|
std::vector<Common::MemoryArena::View> fastmemViews;
|
||||||
|
|
||||||
|
void resetFastmemViews() { fastmemViews.clear(); }
|
||||||
|
void addFastmemView(u32 guestVaddr, size_t arenaOffset, size_t size, bool w, bool x = false) {
|
||||||
|
if (useFastmem) {
|
||||||
|
const auto hostAddr = fastmemArenaBase + guestVaddr;
|
||||||
|
auto view = arena.CreateView(arenaOffset, size, w, x, hostAddr);
|
||||||
|
|
||||||
|
if (view) {
|
||||||
|
fastmemViews.push_back(std::move(view.value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void resetFastmemViews() {}
|
||||||
|
void addFastmemView(u32 guestVaddr, size_t arenaOffset, size_t size, bool r, bool w, bool x = false) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
std::bitset<FCRAM_PAGE_COUNT> usedFCRAMPages;
|
std::bitset<FCRAM_PAGE_COUNT> usedFCRAMPages;
|
||||||
std::optional<u32> findPaddr(u32 size);
|
std::optional<u32> findPaddr(u32 size);
|
||||||
u64 timeSince3DSEpoch();
|
u64 timeSince3DSEpoch();
|
||||||
|
@ -202,6 +236,9 @@ public:
|
||||||
return (addr & pageMask) == 0;
|
return (addr & pageMask) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isFastmemEnabled() { return useFastmem; }
|
||||||
|
u8* getFastmemArenaBase() { return fastmemArenaBase; }
|
||||||
|
|
||||||
// Allocate "size" bytes of RAM starting from FCRAM index "paddr" (We pick it ourself if paddr == 0)
|
// Allocate "size" bytes of RAM starting from FCRAM index "paddr" (We pick it ourself if paddr == 0)
|
||||||
// And map them to virtual address "vaddr" (We also pick it ourself if vaddr == 0).
|
// And map them to virtual address "vaddr" (We also pick it ourself if vaddr == 0).
|
||||||
// If the "linear" flag is on, the paddr pages must be adjacent in FCRAM
|
// If the "linear" flag is on, the paddr pages must be adjacent in FCRAM
|
||||||
|
|
|
@ -12,6 +12,7 @@ CPU::CPU(Memory& mem, Kernel& kernel) : mem(mem), env(mem, kernel, *this) {
|
||||||
config.define_unpredictable_behaviour = true;
|
config.define_unpredictable_behaviour = true;
|
||||||
config.global_monitor = &exclusiveMonitor;
|
config.global_monitor = &exclusiveMonitor;
|
||||||
config.processor_id = 0;
|
config.processor_id = 0;
|
||||||
|
config.fastmem_pointer = mem.isFastmemEnabled() ? mem.getFastmemArenaBase() : nullptr;
|
||||||
|
|
||||||
jit = std::make_unique<Dynarmic::A32::Jit>(config);
|
jit = std::make_unique<Dynarmic::A32::Jit>(config);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,51 @@ Memory::Memory(u64& cpuTicks) : cpuTicks(cpuTicks) {
|
||||||
readTable.resize(totalPageCount, 0);
|
readTable.resize(totalPageCount, 0);
|
||||||
writeTable.resize(totalPageCount, 0);
|
writeTable.resize(totalPageCount, 0);
|
||||||
memoryInfo.reserve(32); // Pre-allocate some room for memory allocation info to avoid dynamic allocs
|
memoryInfo.reserve(32); // Pre-allocate some room for memory allocation info to avoid dynamic allocs
|
||||||
|
|
||||||
|
#ifdef PANDA3DS_HARDWARE_FASTMEM
|
||||||
|
constexpr size_t FASTMEM_MEMORY_SIZE = 0x100000000; // Total size of the virtual address space we will occupy (4GB)
|
||||||
|
u8* arenaFcram = nullptr;
|
||||||
|
u8* arenaDSPRam = nullptr;
|
||||||
|
|
||||||
|
constexpr size_t MEMORY_ARENA_SIZE = FCRAM_SIZE + DSP_RAM_SIZE;
|
||||||
|
if (!arena.Create(MEMORY_ARENA_SIZE, true, false) || !arena.IsValid()) {
|
||||||
|
printf("Failed to create fastmem memory arena\n");
|
||||||
|
goto fastmemSetupFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
fastmemArenaBase = (u8*)arena.FindBaseAddressForMapping(FASTMEM_MEMORY_SIZE);
|
||||||
|
if (!fastmemArenaBase) {
|
||||||
|
printf("Couldn't find base address for fastmem\n");
|
||||||
|
goto fastmemSetupFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
arenaFcram = (u8*)arena.CreateViewPtr(FASTMEM_FCRAM_OFFSET, FCRAM_SIZE, true, false);
|
||||||
|
if (!arenaFcram) {
|
||||||
|
printf("Couldn't allocate FCRAM for fastmem");
|
||||||
|
goto fastmemSetupFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
arenaDSPRam = (u8*)arena.CreateViewPtr(FASTMEM_DSP_RAM_OFFSET, DSP_RAM_SIZE, true, false);
|
||||||
|
if (!arenaDSPRam) {
|
||||||
|
printf("Couldn't allocate FCRAM for fastmem");
|
||||||
|
goto fastmemSetupFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
fcram = arenaFcram;
|
||||||
|
dspRam = arenaDSPRam;
|
||||||
|
useFastmem = true;
|
||||||
|
return;
|
||||||
|
|
||||||
|
fastmemSetupFail:
|
||||||
|
if (arenaFcram) arena.ReleaseViewPtr(arenaFcram, FCRAM_SIZE);
|
||||||
|
if (arenaDSPRam) arena.ReleaseViewPtr(arenaDSPRam, DSP_RAM_SIZE);
|
||||||
|
useFastmem = false;
|
||||||
|
fastmemArenaBase = nullptr;
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
useFastmem = false;
|
||||||
|
fastmemArenaBase = nullptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::reset() {
|
void Memory::reset() {
|
||||||
|
@ -27,6 +72,9 @@ void Memory::reset() {
|
||||||
writeTable[i] = 0;
|
writeTable[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetFastmemViews(); // Reset the entire fastmem state
|
||||||
|
addFastmemView(VirtualAddrs::DSPMemStart, FASTMEM_DSP_RAM_OFFSET, DSP_RAM_SIZE, true, false); // Allocate RW mapping for DSP RAM
|
||||||
|
|
||||||
// Map stack pages as R/W
|
// Map stack pages as R/W
|
||||||
// We have 16KB for the stack, so we allocate the last 16KB of APPLICATION FCRAM for the stack
|
// We have 16KB for the stack, so we allocate the last 16KB of APPLICATION FCRAM for the stack
|
||||||
u32 basePaddrForStack = FCRAM_APPLICATION_SIZE - VirtualAddrs::DefaultStackSize;
|
u32 basePaddrForStack = FCRAM_APPLICATION_SIZE - VirtualAddrs::DefaultStackSize;
|
||||||
|
@ -284,6 +332,9 @@ std::optional<u32> Memory::allocateMemory(u32 vaddr, u32 paddr, u32 size, bool l
|
||||||
|
|
||||||
// Mark FCRAM page as allocated and go on
|
// Mark FCRAM page as allocated and go on
|
||||||
usedFCRAMPages[physPage] = true;
|
usedFCRAMPages[physPage] = true;
|
||||||
|
// Add mapping to the fastmem arena
|
||||||
|
addFastmemView(size_t(virtualPage) * pageSize, FASTMEM_FCRAM_OFFSET + size_t(physPage) * pageSize, pageSize, w, false);
|
||||||
|
|
||||||
virtualPage++;
|
virtualPage++;
|
||||||
physPage++;
|
physPage++;
|
||||||
}
|
}
|
||||||
|
|
1
third_party/Duckstation/memory_arena.cpp
vendored
1
third_party/Duckstation/memory_arena.cpp
vendored
|
@ -125,7 +125,6 @@ static std::string GetFileMappingName()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string ret = std::string("Alber_") + std::to_string(pid);
|
std::string ret = std::string("Alber_") + std::to_string(pid);
|
||||||
printf("File mapping name: %s\n", ret.c_str());
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue