kernel_ldr: finish implementing all core logic.

This commit is contained in:
Michael Scire 2019-12-17 00:37:55 -08:00 committed by SciresM
parent 623b5f4eb9
commit 8efdd04fcd
20 changed files with 854 additions and 81 deletions

View file

@ -39,6 +39,12 @@ namespace ams::kern {
return value;
}
inline u64 GenerateRandomU64() {
u64 value;
smc::GenerateRandomBytes(&value, sizeof(value));
return value;
}
inline smc::MemoryMode GetMemoryMode() {
return static_cast<smc::MemoryMode>((GetKernelConfiguration() >> 10) & 0x3);
}
@ -73,6 +79,24 @@ namespace ams::kern {
return (GetKernelConfiguration() >> 3) & 1;
}
/* Randomness. */
void KSystemControl::GenerateRandomBytes(void *dst, size_t size) {
MESOSPHERE_ABORT_UNLESS(size <= 0x38);
smc::GenerateRandomBytes(dst, size);
}
u64 KSystemControl::GenerateRandomRange(u64 min, u64 max) {
/* This is a biased random, but this is okay for now. */
/* TODO: unbiased random? */
const u64 range_size = ((max + 1) - min);
const u64 effective_max = (std::numeric_limits<u64>::max() / range_size) * range_size;
while (true) {
if (const u64 rnd = GenerateRandomU64(); rnd < effective_max) {
return rnd % effective_max;
}
}
}
void KSystemControl::StopSystem() {
/* Display a panic screen via exosphere. */
smc::Panic(0xF00);

View file

@ -80,6 +80,18 @@ namespace ams::kern::smc {
}
}
void GenerateRandomBytes(void *dst, size_t size) {
/* Call SmcGenerateRandomBytes() */
/* TODO: Lock this to ensure only one core calls at once. */
SecureMonitorArguments args = { FunctionId_GetConfig, size };
MESOSPHERE_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.x[0]));
CallPrivilegedSecureMonitorFunction(args);
MESOSPHERE_ABORT_UNLESS((static_cast<SmcResult>(args.x[0]) == SmcResult::Success));
/* Copy output. */
std::memcpy(dst, &args.x[1], size);
}
void NORETURN Panic(u32 color) {
SecureMonitorArguments args = { FunctionId_Panic, color };
CallPrivilegedSecureMonitorFunction(args);

View file

@ -65,6 +65,7 @@ namespace ams::kern::smc {
/* TODO: Rest of Secure Monitor API. */
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item);
void GenerateRandomBytes(void *dst, size_t size);
void NORETURN Panic(u32 color);
bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value);