mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-03 11:11:14 +00:00
kern: fix support for virtual core IDs
This commit is contained in:
parent
846cc0b47a
commit
621520c30b
5 changed files with 29 additions and 16 deletions
|
@ -45,7 +45,21 @@
|
||||||
|
|
||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
|
|
||||||
static_assert(cpu::NumCores <= static_cast<s32>(BITSIZEOF(u64)));
|
namespace cpu {
|
||||||
static_assert(util::size(cpu::VirtualToPhysicalCoreMap) == BITSIZEOF(u64));
|
|
||||||
|
static constexpr inline size_t NumVirtualCores = BITSIZEOF(u64);
|
||||||
|
|
||||||
|
static constexpr inline u64 VirtualCoreMask = [] {
|
||||||
|
u64 mask = 0;
|
||||||
|
for (size_t i = 0; i < NumVirtualCores; ++i) {
|
||||||
|
mask |= (UINT64_C(1) << i);
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(cpu::NumCores <= cpu::NumVirtualCores);
|
||||||
|
static_assert(util::size(cpu::VirtualToPhysicalCoreMap) == cpu::NumVirtualCores);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace ams::kern {
|
||||||
/* Most fields have already been cleared by our constructor. */
|
/* Most fields have already been cleared by our constructor. */
|
||||||
|
|
||||||
/* Initial processes may run on all cores. */
|
/* Initial processes may run on all cores. */
|
||||||
m_core_mask = (1ul << cpu::NumCores) - 1;
|
m_core_mask = cpu::VirtualCoreMask;
|
||||||
|
|
||||||
/* Initial processes may use any user priority they like. */
|
/* Initial processes may use any user priority they like. */
|
||||||
m_priority_mask = ~0xFul;
|
m_priority_mask = ~0xFul;
|
||||||
|
@ -55,18 +55,17 @@ namespace ams::kern {
|
||||||
const auto max_prio = cap.Get<CorePriority::LowestThreadPriority>();
|
const auto max_prio = cap.Get<CorePriority::LowestThreadPriority>();
|
||||||
const auto min_prio = cap.Get<CorePriority::HighestThreadPriority>();
|
const auto min_prio = cap.Get<CorePriority::HighestThreadPriority>();
|
||||||
|
|
||||||
R_UNLESS(min_core <= max_core, svc::ResultInvalidCombination());
|
R_UNLESS(min_core <= max_core, svc::ResultInvalidCombination());
|
||||||
R_UNLESS(min_prio <= max_prio, svc::ResultInvalidCombination());
|
R_UNLESS(min_prio <= max_prio, svc::ResultInvalidCombination());
|
||||||
R_UNLESS(max_core < cpu::NumCores, svc::ResultInvalidCoreId());
|
R_UNLESS(max_core < cpu::NumVirtualCores, svc::ResultInvalidCoreId());
|
||||||
|
|
||||||
MESOSPHERE_ASSERT(max_core < BITSIZEOF(u64));
|
|
||||||
MESOSPHERE_ASSERT(max_prio < BITSIZEOF(u64));
|
MESOSPHERE_ASSERT(max_prio < BITSIZEOF(u64));
|
||||||
|
|
||||||
/* Set core mask. */
|
/* Set core mask. */
|
||||||
for (auto core_id = min_core; core_id <= max_core; core_id++) {
|
for (auto core_id = min_core; core_id <= max_core; core_id++) {
|
||||||
m_core_mask |= (1ul << core_id);
|
m_core_mask |= (1ul << core_id);
|
||||||
}
|
}
|
||||||
MESOSPHERE_ASSERT((m_core_mask & ((1ul << cpu::NumCores) - 1)) == m_core_mask);
|
MESOSPHERE_ASSERT((m_core_mask & cpu::VirtualCoreMask) == m_core_mask);
|
||||||
|
|
||||||
/* Set priority mask. */
|
/* Set priority mask. */
|
||||||
for (auto prio = min_prio; prio <= max_prio; prio++) {
|
for (auto prio = min_prio; prio <= max_prio; prio++) {
|
||||||
|
|
|
@ -216,7 +216,7 @@ namespace ams::kern::svc {
|
||||||
case ams::svc::InfoType_ThreadTickCount:
|
case ams::svc::InfoType_ThreadTickCount:
|
||||||
{
|
{
|
||||||
/* Verify the requested core is valid. */
|
/* Verify the requested core is valid. */
|
||||||
const bool core_valid = (info_subtype == static_cast<u64>(-1ul)) || (info_subtype < util::size(cpu::VirtualToPhysicalCoreMap));
|
const bool core_valid = (info_subtype == static_cast<u64>(-1ul)) || (info_subtype < cpu::NumVirtualCores);
|
||||||
R_UNLESS(core_valid, svc::ResultInvalidCombination());
|
R_UNLESS(core_valid, svc::ResultInvalidCombination());
|
||||||
|
|
||||||
/* Get the thread from its handle. */
|
/* Get the thread from its handle. */
|
||||||
|
|
|
@ -21,8 +21,8 @@ namespace ams::kern::svc {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr bool IsValidCoreId(int32_t core_id) {
|
constexpr bool IsValidVirtualCoreId(int32_t core_id) {
|
||||||
return (0 <= core_id && core_id < static_cast<int32_t>(cpu::NumCores));
|
return (0 <= core_id && core_id < static_cast<int32_t>(cpu::NumVirtualCores));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExitProcess() {
|
void ExitProcess() {
|
||||||
|
@ -275,7 +275,7 @@ namespace ams::kern::svc {
|
||||||
R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle());
|
R_UNLESS(process.IsNotNull(), svc::ResultInvalidHandle());
|
||||||
|
|
||||||
/* Validate the core id. */
|
/* Validate the core id. */
|
||||||
R_UNLESS(IsValidCoreId(core_id), svc::ResultInvalidCoreId());
|
R_UNLESS(IsValidVirtualCoreId(core_id), svc::ResultInvalidCoreId());
|
||||||
R_UNLESS(((1ul << core_id) & process->GetCoreMask()) != 0, svc::ResultInvalidCoreId());
|
R_UNLESS(((1ul << core_id) & process->GetCoreMask()) != 0, svc::ResultInvalidCoreId());
|
||||||
|
|
||||||
/* Validate the priority. */
|
/* Validate the priority. */
|
||||||
|
|
|
@ -21,8 +21,8 @@ namespace ams::kern::svc {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr bool IsValidCoreId(int32_t core_id) {
|
constexpr bool IsValidVirtualCoreId(int32_t core_id) {
|
||||||
return (0 <= core_id && core_id < static_cast<int32_t>(cpu::NumCores));
|
return (0 <= core_id && core_id < static_cast<int32_t>(cpu::NumVirtualCores));
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateThread(ams::svc::Handle *out, ams::svc::ThreadFunc f, uintptr_t arg, uintptr_t stack_bottom, int32_t priority, int32_t core_id) {
|
Result CreateThread(ams::svc::Handle *out, ams::svc::ThreadFunc f, uintptr_t arg, uintptr_t stack_bottom, int32_t priority, int32_t core_id) {
|
||||||
|
@ -33,7 +33,7 @@ namespace ams::kern::svc {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate arguments. */
|
/* Validate arguments. */
|
||||||
R_UNLESS(IsValidCoreId(core_id), svc::ResultInvalidCoreId());
|
R_UNLESS(IsValidVirtualCoreId(core_id), svc::ResultInvalidCoreId());
|
||||||
R_UNLESS(((1ul << core_id) & process.GetCoreMask()) != 0, svc::ResultInvalidCoreId());
|
R_UNLESS(((1ul << core_id) & process.GetCoreMask()) != 0, svc::ResultInvalidCoreId());
|
||||||
|
|
||||||
R_UNLESS(ams::svc::HighestThreadPriority <= priority && priority <= ams::svc::LowestThreadPriority, svc::ResultInvalidPriority());
|
R_UNLESS(ams::svc::HighestThreadPriority <= priority && priority <= ams::svc::LowestThreadPriority, svc::ResultInvalidPriority());
|
||||||
|
@ -168,7 +168,7 @@ namespace ams::kern::svc {
|
||||||
R_UNLESS(affinity_mask != 0, svc::ResultInvalidCombination());
|
R_UNLESS(affinity_mask != 0, svc::ResultInvalidCombination());
|
||||||
|
|
||||||
/* Validate the core id. */
|
/* Validate the core id. */
|
||||||
if (IsValidCoreId(core_id)) {
|
if (IsValidVirtualCoreId(core_id)) {
|
||||||
R_UNLESS(((1ul << core_id) & affinity_mask) != 0, svc::ResultInvalidCombination());
|
R_UNLESS(((1ul << core_id) & affinity_mask) != 0, svc::ResultInvalidCombination());
|
||||||
} else {
|
} else {
|
||||||
R_UNLESS(core_id == ams::svc::IdealCoreNoUpdate || core_id == ams::svc::IdealCoreDontCare, svc::ResultInvalidCoreId());
|
R_UNLESS(core_id == ams::svc::IdealCoreNoUpdate || core_id == ams::svc::IdealCoreDontCare, svc::ResultInvalidCoreId());
|
||||||
|
|
Loading…
Reference in a new issue