summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar liamwhite2023-11-30 09:20:55 -0500
committerGravatar GitHub2023-11-30 09:20:55 -0500
commit57a391e71db13ade7a3d96f59d53781eff18d2ac (patch)
tree0b4223de40a2d77598ac9095b1374353c2e9da7c /src/core/hle/kernel
parentMerge pull request #12223 from liamwhite/fruit-company (diff)
parentcore: Rename patcher file (diff)
downloadyuzu-57a391e71db13ade7a3d96f59d53781eff18d2ac.tar.gz
yuzu-57a391e71db13ade7a3d96f59d53781eff18d2ac.tar.xz
yuzu-57a391e71db13ade7a3d96f59d53781eff18d2ac.zip
Merge pull request #12074 from GPUCode/yuwu-on-the-metal
Implement Native Code Execution (NCE)
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/code_set.h14
-rw-r--r--src/core/hle/kernel/k_address_space_info.cpp4
-rw-r--r--src/core/hle/kernel/k_page_table_base.cpp33
-rw-r--r--src/core/hle/kernel/k_page_table_base.h3
-rw-r--r--src/core/hle/kernel/k_process.cpp23
-rw-r--r--src/core/hle/kernel/k_process.h14
-rw-r--r--src/core/hle/kernel/k_process_page_table.h9
-rw-r--r--src/core/hle/kernel/k_thread.h16
-rw-r--r--src/core/hle/kernel/physical_core.cpp14
9 files changed, 109 insertions, 21 deletions
diff --git a/src/core/hle/kernel/code_set.h b/src/core/hle/kernel/code_set.h
index af1af2b78..4d2d0098e 100644
--- a/src/core/hle/kernel/code_set.h
+++ b/src/core/hle/kernel/code_set.h
@@ -75,12 +75,26 @@ struct CodeSet final {
75 return segments[2]; 75 return segments[2];
76 } 76 }
77 77
78#ifdef HAS_NCE
79 Segment& PatchSegment() {
80 return patch_segment;
81 }
82
83 const Segment& PatchSegment() const {
84 return patch_segment;
85 }
86#endif
87
78 /// The overall data that backs this code set. 88 /// The overall data that backs this code set.
79 Kernel::PhysicalMemory memory; 89 Kernel::PhysicalMemory memory;
80 90
81 /// The segments that comprise this code set. 91 /// The segments that comprise this code set.
82 std::array<Segment, 3> segments; 92 std::array<Segment, 3> segments;
83 93
94#ifdef HAS_NCE
95 Segment patch_segment;
96#endif
97
84 /// The entry point address for this code set. 98 /// The entry point address for this code set.
85 KProcessAddress entrypoint = 0; 99 KProcessAddress entrypoint = 0;
86}; 100};
diff --git a/src/core/hle/kernel/k_address_space_info.cpp b/src/core/hle/kernel/k_address_space_info.cpp
index 32173e52b..23258071e 100644
--- a/src/core/hle/kernel/k_address_space_info.cpp
+++ b/src/core/hle/kernel/k_address_space_info.cpp
@@ -25,8 +25,8 @@ constexpr std::array<KAddressSpaceInfo, 13> AddressSpaceInfos{{
25 { .bit_width = 36, .address = 2_GiB , .size = 64_GiB - 2_GiB , .type = KAddressSpaceInfo::Type::MapLarge, }, 25 { .bit_width = 36, .address = 2_GiB , .size = 64_GiB - 2_GiB , .type = KAddressSpaceInfo::Type::MapLarge, },
26 { .bit_width = 36, .address = Size_Invalid, .size = 8_GiB , .type = KAddressSpaceInfo::Type::Heap, }, 26 { .bit_width = 36, .address = Size_Invalid, .size = 8_GiB , .type = KAddressSpaceInfo::Type::Heap, },
27 { .bit_width = 36, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Alias, }, 27 { .bit_width = 36, .address = Size_Invalid, .size = 6_GiB , .type = KAddressSpaceInfo::Type::Alias, },
28#ifdef ANDROID 28#ifdef HAS_NCE
29 // With Android, we use a 38-bit address space due to memory limitations. This should (safely) truncate ASLR region. 29 // With NCE, we use a 38-bit address space due to memory limitations. This should (safely) truncate ASLR region.
30 { .bit_width = 39, .address = 128_MiB , .size = 256_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::Map39Bit, }, 30 { .bit_width = 39, .address = 128_MiB , .size = 256_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::Map39Bit, },
31#else 31#else
32 { .bit_width = 39, .address = 128_MiB , .size = 512_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::Map39Bit, }, 32 { .bit_width = 39, .address = 128_MiB , .size = 512_GiB - 128_MiB, .type = KAddressSpaceInfo::Type::Map39Bit, },
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp
index 47dc8fd35..6691586ed 100644
--- a/src/core/hle/kernel/k_page_table_base.cpp
+++ b/src/core/hle/kernel/k_page_table_base.cpp
@@ -88,6 +88,22 @@ Result FlushDataCache(AddressType addr, u64 size) {
88 R_SUCCEED(); 88 R_SUCCEED();
89} 89}
90 90
91constexpr Common::MemoryPermission ConvertToMemoryPermission(KMemoryPermission perm) {
92 Common::MemoryPermission perms{};
93 if (True(perm & KMemoryPermission::UserRead)) {
94 perms |= Common::MemoryPermission::Read;
95 }
96 if (True(perm & KMemoryPermission::UserWrite)) {
97 perms |= Common::MemoryPermission::Write;
98 }
99#ifdef HAS_NCE
100 if (True(perm & KMemoryPermission::UserExecute)) {
101 perms |= Common::MemoryPermission::Execute;
102 }
103#endif
104 return perms;
105}
106
91} // namespace 107} // namespace
92 108
93void KPageTableBase::MemoryRange::Open() { 109void KPageTableBase::MemoryRange::Open() {
@@ -170,7 +186,8 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool
170 KMemoryManager::Pool pool, KProcessAddress code_address, 186 KMemoryManager::Pool pool, KProcessAddress code_address,
171 size_t code_size, KSystemResource* system_resource, 187 size_t code_size, KSystemResource* system_resource,
172 KResourceLimit* resource_limit, 188 KResourceLimit* resource_limit,
173 Core::Memory::Memory& memory) { 189 Core::Memory::Memory& memory,
190 KProcessAddress aslr_space_start) {
174 // Calculate region extents. 191 // Calculate region extents.
175 const size_t as_width = GetAddressSpaceWidth(as_type); 192 const size_t as_width = GetAddressSpaceWidth(as_type);
176 const KProcessAddress start = 0; 193 const KProcessAddress start = 0;
@@ -211,7 +228,8 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool
211 heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Heap); 228 heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Heap);
212 stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Stack); 229 stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Stack);
213 kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type::MapSmall); 230 kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type::MapSmall);
214 m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::Map39Bit); 231 m_code_region_start = m_address_space_start + aslr_space_start +
232 GetSpaceStart(KAddressSpaceInfo::Type::Map39Bit);
215 m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::Map39Bit); 233 m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::Map39Bit);
216 m_alias_code_region_start = m_code_region_start; 234 m_alias_code_region_start = m_code_region_start;
217 m_alias_code_region_end = m_code_region_end; 235 m_alias_code_region_end = m_code_region_end;
@@ -5643,7 +5661,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
5643 case OperationType::Map: { 5661 case OperationType::Map: {
5644 ASSERT(virt_addr != 0); 5662 ASSERT(virt_addr != 0);
5645 ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize)); 5663 ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize));
5646 m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr); 5664 m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr,
5665 ConvertToMemoryPermission(properties.perm));
5647 5666
5648 // Open references to pages, if we should. 5667 // Open references to pages, if we should.
5649 if (this->IsHeapPhysicalAddress(phys_addr)) { 5668 if (this->IsHeapPhysicalAddress(phys_addr)) {
@@ -5658,8 +5677,11 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
5658 } 5677 }
5659 case OperationType::ChangePermissions: 5678 case OperationType::ChangePermissions:
5660 case OperationType::ChangePermissionsAndRefresh: 5679 case OperationType::ChangePermissionsAndRefresh:
5661 case OperationType::ChangePermissionsAndRefreshAndFlush: 5680 case OperationType::ChangePermissionsAndRefreshAndFlush: {
5681 m_memory->ProtectRegion(*m_impl, virt_addr, num_pages * PageSize,
5682 ConvertToMemoryPermission(properties.perm));
5662 R_SUCCEED(); 5683 R_SUCCEED();
5684 }
5663 default: 5685 default:
5664 UNREACHABLE(); 5686 UNREACHABLE();
5665 } 5687 }
@@ -5687,7 +5709,8 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
5687 const size_t size{node.GetNumPages() * PageSize}; 5709 const size_t size{node.GetNumPages() * PageSize};
5688 5710
5689 // Map the pages. 5711 // Map the pages.
5690 m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress()); 5712 m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress(),
5713 ConvertToMemoryPermission(properties.perm));
5691 5714
5692 virt_addr += size; 5715 virt_addr += size;
5693 } 5716 }
diff --git a/src/core/hle/kernel/k_page_table_base.h b/src/core/hle/kernel/k_page_table_base.h
index ee2c41e67..556d230b3 100644
--- a/src/core/hle/kernel/k_page_table_base.h
+++ b/src/core/hle/kernel/k_page_table_base.h
@@ -235,7 +235,8 @@ public:
235 bool enable_device_address_space_merge, bool from_back, 235 bool enable_device_address_space_merge, bool from_back,
236 KMemoryManager::Pool pool, KProcessAddress code_address, 236 KMemoryManager::Pool pool, KProcessAddress code_address,
237 size_t code_size, KSystemResource* system_resource, 237 size_t code_size, KSystemResource* system_resource,
238 KResourceLimit* resource_limit, Core::Memory::Memory& memory); 238 KResourceLimit* resource_limit, Core::Memory::Memory& memory,
239 KProcessAddress aslr_space_start);
239 240
240 void Finalize(); 241 void Finalize();
241 242
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 3cfb414e5..6c29eb72c 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -300,7 +300,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa
300 False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge); 300 False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge);
301 R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, 301 R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool,
302 params.code_address, params.code_num_pages * PageSize, 302 params.code_address, params.code_num_pages * PageSize,
303 m_system_resource, res_limit, this->GetMemory())); 303 m_system_resource, res_limit, this->GetMemory(), 0));
304 } 304 }
305 ON_RESULT_FAILURE_2 { 305 ON_RESULT_FAILURE_2 {
306 m_page_table.Finalize(); 306 m_page_table.Finalize();
@@ -332,7 +332,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa
332 332
333Result KProcess::Initialize(const Svc::CreateProcessParameter& params, 333Result KProcess::Initialize(const Svc::CreateProcessParameter& params,
334 std::span<const u32> user_caps, KResourceLimit* res_limit, 334 std::span<const u32> user_caps, KResourceLimit* res_limit,
335 KMemoryManager::Pool pool) { 335 KMemoryManager::Pool pool, KProcessAddress aslr_space_start) {
336 ASSERT(res_limit != nullptr); 336 ASSERT(res_limit != nullptr);
337 337
338 // Set members. 338 // Set members.
@@ -393,7 +393,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params,
393 False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge); 393 False(params.flags & Svc::CreateProcessFlag::DisableDeviceAddressSpaceMerge);
394 R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool, 394 R_TRY(m_page_table.Initialize(as_type, enable_aslr, enable_das_merge, !enable_aslr, pool,
395 params.code_address, code_size, m_system_resource, res_limit, 395 params.code_address, code_size, m_system_resource, res_limit,
396 this->GetMemory())); 396 this->GetMemory(), aslr_space_start));
397 } 397 }
398 ON_RESULT_FAILURE_2 { 398 ON_RESULT_FAILURE_2 {
399 m_page_table.Finalize(); 399 m_page_table.Finalize();
@@ -1128,7 +1128,7 @@ KProcess::KProcess(KernelCore& kernel)
1128KProcess::~KProcess() = default; 1128KProcess::~KProcess() = default;
1129 1129
1130Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, 1130Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
1131 bool is_hbl) { 1131 KProcessAddress aslr_space_start, bool is_hbl) {
1132 // Create a resource limit for the process. 1132 // Create a resource limit for the process.
1133 const auto physical_memory_size = 1133 const auto physical_memory_size =
1134 m_kernel.MemoryManager().GetSize(Kernel::KMemoryManager::Pool::Application); 1134 m_kernel.MemoryManager().GetSize(Kernel::KMemoryManager::Pool::Application);
@@ -1179,7 +1179,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
1179 .name = {}, 1179 .name = {},
1180 .version = {}, 1180 .version = {},
1181 .program_id = metadata.GetTitleID(), 1181 .program_id = metadata.GetTitleID(),
1182 .code_address = code_address, 1182 .code_address = code_address + GetInteger(aslr_space_start),
1183 .code_num_pages = static_cast<s32>(code_size / PageSize), 1183 .code_num_pages = static_cast<s32>(code_size / PageSize),
1184 .flags = flag, 1184 .flags = flag,
1185 .reslimit = Svc::InvalidHandle, 1185 .reslimit = Svc::InvalidHandle,
@@ -1193,7 +1193,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
1193 1193
1194 // Initialize for application process. 1194 // Initialize for application process.
1195 R_TRY(this->Initialize(params, metadata.GetKernelCapabilities(), res_limit, 1195 R_TRY(this->Initialize(params, metadata.GetKernelCapabilities(), res_limit,
1196 KMemoryManager::Pool::Application)); 1196 KMemoryManager::Pool::Application, aslr_space_start));
1197 1197
1198 // Assign remaining properties. 1198 // Assign remaining properties.
1199 m_is_hbl = is_hbl; 1199 m_is_hbl = is_hbl;
@@ -1214,6 +1214,17 @@ void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) {
1214 ReprotectSegment(code_set.CodeSegment(), Svc::MemoryPermission::ReadExecute); 1214 ReprotectSegment(code_set.CodeSegment(), Svc::MemoryPermission::ReadExecute);
1215 ReprotectSegment(code_set.RODataSegment(), Svc::MemoryPermission::Read); 1215 ReprotectSegment(code_set.RODataSegment(), Svc::MemoryPermission::Read);
1216 ReprotectSegment(code_set.DataSegment(), Svc::MemoryPermission::ReadWrite); 1216 ReprotectSegment(code_set.DataSegment(), Svc::MemoryPermission::ReadWrite);
1217
1218#ifdef HAS_NCE
1219 if (Settings::IsNceEnabled()) {
1220 auto& buffer = m_kernel.System().DeviceMemory().buffer;
1221 const auto& code = code_set.CodeSegment();
1222 const auto& patch = code_set.PatchSegment();
1223 buffer.Protect(GetInteger(base_addr + code.addr), code.size, true, true, true);
1224 buffer.Protect(GetInteger(base_addr + patch.addr), patch.size, true, true, true);
1225 ReprotectSegment(code_set.PatchSegment(), Svc::MemoryPermission::None);
1226 }
1227#endif
1217} 1228}
1218 1229
1219bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) { 1230bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) {
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index 8339465fd..d8cd0fdde 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -120,6 +120,9 @@ private:
120 std::atomic<s64> m_num_ipc_messages{}; 120 std::atomic<s64> m_num_ipc_messages{};
121 std::atomic<s64> m_num_ipc_replies{}; 121 std::atomic<s64> m_num_ipc_replies{};
122 std::atomic<s64> m_num_ipc_receives{}; 122 std::atomic<s64> m_num_ipc_receives{};
123#ifdef HAS_NCE
124 std::unordered_map<u64, u64> m_post_handlers{};
125#endif
123 126
124private: 127private:
125 Result StartTermination(); 128 Result StartTermination();
@@ -150,7 +153,8 @@ public:
150 std::span<const u32> caps, KResourceLimit* res_limit, 153 std::span<const u32> caps, KResourceLimit* res_limit,
151 KMemoryManager::Pool pool, bool immortal); 154 KMemoryManager::Pool pool, bool immortal);
152 Result Initialize(const Svc::CreateProcessParameter& params, std::span<const u32> user_caps, 155 Result Initialize(const Svc::CreateProcessParameter& params, std::span<const u32> user_caps,
153 KResourceLimit* res_limit, KMemoryManager::Pool pool); 156 KResourceLimit* res_limit, KMemoryManager::Pool pool,
157 KProcessAddress aslr_space_start);
154 void Exit(); 158 void Exit();
155 159
156 const char* GetName() const { 160 const char* GetName() const {
@@ -466,6 +470,12 @@ public:
466 470
467 static void Switch(KProcess* cur_process, KProcess* next_process); 471 static void Switch(KProcess* cur_process, KProcess* next_process);
468 472
473#ifdef HAS_NCE
474 std::unordered_map<u64, u64>& GetPostHandlers() noexcept {
475 return m_post_handlers;
476 }
477#endif
478
469public: 479public:
470 // Attempts to insert a watchpoint into a free slot. Returns false if none are available. 480 // Attempts to insert a watchpoint into a free slot. Returns false if none are available.
471 bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type); 481 bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type);
@@ -479,7 +489,7 @@ public:
479 489
480public: 490public:
481 Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, 491 Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
482 bool is_hbl); 492 KProcessAddress aslr_space_start, bool is_hbl);
483 493
484 void LoadModule(CodeSet code_set, KProcessAddress base_addr); 494 void LoadModule(CodeSet code_set, KProcessAddress base_addr);
485 495
diff --git a/src/core/hle/kernel/k_process_page_table.h b/src/core/hle/kernel/k_process_page_table.h
index b7ae5abd0..9e40f68bc 100644
--- a/src/core/hle/kernel/k_process_page_table.h
+++ b/src/core/hle/kernel/k_process_page_table.h
@@ -23,10 +23,11 @@ public:
23 Result Initialize(Svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge, 23 Result Initialize(Svc::CreateProcessFlag as_type, bool enable_aslr, bool enable_das_merge,
24 bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address, 24 bool from_back, KMemoryManager::Pool pool, KProcessAddress code_address,
25 size_t code_size, KSystemResource* system_resource, 25 size_t code_size, KSystemResource* system_resource,
26 KResourceLimit* resource_limit, Core::Memory::Memory& memory) { 26 KResourceLimit* resource_limit, Core::Memory::Memory& memory,
27 R_RETURN(m_page_table.InitializeForProcess(as_type, enable_aslr, enable_das_merge, 27 KProcessAddress aslr_space_start) {
28 from_back, pool, code_address, code_size, 28 R_RETURN(m_page_table.InitializeForProcess(
29 system_resource, resource_limit, memory)); 29 as_type, enable_aslr, enable_das_merge, from_back, pool, code_address, code_size,
30 system_resource, resource_limit, memory, aslr_space_start));
30 } 31 }
31 32
32 void Finalize() { 33 void Finalize() {
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index e1f80b04f..e9ca5dfca 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -655,6 +655,21 @@ public:
655 return m_stack_top; 655 return m_stack_top;
656 } 656 }
657 657
658public:
659 // TODO: This shouldn't be defined in kernel namespace
660 struct NativeExecutionParameters {
661 u64 tpidr_el0{};
662 u64 tpidrro_el0{};
663 void* native_context{};
664 std::atomic<u32> lock{1};
665 bool is_running{};
666 u32 magic{Common::MakeMagic('Y', 'U', 'Z', 'U')};
667 };
668
669 NativeExecutionParameters& GetNativeExecutionParameters() {
670 return m_native_execution_parameters;
671 }
672
658private: 673private:
659 KThread* RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key, 674 KThread* RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key,
660 bool is_kernel_address_key); 675 bool is_kernel_address_key);
@@ -914,6 +929,7 @@ private:
914 ThreadWaitReasonForDebugging m_wait_reason_for_debugging{}; 929 ThreadWaitReasonForDebugging m_wait_reason_for_debugging{};
915 uintptr_t m_argument{}; 930 uintptr_t m_argument{};
916 KProcessAddress m_stack_top{}; 931 KProcessAddress m_stack_top{};
932 NativeExecutionParameters m_native_execution_parameters{};
917 933
918public: 934public:
919 using ConditionVariableThreadTreeType = ConditionVariableThreadTree; 935 using ConditionVariableThreadTreeType = ConditionVariableThreadTree;
diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp
index 5ee869fa2..073039825 100644
--- a/src/core/hle/kernel/physical_core.cpp
+++ b/src/core/hle/kernel/physical_core.cpp
@@ -1,8 +1,12 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/settings.h"
4#include "core/arm/dynarmic/arm_dynarmic_32.h" 5#include "core/arm/dynarmic/arm_dynarmic_32.h"
5#include "core/arm/dynarmic/arm_dynarmic_64.h" 6#include "core/arm/dynarmic/arm_dynarmic_64.h"
7#ifdef HAS_NCE
8#include "core/arm/nce/arm_nce.h"
9#endif
6#include "core/core.h" 10#include "core/core.h"
7#include "core/hle/kernel/k_scheduler.h" 11#include "core/hle/kernel/k_scheduler.h"
8#include "core/hle/kernel/kernel.h" 12#include "core/hle/kernel/kernel.h"
@@ -14,7 +18,8 @@ PhysicalCore::PhysicalCore(std::size_t core_index, Core::System& system, KSchedu
14 : m_core_index{core_index}, m_system{system}, m_scheduler{scheduler} { 18 : m_core_index{core_index}, m_system{system}, m_scheduler{scheduler} {
15#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) 19#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64)
16 // TODO(bunnei): Initialization relies on a core being available. We may later replace this with 20 // TODO(bunnei): Initialization relies on a core being available. We may later replace this with
17 // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager. 21 // an NCE interface or a 32-bit instance of Dynarmic. This should be abstracted out to a CPU
22 // manager.
18 auto& kernel = system.Kernel(); 23 auto& kernel = system.Kernel();
19 m_arm_interface = std::make_unique<Core::ARM_Dynarmic_64>( 24 m_arm_interface = std::make_unique<Core::ARM_Dynarmic_64>(
20 system, kernel.IsMulticore(), 25 system, kernel.IsMulticore(),
@@ -28,6 +33,13 @@ PhysicalCore::PhysicalCore(std::size_t core_index, Core::System& system, KSchedu
28PhysicalCore::~PhysicalCore() = default; 33PhysicalCore::~PhysicalCore() = default;
29 34
30void PhysicalCore::Initialize(bool is_64_bit) { 35void PhysicalCore::Initialize(bool is_64_bit) {
36#if defined(HAS_NCE)
37 if (Settings::IsNceEnabled()) {
38 m_arm_interface = std::make_unique<Core::ARM_NCE>(m_system, m_system.Kernel().IsMulticore(),
39 m_core_index);
40 return;
41 }
42#endif
31#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64) 43#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64)
32 auto& kernel = m_system.Kernel(); 44 auto& kernel = m_system.Kernel();
33 if (!is_64_bit) { 45 if (!is_64_bit) {