exo2: minor fixes, now completes main and receives SMCs on hw

This commit is contained in:
Michael Scire
2020-05-14 13:06:15 -07:00
committed by SciresM
parent 27843314a4
commit 8c4c1db506
11 changed files with 134 additions and 47 deletions

View File

@@ -125,7 +125,7 @@ namespace ams::secmon::boot {
SetL3BlockEntry(l3, MemoryRegionVirtualTzramConfigurationData.GetAddress(), MemoryRegionPhysicalTzramConfigurationData.GetAddress(), MemoryRegionVirtualTzramConfigurationData.GetSize(), MappingAttributesEl3SecureRwData);
/* Map the page tables. */
SetL3BlockEntry(l3, util::AlignDown(MemoryRegionVirtualTzramL1PageTable.GetAddress(), PageSize), util::AlignDown(MemoryRegionPhysicalTzramL1PageTable.GetAddress(), PageSize), PageSize, MappingAttributesEl3SecureDevice);
SetL3BlockEntry(l3, util::AlignDown(MemoryRegionVirtualTzramL1PageTable.GetAddress(), PageSize), util::AlignDown(MemoryRegionPhysicalTzramL1PageTable.GetAddress(), PageSize), PageSize, MappingAttributesEl3SecureRwData);
SetL3BlockEntry(l3, MemoryRegionVirtualTzramL2L3PageTable.GetAddress(), MemoryRegionPhysicalTzramL2L3PageTable.GetAddress(), MemoryRegionVirtualTzramL2L3PageTable.GetSize(), MappingAttributesEl3SecureRwData);
}
}

View File

@@ -19,6 +19,26 @@
namespace ams::diag {
void AbortImpl() {
/* TODO: This is here for debugging. Remove this when exo2 is working. */
#if 1
{
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x00) = 0xDDDDDDDD;
u64 temp_reg;
__asm__ __volatile__("mov %0, lr" : "=r"(temp_reg) :: "memory");
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x10) = static_cast<u32>(temp_reg >> 0);
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x14) = static_cast<u32>(temp_reg >> 32);
__asm__ __volatile__("mov %0, sp" : "=r"(temp_reg) :: "memory");
for (int i = 0; i < 0x100; i += 4) {
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x20 + i) = *(volatile u32 *)(temp_reg + i);
}
*(volatile u32 *)(secmon::MemoryRegionVirtualDevicePmc.GetAddress() + 0x50) = 0x02;
*(volatile u32 *)(secmon::MemoryRegionVirtualDevicePmc.GetAddress() + 0x00) = 0x10;
}
#endif
secmon::SetError(pkg1::ErrorInfo_UnknownAbort);
secmon::ErrorReboot();
}
@@ -36,6 +56,42 @@ namespace ams::secmon {
}
NORETURN void ErrorReboot() {
/* TODO: This is here for debugging. Remove this when exo2 is working. */
#if 1
{
u64 temp_reg;
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x00) = 0x5A5A5A5A;
__asm__ __volatile__("mrs %0, esr_el3" : "=r"(temp_reg) :: "memory");
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x08) = static_cast<u32>(temp_reg >> 0);
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x0C) = static_cast<u32>(temp_reg >> 32);
__asm__ __volatile__("mrs %0, elr_el3" : "=r"(temp_reg) :: "memory");
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x18) = static_cast<u32>(temp_reg >> 0);
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x1C) = static_cast<u32>(temp_reg >> 32);
__asm__ __volatile__("mrs %0, far_el3" : "=r"(temp_reg) :: "memory");
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x18) = static_cast<u32>(temp_reg >> 0);
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x1C) = static_cast<u32>(temp_reg >> 32);
__asm__ __volatile__("mov %0, lr" : "=r"(temp_reg) :: "memory");
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x20) = static_cast<u32>(temp_reg >> 0);
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x24) = static_cast<u32>(temp_reg >> 32);
__asm__ __volatile__("mov %0, sp" : "=r"(temp_reg) :: "memory");
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x30) = static_cast<u32>(temp_reg >> 0);
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x34) = static_cast<u32>(temp_reg >> 32);
for (int i = 0; i < 0x100; i += 4) {
*(volatile u32 *)(secmon::MemoryRegionVirtualDebug.GetAddress() + 0x40 + i) = *(volatile u32 *)(temp_reg + i);
}
*(volatile u32 *)(secmon::MemoryRegionVirtualDevicePmc.GetAddress() + 0x50) = 0x02;
*(volatile u32 *)(secmon::MemoryRegionVirtualDevicePmc.GetAddress() + 0x00) = 0x10;
util::WaitMicroSeconds(1000);
}
#endif
/* Lockout the security engine. */
se::Lockout();

View File

