From fde93381a5fe86a8807762c7d1578b833014763e Mon Sep 17 00:00:00 2001 From: Wunkolo Date: Fri, 16 Jun 2023 07:24:34 -0700 Subject: [PATCH] Use `std::span` for CPU register-state Following the trend of #33: `std::span` provides some useful utility functions like `size_bytes()` and `as_bytes()` and serves as a better non-owning "chunk of data"-type over just passing around an `std::array&`. --- include/cpu_dynarmic.hpp | 18 ++++++++---------- include/kernel/kernel.hpp | 6 ++++-- include/services/service_manager.hpp | 12 +++++++----- src/core/kernel/threads.cpp | 24 +++++++++++++----------- src/core/services/service_manager.cpp | 10 ++++++---- 5 files changed, 38 insertions(+), 32 deletions(-) diff --git a/include/cpu_dynarmic.hpp b/include/cpu_dynarmic.hpp index d51a1f88..2682d0ee 100644 --- a/include/cpu_dynarmic.hpp +++ b/include/cpu_dynarmic.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "dynarmic/interface/A32/a32.h" #include "dynarmic/interface/A32/config.h" #include "dynarmic/interface/exclusive_monitor.h" @@ -132,17 +134,13 @@ public: return jit->Regs()[index]; } - std::array& regs() { - return jit->Regs(); - } + std::span regs() { return jit->Regs(); } - // Get reference to array of FPRs. This array consists of the FPRs as single precision values - // Hence why its base type is u32 - // Note: Dynarmic keeps 64 VFP registers as VFPv3 extends the VFP register set to 64 registers. - // However the 3DS ARM11 is an ARMv6k processor with VFPv2, so only the first 32 registers are actually used - std::array& fprs() { - return jit->ExtRegs(); - } + // Get reference to array of FPRs. This array consists of the FPRs as single precision values + // Hence why its base type is u32 + // Note: Dynarmic keeps 64 VFP registers as VFPv3 extends the VFP register set to 64 registers. + // However the 3DS ARM11 is an ARMv6k processor with VFPv2, so only the first 32 registers are actually used + std::span fprs() { return jit->ExtRegs(); } void setCPSR(u32 value) { jit->SetCpsr(value); diff --git a/include/kernel/kernel.hpp b/include/kernel/kernel.hpp index b4790056..cc2f4a4c 100644 --- a/include/kernel/kernel.hpp +++ b/include/kernel/kernel.hpp @@ -2,10 +2,12 @@ #include #include #include +#include #include #include -#include "kernel_types.hpp" + #include "helpers.hpp" +#include "kernel_types.hpp" #include "logger.hpp" #include "memory.hpp" #include "resource_limits.hpp" @@ -14,7 +16,7 @@ class CPU; class Kernel { - std::array& regs; + std::span regs; CPU& cpu; Memory& mem; diff --git a/include/services/service_manager.hpp b/include/services/service_manager.hpp index 300e8f2e..e09fd455 100644 --- a/include/services/service_manager.hpp +++ b/include/services/service_manager.hpp @@ -1,6 +1,8 @@ #pragma once #include #include +#include + #include "kernel_types.hpp" #include "logger.hpp" #include "memory.hpp" @@ -14,16 +16,16 @@ #include "services/cfg.hpp" #include "services/dlp_srvr.hpp" #include "services/dsp.hpp" -#include "services/hid.hpp" #include "services/frd.hpp" #include "services/fs.hpp" #include "services/gsp_gpu.hpp" #include "services/gsp_lcd.hpp" +#include "services/hid.hpp" #include "services/ldr_ro.hpp" #include "services/mic.hpp" +#include "services/ndm.hpp" #include "services/nfc.hpp" #include "services/nim.hpp" -#include "services/ndm.hpp" #include "services/ptm.hpp" #include "services/y2r.hpp" @@ -31,7 +33,7 @@ class Kernel; class ServiceManager { - std::array& regs; + std::span regs; Memory& mem; Kernel& kernel; @@ -69,8 +71,8 @@ class ServiceManager { void registerClient(u32 messagePointer); void subscribe(u32 messagePointer); -public: - ServiceManager(std::array& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel); + public: + ServiceManager(std::span regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel); void reset(); void initializeFS() { fs.initializeFilesystem(); } void handleSyncRequest(u32 messagePointer); diff --git a/src/core/kernel/threads.cpp b/src/core/kernel/threads.cpp index 8a87edb7..f41de34b 100644 --- a/src/core/kernel/threads.cpp +++ b/src/core/kernel/threads.cpp @@ -1,8 +1,10 @@ #include #include -#include "kernel.hpp" + #include "arm_defs.hpp" -// This header needs to be included because I did stupid forward decl hack so the kernel and CPU can both access each other +#include "kernel.hpp" +// This header needs to be included because I did stupid forward decl hack so the kernel and CPU can both access each +// other #include "cpu.hpp" #include "resource_limits.hpp" @@ -20,17 +22,17 @@ void Kernel::switchThread(int newThreadIndex) { } // Backup context - std::memcpy(&oldThread.gprs[0], &cpu.regs()[0], 16 * sizeof(u32)); // Backup the 16 GPRs - std::memcpy(&oldThread.fprs[0], &cpu.fprs()[0], 32 * sizeof(u32)); // Backup the 32 FPRs - oldThread.cpsr = cpu.getCPSR(); // Backup CPSR - oldThread.fpscr = cpu.getFPSCR(); // Backup FPSCR + std::memcpy(oldThread.gprs.data(), cpu.regs().data(), cpu.regs().size_bytes()); // Backup the 16 GPRs + std::memcpy(oldThread.fprs.data(), cpu.fprs().data(), cpu.fprs().size_bytes()); // Backup the 32 FPRs + oldThread.cpsr = cpu.getCPSR(); // Backup CPSR + oldThread.fpscr = cpu.getFPSCR(); // Backup FPSCR // Load new context - std::memcpy(&cpu.regs()[0], &newThread.gprs[0], 16 * sizeof(u32)); // Load 16 GPRs - std::memcpy(&cpu.fprs()[0], &newThread.fprs[0], 32 * sizeof(u32)); // Load 32 FPRs - cpu.setCPSR(newThread.cpsr); // Load CPSR - cpu.setFPSCR(newThread.fpscr); // Load FPSCR - cpu.setTLSBase(newThread.tlsBase); // Load CP15 thread-local-storage pointer register + std::memcpy(cpu.regs().data(), newThread.gprs.data(), cpu.regs().size_bytes()); // Load 16 GPRs + std::memcpy(cpu.fprs().data(), newThread.fprs.data(), cpu.fprs().size_bytes()); // Load 32 FPRs + cpu.setCPSR(newThread.cpsr); // Load CPSR + cpu.setFPSCR(newThread.fpscr); // Load FPSCR + cpu.setTLSBase(newThread.tlsBase); // Load CP15 thread-local-storage pointer register currentThreadIndex = newThreadIndex; } diff --git a/src/core/services/service_manager.cpp b/src/core/services/service_manager.cpp index 27b39af9..2b9c5167 100644 --- a/src/core/services/service_manager.cpp +++ b/src/core/services/service_manager.cpp @@ -1,13 +1,15 @@ #include "services/service_manager.hpp" + #include + #include "ipc.hpp" #include "kernel.hpp" -ServiceManager::ServiceManager(std::array& regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel) +ServiceManager::ServiceManager(std::span regs, Memory& mem, GPU& gpu, u32& currentPID, Kernel& kernel) : regs(regs), mem(mem), kernel(kernel), ac(mem), am(mem), boss(mem), act(mem), apt(mem, kernel), cam(mem), - cecd(mem, kernel), cfg(mem), dlp_srvr(mem), dsp(mem, kernel), hid(mem, kernel), frd(mem), fs(mem, kernel), - gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem), mic(mem), nfc(mem, kernel), nim(mem), ndm(mem), - ptm(mem), y2r(mem, kernel) {} + cecd(mem, kernel), cfg(mem), dlp_srvr(mem), dsp(mem, kernel), hid(mem, kernel), frd(mem), fs(mem, kernel), + gsp_gpu(mem, gpu, kernel, currentPID), gsp_lcd(mem), ldr(mem), mic(mem), nfc(mem, kernel), nim(mem), ndm(mem), + ptm(mem), y2r(mem, kernel) {} static constexpr int MAX_NOTIFICATION_COUNT = 16;