From f858107dd0ad25dfdc7f991916f26e524b8cecc0 Mon Sep 17 00:00:00 2001
From: wheremyfoodat <gponiris2004@gmail.com>
Date: Mon, 10 Oct 2022 22:55:55 +0300
Subject: [PATCH] [Memory] Add DSP RAM

---
 include/memory.hpp  | 14 +++++++++++++-
 src/core/memory.cpp | 13 +++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/include/memory.hpp b/include/memory.hpp
index 4d69194d..556f03dc 100644
--- a/include/memory.hpp
+++ b/include/memory.hpp
@@ -34,7 +34,9 @@ namespace VirtualAddrs {
 
 		// Start of TLS for first thread. Next thread's storage will be at TLSBase + 0x1000, and so on
 		TLSBase = 0xFF400000,
-		TLSSize = 0x1000
+		TLSSize = 0x1000,
+
+		DSPMemStart = 0x1FF00000
 	};
 }
 
@@ -86,6 +88,8 @@ namespace KernelMemoryTypes {
 
 class Memory {
 	u8* fcram;
+	u8* dspRam;
+
 	u64& cpuTicks; // Reference to the CPU tick counter
 	using SharedMemoryBlock = KernelMemoryTypes::SharedMemoryBlock;
 
@@ -110,6 +114,10 @@ class Memory {
 	static constexpr u32 FCRAM_PAGE_COUNT = FCRAM_SIZE / pageSize;
 	static constexpr u32 FCRAM_APPLICATION_PAGE_COUNT = FCRAM_APPLICATION_SIZE / pageSize;
 
+	static constexpr u32 DSP_RAM_SIZE = 512_KB;
+	static constexpr u32 DSP_CODE_MEMORY_OFFSET = 0_KB;
+	static constexpr u32 DSP_DATA_MEMORY_OFFSET = 256_KB;
+
 	std::bitset<FCRAM_PAGE_COUNT> usedFCRAMPages;
 	std::optional<u32> findPaddr(u32 size);
 	u64 timeSince3DSEpoch();
@@ -178,4 +186,8 @@ public:
 	std::optional<NCCH> loadedCXI = std::nullopt;
 	// File handle for reading the loaded ncch
 	IOFile CXIFile;
+
+	u8* getDSPMem() { return dspRam; }
+	u8* getDSPDataMem() { return &dspRam[DSP_DATA_MEMORY_OFFSET]; }
+	u8* getDSPCodeMem() { return &dspRam[DSP_CODE_MEMORY_OFFSET]; }
 };
\ No newline at end of file
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 004afb52..e69c6ba4 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -8,6 +8,8 @@ using namespace KernelMemoryTypes;
 
 Memory::Memory(u64& cpuTicks) : cpuTicks(cpuTicks) {
 	fcram = new uint8_t[FCRAM_SIZE]();
+	dspRam = new uint8_t[DSP_RAM_SIZE]();
+
 	readTable.resize(totalPageCount, 0);
 	writeTable.resize(totalPageCount, 0);
 	memoryInfo.reserve(32); // Pre-allocate some room for memory allocation info to avoid dynamic allocs
@@ -49,6 +51,17 @@ void Memory::reset() {
 			Helpers::panic("Failed to reserve memory for shared memory block");
 		}
 	}
+
+	// Map DSP RAM as R/W at [0x1FF00000, 0x1FF7FFFF]
+	constexpr u32 dspRamPages = DSP_RAM_SIZE / pageSize; // Number of DSP RAM pages
+	constexpr u32 initialPage = VirtualAddrs::DSPMemStart / pageSize; // First page of DSP RAM in the virtual address space
+
+	for (u32 i = 0; i < dspRamPages; i++) {
+		auto pointer = uintptr_t(&dspRam[i * pageSize]);
+
+		readTable[i + initialPage] = pointer;
+		writeTable[i + initialPage] = pointer;
+	}
 }
 
 u8 Memory::read8(u32 vaddr) {