summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/code_set.h9
-rw-r--r--src/core/hle/kernel/k_address_space_info.cpp4
-rw-r--r--src/core/hle/kernel/k_process.cpp11
-rw-r--r--src/core/hle/kernel/k_process.h9
-rw-r--r--src/core/hle/kernel/k_thread.h16
-rw-r--r--src/core/hle/kernel/physical_core.cpp14
6 files changed, 60 insertions, 3 deletions
diff --git a/src/core/hle/kernel/code_set.h b/src/core/hle/kernel/code_set.h
index af1af2b78..d53da82f4 100644
--- a/src/core/hle/kernel/code_set.h
+++ b/src/core/hle/kernel/code_set.h
@@ -75,11 +75,20 @@ struct CodeSet final {
75 return segments[2]; 75 return segments[2];
76 } 76 }
77 77
78 Segment& PatchSegment() {
79 return patch_segment;
80 }
81
82 const Segment& PatchSegment() const {
83 return patch_segment;
84 }
85
78 /// The overall data that backs this code set. 86 /// The overall data that backs this code set.
79 Kernel::PhysicalMemory memory; 87 Kernel::PhysicalMemory memory;
80 88
81 /// The segments that comprise this code set. 89 /// The segments that comprise this code set.
82 std::array<Segment, 3> segments; 90 std::array<Segment, 3> segments;
91 Segment patch_segment;
83 92
84 /// The entry point address for this code set. 93 /// The entry point address for this code set.
85 KProcessAddress entrypoint = 0; 94 KProcessAddress entrypoint = 0;
diff --git a/src/core/hle/kernel/k_address_space_info.cpp b/src/core/hle/kernel/k_address_space_info.cpp
index 32173e52b..3235a7a37 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 ARCHITECTURE_arm64
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_process.cpp b/src/core/hle/kernel/k_process.cpp
index c6a200320..d2e9f2a2e 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -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 ARCHITECTURE_arm64
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 54b8e0a59..7b97d452b 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -112,6 +112,7 @@ private:
112 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{}; 112 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> m_pinned_threads{};
113 std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{}; 113 std::array<DebugWatchpoint, Core::Hardware::NUM_WATCHPOINTS> m_watchpoints{};
114 std::map<KProcessAddress, u64> m_debug_page_refcounts{}; 114 std::map<KProcessAddress, u64> m_debug_page_refcounts{};
115 std::unordered_map<u64, u64> m_post_handlers{};
115 std::atomic<s64> m_cpu_time{}; 116 std::atomic<s64> m_cpu_time{};
116 std::atomic<s64> m_num_process_switches{}; 117 std::atomic<s64> m_num_process_switches{};
117 std::atomic<s64> m_num_thread_switches{}; 118 std::atomic<s64> m_num_thread_switches{};
@@ -467,6 +468,14 @@ public:
467 468
468 static void Switch(KProcess* cur_process, KProcess* next_process); 469 static void Switch(KProcess* cur_process, KProcess* next_process);
469 470
471 std::unordered_map<u64, u64>& GetPostHandlers() noexcept {
472 return m_post_handlers;
473 }
474
475 KernelCore& GetKernel() noexcept {
476 return m_kernel;
477 }
478
470public: 479public:
471 // 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.
472 bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type); 481 bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type);
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..15434212e 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 ARCHITECTURE_arm64
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(ARCHITECTURE_arm64)
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) {