aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc/svc_thread.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 03:39:52 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-29 03:39:52 -0400
commite17fd9cef116a088f080ca502951e500864a58b6 (patch)
treee7ff65f614622515d6a2e4263521909eea89a5d8 /src/core/hle/kernel/svc/svc_thread.cpp
parentea6c1193fbfa95e586bb6d129dc684163a12cb3e (diff)
parent80c79333fe6fd28a31b65b997f1cbf2987711c91 (diff)
Merge Switch 2 work from local Eden (nx2 at b0dd3fe)
Diffstat (limited to 'src/core/hle/kernel/svc/svc_thread.cpp')
-rw-r--r--src/core/hle/kernel/svc/svc_thread.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp
index dbca13dd26..7f6b959256 100644
--- a/src/core/hle/kernel/svc/svc_thread.cpp
+++ b/src/core/hle/kernel/svc/svc_thread.cpp
@@ -20,6 +20,18 @@ constexpr bool IsValidVirtualCoreId(int32_t core_id) {
return (0 <= core_id && core_id < static_cast<int32_t>(Core::Hardware::NUM_CPU_CORES));
}
+// Switch 2 hardware has eight cores. Six are emulated (the most an application is given), so
+// fold any id past them back onto the low cores, both in core ids and in affinity masks.
+constexpr int32_t FoldExtraCoreId(int32_t core_id) {
+ constexpr auto num_cores = static_cast<int32_t>(Core::Hardware::NUM_CPU_CORES);
+ return core_id >= num_cores && core_id < 2 * num_cores ? core_id - num_cores : core_id;
+}
+
+constexpr u64 FoldExtraCoreMask(u64 mask) {
+ constexpr u64 low = (1ULL << Core::Hardware::NUM_CPU_CORES) - 1;
+ return (mask & low) | ((mask >> Core::Hardware::NUM_CPU_CORES) & low);
+}
+
} // Anonymous namespace
/// Creates a new thread
@@ -36,6 +48,7 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u
if (core_id == IdealCoreUseProcessValue) {
core_id = process.GetIdealCoreId();
}
+ core_id = FoldExtraCoreId(core_id);
// Validate arguments.
R_UNLESS(IsValidVirtualCoreId(core_id), ResultInvalidCoreId);
@@ -261,6 +274,10 @@ Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id
R_UNLESS((affinity_mask | process_core_mask) == process_core_mask, ResultInvalidCoreId);
R_UNLESS(affinity_mask != 0, ResultInvalidCombination);
+ // Validated against the real mask above; fold to the emulated cores from here on.
+ affinity_mask = FoldExtraCoreMask(affinity_mask);
+ core_id = FoldExtraCoreId(core_id);
+
// Validate the core id.
if (IsValidVirtualCoreId(core_id)) {
R_UNLESS(((1ULL << core_id) & affinity_mask) != 0, ResultInvalidCombination);