diff options
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/code_set.h | 9 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_address_space_info.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.cpp | 11 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_process.h | 9 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/physical_core.cpp | 14 |
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 | ||
| 1219 | bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) { | 1230 | bool 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 | |||
| 470 | public: | 479 | public: |
| 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 | ||
| 658 | public: | ||
| 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 | |||
| 658 | private: | 673 | private: |
| 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 | ||
| 918 | public: | 934 | public: |
| 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 | |||
| 28 | PhysicalCore::~PhysicalCore() = default; | 33 | PhysicalCore::~PhysicalCore() = default; |
| 29 | 34 | ||
| 30 | void PhysicalCore::Initialize(bool is_64_bit) { | 35 | void 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) { |