summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/file_sys/program_metadata.cpp6
-rw-r--r--src/core/file_sys/program_metadata.h13
-rw-r--r--src/core/hle/kernel/k_client_port.cpp3
-rw-r--r--src/core/hle/kernel/k_handle_table.h8
-rw-r--r--src/core/hle/kernel/k_process.cpp36
-rw-r--r--src/core/hle/kernel/k_process.h2
-rw-r--r--src/core/hle/kernel/k_session.cpp3
-rw-r--r--src/core/hle/kernel/k_thread.cpp3
-rw-r--r--src/core/hle/kernel/kernel.cpp21
-rw-r--r--src/core/hle/kernel/kernel.h3
-rw-r--r--src/core/hle/service/fatal/fatal.cpp2
-rw-r--r--src/core/hle/service/server_manager.cpp19
-rw-r--r--src/core/hle/service/set/set_sys.cpp12
-rw-r--r--src/core/hle/service/set/set_sys.h1
-rw-r--r--src/core/hle/service/sm/sm.cpp36
-rw-r--r--src/core/hle/service/sm/sm.h8
-rw-r--r--src/core/memory.cpp28
17 files changed, 102 insertions, 102 deletions
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp
index 763a44fee..539c7f7af 100644
--- a/src/core/file_sys/program_metadata.cpp
+++ b/src/core/file_sys/program_metadata.cpp
@@ -166,6 +166,10 @@ u32 ProgramMetadata::GetSystemResourceSize() const {
166 return npdm_header.system_resource_size; 166 return npdm_header.system_resource_size;
167} 167}
168 168
169PoolPartition ProgramMetadata::GetPoolPartition() const {
170 return acid_header.pool_partition;
171}
172
169const ProgramMetadata::KernelCapabilityDescriptors& ProgramMetadata::GetKernelCapabilities() const { 173const ProgramMetadata::KernelCapabilityDescriptors& ProgramMetadata::GetKernelCapabilities() const {
170 return aci_kernel_capabilities; 174 return aci_kernel_capabilities;
171} 175}
@@ -201,7 +205,7 @@ void ProgramMetadata::Print() const {
201 // Begin ACID printing (potential perms, signed) 205 // Begin ACID printing (potential perms, signed)
202 LOG_DEBUG(Service_FS, "Magic: {:.4}", acid_header.magic.data()); 206 LOG_DEBUG(Service_FS, "Magic: {:.4}", acid_header.magic.data());
203 LOG_DEBUG(Service_FS, "Flags: 0x{:02X}", acid_header.flags); 207 LOG_DEBUG(Service_FS, "Flags: 0x{:02X}", acid_header.flags);
204 LOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO"); 208 LOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.production_flag ? "YES" : "NO");
205 LOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min); 209 LOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min);
206 LOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max); 210 LOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max);
207 LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", acid_file_access.permissions); 211 LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", acid_file_access.permissions);
diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h
index 76ee97d78..a53092b87 100644
--- a/src/core/file_sys/program_metadata.h
+++ b/src/core/file_sys/program_metadata.h
@@ -34,6 +34,13 @@ enum class ProgramFilePermission : u64 {
34 Everything = 1ULL << 63, 34 Everything = 1ULL << 63,
35}; 35};
36 36
37enum class PoolPartition : u32 {
38 Application = 0,
39 Applet = 1,
40 System = 2,
41 SystemNonSecure = 3,
42};
43
37/** 44/**
38 * Helper which implements an interface to parse Program Description Metadata (NPDM) 45 * Helper which implements an interface to parse Program Description Metadata (NPDM)
39 * Data can either be loaded from a file path or with data and an offset into it. 46 * Data can either be loaded from a file path or with data and an offset into it.
@@ -72,6 +79,7 @@ public:
72 u64 GetTitleID() const; 79 u64 GetTitleID() const;
73 u64 GetFilesystemPermissions() const; 80 u64 GetFilesystemPermissions() const;
74 u32 GetSystemResourceSize() const; 81 u32 GetSystemResourceSize() const;
82 PoolPartition GetPoolPartition() const;
75 const KernelCapabilityDescriptors& GetKernelCapabilities() const; 83 const KernelCapabilityDescriptors& GetKernelCapabilities() const;
76 const std::array<u8, 0x10>& GetName() const { 84 const std::array<u8, 0x10>& GetName() const {
77 return npdm_header.application_name; 85 return npdm_header.application_name;
@@ -116,8 +124,9 @@ private:
116 union { 124 union {
117 u32 flags; 125 u32 flags;
118 126
119 BitField<0, 1, u32> is_retail; 127 BitField<0, 1, u32> production_flag;
120 BitField<1, 31, u32> flags_unk; 128 BitField<1, 1, u32> unqualified_approval;
129 BitField<2, 4, PoolPartition> pool_partition;
121 }; 130 };
122 u64_le title_id_min; 131 u64_le title_id_min;
123 u64_le title_id_max; 132 u64_le title_id_max;
diff --git a/src/core/hle/kernel/k_client_port.cpp b/src/core/hle/kernel/k_client_port.cpp
index 11b1b977e..9b20c4d75 100644
--- a/src/core/hle/kernel/k_client_port.cpp
+++ b/src/core/hle/kernel/k_client_port.cpp
@@ -58,9 +58,8 @@ Result KClientPort::CreateSession(KClientSession** out) {
58 KSession* session{}; 58 KSession* session{};
59 59
60 // Reserve a new session from the resource limit. 60 // Reserve a new session from the resource limit.
61 //! FIXME: we are reserving this from the wrong resource limit!
62 KScopedResourceReservation session_reservation( 61 KScopedResourceReservation session_reservation(
63 m_kernel.ApplicationProcess()->GetResourceLimit(), LimitableResource::SessionCountMax); 62 GetCurrentProcessPointer(m_kernel)->GetResourceLimit(), LimitableResource::SessionCountMax);
64 R_UNLESS(session_reservation.Succeeded(), ResultLimitReached); 63 R_UNLESS(session_reservation.Succeeded(), ResultLimitReached);
65 64
66 // Allocate a session normally. 65 // Allocate a session normally.
diff --git a/src/core/hle/kernel/k_handle_table.h b/src/core/hle/kernel/k_handle_table.h
index d7660630c..4e6dcd66b 100644
--- a/src/core/hle/kernel/k_handle_table.h
+++ b/src/core/hle/kernel/k_handle_table.h
@@ -30,7 +30,7 @@ public:
30public: 30public:
31 explicit KHandleTable(KernelCore& kernel) : m_kernel(kernel) {} 31 explicit KHandleTable(KernelCore& kernel) : m_kernel(kernel) {}
32 32
33 Result Initialize(s32 size) { 33 Result Initialize(KProcess* owner, s32 size) {
34 // Check that the table size is valid. 34 // Check that the table size is valid.
35 R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory); 35 R_UNLESS(size <= static_cast<s32>(MaxTableSize), ResultOutOfMemory);
36 36
@@ -44,6 +44,7 @@ public:
44 m_next_linear_id = MinLinearId; 44 m_next_linear_id = MinLinearId;
45 m_count = 0; 45 m_count = 0;
46 m_free_head_index = -1; 46 m_free_head_index = -1;
47 m_owner = owner;
47 48
48 // Free all entries. 49 // Free all entries.
49 for (s32 i = 0; i < static_cast<s32>(m_table_size); ++i) { 50 for (s32 i = 0; i < static_cast<s32>(m_table_size); ++i) {
@@ -90,8 +91,8 @@ public:
90 // Handle pseudo-handles. 91 // Handle pseudo-handles.
91 if constexpr (std::derived_from<KProcess, T>) { 92 if constexpr (std::derived_from<KProcess, T>) {
92 if (handle == Svc::PseudoHandle::CurrentProcess) { 93 if (handle == Svc::PseudoHandle::CurrentProcess) {
93 //! FIXME: this is the wrong process! 94 // TODO: this should be the current process
94 auto* const cur_process = m_kernel.ApplicationProcess(); 95 auto* const cur_process = m_owner;
95 ASSERT(cur_process != nullptr); 96 ASSERT(cur_process != nullptr);
96 return cur_process; 97 return cur_process;
97 } 98 }
@@ -301,6 +302,7 @@ private:
301 302
302private: 303private:
303 KernelCore& m_kernel; 304 KernelCore& m_kernel;
305 KProcess* m_owner{};
304 std::array<EntryInfo, MaxTableSize> m_entry_infos{}; 306 std::array<EntryInfo, MaxTableSize> m_entry_infos{};
305 std::array<KAutoObject*, MaxTableSize> m_objects{}; 307 std::array<KAutoObject*, MaxTableSize> m_objects{};
306 mutable KSpinLock m_lock; 308 mutable KSpinLock m_lock;
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 905d141ea..2bfb71b3a 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -306,12 +306,16 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa
306 False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge); 306 False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge);
307 R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, 307 R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool,
308 params.code_address, params.code_num_pages * PageSize, 308 params.code_address, params.code_num_pages * PageSize,
309 m_system_resource, res_limit, this->GetMemory(), 0)); 309 m_system_resource, res_limit, m_memory, 0));
310 } 310 }
311 ON_RESULT_FAILURE_2 { 311 ON_RESULT_FAILURE_2 {
312 m_page_table.Finalize(); 312 m_page_table.Finalize();
313 }; 313 };
314 314
315 // Ensure our memory is initialized.
316 m_memory.SetCurrentPageTable(*this);
317 m_memory.SetGPUDirtyManagers(m_dirty_memory_managers);
318
315 // Ensure we can insert the code region. 319 // Ensure we can insert the code region.
316 R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize, 320 R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize,
317 KMemoryState::Code), 321 KMemoryState::Code),
@@ -399,12 +403,16 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params,
399 False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge); 403 False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge);
400 R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, 404 R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool,
401 params.code_address, code_size, m_system_resource, res_limit, 405 params.code_address, code_size, m_system_resource, res_limit,
402 this->GetMemory(), aslr_space_start)); 406 m_memory, aslr_space_start));
403 } 407 }
404 ON_RESULT_FAILURE_2 { 408 ON_RESULT_FAILURE_2 {
405 m_page_table.Finalize(); 409 m_page_table.Finalize();
406 }; 410 };
407 411
412 // Ensure our memory is initialized.
413 m_memory.SetCurrentPageTable(*this);
414 m_memory.SetGPUDirtyManagers(m_dirty_memory_managers);
415
408 // Ensure we can insert the code region. 416 // Ensure we can insert the code region.
409 R_UNLESS(m_page_table.CanContain(params.code_address, code_size, KMemoryState::Code), 417 R_UNLESS(m_page_table.CanContain(params.code_address, code_size, KMemoryState::Code),
410 ResultInvalidMemoryRegion); 418 ResultInvalidMemoryRegion);
@@ -1094,8 +1102,7 @@ void KProcess::UnpinThread(KThread* thread) {
1094 1102
1095Result KProcess::GetThreadList(s32* out_num_threads, KProcessAddress out_thread_ids, 1103Result KProcess::GetThreadList(s32* out_num_threads, KProcessAddress out_thread_ids,
1096 s32 max_out_count) { 1104 s32 max_out_count) {
1097 // TODO: use current memory reference 1105 auto& memory = this->GetMemory();
1098 auto& memory = m_kernel.System().ApplicationMemory();
1099 1106
1100 // Lock the list. 1107 // Lock the list.
1101 KScopedLightLock lk(m_list_lock); 1108 KScopedLightLock lk(m_list_lock);
@@ -1128,15 +1135,15 @@ void KProcess::Switch(KProcess* cur_process, KProcess* next_process) {}
1128KProcess::KProcess(KernelCore& kernel) 1135KProcess::KProcess(KernelCore& kernel)
1129 : KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel}, m_state_lock{kernel}, 1136 : 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()}, 1137 m_list_lock{kernel}, m_cond_var{kernel.System()}, m_address_arbiter{kernel.System()},
1131 m_handle_table{kernel}, m_dirty_memory_managers{}, m_exclusive_monitor{}, 1138 m_handle_table{kernel}, m_dirty_memory_managers{},
1132 m_memory{kernel.System()} {} 1139 m_exclusive_monitor{}, m_memory{kernel.System()} {}
1133KProcess::~KProcess() = default; 1140KProcess::~KProcess() = default;
1134 1141
1135Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, 1142Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
1136 KProcessAddress aslr_space_start, bool is_hbl) { 1143 KProcessAddress aslr_space_start, bool is_hbl) {
1137 // Create a resource limit for the process. 1144 // Create a resource limit for the process.
1138 const auto physical_memory_size = 1145 const auto pool = static_cast<KMemoryManager::Pool>(metadata.GetPoolPartition());
1139 m_kernel.MemoryManager().GetSize(Kernel::KMemoryManager::Pool::Application); 1146 const auto physical_memory_size = m_kernel.MemoryManager().GetSize(pool);
1140 auto* res_limit = 1147 auto* res_limit =
1141 Kernel::CreateResourceLimitForProcess(m_kernel.System(), physical_memory_size); 1148 Kernel::CreateResourceLimitForProcess(m_kernel.System(), physical_memory_size);
1142 1149
@@ -1147,8 +1154,10 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
1147 Svc::CreateProcessFlag flag{}; 1154 Svc::CreateProcessFlag flag{};
1148 u64 code_address{}; 1155 u64 code_address{};
1149 1156
1150 // We are an application. 1157 // Determine if we are an application.
1151 flag |= Svc::CreateProcessFlag::IsApplication; 1158 if (pool == KMemoryManager::Pool::Application) {
1159 flag |= Svc::CreateProcessFlag::IsApplication;
1160 }
1152 1161
1153 // If we are 64-bit, create as such. 1162 // If we are 64-bit, create as such.
1154 if (metadata.Is64BitProgram()) { 1163 if (metadata.Is64BitProgram()) {
@@ -1197,8 +1206,8 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
1197 std::memcpy(params.name.data(), name.data(), sizeof(params.name)); 1206 std::memcpy(params.name.data(), name.data(), sizeof(params.name));
1198 1207
1199 // Initialize for application process. 1208 // Initialize for application process.
1200 R_TRY(this->Initialize(params, metadata.GetKernelCapabilities(), res_limit, 1209 R_TRY(this->Initialize(params, metadata.GetKernelCapabilities(), res_limit, pool,
1201 KMemoryManager::Pool::Application, aslr_space_start)); 1210 aslr_space_start));
1202 1211
1203 // Assign remaining properties. 1212 // Assign remaining properties.
1204 m_is_hbl = is_hbl; 1213 m_is_hbl = is_hbl;
@@ -1239,9 +1248,6 @@ void KProcess::InitializeInterfaces() {
1239 m_exclusive_monitor = 1248 m_exclusive_monitor =
1240 Core::MakeExclusiveMonitor(this->GetMemory(), Core::Hardware::NUM_CPU_CORES); 1249 Core::MakeExclusiveMonitor(this->GetMemory(), Core::Hardware::NUM_CPU_CORES);
1241 1250
1242 this->GetMemory().SetCurrentPageTable(*this);
1243 this->GetMemory().SetGPUDirtyManagers(m_dirty_memory_managers);
1244
1245#ifdef HAS_NCE 1251#ifdef HAS_NCE
1246 if (this->Is64Bit() && Settings::IsNceEnabled()) { 1252 if (this->Is64Bit() && Settings::IsNceEnabled()) {
1247 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++) {
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index 53c0e3316..b5c6867a1 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -552,7 +552,7 @@ private:
552 552
553 Result InitializeHandleTable(s32 size) { 553 Result InitializeHandleTable(s32 size) {
554 // Try to initialize the handle table. 554 // Try to initialize the handle table.
555 R_TRY(m_handle_table.Initialize(size)); 555 R_TRY(m_handle_table.Initialize(this, size));
556 556
557 // We succeeded, so note that we did. 557 // We succeeded, so note that we did.
558 m_is_handle_table_initialized = true; 558 m_is_handle_table_initialized = true;
diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp
index 44d7a8f02..4a1f6027e 100644
--- a/src/core/hle/kernel/k_session.cpp
+++ b/src/core/hle/kernel/k_session.cpp
@@ -33,8 +33,7 @@ void KSession::Initialize(KClientPort* client_port, uintptr_t name) {
33 m_name = name; 33 m_name = name;
34 34
35 // Set our owner process. 35 // Set our owner process.
36 //! FIXME: this is the wrong process! 36 m_process = GetCurrentProcessPointer(m_kernel);
37 m_process = m_kernel.ApplicationProcess();
38 m_process->Open(); 37 m_process->Open();
39 38
40 // Set our port. 39 // Set our port.
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 7d9a6e9cf..24394d222 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -1422,8 +1422,7 @@ s32 GetCurrentCoreId(KernelCore& kernel) {
1422} 1422}
1423 1423
1424Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel) { 1424Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel) {
1425 // TODO: per-process memory 1425 return GetCurrentProcess(kernel).GetMemory();
1426 return kernel.System().ApplicationMemory();
1427} 1426}
1428 1427
1429KScopedDisableDispatch::~KScopedDisableDispatch() { 1428KScopedDisableDispatch::~KScopedDisableDispatch() {
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 2efca27c2..c14d2d2f3 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -68,8 +68,6 @@ struct KernelCore::Impl {
68 68
69 global_object_list_container = std::make_unique<KAutoObjectWithListContainer>(kernel); 69 global_object_list_container = std::make_unique<KAutoObjectWithListContainer>(kernel);
70 global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); 70 global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
71 global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
72 global_handle_table->Initialize(KHandleTable::MaxTableSize);
73 71
74 is_phantom_mode_for_singlecore = false; 72 is_phantom_mode_for_singlecore = false;
75 73
@@ -121,9 +119,6 @@ struct KernelCore::Impl {
121 next_user_process_id = KProcess::ProcessIdMin; 119 next_user_process_id = KProcess::ProcessIdMin;
122 next_thread_id = 1; 120 next_thread_id = 1;
123 121
124 global_handle_table->Finalize();
125 global_handle_table.reset();
126
127 preemption_event = nullptr; 122 preemption_event = nullptr;
128 123
129 // Cleanup persistent kernel objects 124 // Cleanup persistent kernel objects
@@ -787,10 +782,6 @@ struct KernelCore::Impl {
787 782
788 std::shared_ptr<Core::Timing::EventType> preemption_event; 783 std::shared_ptr<Core::Timing::EventType> preemption_event;
789 784
790 // This is the kernel's handle table or supervisor handle table which
791 // stores all the objects in place.
792 std::unique_ptr<KHandleTable> global_handle_table;
793
794 std::unique_ptr<KAutoObjectWithListContainer> global_object_list_container; 785 std::unique_ptr<KAutoObjectWithListContainer> global_object_list_container;
795 786
796 std::unique_ptr<KObjectNameGlobalData> object_name_global_data; 787 std::unique_ptr<KObjectNameGlobalData> object_name_global_data;
@@ -877,10 +868,6 @@ KResourceLimit* KernelCore::GetSystemResourceLimit() {
877 return impl->system_resource_limit; 868 return impl->system_resource_limit;
878} 869}
879 870
880KScopedAutoObject<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const {
881 return impl->global_handle_table->GetObject<KThread>(handle);
882}
883
884void KernelCore::AppendNewProcess(KProcess* process) { 871void KernelCore::AppendNewProcess(KProcess* process) {
885 impl->process_list.push_back(process); 872 impl->process_list.push_back(process);
886} 873}
@@ -1017,14 +1004,6 @@ u64 KernelCore::CreateNewUserProcessID() {
1017 return impl->next_user_process_id++; 1004 return impl->next_user_process_id++;
1018} 1005}
1019 1006
1020KHandleTable& KernelCore::GlobalHandleTable() {
1021 return *impl->global_handle_table;
1022}
1023
1024const KHandleTable& KernelCore::GlobalHandleTable() const {
1025 return *impl->global_handle_table;
1026}
1027
1028void KernelCore::RegisterCoreThread(std::size_t core_id) { 1007void KernelCore::RegisterCoreThread(std::size_t core_id) {
1029 impl->RegisterCoreThread(core_id); 1008 impl->RegisterCoreThread(core_id);
1030} 1009}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index fefd7aaba..5d4102145 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -116,9 +116,6 @@ public:
116 /// Retrieves a shared pointer to the system resource limit instance. 116 /// Retrieves a shared pointer to the system resource limit instance.
117 KResourceLimit* GetSystemResourceLimit(); 117 KResourceLimit* GetSystemResourceLimit();
118 118
119 /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
120 KScopedAutoObject<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const;
121
122 /// Adds the given shared pointer to an internal list of active processes. 119 /// Adds the given shared pointer to an internal list of active processes.
123 void AppendNewProcess(KProcess* process); 120 void AppendNewProcess(KProcess* process);
124 121
diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp
index fe2ed8df8..31da86074 100644
--- a/src/core/hle/service/fatal/fatal.cpp
+++ b/src/core/hle/service/fatal/fatal.cpp
@@ -89,7 +89,7 @@ static void GenerateErrorReport(Core::System& system, Result error_code, const F
89 crash_report += fmt::format(" ESR: {:016x}\n", info.esr); 89 crash_report += fmt::format(" ESR: {:016x}\n", info.esr);
90 crash_report += fmt::format(" FAR: {:016x}\n", info.far); 90 crash_report += fmt::format(" FAR: {:016x}\n", info.far);
91 crash_report += "\nBacktrace:\n"; 91 crash_report += "\nBacktrace:\n";
92 for (size_t i = 0; i < info.backtrace_size; i++) { 92 for (u32 i = 0; i < std::min<u32>(info.backtrace_size, 32); i++) {
93 crash_report += 93 crash_report +=
94 fmt::format(" Backtrace[{:02d}]: {:016x}\n", i, info.backtrace[i]); 94 fmt::format(" Backtrace[{:02d}]: {:016x}\n", i, info.backtrace[i]);
95 } 95 }
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp
index ec599dac2..15edb23e0 100644
--- a/src/core/hle/service/server_manager.cpp
+++ b/src/core/hle/service/server_manager.cpp
@@ -47,7 +47,7 @@ ServerManager::~ServerManager() {
47 m_stopped.Wait(); 47 m_stopped.Wait();
48 m_threads.clear(); 48 m_threads.clear();
49 49
50 // Clean up ports. 50 // Clean up server ports.
51 for (const auto& [port, handler] : m_ports) { 51 for (const auto& [port, handler] : m_ports) {
52 port->Close(); 52 port->Close();
53 } 53 }
@@ -97,22 +97,15 @@ Result ServerManager::RegisterNamedService(const std::string& service_name,
97 u32 max_sessions) { 97 u32 max_sessions) {
98 ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects); 98 ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
99 99
100 // Add the new server to sm:. 100 // Add the new server to sm: and get the moved server port.
101 ASSERT(R_SUCCEEDED( 101 Kernel::KServerPort* server_port{};
102 m_system.ServiceManager().RegisterService(service_name, max_sessions, handler_factory))); 102 R_ASSERT(m_system.ServiceManager().RegisterService(std::addressof(server_port), service_name,
103 103 max_sessions, handler_factory));
104 // Get the registered port.
105 Kernel::KPort* port{};
106 ASSERT(
107 R_SUCCEEDED(m_system.ServiceManager().GetServicePort(std::addressof(port), service_name)));
108
109 // Open a new reference to the server port.
110 port->GetServerPort().Open();
111 104
112 // Begin tracking the server port. 105 // Begin tracking the server port.
113 { 106 {
114 std::scoped_lock ll{m_list_mutex}; 107 std::scoped_lock ll{m_list_mutex};
115 m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler_factory)); 108 m_ports.emplace(server_port, std::move(handler_factory));
116 } 109 }
117 110
118 // Signal the wakeup event. 111 // Signal the wakeup event.
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index 0653779d5..8e637f963 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -507,6 +507,14 @@ void SET_SYS::SetTvSettings(HLERequestContext& ctx) {
507 rb.Push(ResultSuccess); 507 rb.Push(ResultSuccess);
508} 508}
509 509
510void SET_SYS::GetDebugModeFlag(HLERequestContext& ctx) {
511 LOG_DEBUG(Service_SET, "called");
512
513 IPC::ResponseBuilder rb{ctx, 3};
514 rb.Push(ResultSuccess);
515 rb.Push<u32>(0);
516}
517
510void SET_SYS::GetQuestFlag(HLERequestContext& ctx) { 518void SET_SYS::GetQuestFlag(HLERequestContext& ctx) {
511 LOG_WARNING(Service_SET, "(STUBBED) called"); 519 LOG_WARNING(Service_SET, "(STUBBED) called");
512 520
@@ -926,7 +934,7 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"},
926 {59, &SET_SYS::SetNetworkSystemClockContext, "SetNetworkSystemClockContext"}, 934 {59, &SET_SYS::SetNetworkSystemClockContext, "SetNetworkSystemClockContext"},
927 {60, &SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled, "IsUserSystemClockAutomaticCorrectionEnabled"}, 935 {60, &SET_SYS::IsUserSystemClockAutomaticCorrectionEnabled, "IsUserSystemClockAutomaticCorrectionEnabled"},
928 {61, &SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled, "SetUserSystemClockAutomaticCorrectionEnabled"}, 936 {61, &SET_SYS::SetUserSystemClockAutomaticCorrectionEnabled, "SetUserSystemClockAutomaticCorrectionEnabled"},
929 {62, nullptr, "GetDebugModeFlag"}, 937 {62, &SET_SYS::GetDebugModeFlag, "GetDebugModeFlag"},
930 {63, &SET_SYS::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"}, 938 {63, &SET_SYS::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"},
931 {64, nullptr, "SetPrimaryAlbumStorage"}, 939 {64, nullptr, "SetPrimaryAlbumStorage"},
932 {65, nullptr, "GetUsb30EnableFlag"}, 940 {65, nullptr, "GetUsb30EnableFlag"},
@@ -1143,6 +1151,8 @@ void SET_SYS::StoreSettings() {
1143} 1151}
1144 1152
1145void SET_SYS::StoreSettingsThreadFunc(std::stop_token stop_token) { 1153void SET_SYS::StoreSettingsThreadFunc(std::stop_token stop_token) {
1154 Common::SetCurrentThreadName("SettingsStore");
1155
1146 while (Common::StoppableTimedWait(stop_token, std::chrono::minutes(1))) { 1156 while (Common::StoppableTimedWait(stop_token, std::chrono::minutes(1))) {
1147 std::scoped_lock l{m_save_needed_mutex}; 1157 std::scoped_lock l{m_save_needed_mutex};
1148 if (!std::exchange(m_save_needed, false)) { 1158 if (!std::exchange(m_save_needed, false)) {
diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h
index 3785d93d8..853f76fce 100644
--- a/src/core/hle/service/set/set_sys.h
+++ b/src/core/hle/service/set/set_sys.h
@@ -98,6 +98,7 @@ private:
98 void GetSettingsItemValue(HLERequestContext& ctx); 98 void GetSettingsItemValue(HLERequestContext& ctx);
99 void GetTvSettings(HLERequestContext& ctx); 99 void GetTvSettings(HLERequestContext& ctx);
100 void SetTvSettings(HLERequestContext& ctx); 100 void SetTvSettings(HLERequestContext& ctx);
101 void GetDebugModeFlag(HLERequestContext& ctx);
101 void GetQuestFlag(HLERequestContext& ctx); 102 void GetQuestFlag(HLERequestContext& ctx);
102 void GetDeviceTimeZoneLocationName(HLERequestContext& ctx); 103 void GetDeviceTimeZoneLocationName(HLERequestContext& ctx);
103 void SetDeviceTimeZoneLocationName(HLERequestContext& ctx); 104 void SetDeviceTimeZoneLocationName(HLERequestContext& ctx);
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 296ee6e89..1095dcf6c 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -29,8 +29,7 @@ ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
29 29
30ServiceManager::~ServiceManager() { 30ServiceManager::~ServiceManager() {
31 for (auto& [name, port] : service_ports) { 31 for (auto& [name, port] : service_ports) {
32 port->GetClientPort().Close(); 32 port->Close();
33 port->GetServerPort().Close();
34 } 33 }
35 34
36 if (deferral_event) { 35 if (deferral_event) {
@@ -50,8 +49,8 @@ static Result ValidateServiceName(const std::string& name) {
50 return ResultSuccess; 49 return ResultSuccess;
51} 50}
52 51
53Result ServiceManager::RegisterService(std::string name, u32 max_sessions, 52Result ServiceManager::RegisterService(Kernel::KServerPort** out_server_port, std::string name,
54 SessionRequestHandlerFactory handler) { 53 u32 max_sessions, SessionRequestHandlerFactory handler) {
55 R_TRY(ValidateServiceName(name)); 54 R_TRY(ValidateServiceName(name));
56 55
57 std::scoped_lock lk{lock}; 56 std::scoped_lock lk{lock};
@@ -66,13 +65,17 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
66 // Register the port. 65 // Register the port.
67 Kernel::KPort::Register(kernel, port); 66 Kernel::KPort::Register(kernel, port);
68 67
69 service_ports.emplace(name, port); 68 service_ports.emplace(name, std::addressof(port->GetClientPort()));
70 registered_services.emplace(name, handler); 69 registered_services.emplace(name, handler);
71 if (deferral_event) { 70 if (deferral_event) {
72 deferral_event->Signal(); 71 deferral_event->Signal();
73 } 72 }
74 73
75 return ResultSuccess; 74 // Set our output.
75 *out_server_port = std::addressof(port->GetServerPort());
76
77 // We succeeded.
78 R_SUCCEED();
76} 79}
77 80
78Result ServiceManager::UnregisterService(const std::string& name) { 81Result ServiceManager::UnregisterService(const std::string& name) {
@@ -91,7 +94,8 @@ Result ServiceManager::UnregisterService(const std::string& name) {
91 return ResultSuccess; 94 return ResultSuccess;
92} 95}
93 96
94Result ServiceManager::GetServicePort(Kernel::KPort** out_port, const std::string& name) { 97Result ServiceManager::GetServicePort(Kernel::KClientPort** out_client_port,
98 const std::string& name) {
95 R_TRY(ValidateServiceName(name)); 99 R_TRY(ValidateServiceName(name));
96 100
97 std::scoped_lock lk{lock}; 101 std::scoped_lock lk{lock};
@@ -101,7 +105,7 @@ Result ServiceManager::GetServicePort(Kernel::KPort** out_port, const std::strin
101 return Service::SM::ResultNotRegistered; 105 return Service::SM::ResultNotRegistered;
102 } 106 }
103 107
104 *out_port = it->second; 108 *out_client_port = it->second;
105 return ResultSuccess; 109 return ResultSuccess;
106} 110}
107 111
@@ -172,8 +176,8 @@ Result SM::GetServiceImpl(Kernel::KClientSession** out_client_session, HLEReques
172 std::string name(PopServiceName(rp)); 176 std::string name(PopServiceName(rp));
173 177
174 // Find the named port. 178 // Find the named port.
175 Kernel::KPort* port{}; 179 Kernel::KClientPort* client_port{};
176 auto port_result = service_manager.GetServicePort(&port, name); 180 auto port_result = service_manager.GetServicePort(&client_port, name);
177 if (port_result == Service::SM::ResultInvalidServiceName) { 181 if (port_result == Service::SM::ResultInvalidServiceName) {
178 LOG_ERROR(Service_SM, "Invalid service name '{}'", name); 182 LOG_ERROR(Service_SM, "Invalid service name '{}'", name);
179 return Service::SM::ResultInvalidServiceName; 183 return Service::SM::ResultInvalidServiceName;
@@ -187,7 +191,7 @@ Result SM::GetServiceImpl(Kernel::KClientSession** out_client_session, HLEReques
187 191
188 // Create a new session. 192 // Create a new session.
189 Kernel::KClientSession* session{}; 193 Kernel::KClientSession* session{};
190 if (const auto result = port->GetClientPort().CreateSession(&session); result.IsError()) { 194 if (const auto result = client_port->CreateSession(&session); result.IsError()) {
191 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); 195 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw);
192 return result; 196 return result;
193 } 197 }
@@ -221,7 +225,9 @@ void SM::RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_s
221 LOG_DEBUG(Service_SM, "called with name={}, max_session_count={}, is_light={}", name, 225 LOG_DEBUG(Service_SM, "called with name={}, max_session_count={}, is_light={}", name,
222 max_session_count, is_light); 226 max_session_count, is_light);
223 227
224 if (const auto result = service_manager.RegisterService(name, max_session_count, nullptr); 228 Kernel::KServerPort* server_port{};
229 if (const auto result = service_manager.RegisterService(std::addressof(server_port), name,
230 max_session_count, nullptr);
225 result.IsError()) { 231 result.IsError()) {
226 LOG_ERROR(Service_SM, "failed to register service with error_code={:08X}", result.raw); 232 LOG_ERROR(Service_SM, "failed to register service with error_code={:08X}", result.raw);
227 IPC::ResponseBuilder rb{ctx, 2}; 233 IPC::ResponseBuilder rb{ctx, 2};
@@ -229,13 +235,9 @@ void SM::RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_s
229 return; 235 return;
230 } 236 }
231 237
232 auto* port = Kernel::KPort::Create(kernel);
233 port->Initialize(ServerSessionCountMax, is_light, 0);
234 SCOPE_EXIT({ port->GetClientPort().Close(); });
235
236 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 238 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
237 rb.Push(ResultSuccess); 239 rb.Push(ResultSuccess);
238 rb.PushMoveObjects(port->GetServerPort()); 240 rb.PushMoveObjects(server_port);
239} 241}
240 242
241void SM::UnregisterService(HLERequestContext& ctx) { 243void SM::UnregisterService(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index ff74f588a..4ae32a9c1 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -56,10 +56,10 @@ public:
56 explicit ServiceManager(Kernel::KernelCore& kernel_); 56 explicit ServiceManager(Kernel::KernelCore& kernel_);
57 ~ServiceManager(); 57 ~ServiceManager();
58 58
59 Result RegisterService(std::string name, u32 max_sessions, 59 Result RegisterService(Kernel::KServerPort** out_server_port, std::string name,
60 SessionRequestHandlerFactory handler_factory); 60 u32 max_sessions, SessionRequestHandlerFactory handler_factory);
61 Result UnregisterService(const std::string& name); 61 Result UnregisterService(const std::string& name);
62 Result GetServicePort(Kernel::KPort** out_port, const std::string& name); 62 Result GetServicePort(Kernel::KClientPort** out_client_port, const std::string& name);
63 63
64 template <Common::DerivedFrom<SessionRequestHandler> T> 64 template <Common::DerivedFrom<SessionRequestHandler> T>
65 std::shared_ptr<T> GetService(const std::string& service_name) const { 65 std::shared_ptr<T> GetService(const std::string& service_name) const {
@@ -84,7 +84,7 @@ private:
84 /// Map of registered services, retrieved using GetServicePort. 84 /// Map of registered services, retrieved using GetServicePort.
85 std::mutex lock; 85 std::mutex lock;
86 std::unordered_map<std::string, SessionRequestHandlerFactory> registered_services; 86 std::unordered_map<std::string, SessionRequestHandlerFactory> registered_services;
87 std::unordered_map<std::string, Kernel::KPort*> service_ports; 87 std::unordered_map<std::string, Kernel::KClientPort*> service_ports;
88 88
89 /// Kernel context 89 /// Kernel context
90 Kernel::KernelCore& kernel; 90 Kernel::KernelCore& kernel;
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 169bf4c8c..c7eb32c19 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -45,7 +45,13 @@ struct Memory::Impl {
45 45
46 void SetCurrentPageTable(Kernel::KProcess& process) { 46 void SetCurrentPageTable(Kernel::KProcess& process) {
47 current_page_table = &process.GetPageTable().GetImpl(); 47 current_page_table = &process.GetPageTable().GetImpl();
48 current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer(); 48
49 if (std::addressof(process) == system.ApplicationProcess() &&
50 Settings::IsFastmemEnabled()) {
51 current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer();
52 } else {
53 current_page_table->fastmem_arena = nullptr;
54 }
49 } 55 }
50 56
51 void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size, 57 void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
@@ -57,7 +63,7 @@ struct Memory::Impl {
57 MapPages(page_table, base / YUZU_PAGESIZE, size / YUZU_PAGESIZE, target, 63 MapPages(page_table, base / YUZU_PAGESIZE, size / YUZU_PAGESIZE, target,
58 Common::PageType::Memory); 64 Common::PageType::Memory);
59 65
60 if (Settings::IsFastmemEnabled()) { 66 if (current_page_table->fastmem_arena) {
61 system.DeviceMemory().buffer.Map(GetInteger(base), 67 system.DeviceMemory().buffer.Map(GetInteger(base),
62 GetInteger(target) - DramMemoryMap::Base, size, perms); 68 GetInteger(target) - DramMemoryMap::Base, size, perms);
63 } 69 }
@@ -69,7 +75,7 @@ struct Memory::Impl {
69 MapPages(page_table, base / YUZU_PAGESIZE, size / YUZU_PAGESIZE, 0, 75 MapPages(page_table, base / YUZU_PAGESIZE, size / YUZU_PAGESIZE, 0,
70 Common::PageType::Unmapped); 76 Common::PageType::Unmapped);
71 77
72 if (Settings::IsFastmemEnabled()) { 78 if (current_page_table->fastmem_arena) {
73 system.DeviceMemory().buffer.Unmap(GetInteger(base), size); 79 system.DeviceMemory().buffer.Unmap(GetInteger(base), size);
74 } 80 }
75 } 81 }
@@ -79,7 +85,7 @@ struct Memory::Impl {
79 ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size); 85 ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
80 ASSERT_MSG((vaddr & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", vaddr); 86 ASSERT_MSG((vaddr & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", vaddr);
81 87
82 if (!Settings::IsFastmemEnabled()) { 88 if (!current_page_table->fastmem_arena) {
83 return; 89 return;
84 } 90 }
85 91
@@ -88,11 +94,6 @@ struct Memory::Impl {
88 const bool is_x = 94 const bool is_x =
89 True(perms & Common::MemoryPermission::Execute) && Settings::IsNceEnabled(); 95 True(perms & Common::MemoryPermission::Execute) && Settings::IsNceEnabled();
90 96
91 if (!current_page_table) {
92 system.DeviceMemory().buffer.Protect(vaddr, size, is_r, is_w, is_x);
93 return;
94 }
95
96 u64 protect_bytes{}; 97 u64 protect_bytes{};
97 u64 protect_begin{}; 98 u64 protect_begin{};
98 for (u64 addr = vaddr; addr < vaddr + size; addr += YUZU_PAGESIZE) { 99 for (u64 addr = vaddr; addr < vaddr + size; addr += YUZU_PAGESIZE) {
@@ -239,7 +240,7 @@ struct Memory::Impl {
239 240
240 bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped, 241 bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped,
241 auto on_memory, auto on_rasterizer, auto increment) { 242 auto on_memory, auto on_rasterizer, auto increment) {
242 const auto& page_table = system.ApplicationProcess()->GetPageTable().GetImpl(); 243 const auto& page_table = *current_page_table;
243 std::size_t remaining_size = size; 244 std::size_t remaining_size = size;
244 std::size_t page_index = addr >> YUZU_PAGEBITS; 245 std::size_t page_index = addr >> YUZU_PAGEBITS;
245 std::size_t page_offset = addr & YUZU_PAGEMASK; 246 std::size_t page_offset = addr & YUZU_PAGEMASK;
@@ -484,7 +485,7 @@ struct Memory::Impl {
484 return; 485 return;
485 } 486 }
486 487
487 if (Settings::IsFastmemEnabled()) { 488 if (current_page_table->fastmem_arena) {
488 system.DeviceMemory().buffer.Protect(vaddr, size, !debug, !debug); 489 system.DeviceMemory().buffer.Protect(vaddr, size, !debug, !debug);
489 } 490 }
490 491
@@ -541,7 +542,7 @@ struct Memory::Impl {
541 return; 542 return;
542 } 543 }
543 544
544 if (Settings::IsFastmemEnabled()) { 545 if (current_page_table->fastmem_arena) {
545 const bool is_read_enable = 546 const bool is_read_enable =
546 !Settings::values.use_reactive_flushing.GetValue() || !cached; 547 !Settings::values.use_reactive_flushing.GetValue() || !cached;
547 system.DeviceMemory().buffer.Protect(vaddr, size, is_read_enable, !cached); 548 system.DeviceMemory().buffer.Protect(vaddr, size, is_read_enable, !cached);
@@ -886,8 +887,7 @@ void Memory::ProtectRegion(Common::PageTable& page_table, Common::ProcessAddress
886} 887}
887 888
888bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { 889bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
889 const Kernel::KProcess& process = *system.ApplicationProcess(); 890 const auto& page_table = *impl->current_page_table;
890 const auto& page_table = process.GetPageTable().GetImpl();
891 const size_t page = vaddr >> YUZU_PAGEBITS; 891 const size_t page = vaddr >> YUZU_PAGEBITS;
892 if (page >= page_table.pointers.size()) { 892 if (page >= page_table.pointers.size()) {
893 return false; 893 return false;