mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-12 16:16:35 +00:00
kern: update KSystemControl::InitializePhase1, dynamically scale 39-bit address space regions
This commit is contained in:
parent
6e2dd791b2
commit
db510f96c3
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 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 size_t GetWidth() const { return m_bit_width; }
|
||||
constexpr size_t GetAddress() const { return m_address; }
|
||||
constexpr size_t GetSize() const { return m_size; }
|
||||
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 u64 GenerateRandomRange(u64 min, u64 max);
|
||||
};
|
||||
protected:
|
||||
static NOINLINE void InitializePhase1Base(u64 seed);
|
||||
public:
|
||||
/* Initialization. */
|
||||
static NOINLINE void InitializePhase1(bool skip_target_system = false);
|
||||
static NOINLINE void InitializePhase1();
|
||||
static NOINLINE void InitializePhase2();
|
||||
static NOINLINE u32 GetCreateProcessMemoryPool();
|
||||
|
||||
|
|
|
@ -398,40 +398,41 @@ namespace ams::kern::board::nintendo::nx {
|
|||
|
||||
/* System Initialization. */
|
||||
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;
|
||||
smc::GenerateRandomBytes(std::addressof(seed), sizeof(seed));
|
||||
s_random_generator.Initialize(reinterpret_cast<const u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
|
||||
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));
|
||||
KSystemControlBase::InitializePhase1Base(seed);
|
||||
}
|
||||
|
||||
/* Configure the Kernel Carveout region. */
|
||||
|
@ -441,9 +442,6 @@ namespace ams::kern::board::nintendo::nx {
|
|||
|
||||
smc::ConfigureCarveout(0, carveout.GetAddress(), carveout.GetSize());
|
||||
}
|
||||
|
||||
/* Initialize the system resource limit (and potentially other things). */
|
||||
KSystemControlBase::InitializePhase1(true);
|
||||
}
|
||||
|
||||
void KSystemControl::InitializePhase2() {
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace ams::kern {
|
|||
|
||||
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::AddressLargeMap32Start, ams::svc::AddressLargeMap32Size, KAddressSpaceInfo::Type_MapLarge, },
|
||||
{ 32, Invalid, ams::svc::AddressMemoryRegionHeap32Size, KAddressSpaceInfo::Type_Heap, },
|
||||
|
@ -37,67 +37,27 @@ namespace ams::kern {
|
|||
{ 39, Invalid, ams::svc::AddressMemoryRegionStack39Size, KAddressSpaceInfo::Type_Stack, },
|
||||
};
|
||||
|
||||
constexpr bool IsAllowedIndexForAddress(size_t index) {
|
||||
return index < util::size(AddressSpaceInfos) && AddressSpaceInfos[index].GetAddress() != Invalid;
|
||||
}
|
||||
|
||||
constexpr size_t AddressSpaceIndices32Bit[KAddressSpaceInfo::Type_Count] = {
|
||||
0, 1, 0, 2, 0, 3,
|
||||
};
|
||||
|
||||
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;
|
||||
KAddressSpaceInfo &GetAddressSpaceInfo(size_t width, KAddressSpaceInfo::Type type) {
|
||||
for (auto &info : AddressSpaceInfos) {
|
||||
if (info.GetWidth() == width && info.GetType() == type) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
MESOSPHERE_PANIC("Could not find AddressSpaceInfo");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uintptr_t KAddressSpaceInfo::GetAddressSpaceStart(size_t width, KAddressSpaceInfo::Type type) {
|
||||
switch (width) {
|
||||
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();
|
||||
}
|
||||
return GetAddressSpaceInfo(width, type).GetAddress();
|
||||
}
|
||||
|
||||
size_t KAddressSpaceInfo::GetAddressSpaceSize(size_t width, KAddressSpaceInfo::Type type) {
|
||||
switch (width) {
|
||||
case 32:
|
||||
MESOSPHERE_ABORT_UNLESS(IsAllowed32BitType(type));
|
||||
return AddressSpaceInfos[AddressSpaceIndices32Bit[type]].GetSize();
|
||||
case 36:
|
||||
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();
|
||||
}
|
||||
return GetAddressSpaceInfo(width, type).GetSize();
|
||||
}
|
||||
|
||||
void KAddressSpaceInfo::SetAddressSpaceSize(size_t width, Type type, size_t size) {
|
||||
GetAddressSpaceInfo(width, type).SetSize(size);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -100,23 +100,15 @@ namespace ams::kern {
|
|||
}
|
||||
|
||||
/* System Initialization. */
|
||||
void KSystemControlBase::InitializePhase1(bool skip_target_system) {
|
||||
/* Initialize the rng, if we somehow haven't already. */
|
||||
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) {
|
||||
void KSystemControlBase::InitializePhase1() {
|
||||
/* Configure KTargetSystem. */
|
||||
{
|
||||
/* Set IsDebugMode. */
|
||||
{
|
||||
KTargetSystem::SetIsDebugMode(true);
|
||||
|
||||
/* If debug mode, we want to initialize uart logging. */
|
||||
KTargetSystem::EnableDebugLogging(true);
|
||||
KDebugLog::Initialize();
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
{
|
||||
/* Construct the resource limit object. */
|
||||
|
@ -144,6 +150,19 @@ namespace ams::kern {
|
|||
|
||||
/* Set the initial limits. */
|
||||
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();
|
||||
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));
|
||||
|
|
Loading…
Reference in a new issue