@@ -21,6 +21,9 @@ namespace ams::secmon {
namespace {
constexpr inline const uintptr_t BootCodeAddress = MemoryRegionVirtualTzramBootCode.GetAddress();
constexpr inline const size_t BootCodeSize = MemoryRegionVirtualTzramBootCode.GetSize();
using namespace ams::mmu;
constexpr void UnmapBootCodeImpl(u64 *l1, u64 *l2, u64 *l3, uintptr_t boot_code, size_t boot_code_size) {
@@ -39,6 +42,20 @@ namespace ams::secmon {
InvalidateL1Entries(l1, MemoryRegionPhysical.GetAddress(), MemoryRegionPhysical.GetSize());
}
void ClearLow(uintptr_t address, size_t size) {
/* Clear the low part. */
util::ClearMemory(reinterpret_cast<void *>(address), size / 2);
}
void ClearHigh(uintptr_t address, size_t size) {
/* Clear the high part. */
util::ClearMemory(reinterpret_cast<void *>(address + size / 2), size / 2);
}
}
void ClearBootCodeHigh() {
ClearHigh(BootCodeAddress, BootCodeSize);
}
void UnmapBootCode() {
@@ -46,15 +63,11 @@ namespace ams::secmon {
u64 * const l1 = MemoryRegionVirtualTzramL1PageTable.GetPointer<u64>();
u64 * const l2_l3 = MemoryRegionVirtualTzramL2L3PageTable.GetPointer<u64>();
/* Get the boot code region. */
const uintptr_t boot_code = MemoryRegionVirtualTzramBootCode.GetAddress();
const size_t boot_code_size = MemoryRegionVirtualTzramBootCode.GetSize();
/* Clear the boot code. */
util::ClearMemory(reinterpret_cast<void *>(boot_code), boot_code_size);
/* Clear the low boot code region; high was already cleared by a previous call. */
ClearLow(BootCodeAddress, BootCodeSize);
/* Unmap. */
UnmapBootCodeImpl(l1, l2_l3, l2_l3, boot_code, boot_code_size);
UnmapBootCodeImpl(l1, l2_l3, l2_l3, BootCodeAddress, BootCodeSize);
/* Ensure the mappings are consistent. */
secmon::EnsureMappingConsistency();

View File

@@ -52,7 +52,7 @@ namespace ams::secmon {
constinit const se::StickyBits ExpectedSeStickyBits = {
.se_security = (1 << 0), /* SE_HARD_SETTING */
.tzram_security = 0,
.crypto_security_perkey = 0,
.crypto_security_perkey = (1 << pkg1::AesKeySlot_UserEnd) - 1,
.crypto_keytable_access = {
(1 << 6) | (1 << 5) | (0 << 4) | (1 << 3) | (0 << 2) | (1 << 1) | (0 << 0), /* 0: User keyslot. KEYUSE, UIVUPDATE, OIVUPDATE, KEYUPDATE enabled. UIVREAD, OIVREAD, KEYREAD disabled. */
(1 << 6) | (1 << 5) | (0 << 4) | (1 << 3) | (0 << 2) | (1 << 1) | (0 << 0), /* 1: User keyslot. KEYUSE, UIVUPDATE, OIVUPDATE, KEYUPDATE enabled. UIVREAD, OIVREAD, KEYREAD disabled. */
@@ -60,15 +60,15 @@ namespace ams::secmon {
(1 << 6) | (1 << 5) | (0 << 4) | (1 << 3) | (0 << 2) | (1 << 1) | (0 << 0), /* 3: User keyslot. KEYUSE, UIVUPDATE, OIVUPDATE, KEYUPDATE enabled. UIVREAD, OIVREAD, KEYREAD disabled. */
(1 << 6) | (1 << 5) | (0 << 4) | (1 << 3) | (0 << 2) | (1 << 1) | (0 << 0), /* 4: User keyslot. KEYUSE, UIVUPDATE, OIVUPDATE, KEYUPDATE enabled. UIVREAD, OIVREAD, KEYREAD disabled. */
(1 << 6) | (1 << 5) | (0 << 4) | (1 << 3) | (0 << 2) | (1 << 1) | (0 << 0), /* 5: User keyslot. KEYUSE, UIVUPDATE, OIVUPDATE, KEYUPDATE enabled. UIVREAD, OIVREAD, KEYREAD disabled. */
(0 << 6) | (1 << 5) | (0 << 4) | (1 << 3) | (0 << 2) | (1 << 1) | (0 << 0), /* 6: Unused keyslot. UIVUPDATE, OIVUPDATE, KEYUPDATE enabled. KEYUSE, UIVREAD, OIVREAD, KEYREAD disabled. */
(0 << 6) | (1 << 5) | (0 << 4) | (1 << 3) | (0 << 2) | (1 << 1) | (0 << 0), /* 7: Unused keyslot. UIVUPDATE, OIVUPDATE, KEYUPDATE enabled. KEYUSE, UIVREAD, OIVREAD, KEYREAD disabled. */
(0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (0 << 1) | (0 << 0), /* 6: Unused keyslot. KEYUSE, UIVUPDATE, UIVREAD, OIVUPDATE, OIVREAD, KEYUPDATE, KEYREAD disabled. */
(0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (0 << 1) | (0 << 0), /* 7: Unused keyslot. KEYUSE, UIVUPDATE, UIVREAD, OIVUPDATE, OIVREAD, KEYUPDATE, KEYREAD disabled. */
(0 << 6) | (1 << 5) | (0 << 4) | (1 << 3) | (0 << 2) | (1 << 1) | (0 << 0), /* 8: Temp keyslot. UIVUPDATE, OIVUPDATE, KEYUPDATE enabled. KEYUSE, UIVREAD, OIVREAD, KEYREAD disabled. */
(0 << 6) | (1 << 5) | (0 << 4) | (1 << 3) | (0 << 2) | (1 << 1) | (0 << 0), /* 9: SmcTemp keyslot. UIVUPDATE, OIVUPDATE, KEYUPDATE enabled. KEYUSE, UIVREAD, OIVREAD, KEYREAD disabled. */
(0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (0 << 1) | (0 << 0), /* 10: Wrap1 keyslot. KEYUSE, UIVUPDATE, UIVREAD, OIVUPDATE, OIVREAD, KEYUPDATE, KEYREAD disabled. */
(0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (0 << 1) | (0 << 0), /* 11: Wrap2 keyslot. KEYUSE, UIVUPDATE, UIVREAD, OIVUPDATE, OIVREAD, KEYUPDATE, KEYREAD disabled. */
(0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (0 << 1) | (0 << 0), /* 12: DMaster keyslot. KEYUSE, UIVUPDATE, UIVREAD, OIVUPDATE, OIVREAD, KEYUPDATE, KEYREAD disabled. */
(0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (0 << 1) | (0 << 0), /* 13: Master keyslot. KEYUSE, UIVUPDATE, UIVREAD, OIVUPDATE, OIVREAD, KEYUPDATE, KEYREAD disabled. */
(0 << 6) | (1 << 5) | (0 << 4) | (1 << 3) | (0 << 2) | (1 << 1) | (0 << 0), /* 14: Unused keyslot. UIVUPDATE, OIVUPDATE, KEYUPDATE enabled. KEYUSE, UIVREAD, OIVREAD, KEYREAD disabled. */
(0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (0 << 1) | (0 << 0), /* 14: Unused keyslot. KEYUSE, UIVUPDATE, UIVREAD, OIVUPDATE, OIVREAD, KEYUPDATE, KEYREAD disabled. */
(0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (0 << 1) | (0 << 0), /* 13: Device keyslot. KEYUSE, UIVUPDATE, UIVREAD, OIVUPDATE, OIVREAD, KEYUPDATE, KEYREAD disabled. */
},
.rsa_security_perkey = 0,

View File

@@ -24,7 +24,7 @@ _ZN3ams6secmon5StartEv:
mov sp, x20
/* Set SPSEL 0 stack pointer to a temporary location in volatile memory. */
msr spsel, #1
msr spsel, #0
ldr x20, =0x1F01C0800
mov sp, x20
@@ -34,17 +34,20 @@ _ZN3ams6secmon5StartEv:
/* Invoke main. */
bl _ZN3ams6secmon4MainEv
/* Clear boot code high. */
bl _ZN3ams6secmon17ClearBootCodeHighEv
/* Set the stack pointer to the core 3 exception stack address. */
ldr x20, =0x1F01F9000
mov sp, x20
/* Unmap the boot code region (and clear the low part). */
bl _ZN3ams6secmon13UnmapBootCodeEv
/* Initialize the random cache. */
/* NOTE: Nintendo does this much earlier, but we reuse volatile space. */
bl _ZN3ams6secmon3smc15FillRandomCacheEv
/* Unmap the boot code region. */
bl _ZN3ams6secmon13UnmapBootCodeEv
/* Jump to lower exception level. */
b _ZN3ams6secmon25JumpToLowerExceptionLevelEv
@@ -169,7 +172,6 @@ _ZN3ams6secmon25ReleaseCommonSmcStackLockEv:
/* Return. */
ret
ret
.section .text._ZN3ams6secmon26ReleaseCommonWarmbootStackEv, "ax", %progbits
.align 4

View File

@@ -228,6 +228,21 @@ namespace ams::secmon::smc {
/* Set the invocation result. */
args.r[0] = static_cast<u64>(InvokeSmcHandler(info, 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);
}
#endif
}
}