mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-12 09:09:47 +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 "handles.hpp"
|
||||
#include "loader/ncsd.hpp"
|
||||
#include "MemArena/memory_arena.hpp"
|
||||
#include "services/shared_font.hpp"
|
||||
|
||||
// Comment this out to disable fastmem
|
||||
#define PANDA3DS_HARDWARE_FASTMEM
|
||||
|
||||
namespace PhysicalAddrs {
|
||||
enum : u32 {
|
||||
VRAM = 0x18000000,
|
||||
|
@ -100,7 +104,7 @@ class Memory {
|
|||
u64& cpuTicks; // Reference to the CPU tick counter
|
||||
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;
|
||||
|
||||
// This tracks our OS' memory allocations
|
||||
|
@ -128,6 +132,36 @@ public:
|
|||
static constexpr u32 DSP_DATA_MEMORY_OFFSET = 256_KB;
|
||||
|
||||
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::optional<u32> findPaddr(u32 size);
|
||||
u64 timeSince3DSEpoch();
|
||||
|
@ -202,6 +236,9 @@ public:
|
|||
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)
|
||||
// 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
|
||||
|
|
|
@ -12,7 +12,8 @@ CPU::CPU(Memory& mem, Kernel& kernel) : mem(mem), env(mem, kernel, *this) {
|
|||
config.define_unpredictable_behaviour = true;
|
||||
config.global_monitor = &exclusiveMonitor;
|
||||
config.processor_id = 0;
|
||||
|
||||
config.fastmem_pointer = mem.isFastmemEnabled() ? mem.getFastmemArenaBase() : nullptr;
|
||||
|
||||
jit = std::make_unique<Dynarmic::A32::Jit>(config);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,51 @@ Memory::Memory(u64& cpuTicks) : cpuTicks(cpuTicks) {
|
|||
readTable.resize(totalPageCount, 0);
|
||||
writeTable.resize(totalPageCount, 0);
|
||||
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() {
|
||||
|
@ -27,6 +72,9 @@ void Memory::reset() {
|
|||
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
|
||||
// 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;
|
||||
|
@ -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
|
||||
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++;
|
||||
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
|
||||
|
||||
std::string ret = std::string("Alber_") + std::to_string(pid);
|
||||
printf("File mapping name: %s\n", ret.c_str());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue