mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-18 16:32:05 +00:00
kern: update KSystemControl::InitializePhase1, dynamically scale 39-bit address space regions
This commit is contained in:
parent
afa4a50d99
commit
89f8bee3b6
5 changed files with 83 additions and 100 deletions
|
@ -40,12 +40,16 @@ namespace ams::kern {
|
||||||
static uintptr_t GetAddressSpaceStart(size_t width, Type type);
|
static uintptr_t GetAddressSpaceStart(size_t width, Type type);
|
||||||
static size_t GetAddressSpaceSize(size_t width, Type type);
|
static size_t GetAddressSpaceSize(size_t width, Type type);
|
||||||
|
|
||||||
|
static void SetAddressSpaceSize(size_t width, Type type, size_t size);
|
||||||
|
|
||||||
constexpr KAddressSpaceInfo(size_t bw, size_t a, size_t s, Type t) : m_bit_width(bw), m_address(a), m_size(s), m_type(t) { /* ... */ }
|
constexpr KAddressSpaceInfo(size_t bw, size_t a, size_t s, Type t) : m_bit_width(bw), m_address(a), m_size(s), m_type(t) { /* ... */ }
|
||||||
|
|
||||||
constexpr size_t GetWidth() const { return m_bit_width; }
|
constexpr size_t GetWidth() const { return m_bit_width; }
|
||||||
constexpr size_t GetAddress() const { return m_address; }
|
constexpr size_t GetAddress() const { return m_address; }
|
||||||
constexpr size_t GetSize() const { return m_size; }
|
constexpr size_t GetSize() const { return m_size; }
|
||||||
constexpr Type GetType() const { return m_type; }
|
constexpr Type GetType() const { return m_type; }
|
||||||
|
|
||||||
|
constexpr void SetSize(size_t size) { m_size = size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,11 @@ namespace ams::kern {
|
||||||
static void GenerateRandom(u64 *dst, size_t count);
|
static void GenerateRandom(u64 *dst, size_t count);
|
||||||
static u64 GenerateRandomRange(u64 min, u64 max);
|
static u64 GenerateRandomRange(u64 min, u64 max);
|
||||||
};
|
};
|
||||||
|
protected:
|
||||||
|
static NOINLINE void InitializePhase1Base(u64 seed);
|
||||||
public:
|
public:
|
||||||
/* Initialization. */
|
/* Initialization. */
|
||||||
static NOINLINE void InitializePhase1(bool skip_target_system = false);
|
static NOINLINE void InitializePhase1();
|
||||||
static NOINLINE void InitializePhase2();
|
static NOINLINE void InitializePhase2();
|
||||||
static NOINLINE u32 GetCreateProcessMemoryPool();
|
static NOINLINE u32 GetCreateProcessMemoryPool();
|
||||||
|
|
||||||
|
|
|
@ -398,40 +398,41 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
|
|
||||||
/* System Initialization. */
|
/* System Initialization. */
|
||||||
void KSystemControl::InitializePhase1() {
|
void KSystemControl::InitializePhase1() {
|
||||||
/* Initialize our random generator. */
|
/* Configure KTargetSystem. */
|
||||||
|
{
|
||||||
|
/* Set IsDebugMode. */
|
||||||
|
{
|
||||||
|
KTargetSystem::SetIsDebugMode(GetConfigBool(smc::ConfigItem::IsDebugMode));
|
||||||
|
|
||||||
|
/* If debug mode, we want to initialize uart logging. */
|
||||||
|
KTargetSystem::EnableDebugLogging(KTargetSystem::IsDebugMode());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Kernel Configuration. */
|
||||||
|
{
|
||||||
|
const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)};
|
||||||
|
|
||||||
|
KTargetSystem::EnableDebugMemoryFill(kernel_config.Get<smc::KernelConfiguration::DebugFillMemory>());
|
||||||
|
KTargetSystem::EnableUserExceptionHandlers(kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>());
|
||||||
|
KTargetSystem::EnableDynamicResourceLimits(!kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>());
|
||||||
|
KTargetSystem::EnableUserPmuAccess(kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>());
|
||||||
|
|
||||||
|
g_call_smc_on_panic = kernel_config.Get<smc::KernelConfiguration::UseSecureMonitorPanicCall>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Kernel Debugging. */
|
||||||
|
{
|
||||||
|
/* NOTE: This is used to restrict access to SvcKernelDebug/SvcChangeKernelTraceState. */
|
||||||
|
/* Mesosphere may wish to not require this, as we'd ideally keep ProgramVerification enabled for userland. */
|
||||||
|
KTargetSystem::EnableKernelDebugging(GetConfigBool(smc::ConfigItem::DisableProgramVerification));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize random and resource limit. */
|
||||||
{
|
{
|
||||||
u64 seed;
|
u64 seed;
|
||||||
smc::GenerateRandomBytes(std::addressof(seed), sizeof(seed));
|
smc::GenerateRandomBytes(std::addressof(seed), sizeof(seed));
|
||||||
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
|
KSystemControlBase::InitializePhase1Base(seed);
|
||||||
s_initialized_random_generator = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set IsDebugMode. */
|
|
||||||
{
|
|
||||||
KTargetSystem::SetIsDebugMode(GetConfigBool(smc::ConfigItem::IsDebugMode));
|
|
||||||
|
|
||||||
/* If debug mode, we want to initialize uart logging. */
|
|
||||||
KTargetSystem::EnableDebugLogging(KTargetSystem::IsDebugMode());
|
|
||||||
KDebugLog::Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set Kernel Configuration. */
|
|
||||||
{
|
|
||||||
const auto kernel_config = util::BitPack32{GetConfigU32(smc::ConfigItem::KernelConfiguration)};
|
|
||||||
|
|
||||||
KTargetSystem::EnableDebugMemoryFill(kernel_config.Get<smc::KernelConfiguration::DebugFillMemory>());
|
|
||||||
KTargetSystem::EnableUserExceptionHandlers(kernel_config.Get<smc::KernelConfiguration::EnableUserExceptionHandlers>());
|
|
||||||
KTargetSystem::EnableDynamicResourceLimits(!kernel_config.Get<smc::KernelConfiguration::DisableDynamicResourceLimits>());
|
|
||||||
KTargetSystem::EnableUserPmuAccess(kernel_config.Get<smc::KernelConfiguration::EnableUserPmuAccess>());
|
|
||||||
|
|
||||||
g_call_smc_on_panic = kernel_config.Get<smc::KernelConfiguration::UseSecureMonitorPanicCall>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set Kernel Debugging. */
|
|
||||||
{
|
|
||||||
/* NOTE: This is used to restrict access to SvcKernelDebug/SvcChangeKernelTraceState. */
|
|
||||||
/* Mesosphere may wish to not require this, as we'd ideally keep ProgramVerification enabled for userland. */
|
|
||||||
KTargetSystem::EnableKernelDebugging(GetConfigBool(smc::ConfigItem::DisableProgramVerification));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure the Kernel Carveout region. */
|
/* Configure the Kernel Carveout region. */
|
||||||
|
@ -441,9 +442,6 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
|
|
||||||
smc::ConfigureCarveout(0, carveout.GetAddress(), carveout.GetSize());
|
smc::ConfigureCarveout(0, carveout.GetAddress(), carveout.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the system resource limit (and potentially other things). */
|
|
||||||
KSystemControlBase::InitializePhase1(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KSystemControl::InitializePhase2() {
|
void KSystemControl::InitializePhase2() {
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace ams::kern {
|
||||||
|
|
||||||
constexpr uintptr_t Invalid = std::numeric_limits<uintptr_t>::max();
|
constexpr uintptr_t Invalid = std::numeric_limits<uintptr_t>::max();
|
||||||
|
|
||||||
constexpr KAddressSpaceInfo AddressSpaceInfos[] = {
|
constinit KAddressSpaceInfo AddressSpaceInfos[] = {
|
||||||
{ 32, ams::svc::AddressSmallMap32Start, ams::svc::AddressSmallMap32Size, KAddressSpaceInfo::Type_MapSmall, },
|
{ 32, ams::svc::AddressSmallMap32Start, ams::svc::AddressSmallMap32Size, KAddressSpaceInfo::Type_MapSmall, },
|
||||||
{ 32, ams::svc::AddressLargeMap32Start, ams::svc::AddressLargeMap32Size, KAddressSpaceInfo::Type_MapLarge, },
|
{ 32, ams::svc::AddressLargeMap32Start, ams::svc::AddressLargeMap32Size, KAddressSpaceInfo::Type_MapLarge, },
|
||||||
{ 32, Invalid, ams::svc::AddressMemoryRegionHeap32Size, KAddressSpaceInfo::Type_Heap, },
|
{ 32, Invalid, ams::svc::AddressMemoryRegionHeap32Size, KAddressSpaceInfo::Type_Heap, },
|
||||||
|
@ -37,67 +37,27 @@ namespace ams::kern {
|
||||||
{ 39, Invalid, ams::svc::AddressMemoryRegionStack39Size, KAddressSpaceInfo::Type_Stack, },
|
{ 39, Invalid, ams::svc::AddressMemoryRegionStack39Size, KAddressSpaceInfo::Type_Stack, },
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr bool IsAllowedIndexForAddress(size_t index) {
|
KAddressSpaceInfo &GetAddressSpaceInfo(size_t width, KAddressSpaceInfo::Type type) {
|
||||||
return index < util::size(AddressSpaceInfos) && AddressSpaceInfos[index].GetAddress() != Invalid;
|
for (auto &info : AddressSpaceInfos) {
|
||||||
}
|
if (info.GetWidth() == width && info.GetType() == type) {
|
||||||
|
return info;
|
||||||
constexpr size_t AddressSpaceIndices32Bit[KAddressSpaceInfo::Type_Count] = {
|
}
|
||||||
0, 1, 0, 2, 0, 3,
|
}
|
||||||
};
|
MESOSPHERE_PANIC("Could not find AddressSpaceInfo");
|
||||||
|
|
||||||
constexpr size_t AddressSpaceIndices36Bit[KAddressSpaceInfo::Type_Count] = {
|
|
||||||
4, 5, 4, 6, 4, 7,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr size_t AddressSpaceIndices39Bit[KAddressSpaceInfo::Type_Count] = {
|
|
||||||
9, 8, 8, 10, 12, 11,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr bool IsAllowed32BitType(KAddressSpaceInfo::Type type) {
|
|
||||||
return type < KAddressSpaceInfo::Type_Count && type != KAddressSpaceInfo::Type_Map39Bit && type != KAddressSpaceInfo::Type_Stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool IsAllowed36BitType(KAddressSpaceInfo::Type type) {
|
|
||||||
return type < KAddressSpaceInfo::Type_Count && type != KAddressSpaceInfo::Type_Map39Bit && type != KAddressSpaceInfo::Type_Stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr bool IsAllowed39BitType(KAddressSpaceInfo::Type type) {
|
|
||||||
return type < KAddressSpaceInfo::Type_Count && type != KAddressSpaceInfo::Type_MapLarge;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) {
|
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) {
|
||||||
switch (width) {
|
return GetAddressSpaceInfo(width, type).GetAddress();
|
||||||
case 32:
|
|
||||||
MESOSPHERE_ABORT_UNLESS(IsAllowed32BitType(type));
|
|
||||||
MESOSPHERE_ABORT_UNLESS(IsAllowedIndexForAddress(AddressSpaceIndices32Bit[type]));
|
|
||||||
return AddressSpaceInfos[AddressSpaceIndices32Bit[type]].GetAddress();
|
|
||||||
case 36:
|
|
||||||
MESOSPHERE_ABORT_UNLESS(IsAllowed36BitType(type));
|
|
||||||
MESOSPHERE_ABORT_UNLESS(IsAllowedIndexForAddress(AddressSpaceIndices36Bit[type]));
|
|
||||||
return AddressSpaceInfos[AddressSpaceIndices36Bit[type]].GetAddress();
|
|
||||||
case 39:
|
|
||||||
MESOSPHERE_ABORT_UNLESS(IsAllowed39BitType(type));
|
|
||||||
MESOSPHERE_ABORT_UNLESS(IsAllowedIndexForAddress(AddressSpaceIndices39Bit[type]));
|
|
||||||
return AddressSpaceInfos[AddressSpaceIndices39Bit[type]].GetAddress();
|
|
||||||
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) {
|
size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) {
|
||||||
switch (width) {
|
return GetAddressSpaceInfo(width, type).GetSize();
|
||||||
case 32:
|
}
|
||||||
MESOSPHERE_ABORT_UNLESS(IsAllowed32BitType(type));
|
|
||||||
return AddressSpaceInfos[AddressSpaceIndices32Bit[type]].GetSize();
|
void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) {
|
||||||
case 36:
|
GetAddressSpaceInfo(width, type).SetSize(size);
|
||||||
MESOSPHERE_ABORT_UNLESS(IsAllowed36BitType(type));
|
|
||||||
return AddressSpaceInfos[AddressSpaceIndices36Bit[type]].GetSize();
|
|
||||||
case 39:
|
|
||||||
MESOSPHERE_ABORT_UNLESS(IsAllowed39BitType(type));
|
|
||||||
return AddressSpaceInfos[AddressSpaceIndices39Bit[type]].GetSize();
|
|
||||||
MESOSPHERE_UNREACHABLE_DEFAULT_CASE();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,23 +100,15 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* System Initialization. */
|
/* System Initialization. */
|
||||||
void KSystemControlBase::InitializePhase1(bool skip_target_system) {
|
void KSystemControlBase::InitializePhase1() {
|
||||||
/* Initialize the rng, if we somehow haven't already. */
|
/* Configure KTargetSystem. */
|
||||||
if (AMS_UNLIKELY(!s_initialized_random_generator)) {
|
{
|
||||||
const u64 seed = KHardwareTimer::GetTick();
|
|
||||||
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
|
|
||||||
s_initialized_random_generator = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Configure KTargetSystem, if we haven't already by an implementation SystemControl. */
|
|
||||||
if (!skip_target_system) {
|
|
||||||
/* Set IsDebugMode. */
|
/* Set IsDebugMode. */
|
||||||
{
|
{
|
||||||
KTargetSystem::SetIsDebugMode(true);
|
KTargetSystem::SetIsDebugMode(true);
|
||||||
|
|
||||||
/* If debug mode, we want to initialize uart logging. */
|
/* If debug mode, we want to initialize uart logging. */
|
||||||
KTargetSystem::EnableDebugLogging(true);
|
KTargetSystem::EnableDebugLogging(true);
|
||||||
KDebugLog::Initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set Kernel Configuration. */
|
/* Set Kernel Configuration. */
|
||||||
|
@ -135,6 +127,20 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize random and resource limit. */
|
||||||
|
KSystemControlBase::InitializePhase1Base(KHardwareTimer::GetTick());
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSystemControlBase::InitializePhase1Base(u64 seed) {
|
||||||
|
/* Initialize the rng, if we somehow haven't already. */
|
||||||
|
if (AMS_UNLIKELY(!s_initialized_random_generator)) {
|
||||||
|
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
|
||||||
|
s_initialized_random_generator = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize debug logging. */
|
||||||
|
KDebugLog::Initialize();
|
||||||
|
|
||||||
/* System ResourceLimit initialization. */
|
/* System ResourceLimit initialization. */
|
||||||
{
|
{
|
||||||
/* Construct the resource limit object. */
|
/* Construct the resource limit object. */
|
||||||
|
@ -144,6 +150,19 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Set the initial limits. */
|
/* Set the initial limits. */
|
||||||
const auto [total_memory_size, kernel_memory_size] = KMemoryLayout::GetTotalAndKernelMemorySizes();
|
const auto [total_memory_size, kernel_memory_size] = KMemoryLayout::GetTotalAndKernelMemorySizes();
|
||||||
|
|
||||||
|
/* Update 39-bit address space infos. */
|
||||||
|
{
|
||||||
|
/* Heap should be equal to the total memory size, minimum 8 GB, maximum 32 GB. */
|
||||||
|
/* Alias should be equal to 8 * heap size, maximum 128 GB. */
|
||||||
|
const size_t heap_size = std::max(std::min(util::AlignUp(total_memory_size, 1_GB), 32_GB), 8_GB);
|
||||||
|
const size_t alias_size = std::min(heap_size * 8, 128_GB);
|
||||||
|
|
||||||
|
/* Set the address space sizes. */
|
||||||
|
KAddressSpaceInfo::SetAddressSpaceSize(39, KAddressSpaceInfo::Type_Heap, heap_size);
|
||||||
|
KAddressSpaceInfo::SetAddressSpaceSize(39, KAddressSpaceInfo::Type_Alias, alias_size);
|
||||||
|
}
|
||||||
|
|
||||||
const auto &slab_counts = init::GetSlabResourceCounts();
|
const auto &slab_counts = init::GetSlabResourceCounts();
|
||||||
MESOSPHERE_R_ABORT_UNLESS(sys_res_limit.SetLimitValue(ams::svc::LimitableResource_PhysicalMemoryMax, total_memory_size));
|
MESOSPHERE_R_ABORT_UNLESS(sys_res_limit.SetLimitValue(ams::svc::LimitableResource_PhysicalMemoryMax, total_memory_size));
|
||||||
MESOSPHERE_R_ABORT_UNLESS(sys_res_limit.SetLimitValue(ams::svc::LimitableResource_ThreadCountMax, slab_counts.num_KThread));
|
MESOSPHERE_R_ABORT_UNLESS(sys_res_limit.SetLimitValue(ams::svc::LimitableResource_ThreadCountMax, slab_counts.num_KThread));
|
||||||
|
|
Loading…
Reference in a new issue