summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/arm_interface.cpp2
-rw-r--r--src/core/arm/arm_interface.h2
-rw-r--r--src/core/arm/debug.cpp14
-rw-r--r--src/core/arm/debug.h6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h2
-rw-r--r--src/core/core.cpp73
-rw-r--r--src/core/core.h13
-rw-r--r--src/core/hle/kernel/k_address_arbiter.cpp19
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp8
-rw-r--r--src/core/hle/kernel/k_process.cpp18
-rw-r--r--src/core/hle/kernel/k_process.h15
-rw-r--r--src/core/hle/kernel/k_thread.h6
-rw-r--r--src/core/hle/kernel/kernel.cpp13
-rw-r--r--src/core/hle/kernel/kernel.h4
17 files changed, 82 insertions, 127 deletions
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 698c9c8ad..5dc7e5d59 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -9,7 +9,7 @@
9 9
10namespace Core { 10namespace Core {
11 11
12void ArmInterface::LogBacktrace(const Kernel::KProcess* process) const { 12void ArmInterface::LogBacktrace(Kernel::KProcess* process) const {
13 Kernel::Svc::ThreadContext ctx; 13 Kernel::Svc::ThreadContext ctx;
14 this->GetContext(ctx); 14 this->GetContext(ctx);
15 15
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 806c7c9e9..495963eef 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -95,7 +95,7 @@ public:
95 virtual void SignalInterrupt(Kernel::KThread* thread) = 0; 95 virtual void SignalInterrupt(Kernel::KThread* thread) = 0;
96 96
97 // Stack trace generation. 97 // Stack trace generation.
98 void LogBacktrace(const Kernel::KProcess* process) const; 98 void LogBacktrace(Kernel::KProcess* process) const;
99 99
100 // Debug functionality. 100 // Debug functionality.
101 virtual const Kernel::DebugWatchpoint* HaltedWatchpoint() const = 0; 101 virtual const Kernel::DebugWatchpoint* HaltedWatchpoint() const = 0;
diff --git a/src/core/arm/debug.cpp b/src/core/arm/debug.cpp
index af1c34bc3..854509463 100644
--- a/src/core/arm/debug.cpp
+++ b/src/core/arm/debug.cpp
@@ -79,7 +79,7 @@ constexpr std::array<u64, 2> SegmentBases{
79 0x7100000000ULL, 79 0x7100000000ULL,
80}; 80};
81 81
82void SymbolicateBacktrace(const Kernel::KProcess* process, std::vector<BacktraceEntry>& out) { 82void SymbolicateBacktrace(Kernel::KProcess* process, std::vector<BacktraceEntry>& out) {
83 auto modules = FindModules(process); 83 auto modules = FindModules(process);
84 84
85 const bool is_64 = process->Is64Bit(); 85 const bool is_64 = process->Is64Bit();
@@ -118,7 +118,7 @@ void SymbolicateBacktrace(const Kernel::KProcess* process, std::vector<Backtrace
118 } 118 }
119} 119}
120 120
121std::vector<BacktraceEntry> GetAArch64Backtrace(const Kernel::KProcess* process, 121std::vector<BacktraceEntry> GetAArch64Backtrace(Kernel::KProcess* process,
122 const Kernel::Svc::ThreadContext& ctx) { 122 const Kernel::Svc::ThreadContext& ctx) {
123 std::vector<BacktraceEntry> out; 123 std::vector<BacktraceEntry> out;
124 auto& memory = process->GetMemory(); 124 auto& memory = process->GetMemory();
@@ -144,7 +144,7 @@ std::vector<BacktraceEntry> GetAArch64Backtrace(const Kernel::KProcess* process,
144 return out; 144 return out;
145} 145}
146 146
147std::vector<BacktraceEntry> GetAArch32Backtrace(const Kernel::KProcess* process, 147std::vector<BacktraceEntry> GetAArch32Backtrace(Kernel::KProcess* process,
148 const Kernel::Svc::ThreadContext& ctx) { 148 const Kernel::Svc::ThreadContext& ctx) {
149 std::vector<BacktraceEntry> out; 149 std::vector<BacktraceEntry> out;
150 auto& memory = process->GetMemory(); 150 auto& memory = process->GetMemory();
@@ -173,7 +173,7 @@ std::vector<BacktraceEntry> GetAArch32Backtrace(const Kernel::KProcess* process,
173} // namespace 173} // namespace
174 174
175std::optional<std::string> GetThreadName(const Kernel::KThread* thread) { 175std::optional<std::string> GetThreadName(const Kernel::KThread* thread) {
176 const auto* process = thread->GetOwnerProcess(); 176 auto* process = thread->GetOwnerProcess();
177 if (process->Is64Bit()) { 177 if (process->Is64Bit()) {
178 return GetNameFromThreadType64(process->GetMemory(), *thread); 178 return GetNameFromThreadType64(process->GetMemory(), *thread);
179 } else { 179 } else {
@@ -248,7 +248,7 @@ Kernel::KProcessAddress GetModuleEnd(const Kernel::KProcess* process,
248 return cur_addr - 1; 248 return cur_addr - 1;
249} 249}
250 250
251Loader::AppLoader::Modules FindModules(const Kernel::KProcess* process) { 251Loader::AppLoader::Modules FindModules(Kernel::KProcess* process) {
252 Loader::AppLoader::Modules modules; 252 Loader::AppLoader::Modules modules;
253 253
254 auto& page_table = process->GetPageTable(); 254 auto& page_table = process->GetPageTable();
@@ -312,7 +312,7 @@ Loader::AppLoader::Modules FindModules(const Kernel::KProcess* process) {
312 return modules; 312 return modules;
313} 313}
314 314
315Kernel::KProcessAddress FindMainModuleEntrypoint(const Kernel::KProcess* process) { 315Kernel::KProcessAddress FindMainModuleEntrypoint(Kernel::KProcess* process) {
316 // Do we have any loaded executable sections? 316 // Do we have any loaded executable sections?
317 auto modules = FindModules(process); 317 auto modules = FindModules(process);
318 318
@@ -337,7 +337,7 @@ void InvalidateInstructionCacheRange(const Kernel::KProcess* process, u64 addres
337 } 337 }
338} 338}
339 339
340std::vector<BacktraceEntry> GetBacktraceFromContext(const Kernel::KProcess* process, 340std::vector<BacktraceEntry> GetBacktraceFromContext(Kernel::KProcess* process,
341 const Kernel::Svc::ThreadContext& ctx) { 341 const Kernel::Svc::ThreadContext& ctx) {
342 if (process->Is64Bit()) { 342 if (process->Is64Bit()) {
343 return GetAArch64Backtrace(process, ctx); 343 return GetAArch64Backtrace(process, ctx);
diff --git a/src/core/arm/debug.h b/src/core/arm/debug.h
index c542633db..3cd671365 100644
--- a/src/core/arm/debug.h
+++ b/src/core/arm/debug.h
@@ -14,9 +14,9 @@ std::optional<std::string> GetThreadName(const Kernel::KThread* thread);
14std::string_view GetThreadWaitReason(const Kernel::KThread* thread); 14std::string_view GetThreadWaitReason(const Kernel::KThread* thread);
15std::string GetThreadState(const Kernel::KThread* thread); 15std::string GetThreadState(const Kernel::KThread* thread);
16 16
17Loader::AppLoader::Modules FindModules(const Kernel::KProcess* process); 17Loader::AppLoader::Modules FindModules(Kernel::KProcess* process);
18Kernel::KProcessAddress GetModuleEnd(const Kernel::KProcess* process, Kernel::KProcessAddress base); 18Kernel::KProcessAddress GetModuleEnd(const Kernel::KProcess* process, Kernel::KProcessAddress base);
19Kernel::KProcessAddress FindMainModuleEntrypoint(const Kernel::KProcess* process); 19Kernel::KProcessAddress FindMainModuleEntrypoint(Kernel::KProcess* process);
20 20
21void InvalidateInstructionCacheRange(const Kernel::KProcess* process, u64 address, u64 size); 21void InvalidateInstructionCacheRange(const Kernel::KProcess* process, u64 address, u64 size);
22 22
@@ -28,7 +28,7 @@ struct BacktraceEntry {
28 std::string name; 28 std::string name;
29}; 29};
30 30
31std::vector<BacktraceEntry> GetBacktraceFromContext(const Kernel::KProcess* process, 31std::vector<BacktraceEntry> GetBacktraceFromContext(Kernel::KProcess* process,
32 const Kernel::Svc::ThreadContext& ctx); 32 const Kernel::Svc::ThreadContext& ctx);
33std::vector<BacktraceEntry> GetBacktrace(const Kernel::KThread* thread); 33std::vector<BacktraceEntry> GetBacktrace(const Kernel::KThread* thread);
34 34
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index f34865e26..c78cfd528 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -15,7 +15,7 @@ using namespace Common::Literals;
15 15
16class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks { 16class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks {
17public: 17public:
18 explicit DynarmicCallbacks32(ArmDynarmic32& parent, const Kernel::KProcess* process) 18 explicit DynarmicCallbacks32(ArmDynarmic32& parent, Kernel::KProcess* process)
19 : m_parent{parent}, m_memory(process->GetMemory()), 19 : m_parent{parent}, m_memory(process->GetMemory()),
20 m_process(process), m_debugger_enabled{parent.m_system.DebuggerEnabled()}, 20 m_process(process), m_debugger_enabled{parent.m_system.DebuggerEnabled()},
21 m_check_memory_access{m_debugger_enabled || 21 m_check_memory_access{m_debugger_enabled ||
@@ -169,7 +169,7 @@ public:
169 169
170 ArmDynarmic32& m_parent; 170 ArmDynarmic32& m_parent;
171 Core::Memory::Memory& m_memory; 171 Core::Memory::Memory& m_memory;
172 const Kernel::KProcess* m_process{}; 172 Kernel::KProcess* m_process{};
173 const bool m_debugger_enabled{}; 173 const bool m_debugger_enabled{};
174 const bool m_check_memory_access{}; 174 const bool m_check_memory_access{};
175 static constexpr u64 MinimumRunCycles = 10000U; 175 static constexpr u64 MinimumRunCycles = 10000U;
@@ -370,7 +370,7 @@ void ArmDynarmic32::RewindBreakpointInstruction() {
370 this->SetContext(m_breakpoint_context); 370 this->SetContext(m_breakpoint_context);
371} 371}
372 372
373ArmDynarmic32::ArmDynarmic32(System& system, bool uses_wall_clock, const Kernel::KProcess* process, 373ArmDynarmic32::ArmDynarmic32(System& system, bool uses_wall_clock, Kernel::KProcess* process,
374 DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index) 374 DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index)
375 : ArmInterface{uses_wall_clock}, m_system{system}, m_exclusive_monitor{exclusive_monitor}, 375 : ArmInterface{uses_wall_clock}, m_system{system}, m_exclusive_monitor{exclusive_monitor},
376 m_cb(std::make_unique<DynarmicCallbacks32>(*this, process)), 376 m_cb(std::make_unique<DynarmicCallbacks32>(*this, process)),
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h
index 185ac7cbf..b580efe61 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.h
@@ -20,7 +20,7 @@ class System;
20 20
21class ArmDynarmic32 final : public ArmInterface { 21class ArmDynarmic32 final : public ArmInterface {
22public: 22public:
23 ArmDynarmic32(System& system, bool uses_wall_clock, const Kernel::KProcess* process, 23 ArmDynarmic32(System& system, bool uses_wall_clock, Kernel::KProcess* process,
24 DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index); 24 DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index);
25 ~ArmDynarmic32() override; 25 ~ArmDynarmic32() override;
26 26
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index dff14756e..f351b13d9 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -15,7 +15,7 @@ using namespace Common::Literals;
15 15
16class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks { 16class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks {
17public: 17public:
18 explicit DynarmicCallbacks64(ArmDynarmic64& parent, const Kernel::KProcess* process) 18 explicit DynarmicCallbacks64(ArmDynarmic64& parent, Kernel::KProcess* process)
19 : m_parent{parent}, m_memory(process->GetMemory()), 19 : m_parent{parent}, m_memory(process->GetMemory()),
20 m_process(process), m_debugger_enabled{parent.m_system.DebuggerEnabled()}, 20 m_process(process), m_debugger_enabled{parent.m_system.DebuggerEnabled()},
21 m_check_memory_access{m_debugger_enabled || 21 m_check_memory_access{m_debugger_enabled ||
@@ -216,7 +216,7 @@ public:
216 Core::Memory::Memory& m_memory; 216 Core::Memory::Memory& m_memory;
217 u64 m_tpidrro_el0{}; 217 u64 m_tpidrro_el0{};
218 u64 m_tpidr_el0{}; 218 u64 m_tpidr_el0{};
219 const Kernel::KProcess* m_process{}; 219 Kernel::KProcess* m_process{};
220 const bool m_debugger_enabled{}; 220 const bool m_debugger_enabled{};
221 const bool m_check_memory_access{}; 221 const bool m_check_memory_access{};
222 static constexpr u64 MinimumRunCycles = 10000U; 222 static constexpr u64 MinimumRunCycles = 10000U;
@@ -399,7 +399,7 @@ void ArmDynarmic64::RewindBreakpointInstruction() {
399 this->SetContext(m_breakpoint_context); 399 this->SetContext(m_breakpoint_context);
400} 400}
401 401
402ArmDynarmic64::ArmDynarmic64(System& system, bool uses_wall_clock, const Kernel::KProcess* process, 402ArmDynarmic64::ArmDynarmic64(System& system, bool uses_wall_clock, Kernel::KProcess* process,
403 DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index) 403 DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index)
404 : ArmInterface{uses_wall_clock}, m_system{system}, m_exclusive_monitor{exclusive_monitor}, 404 : ArmInterface{uses_wall_clock}, m_system{system}, m_exclusive_monitor{exclusive_monitor},
405 m_cb(std::make_unique<DynarmicCallbacks64>(*this, process)), m_core_index{core_index} { 405 m_cb(std::make_unique<DynarmicCallbacks64>(*this, process)), m_core_index{core_index} {
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index 4f3dd026f..08cd982b3 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -25,7 +25,7 @@ class System;
25 25
26class ArmDynarmic64 final : public ArmInterface { 26class ArmDynarmic64 final : public ArmInterface {
27public: 27public:
28 ArmDynarmic64(System& system, bool uses_wall_clock, const Kernel::KProcess* process, 28 ArmDynarmic64(System& system, bool uses_wall_clock, Kernel::KProcess* process,
29 DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index); 29 DynarmicExclusiveMonitor& exclusive_monitor, std::size_t core_index);
30 ~ArmDynarmic64() override; 30 ~ArmDynarmic64() override;
31 31
diff --git a/src/core/core.cpp b/src/core/core.cpp
index b14f74976..66f444d39 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -28,7 +28,6 @@
28#include "core/file_sys/savedata_factory.h" 28#include "core/file_sys/savedata_factory.h"
29#include "core/file_sys/vfs_concat.h" 29#include "core/file_sys/vfs_concat.h"
30#include "core/file_sys/vfs_real.h" 30#include "core/file_sys/vfs_real.h"
31#include "core/gpu_dirty_memory_manager.h"
32#include "core/hid/hid_core.h" 31#include "core/hid/hid_core.h"
33#include "core/hle/kernel/k_memory_manager.h" 32#include "core/hle/kernel/k_memory_manager.h"
34#include "core/hle/kernel/k_process.h" 33#include "core/hle/kernel/k_process.h"
@@ -130,11 +129,8 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
130 129
131struct System::Impl { 130struct System::Impl {
132 explicit Impl(System& system) 131 explicit Impl(System& system)
133 : kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{}, 132 : kernel{system}, fs_controller{system}, hid_core{}, room_network{}, cpu_manager{system},
134 cpu_manager{system}, reporter{system}, applet_manager{system}, profile_manager{}, 133 reporter{system}, applet_manager{system}, profile_manager{}, time_manager{system} {}
135 time_manager{system}, gpu_dirty_memory_write_manager{} {
136 memory.SetGPUDirtyManagers(gpu_dirty_memory_write_manager);
137 }
138 134
139 void Initialize(System& system) { 135 void Initialize(System& system) {
140 device_memory = std::make_unique<Core::DeviceMemory>(); 136 device_memory = std::make_unique<Core::DeviceMemory>();
@@ -241,17 +237,17 @@ struct System::Impl {
241 debugger = std::make_unique<Debugger>(system, port); 237 debugger = std::make_unique<Debugger>(system, port);
242 } 238 }
243 239
244 SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) { 240 void InitializeKernel(System& system) {
245 LOG_DEBUG(Core, "initialized OK"); 241 LOG_DEBUG(Core, "initialized OK");
246 242
247 // Setting changes may require a full system reinitialization (e.g., disabling multicore). 243 // Setting changes may require a full system reinitialization (e.g., disabling multicore).
248 ReinitializeIfNecessary(system); 244 ReinitializeIfNecessary(system);
249 245
250 memory.SetGPUDirtyManagers(gpu_dirty_memory_write_manager);
251
252 kernel.Initialize(); 246 kernel.Initialize();
253 cpu_manager.Initialize(); 247 cpu_manager.Initialize();
248 }
254 249
250 SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
255 /// Reset all glue registrations 251 /// Reset all glue registrations
256 arp_manager.ResetAll(); 252 arp_manager.ResetAll();
257 253
@@ -300,17 +296,9 @@ struct System::Impl {
300 return SystemResultStatus::ErrorGetLoader; 296 return SystemResultStatus::ErrorGetLoader;
301 } 297 }
302 298
303 SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)}; 299 InitializeKernel(system);
304 if (init_result != SystemResultStatus::Success) {
305 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
306 static_cast<int>(init_result));
307 ShutdownMainProcess();
308 return init_result;
309 }
310
311 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
312 300
313 // Create the process. 301 // Create the application process.
314 auto main_process = Kernel::KProcess::Create(system.Kernel()); 302 auto main_process = Kernel::KProcess::Create(system.Kernel());
315 Kernel::KProcess::Register(system.Kernel(), main_process); 303 Kernel::KProcess::Register(system.Kernel(), main_process);
316 kernel.AppendNewProcess(main_process); 304 kernel.AppendNewProcess(main_process);
@@ -323,7 +311,18 @@ struct System::Impl {
323 return static_cast<SystemResultStatus>( 311 return static_cast<SystemResultStatus>(
324 static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result)); 312 static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
325 } 313 }
314
315 // Set up the rest of the system.
316 SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
317 if (init_result != SystemResultStatus::Success) {
318 LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
319 static_cast<int>(init_result));
320 ShutdownMainProcess();
321 return init_result;
322 }
323
326 AddGlueRegistrationForProcess(*app_loader, *main_process); 324 AddGlueRegistrationForProcess(*app_loader, *main_process);
325 telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
327 326
328 // Initialize cheat engine 327 // Initialize cheat engine
329 if (cheat_engine) { 328 if (cheat_engine) {
@@ -426,7 +425,6 @@ struct System::Impl {
426 cpu_manager.Shutdown(); 425 cpu_manager.Shutdown();
427 debugger.reset(); 426 debugger.reset();
428 kernel.Shutdown(); 427 kernel.Shutdown();
429 memory.Reset();
430 Network::RestartSocketOperations(); 428 Network::RestartSocketOperations();
431 429
432 if (auto room_member = room_network.GetRoomMember().lock()) { 430 if (auto room_member = room_network.GetRoomMember().lock()) {
@@ -507,7 +505,6 @@ struct System::Impl {
507 std::unique_ptr<Tegra::Host1x::Host1x> host1x_core; 505 std::unique_ptr<Tegra::Host1x::Host1x> host1x_core;
508 std::unique_ptr<Core::DeviceMemory> device_memory; 506 std::unique_ptr<Core::DeviceMemory> device_memory;
509 std::unique_ptr<AudioCore::AudioCore> audio_core; 507 std::unique_ptr<AudioCore::AudioCore> audio_core;
510 Core::Memory::Memory memory;
511 Core::HID::HIDCore hid_core; 508 Core::HID::HIDCore hid_core;
512 Network::RoomNetwork room_network; 509 Network::RoomNetwork room_network;
513 510
@@ -567,9 +564,6 @@ struct System::Impl {
567 std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; 564 std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
568 std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_cpu{}; 565 std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_cpu{};
569 566
570 std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES>
571 gpu_dirty_memory_write_manager{};
572
573 std::deque<std::vector<u8>> user_channel; 567 std::deque<std::vector<u8>> user_channel;
574}; 568};
575 569
@@ -652,29 +646,12 @@ void System::PrepareReschedule(const u32 core_index) {
652 impl->kernel.PrepareReschedule(core_index); 646 impl->kernel.PrepareReschedule(core_index);
653} 647}
654 648
655Core::GPUDirtyMemoryManager& System::CurrentGPUDirtyMemoryManager() {
656 const std::size_t core = impl->kernel.GetCurrentHostThreadID();
657 return impl->gpu_dirty_memory_write_manager[core < Core::Hardware::NUM_CPU_CORES
658 ? core
659 : Core::Hardware::NUM_CPU_CORES - 1];
660}
661
662/// Provides a constant reference to the current gou dirty memory manager.
663const Core::GPUDirtyMemoryManager& System::CurrentGPUDirtyMemoryManager() const {
664 const std::size_t core = impl->kernel.GetCurrentHostThreadID();
665 return impl->gpu_dirty_memory_write_manager[core < Core::Hardware::NUM_CPU_CORES
666 ? core
667 : Core::Hardware::NUM_CPU_CORES - 1];
668}
669
670size_t System::GetCurrentHostThreadID() const { 649size_t System::GetCurrentHostThreadID() const {
671 return impl->kernel.GetCurrentHostThreadID(); 650 return impl->kernel.GetCurrentHostThreadID();
672} 651}
673 652
674void System::GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback) { 653void System::GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback) {
675 for (auto& manager : impl->gpu_dirty_memory_write_manager) { 654 return this->ApplicationProcess()->GatherGPUDirtyMemory(callback);
676 manager.Gather(callback);
677 }
678} 655}
679 656
680PerfStatsResults System::GetAndResetPerfStats() { 657PerfStatsResults System::GetAndResetPerfStats() {
@@ -723,20 +700,12 @@ const Kernel::KProcess* System::ApplicationProcess() const {
723 return impl->kernel.ApplicationProcess(); 700 return impl->kernel.ApplicationProcess();
724} 701}
725 702
726ExclusiveMonitor& System::Monitor() {
727 return impl->kernel.GetExclusiveMonitor();
728}
729
730const ExclusiveMonitor& System::Monitor() const {
731 return impl->kernel.GetExclusiveMonitor();
732}
733
734Memory::Memory& System::ApplicationMemory() { 703Memory::Memory& System::ApplicationMemory() {
735 return impl->memory; 704 return impl->kernel.ApplicationProcess()->GetMemory();
736} 705}
737 706
738const Core::Memory::Memory& System::ApplicationMemory() const { 707const Core::Memory::Memory& System::ApplicationMemory() const {
739 return impl->memory; 708 return impl->kernel.ApplicationProcess()->GetMemory();
740} 709}
741 710
742Tegra::GPU& System::GPU() { 711Tegra::GPU& System::GPU() {
diff --git a/src/core/core.h b/src/core/core.h
index 473204db7..ba5add0dc 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -116,7 +116,6 @@ class CpuManager;
116class Debugger; 116class Debugger;
117class DeviceMemory; 117class DeviceMemory;
118class ExclusiveMonitor; 118class ExclusiveMonitor;
119class GPUDirtyMemoryManager;
120class PerfStats; 119class PerfStats;
121class Reporter; 120class Reporter;
122class SpeedLimiter; 121class SpeedLimiter;
@@ -225,12 +224,6 @@ public:
225 /// Prepare the core emulation for a reschedule 224 /// Prepare the core emulation for a reschedule
226 void PrepareReschedule(u32 core_index); 225 void PrepareReschedule(u32 core_index);
227 226
228 /// Provides a reference to the gou dirty memory manager.
229 [[nodiscard]] Core::GPUDirtyMemoryManager& CurrentGPUDirtyMemoryManager();
230
231 /// Provides a constant reference to the current gou dirty memory manager.
232 [[nodiscard]] const Core::GPUDirtyMemoryManager& CurrentGPUDirtyMemoryManager() const;
233
234 void GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback); 227 void GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback);
235 228
236 [[nodiscard]] size_t GetCurrentHostThreadID() const; 229 [[nodiscard]] size_t GetCurrentHostThreadID() const;
@@ -250,12 +243,6 @@ public:
250 /// Gets a const reference to the underlying CPU manager 243 /// Gets a const reference to the underlying CPU manager
251 [[nodiscard]] const CpuManager& GetCpuManager() const; 244 [[nodiscard]] const CpuManager& GetCpuManager() const;
252 245
253 /// Gets a reference to the exclusive monitor
254 [[nodiscard]] ExclusiveMonitor& Monitor();
255
256 /// Gets a constant reference to the exclusive monitor
257 [[nodiscard]] const ExclusiveMonitor& Monitor() const;
258
259 /// Gets a mutable reference to the system memory instance. 246 /// Gets a mutable reference to the system memory instance.
260 [[nodiscard]] Core::Memory::Memory& ApplicationMemory(); 247 [[nodiscard]] Core::Memory::Memory& ApplicationMemory();
261 248
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp
index 78d43d729..48889253d 100644
--- a/src/core/hle/kernel/k_address_arbiter.cpp
+++ b/src/core/hle/kernel/k_address_arbiter.cpp
@@ -4,6 +4,7 @@
4#include "core/arm/exclusive_monitor.h" 4#include "core/arm/exclusive_monitor.h"
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/kernel/k_address_arbiter.h" 6#include "core/hle/kernel/k_address_arbiter.h"
7#include "core/hle/kernel/k_process.h"
7#include "core/hle/kernel/k_scheduler.h" 8#include "core/hle/kernel/k_scheduler.h"
8#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" 9#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
9#include "core/hle/kernel/k_thread.h" 10#include "core/hle/kernel/k_thread.h"
@@ -26,9 +27,9 @@ bool ReadFromUser(KernelCore& kernel, s32* out, KProcessAddress address) {
26 return true; 27 return true;
27} 28}
28 29
29bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address, s32 value) { 30bool DecrementIfLessThan(KernelCore& kernel, s32* out, KProcessAddress address, s32 value) {
30 auto& monitor = system.Monitor(); 31 auto& monitor = GetCurrentProcess(kernel).GetExclusiveMonitor();
31 const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); 32 const auto current_core = kernel.CurrentPhysicalCoreIndex();
32 33
33 // NOTE: If scheduler lock is not held here, interrupt disable is required. 34 // NOTE: If scheduler lock is not held here, interrupt disable is required.
34 // KScopedInterruptDisable di; 35 // KScopedInterruptDisable di;
@@ -66,10 +67,10 @@ bool DecrementIfLessThan(Core::System& system, s32* out, KProcessAddress address
66 return true; 67 return true;
67} 68}
68 69
69bool UpdateIfEqual(Core::System& system, s32* out, KProcessAddress address, s32 value, 70bool UpdateIfEqual(KernelCore& kernel, s32* out, KProcessAddress address, s32 value,
70 s32 new_value) { 71 s32 new_value) {
71 auto& monitor = system.Monitor(); 72 auto& monitor = GetCurrentProcess(kernel).GetExclusiveMonitor();
72 const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); 73 const auto current_core = kernel.CurrentPhysicalCoreIndex();
73 74
74 // NOTE: If scheduler lock is not held here, interrupt disable is required. 75 // NOTE: If scheduler lock is not held here, interrupt disable is required.
75 // KScopedInterruptDisable di; 76 // KScopedInterruptDisable di;
@@ -159,7 +160,7 @@ Result KAddressArbiter::SignalAndIncrementIfEqual(uint64_t addr, s32 value, s32
159 160
160 // Check the userspace value. 161 // Check the userspace value.
161 s32 user_value{}; 162 s32 user_value{};
162 R_UNLESS(UpdateIfEqual(m_system, std::addressof(user_value), addr, value, value + 1), 163 R_UNLESS(UpdateIfEqual(m_kernel, std::addressof(user_value), addr, value, value + 1),
163 ResultInvalidCurrentMemory); 164 ResultInvalidCurrentMemory);
164 R_UNLESS(user_value == value, ResultInvalidState); 165 R_UNLESS(user_value == value, ResultInvalidState);
165 166
@@ -219,7 +220,7 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32
219 s32 user_value{}; 220 s32 user_value{};
220 bool succeeded{}; 221 bool succeeded{};
221 if (value != new_value) { 222 if (value != new_value) {
222 succeeded = UpdateIfEqual(m_system, std::addressof(user_value), addr, value, new_value); 223 succeeded = UpdateIfEqual(m_kernel, std::addressof(user_value), addr, value, new_value);
223 } else { 224 } else {
224 succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr); 225 succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr);
225 } 226 }
@@ -262,7 +263,7 @@ Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement,
262 s32 user_value{}; 263 s32 user_value{};
263 bool succeeded{}; 264 bool succeeded{};
264 if (decrement) { 265 if (decrement) {
265 succeeded = DecrementIfLessThan(m_system, std::addressof(user_value), addr, value); 266 succeeded = DecrementIfLessThan(m_kernel, std::addressof(user_value), addr, value);
266 } else { 267 } else {
267 succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr); 268 succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr);
268 } 269 }
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp
index 7633a51fb..94ea3527a 100644
--- a/src/core/hle/kernel/k_condition_variable.cpp
+++ b/src/core/hle/kernel/k_condition_variable.cpp
@@ -28,10 +28,10 @@ bool WriteToUser(KernelCore& kernel, KProcessAddress address, const u32* p) {
28 return true; 28 return true;
29} 29}
30 30
31bool UpdateLockAtomic(Core::System& system, u32* out, KProcessAddress address, u32 if_zero, 31bool UpdateLockAtomic(KernelCore& kernel, u32* out, KProcessAddress address, u32 if_zero,
32 u32 new_orr_mask) { 32 u32 new_orr_mask) {
33 auto& monitor = system.Monitor(); 33 auto& monitor = GetCurrentProcess(kernel).GetExclusiveMonitor();
34 const auto current_core = system.Kernel().CurrentPhysicalCoreIndex(); 34 const auto current_core = kernel.CurrentPhysicalCoreIndex();
35 35
36 u32 expected{}; 36 u32 expected{};
37 37
@@ -208,7 +208,7 @@ void KConditionVariable::SignalImpl(KThread* thread) {
208 // TODO(bunnei): We should call CanAccessAtomic(..) here. 208 // TODO(bunnei): We should call CanAccessAtomic(..) here.
209 can_access = true; 209 can_access = true;
210 if (can_access) [[likely]] { 210 if (can_access) [[likely]] {
211 UpdateLockAtomic(m_system, std::addressof(prev_tag), address, own_tag, 211 UpdateLockAtomic(m_kernel, std::addressof(prev_tag), address, own_tag,
212 Svc::HandleWaitMask); 212 Svc::HandleWaitMask);
213 } 213 }
214 } 214 }
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 3a2635e1f..905d141ea 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -1128,7 +1128,8 @@ void KProcess::Switch(KProcess* cur_process, KProcess* next_process) {}
1128KProcess::KProcess(KernelCore& kernel) 1128KProcess::KProcess(KernelCore& kernel)
1129 : KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel}, m_state_lock{kernel}, 1129 : KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel}, m_state_lock{kernel},
1130 m_list_lock{kernel}, m_cond_var{kernel.System()}, m_address_arbiter{kernel.System()}, 1130 m_list_lock{kernel}, m_cond_var{kernel.System()}, m_address_arbiter{kernel.System()},
1131 m_handle_table{kernel} {} 1131 m_handle_table{kernel}, m_dirty_memory_managers{}, m_exclusive_monitor{},
1132 m_memory{kernel.System()} {}
1132KProcess::~KProcess() = default; 1133KProcess::~KProcess() = default;
1133 1134
1134Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, 1135Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
@@ -1235,7 +1236,11 @@ void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) {
1235} 1236}
1236 1237
1237void KProcess::InitializeInterfaces() { 1238void KProcess::InitializeInterfaces() {
1239 m_exclusive_monitor =
1240 Core::MakeExclusiveMonitor(this->GetMemory(), Core::Hardware::NUM_CPU_CORES);
1241
1238 this->GetMemory().SetCurrentPageTable(*this); 1242 this->GetMemory().SetCurrentPageTable(*this);
1243 this->GetMemory().SetGPUDirtyManagers(m_dirty_memory_managers);
1239 1244
1240#ifdef HAS_NCE 1245#ifdef HAS_NCE
1241 if (this->Is64Bit() && Settings::IsNceEnabled()) { 1246 if (this->Is64Bit() && Settings::IsNceEnabled()) {
@@ -1248,13 +1253,13 @@ void KProcess::InitializeInterfaces() {
1248 for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 1253 for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
1249 m_arm_interfaces[i] = std::make_unique<Core::ArmDynarmic64>( 1254 m_arm_interfaces[i] = std::make_unique<Core::ArmDynarmic64>(
1250 m_kernel.System(), m_kernel.IsMulticore(), this, 1255 m_kernel.System(), m_kernel.IsMulticore(), this,
1251 static_cast<Core::DynarmicExclusiveMonitor&>(m_kernel.GetExclusiveMonitor()), i); 1256 static_cast<Core::DynarmicExclusiveMonitor&>(*m_exclusive_monitor), i);
1252 } 1257 }
1253 } else { 1258 } else {
1254 for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 1259 for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
1255 m_arm_interfaces[i] = std::make_unique<Core::ArmDynarmic32>( 1260 m_arm_interfaces[i] = std::make_unique<Core::ArmDynarmic32>(
1256 m_kernel.System(), m_kernel.IsMulticore(), this, 1261 m_kernel.System(), m_kernel.IsMulticore(), this,
1257 static_cast<Core::DynarmicExclusiveMonitor&>(m_kernel.GetExclusiveMonitor()), i); 1262 static_cast<Core::DynarmicExclusiveMonitor&>(*m_exclusive_monitor), i);
1258 } 1263 }
1259 } 1264 }
1260} 1265}
@@ -1305,9 +1310,10 @@ bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointT
1305 return true; 1310 return true;
1306} 1311}
1307 1312
1308Core::Memory::Memory& KProcess::GetMemory() const { 1313void KProcess::GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback) {
1309 // TODO: per-process memory 1314 for (auto& manager : m_dirty_memory_managers) {
1310 return m_kernel.System().ApplicationMemory(); 1315 manager.Gather(callback);
1316 }
1311} 1317}
1312 1318
1313} // namespace Kernel 1319} // namespace Kernel
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index 4b114e39b..53c0e3316 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -7,6 +7,7 @@
7 7
8#include "core/arm/arm_interface.h" 8#include "core/arm/arm_interface.h"
9#include "core/file_sys/program_metadata.h" 9#include "core/file_sys/program_metadata.h"
10#include "core/gpu_dirty_memory_manager.h"
10#include "core/hle/kernel/code_set.h" 11#include "core/hle/kernel/code_set.h"
11#include "core/hle/kernel/k_address_arbiter.h" 12#include "core/hle/kernel/k_address_arbiter.h"
12#include "core/hle/kernel/k_capabilities.h" 13#include "core/hle/kernel/k_capabilities.h"
@@ -17,6 +18,7 @@
17#include "core/hle/kernel/k_system_resource.h" 18#include "core/hle/kernel/k_system_resource.h"
18#include "core/hle/kernel/k_thread.h" 19#include "core/hle/kernel/k_thread.h"
19#include "core/hle/kernel/k_thread_local_page.h" 20#include "core/hle/kernel/k_thread_local_page.h"
21#include "core/memory.h"
20 22
21namespace Kernel { 23namespace Kernel {
22 24
@@ -126,6 +128,9 @@ private:
126#ifdef HAS_NCE 128#ifdef HAS_NCE
127 std::unordered_map<u64, u64> m_post_handlers{}; 129 std::unordered_map<u64, u64> m_post_handlers{};
128#endif 130#endif
131 std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES> m_dirty_memory_managers;
132 std::unique_ptr<Core::ExclusiveMonitor> m_exclusive_monitor;
133 Core::Memory::Memory m_memory;
129 134
130private: 135private:
131 Result StartTermination(); 136 Result StartTermination();
@@ -502,7 +507,15 @@ public:
502 507
503 void InitializeInterfaces(); 508 void InitializeInterfaces();
504 509
505 Core::Memory::Memory& GetMemory() const; 510 Core::Memory::Memory& GetMemory() {
511 return m_memory;
512 }
513
514 void GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback);
515
516 Core::ExclusiveMonitor& GetExclusiveMonitor() const {
517 return *m_exclusive_monitor;
518 }
506 519
507public: 520public:
508 // Overridden parent functions. 521 // Overridden parent functions.
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index e9925d231..f13e232b2 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -314,11 +314,7 @@ public:
314 m_current_core_id = core; 314 m_current_core_id = core;
315 } 315 }
316 316
317 KProcess* GetOwnerProcess() { 317 KProcess* GetOwnerProcess() const {
318 return m_parent;
319 }
320
321 const KProcess* GetOwnerProcess() const {
322 return m_parent; 318 return m_parent;
323 } 319 }
324 320
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index e479dacde..2efca27c2 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -126,8 +126,6 @@ struct KernelCore::Impl {
126 126
127 preemption_event = nullptr; 127 preemption_event = nullptr;
128 128
129 exclusive_monitor.reset();
130
131 // Cleanup persistent kernel objects 129 // Cleanup persistent kernel objects
132 auto CleanupObject = [](KAutoObject* obj) { 130 auto CleanupObject = [](KAutoObject* obj) {
133 if (obj) { 131 if (obj) {
@@ -191,8 +189,6 @@ struct KernelCore::Impl {
191 } 189 }
192 190
193 void InitializePhysicalCores() { 191 void InitializePhysicalCores() {
194 exclusive_monitor =
195 Core::MakeExclusiveMonitor(system.ApplicationMemory(), Core::Hardware::NUM_CPU_CORES);
196 for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 192 for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
197 const s32 core{static_cast<s32>(i)}; 193 const s32 core{static_cast<s32>(i)};
198 194
@@ -805,7 +801,6 @@ struct KernelCore::Impl {
805 std::mutex server_lock; 801 std::mutex server_lock;
806 std::vector<std::unique_ptr<Service::ServerManager>> server_managers; 802 std::vector<std::unique_ptr<Service::ServerManager>> server_managers;
807 803
808 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
809 std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores; 804 std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores;
810 805
811 // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others 806 // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
@@ -959,14 +954,6 @@ Kernel::KHardwareTimer& KernelCore::HardwareTimer() {
959 return *impl->hardware_timer; 954 return *impl->hardware_timer;
960} 955}
961 956
962Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {
963 return *impl->exclusive_monitor;
964}
965
966const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const {
967 return *impl->exclusive_monitor;
968}
969
970KAutoObjectWithListContainer& KernelCore::ObjectListContainer() { 957KAutoObjectWithListContainer& KernelCore::ObjectListContainer() {
971 return *impl->global_object_list_container; 958 return *impl->global_object_list_container;
972} 959}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 78c88902c..fefd7aaba 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -170,10 +170,6 @@ public:
170 /// Stops execution of 'id' core, in order to reschedule a new thread. 170 /// Stops execution of 'id' core, in order to reschedule a new thread.
171 void PrepareReschedule(std::size_t id); 171 void PrepareReschedule(std::size_t id);
172 172
173 Core::ExclusiveMonitor& GetExclusiveMonitor();
174
175 const Core::ExclusiveMonitor& GetExclusiveMonitor() const;
176
177 KAutoObjectWithListContainer& ObjectListContainer(); 173 KAutoObjectWithListContainer& ObjectListContainer();
178 174
179 const KAutoObjectWithListContainer& ObjectListContainer() const; 175 const KAutoObjectWithListContainer& ObjectListContainer() const;