mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-23 02:42:09 +00:00
kern: simplify global rng initialization
This commit is contained in:
parent
0f8b7be2d2
commit
8e4be9aef9
2 changed files with 30 additions and 14 deletions
|
@ -42,8 +42,8 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
/* Nintendo uses std::mt19937_t for randomness. */
|
/* Nintendo uses std::mt19937_t for randomness. */
|
||||||
/* To save space (and because mt19337_t isn't secure anyway), */
|
/* To save space (and because mt19337_t isn't secure anyway), */
|
||||||
/* We will use TinyMT. */
|
/* We will use TinyMT. */
|
||||||
bool g_initialized_random_generator;
|
constinit bool g_initialized_random_generator;
|
||||||
util::TinyMT g_random_generator;
|
constinit util::TinyMT g_random_generator;
|
||||||
constinit KSpinLock g_random_lock;
|
constinit KSpinLock g_random_lock;
|
||||||
|
|
||||||
ALWAYS_INLINE size_t GetRealMemorySizeForInit() {
|
ALWAYS_INLINE size_t GetRealMemorySizeForInit() {
|
||||||
|
@ -90,13 +90,10 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureRandomGeneratorInitialized() {
|
ALWAYS_INLINE u64 GenerateRandomU64FromSmc() {
|
||||||
if (AMS_UNLIKELY(!g_initialized_random_generator)) {
|
u64 value;
|
||||||
u64 seed;
|
smc::GenerateRandomBytes(std::addressof(value), sizeof(value));
|
||||||
smc::GenerateRandomBytes(&seed, sizeof(seed));
|
return value;
|
||||||
g_random_generator.Initialize(reinterpret_cast<u32*>(&seed), sizeof(seed) / sizeof(u32));
|
|
||||||
g_initialized_random_generator = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE u64 GenerateRandomU64FromGenerator() {
|
ALWAYS_INLINE u64 GenerateRandomU64FromGenerator() {
|
||||||
|
@ -439,6 +436,14 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
|
|
||||||
/* System Initialization. */
|
/* System Initialization. */
|
||||||
void KSystemControl::InitializePhase1() {
|
void KSystemControl::InitializePhase1() {
|
||||||
|
/* Initialize our random generator. */
|
||||||
|
{
|
||||||
|
u64 seed;
|
||||||
|
smc::GenerateRandomBytes(std::addressof(seed), sizeof(seed));
|
||||||
|
g_random_generator.Initialize(reinterpret_cast<u32*>(std::addressof(seed)), sizeof(seed) / sizeof(u32));
|
||||||
|
g_initialized_random_generator = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set IsDebugMode. */
|
/* Set IsDebugMode. */
|
||||||
{
|
{
|
||||||
KTargetSystem::SetIsDebugMode(GetConfigBool(smc::ConfigItem::IsDebugMode));
|
KTargetSystem::SetIsDebugMode(GetConfigBool(smc::ConfigItem::IsDebugMode));
|
||||||
|
@ -544,18 +549,23 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
KScopedInterruptDisable intr_disable;
|
KScopedInterruptDisable intr_disable;
|
||||||
KScopedSpinLock lk(g_random_lock);
|
KScopedSpinLock lk(g_random_lock);
|
||||||
|
|
||||||
EnsureRandomGeneratorInitialized();
|
|
||||||
|
|
||||||
|
if (AMS_LIKELY(g_initialized_random_generator)) {
|
||||||
return GenerateUniformRange(min, max, GenerateRandomU64FromGenerator);
|
return GenerateUniformRange(min, max, GenerateRandomU64FromGenerator);
|
||||||
|
} else {
|
||||||
|
return GenerateUniformRange(min, max, GenerateRandomU64FromSmc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 KSystemControl::GenerateRandomU64() {
|
u64 KSystemControl::GenerateRandomU64() {
|
||||||
KScopedInterruptDisable intr_disable;
|
KScopedInterruptDisable intr_disable;
|
||||||
KScopedSpinLock lk(g_random_lock);
|
KScopedSpinLock lk(g_random_lock);
|
||||||
|
|
||||||
EnsureRandomGeneratorInitialized();
|
if (AMS_LIKELY(g_initialized_random_generator)) {
|
||||||
|
|
||||||
return GenerateRandomU64FromGenerator();
|
return GenerateRandomU64FromGenerator();
|
||||||
|
} else {
|
||||||
|
return GenerateRandomU64FromSmc();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KSystemControl::SleepSystem() {
|
void KSystemControl::SleepSystem() {
|
||||||
|
|
|
@ -49,6 +49,9 @@ namespace ams::kern {
|
||||||
/* Initialize the carveout and the system resource limit. */
|
/* Initialize the carveout and the system resource limit. */
|
||||||
KSystemControl::InitializePhase1();
|
KSystemControl::InitializePhase1();
|
||||||
|
|
||||||
|
/* Synchronize all cores before proceeding, to ensure access to the global rng is consistent. */
|
||||||
|
cpu::SynchronizeAllCores();
|
||||||
|
|
||||||
/* Initialize the memory manager and the KPageBuffer slabheap. */
|
/* Initialize the memory manager and the KPageBuffer slabheap. */
|
||||||
{
|
{
|
||||||
const auto &management_region = KMemoryLayout::GetPoolManagementRegion();
|
const auto &management_region = KMemoryLayout::GetPoolManagementRegion();
|
||||||
|
@ -74,6 +77,9 @@ namespace ams::kern {
|
||||||
|
|
||||||
Kernel::InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize());
|
Kernel::InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* Synchronize all cores before proceeding, to ensure access to the global rng is consistent. */
|
||||||
|
cpu::SynchronizeAllCores();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the supervisor page table for each core. */
|
/* Initialize the supervisor page table for each core. */
|
||||||
|
|
Loading…
Reference in a new issue