mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-14 00:56:35 +00:00
exo2: resolve remaining erista TODOs, clean up debugging code
This commit is contained in:
parent
23d3f786e3
commit
0698338312
5 changed files with 62 additions and 90 deletions
|
@ -60,7 +60,12 @@ namespace ams::secmon::boot {
|
||||||
reg::ReadWrite(pmc + APBDEV_PMC_SECURE_SCRATCH21, REG_BITS_VALUE(4, 1, 1));
|
reg::ReadWrite(pmc + APBDEV_PMC_SECURE_SCRATCH21, REG_BITS_VALUE(4, 1, 1));
|
||||||
|
|
||||||
/* Write the warmboot key. */
|
/* Write the warmboot key. */
|
||||||
/* TODO */
|
/* TODO: This is necessary for mariko. We should decide how to handle this. */
|
||||||
|
/* In particular, mariko will need to support loading older-than-expected warmboot firmware. */
|
||||||
|
/* We could hash the warmboot firmware and use a lookup table, or require bootloader to provide */
|
||||||
|
/* The warmboot key as a parameter. The latter is a better solution, but it would be nice to take */
|
||||||
|
/* care of it here. Perhaps we should read the number of anti-downgrade fuses burnt, and translate that */
|
||||||
|
/* to the warmboot key? To be decided during the process of implementing ams-on-mariko support. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function derives the master kek and device keys using the tsec root key. */
|
/* This function derives the master kek and device keys using the tsec root key. */
|
||||||
|
|
|
@ -16,12 +16,17 @@
|
||||||
#include <exosphere.hpp>
|
#include <exosphere.hpp>
|
||||||
#include "secmon_error.hpp"
|
#include "secmon_error.hpp"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr bool SaveSystemStateForDebug = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
namespace ams::diag {
|
namespace ams::diag {
|
||||||
|
|
||||||
void AbortImpl() {
|
namespace {
|
||||||
/* TODO: This is here for debugging. Remove this when exo2 is working. */
|
|
||||||
#if 1
|
ALWAYS_INLINE void SaveSystemStateForDebugAbort() {
|
||||||
{
|
|
||||||
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x00) = 0xDDDDDDDD;
|
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x00) = 0xDDDDDDDD;
|
||||||
|
|
||||||
u64 temp_reg;
|
u64 temp_reg;
|
||||||
|
@ -39,7 +44,14 @@ namespace ams::diag {
|
||||||
|
|
||||||
util::WaitMicroSeconds(1000);
|
util::WaitMicroSeconds(1000);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbortImpl() {
|
||||||
|
/* Perform any necessary (typically none) debugging. */
|
||||||
|
if constexpr (SaveSystemStateForDebug) {
|
||||||
|
SaveSystemStateForDebugAbort();
|
||||||
|
}
|
||||||
|
|
||||||
secmon::SetError(pkg1::ErrorInfo_UnknownAbort);
|
secmon::SetError(pkg1::ErrorInfo_UnknownAbort);
|
||||||
secmon::ErrorReboot();
|
secmon::ErrorReboot();
|
||||||
|
@ -49,18 +61,11 @@ namespace ams::diag {
|
||||||
|
|
||||||
namespace ams::secmon {
|
namespace ams::secmon {
|
||||||
|
|
||||||
void SetError(pkg1::ErrorInfo info) {
|
namespace {
|
||||||
const uintptr_t address = secmon::MemoryRegionVirtualDevicePmc.GetAddress() + PKG1_SECURE_MONITOR_PMC_ERROR_SCRATCH;
|
|
||||||
|
|
||||||
if (reg::Read(address) == pkg1::ErrorInfo_None) {
|
constexpr inline uintptr_t PMC = MemoryRegionVirtualDevicePmc.GetAddress();
|
||||||
reg::Write(address, info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NORETURN void ErrorReboot() {
|
ALWAYS_INLINE void SaveSystemStateForDebugErrorReboot() {
|
||||||
/* TODO: This is here for debugging. Remove this when exo2 is working. */
|
|
||||||
#if 1
|
|
||||||
{
|
|
||||||
u64 temp_reg;
|
u64 temp_reg;
|
||||||
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x00) = 0x5A5A5A5A;
|
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x00) = 0x5A5A5A5A;
|
||||||
|
|
||||||
|
@ -92,14 +97,31 @@ namespace ams::secmon {
|
||||||
|
|
||||||
util::WaitMicroSeconds(1000);
|
util::WaitMicroSeconds(1000);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetError(pkg1::ErrorInfo info) {
|
||||||
|
const uintptr_t address = secmon::MemoryRegionVirtualDevicePmc.GetAddress() + PKG1_SECURE_MONITOR_PMC_ERROR_SCRATCH;
|
||||||
|
|
||||||
|
if (reg::Read(address) == pkg1::ErrorInfo_None) {
|
||||||
|
reg::Write(address, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NORETURN void ErrorReboot() {
|
||||||
|
/* Perform any necessary (typically none) debugging. */
|
||||||
|
if constexpr (SaveSystemStateForDebug) {
|
||||||
|
SaveSystemStateForDebugErrorReboot();
|
||||||
|
}
|
||||||
|
|
||||||
/* Lockout the security engine. */
|
/* Lockout the security engine. */
|
||||||
se::Lockout();
|
se::Lockout();
|
||||||
|
|
||||||
/* TODO: Lockout fuses. */
|
/* Lockout fuses. */
|
||||||
|
fuse::Lockout();
|
||||||
|
|
||||||
/* TODO: Disable SE Crypto Operations. */
|
/* Disable crypto operations after reboot. */
|
||||||
|
reg::Write(PMC + APBDEV_PMC_CRYPTO_OP, 0);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
wdt::Reboot();
|
wdt::Reboot();
|
||||||
|
|
|
@ -20,8 +20,21 @@
|
||||||
namespace ams::secmon::smc {
|
namespace ams::secmon::smc {
|
||||||
|
|
||||||
SmcResult SmcShowError(SmcArguments &args) {
|
SmcResult SmcShowError(SmcArguments &args) {
|
||||||
/* TODO */
|
/* Decode arguments. */
|
||||||
return SmcResult::NotImplemented;
|
const u32 r = ((args.r[1] >> 8) & 0xF);
|
||||||
|
const u32 g = ((args.r[1] >> 4) & 0xF);
|
||||||
|
const u32 b = ((args.r[1] >> 0) & 0xF);
|
||||||
|
|
||||||
|
const u32 rgb = (b << 8) | (g << 4) | (r << 0);
|
||||||
|
|
||||||
|
/* Set the error info. */
|
||||||
|
SetError(pkg1::MakeKernelPanicResetInfo(rgb));
|
||||||
|
|
||||||
|
/* Reboot. */
|
||||||
|
ErrorReboot();
|
||||||
|
|
||||||
|
/* This point will never be reached. */
|
||||||
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,40 +239,6 @@ namespace ams::secmon::smc {
|
||||||
return info.handler(args);
|
return info.handler(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
constinit std::atomic<int> g_logged = 0;
|
|
||||||
|
|
||||||
constexpr int LogMin = 0x1000000;
|
|
||||||
constexpr int LogMax = 0x1000000;
|
|
||||||
|
|
||||||
constexpr size_t LogBufSize = 0x5000;
|
|
||||||
|
|
||||||
void DebugLog(SmcArguments &args) {
|
|
||||||
const int current = g_logged.fetch_add(1);
|
|
||||||
|
|
||||||
if (current == 0) {
|
|
||||||
std::memset(MemoryRegionVirtualDebug.GetPointer<void>(), 0xCC, LogBufSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current < LogMin) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int ind = current - LogMin;
|
|
||||||
const int ofs = (ind * sizeof(args)) % LogBufSize;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(args) / sizeof(u32); ++i) {
|
|
||||||
((volatile u32 *)(MemoryRegionVirtualDebug.GetAddress() + ofs))[i] = reinterpret_cast<u32 *>(std::addressof(args))[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current >= LogMax) {
|
|
||||||
*(volatile u32 *)(MemoryRegionVirtualDevicePmc.GetAddress() + 0x50) = 0x02;
|
|
||||||
*(volatile u32 *)(MemoryRegionVirtualDevicePmc.GetAddress() + 0x00) = 0x10;
|
|
||||||
|
|
||||||
util::WaitMicroSeconds(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSmcHandlersForTargetFirmware() {
|
void ConfigureSmcHandlersForTargetFirmware() {
|
||||||
|
@ -288,45 +254,11 @@ namespace ams::secmon::smc {
|
||||||
/* Get the table. */
|
/* Get the table. */
|
||||||
const auto &table = GetHandlerTable(static_cast<HandlerType>(type), args.r[0]);
|
const auto &table = GetHandlerTable(static_cast<HandlerType>(type), args.r[0]);
|
||||||
|
|
||||||
if (std::addressof(table) == std::addressof(g_handler_tables[HandlerType_User])) {
|
|
||||||
DebugLog(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the handler info. */
|
/* Get the handler info. */
|
||||||
const auto &info = GetHandlerInfo(table, args.r[0]);
|
const auto &info = GetHandlerInfo(table, args.r[0]);
|
||||||
|
|
||||||
/* Set the invocation result. */
|
/* Set the invocation result. */
|
||||||
args.r[0] = static_cast<u64>(InvokeSmcHandler(info, args));
|
args.r[0] = static_cast<u64>(InvokeSmcHandler(info, args));
|
||||||
|
|
||||||
if (std::addressof(table) == std::addressof(g_handler_tables[HandlerType_User])) {
|
|
||||||
DebugLog(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: For debugging. Remove this when exo2 is complete. */
|
|
||||||
#if 1
|
|
||||||
if (args.r[0] == static_cast<u64>(SmcResult::NotImplemented)) {
|
|
||||||
*(volatile u32 *)(MemoryRegionVirtualDebug.GetAddress()) = 0xBBBBBBBB;
|
|
||||||
*(volatile u32 *)(MemoryRegionVirtualDebug.GetAddress() + 0x10) = static_cast<u32>(info.function_id);
|
|
||||||
for (size_t i = 0; i < sizeof(args) / sizeof(u32); ++i) {
|
|
||||||
((volatile u32 *)(MemoryRegionVirtualDebug.GetAddress() + 0x20))[i] = reinterpret_cast<u32 *>(std::addressof(args))[i];
|
|
||||||
}
|
|
||||||
*(volatile u32 *)(MemoryRegionVirtualDevicePmc.GetAddress() + 0x50) = 0x02;
|
|
||||||
*(volatile u32 *)(MemoryRegionVirtualDevicePmc.GetAddress() + 0x00) = 0x10;
|
|
||||||
|
|
||||||
util::WaitMicroSeconds(1000);
|
|
||||||
}
|
|
||||||
if (args.r[0] != static_cast<u64>(SmcResult::Success) && info.function_id != 0xC3000007 /* generate aes key fails during SetupKekAccessKeys */) {
|
|
||||||
*(volatile u32 *)(MemoryRegionVirtualDebug.GetAddress()) = 0xCCCCCCCC;
|
|
||||||
*(volatile u32 *)(MemoryRegionVirtualDebug.GetAddress() + 0x10) = static_cast<u32>(info.function_id);
|
|
||||||
for (size_t i = 0; i < sizeof(args) / sizeof(u32); ++i) {
|
|
||||||
((volatile u32 *)(MemoryRegionVirtualDebug.GetAddress() + 0x20))[i] = reinterpret_cast<u32 *>(std::addressof(args))[i];
|
|
||||||
}
|
|
||||||
*(volatile u32 *)(MemoryRegionVirtualDevicePmc.GetAddress() + 0x50) = 0x02;
|
|
||||||
*(volatile u32 *)(MemoryRegionVirtualDevicePmc.GetAddress() + 0x00) = 0x10;
|
|
||||||
|
|
||||||
util::WaitMicroSeconds(1000);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,7 +325,7 @@ namespace ams::secmon::smc {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveSecureContextForMariko() {
|
void SaveSecureContextForMariko() {
|
||||||
/* TODO */
|
/* TODO: Implement this when adding ams-on-mariko support. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveSecureContext() {
|
void SaveSecureContext() {
|
||||||
|
|
Loading…
Reference in a new issue