diff options
| -rw-r--r-- | src/core/file_sys/program_metadata.cpp | 6 | ||||
| -rw-r--r-- | src/core/file_sys/program_metadata.h | 13 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_client_port.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_handle_table.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.cpp | 36 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_session.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 21 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/fatal/fatal.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/server_manager.cpp | 19 | ||||
| -rw-r--r-- | src/core/hle/service/set/set_sys.cpp | 12 | ||||
| -rw-r--r-- | src/core/hle/service/set/set_sys.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.cpp | 36 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.h | 8 | ||||
| -rw-r--r-- | src/core/memory.cpp | 28 |
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 | ||
| 169 | PoolPartition ProgramMetadata::GetPoolPartition() const { | ||
| 170 | return acid_header.pool_partition; | ||
| 171 | } | ||
| 172 | |||
| 169 | const ProgramMetadata::KernelCapabilityDescriptors& ProgramMetadata::GetKernelCapabilities() const { | 173 | const 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 | ||
| 37 | enum 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: | |||
| 30 | public: | 30 | public: |
| 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 | ||
| 302 | private: | 303 | private: |
| 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 | ||
| 1095 | Result KProcess::GetThreadList(s32* out_num_threads, KProcessAddress out_thread_ids, | 1103 | Result 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) {} | |||
| 1128 | KProcess::KProcess(KernelCore& kernel) | 1135 | KProcess::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()} {} |
| 1133 | KProcess::~KProcess() = default; | 1140 | KProcess::~KProcess() = default; |
| 1134 | 1141 | ||
| 1135 | Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, | 1142 | Result 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 | ||
| 1424 | Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel) { | 1424 | Core::Memory::Memory& GetCurrentMemory(KernelCore& kernel) { |
| 1425 | // TODO: per-process memory | 1425 | return GetCurrentProcess(kernel).GetMemory(); |
| 1426 | return kernel.System().ApplicationMemory(); | ||
| 1427 | } | 1426 | } |
| 1428 | 1427 | ||
| 1429 | KScopedDisableDispatch::~KScopedDisableDispatch() { | 1428 | KScopedDisableDispatch::~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 | ||
| 880 | KScopedAutoObject<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { | ||
| 881 | return impl->global_handle_table->GetObject<KThread>(handle); | ||
| 882 | } | ||
| 883 | |||
| 884 | void KernelCore::AppendNewProcess(KProcess* process) { | 871 | void 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 | ||
| 1020 | KHandleTable& KernelCore::GlobalHandleTable() { | ||
| 1021 | return *impl->global_handle_table; | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | const KHandleTable& KernelCore::GlobalHandleTable() const { | ||
| 1025 | return *impl->global_handle_table; | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | void KernelCore::RegisterCoreThread(std::size_t core_id) { | 1007 | void 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 | ||
| 510 | void 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 | |||
| 510 | void SET_SYS::GetQuestFlag(HLERequestContext& ctx) { | 518 | void 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 | ||
| 1145 | void SET_SYS::StoreSettingsThreadFunc(std::stop_token stop_token) { | 1153 | void 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 | ||
| 30 | ServiceManager::~ServiceManager() { | 30 | ServiceManager::~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 | ||
| 53 | Result ServiceManager::RegisterService(std::string name, u32 max_sessions, | 52 | Result 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 | ||
| 78 | Result ServiceManager::UnregisterService(const std::string& name) { | 81 | Result 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 | ||
| 94 | Result ServiceManager::GetServicePort(Kernel::KPort** out_port, const std::string& name) { | 97 | Result 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 | ||
| 241 | void SM::UnregisterService(HLERequestContext& ctx) { | 243 | void 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 | ||
| 888 | bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { | 889 | bool 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; |