diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-28 11:29:20 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-28 11:29:20 -0400 |
| commit | 3b1639daa3650faf1b56906524b75f019f707f00 (patch) | |
| tree | 6c95deff575a0de9be2768dc5002fcb1117c792b /src | |
| parent | 12cca280bf750eb7674fd055428f1f7c65deed42 (diff) | |
core: emulate six CPU cores
Switch 2 applications are given cores 0..5 (title 4's npdm) and start a
job worker per core. With four emulated cores, 4 and 5 were folded onto
0 and 1, so two cores ran two workers each. Switch 1 titles keep using
cores 0..3; core 3 stays the shared system core.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hardware_properties.h | 7 | ||||
| -rw-r--r-- | src/core/hle/kernel/global_scheduler_context.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_thread.cpp | 4 | ||||
| -rw-r--r-- | src/dynarmic/src/dynarmic/interface/exclusive_monitor.h | 2 |
5 files changed, 13 insertions, 7 deletions
diff --git a/src/core/hardware_properties.h b/src/core/hardware_properties.h index 3f870becbf..aeea5f858f 100644 --- a/src/core/hardware_properties.h +++ b/src/core/hardware_properties.h @@ -15,11 +15,14 @@ namespace Hardware { constexpr u64 BASE_CLOCK_RATE = 1'020'000'000; // Default CPU Frequency = 1020 MHz constexpr u64 CNTFREQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz -constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores - sync with dynarmic exclusive_monitor.h +// Switch 1 applications get cores 0..3. Switch 2 applications ask for 0..5 (title 4's npdm), and +// its job system starts a worker per core, so emulate six: with four, cores 0 and 1 each ran two +// of its workers. Switch 1 titles leave cores 4 and 5 idle. +constexpr u32 NUM_CPU_CORES = 6; // Number of CPU Cores - sync with dynarmic exclusive_monitor.h // Virtual to Physical core map. constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{ - 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, }; diff --git a/src/core/hle/kernel/global_scheduler_context.cpp b/src/core/hle/kernel/global_scheduler_context.cpp index 6d1cd030e0..98d14c8549 100644 --- a/src/core/hle/kernel/global_scheduler_context.cpp +++ b/src/core/hle/kernel/global_scheduler_context.cpp @@ -40,12 +40,15 @@ void GlobalSchedulerContext::RemoveThread(KThread* thread) noexcept { /// @note This operation happens every 10ms. void GlobalSchedulerContext::PreemptThreads(KernelCore& kernel) noexcept { // The priority levels at which the global scheduler preempts threads every 10 ms. They are - // ordered from Core 0 to Core 3. + // ordered from Core 0 to Core 5; core 3 is shared with the system, 4 and 5 are application + // cores like 0..2. static constexpr std::array<u32, Core::Hardware::NUM_CPU_CORES> per_core{ 59, 59, 59, 63, + 59, + 59, }; ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); for (u32 core_id = 0; core_id < per_core.size(); core_id++) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 4f1d849209..b437dd4b4e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -171,7 +171,7 @@ struct KernelCore::Impl { schedulers[core_id].reset(); } - // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others + // Next host thead ID to use, IDs below NUM_CPU_CORES represent core threads, the rest others next_host_thread_id = Core::Hardware::NUM_CPU_CORES; // Close kernel objects that were not freed on shutdown diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index 9838e68476..7f6b959256 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp @@ -20,8 +20,8 @@ constexpr bool IsValidVirtualCoreId(int32_t core_id) { return (0 <= core_id && core_id < static_cast<int32_t>(Core::Hardware::NUM_CPU_CORES)); } -// Switch 2 processes may be given virtual cores 4 and 5 (core mask 0x3f). Only four cores are -// emulated, so fold the extra ones back onto 0..3, both in core ids and in affinity masks. +// 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; diff --git a/src/dynarmic/src/dynarmic/interface/exclusive_monitor.h b/src/dynarmic/src/dynarmic/interface/exclusive_monitor.h index 05b067bdd8..46fce86bda 100644 --- a/src/dynarmic/src/dynarmic/interface/exclusive_monitor.h +++ b/src/dynarmic/src/dynarmic/interface/exclusive_monitor.h @@ -82,7 +82,7 @@ private: static constexpr VAddr RESERVATION_GRANULE_MASK = 0xFFFF'FFFF'FFFF'FFFFull; static constexpr VAddr INVALID_EXCLUSIVE_ADDRESS = 0xDEAD'DEAD'DEAD'DEADull; - static constexpr size_t MAX_NUM_CPU_CORES = 4; // Sync with src/core/hardware_properties + static constexpr size_t MAX_NUM_CPU_CORES = 6; // Sync with src/core/hardware_properties boost::container::static_vector<VAddr, MAX_NUM_CPU_CORES> exclusive_addresses; boost::container::static_vector<Vector, MAX_NUM_CPU_CORES> exclusive_values; SpinLock lock; |
