From 13ee5bab6a711ebd280647e6b71e9657cb9257a9 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 14 May 2020 13:06:15 -0700 Subject: [PATCH] exo2: minor fixes, now completes main and receives SMCs on hw --- .../exosphere/mmu/mmu_api.arch.arm64.hpp | 37 +++++++++++-------- ...ecmon_configuration_context.arch.arm64.hpp | 10 ++--- libexosphere/source/se/se_execute.cpp | 4 +- libexosphere/source/se/se_management.cpp | 6 --- libexosphere/source/se/se_suspend.cpp | 4 +- 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/libexosphere/include/exosphere/mmu/mmu_api.arch.arm64.hpp b/libexosphere/include/exosphere/mmu/mmu_api.arch.arm64.hpp index ada818af..07fea9c4 100644 --- a/libexosphere/include/exosphere/mmu/mmu_api.arch.arm64.hpp +++ b/libexosphere/include/exosphere/mmu/mmu_api.arch.arm64.hpp @@ -201,22 +201,29 @@ namespace ams::mmu::arch::arm64 { return ((address >> L3EntryShift) & TableEntryIndexMask); } - constexpr ALWAYS_INLINE void SetTableImpl(u64 *table, u64 index, u64 value) { - /* Ensure (for constexpr validation purposes) that the entry we set is clear. */ - if (table[index]) { - __builtin_unreachable(); - } - - /* Set the value. */ + constexpr ALWAYS_INLINE void SetTableEntryImpl(volatile u64 *table, u64 index, u64 value) { + /* Write the value. */ table[index] = value; } + constexpr ALWAYS_INLINE void SetTableEntry(u64 *table, u64 index, u64 value) { + /* Ensure (for constexpr validation purposes) that the entry we set is clear. */ + if (std::is_constant_evaluated()) { + if (table[index]) { + __builtin_unreachable(); + } + } + + /* Set the value. */ + SetTableEntryImpl(table, index, value); + } + constexpr void SetL1TableEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, PageTableTableAttribute attr) { - SetTableImpl(table, GetL1EntryIndex(virt_addr), MakeTableEntry(phys_addr & TableEntryMask, attr)); + SetTableEntry(table, GetL1EntryIndex(virt_addr), MakeTableEntry(phys_addr & TableEntryMask, attr)); } constexpr void SetL2TableEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, PageTableTableAttribute attr) { - SetTableImpl(table, GetL2EntryIndex(virt_addr), MakeTableEntry(phys_addr & TableEntryMask, attr)); + SetTableEntry(table, GetL2EntryIndex(virt_addr), MakeTableEntry(phys_addr & TableEntryMask, attr)); } constexpr void SetL1BlockEntry(u64 *table, uintptr_t virt_addr, uintptr_t phys_addr, size_t size, PageTableMappingAttribute attr) { @@ -224,7 +231,7 @@ namespace ams::mmu::arch::arm64 { const u64 count = (size >> L1EntryShift); for (u64 i = 0; i < count; ++i) { - SetTableImpl(table, start + i, MakeL1BlockEntry((phys_addr & L1EntryMask) + (i << L1EntryShift), attr)); + SetTableEntry(table, start + i, MakeL1BlockEntry((phys_addr & L1EntryMask) + (i << L1EntryShift), attr)); } } @@ -233,7 +240,7 @@ namespace ams::mmu::arch::arm64 { const u64 count = (size >> L2EntryShift); for (u64 i = 0; i < count; ++i) { - SetTableImpl(table, start + i, MakeL2BlockEntry((phys_addr & L2EntryMask) + (i << L2EntryShift), attr)); + SetTableEntry(table, start + i, MakeL2BlockEntry((phys_addr & L2EntryMask) + (i << L2EntryShift), attr)); } } @@ -242,11 +249,11 @@ namespace ams::mmu::arch::arm64 { const u64 count = (size >> L3EntryShift); for (u64 i = 0; i < count; ++i) { - SetTableImpl(table, start + i, MakeL3BlockEntry((phys_addr & L3EntryMask) + (i << L3EntryShift), attr)); + SetTableEntry(table, start + i, MakeL3BlockEntry((phys_addr & L3EntryMask) + (i << L3EntryShift), attr)); } } - constexpr void InvalidateL1Entries(u64 *table, uintptr_t virt_addr, size_t size) { + constexpr void InvalidateL1Entries(volatile u64 *table, uintptr_t virt_addr, size_t size) { const u64 start = GetL1EntryIndex(virt_addr); const u64 count = (size >> L1EntryShift); const u64 end = start + count; @@ -256,7 +263,7 @@ namespace ams::mmu::arch::arm64 { } } - constexpr void InvalidateL2Entries(u64 *table, uintptr_t virt_addr, size_t size) { + constexpr void InvalidateL2Entries(volatile u64 *table, uintptr_t virt_addr, size_t size) { const u64 start = GetL2EntryIndex(virt_addr); const u64 count = (size >> L2EntryShift); const u64 end = start + count; @@ -266,7 +273,7 @@ namespace ams::mmu::arch::arm64 { } } - constexpr void InvalidateL3Entries(u64 *table, uintptr_t virt_addr, size_t size) { + constexpr void InvalidateL3Entries(volatile u64 *table, uintptr_t virt_addr, size_t size) { const u64 start = GetL3EntryIndex(virt_addr); const u64 count = (size >> L3EntryShift); const u64 end = start + count; diff --git a/libexosphere/include/exosphere/secmon/secmon_configuration_context.arch.arm64.hpp b/libexosphere/include/exosphere/secmon/secmon_configuration_context.arch.arm64.hpp index bf851565..5b2c5bdc 100644 --- a/libexosphere/include/exosphere/secmon/secmon_configuration_context.arch.arm64.hpp +++ b/libexosphere/include/exosphere/secmon/secmon_configuration_context.arch.arm64.hpp @@ -30,17 +30,17 @@ namespace ams::secmon { EmummcConfiguration emummc_cfg; u8 _raw_emummc_config[0x120]; }; - union { - u8 _misc_data[0x400 - sizeof(_raw_exosphere_config) - sizeof(_raw_emummc_config)]; - }; u8 sealed_device_keys[pkg1::KeyGeneration_Max][se::AesBlockSize]; u8 sealed_master_keys[pkg1::KeyGeneration_Max][se::AesBlockSize]; pkg1::BootConfig boot_config; u8 rsa_private_exponents[4][se::RsaSize]; + union { + u8 _misc_data[0xFC0 - sizeof(_raw_exosphere_config) - sizeof(_raw_emummc_config) - sizeof(sealed_device_keys) - sizeof(sealed_master_keys) - sizeof(boot_config) - sizeof(rsa_private_exponents)]; + }; + /* u8 l1_page_table[0x40]; */ }; - static_assert(sizeof(ConfigurationContext) == 0x1000); + static_assert(sizeof(ConfigurationContext) == 0xFC0); static_assert(util::is_pod::value); - static_assert(offsetof(ConfigurationContext, sealed_device_keys) == 0x400); namespace impl { diff --git a/libexosphere/source/se/se_execute.cpp b/libexosphere/source/se/se_execute.cpp index dbe3cbcc..35b18fcd 100644 --- a/libexosphere/source/se/se_execute.cpp +++ b/libexosphere/source/se/se_execute.cpp @@ -101,14 +101,14 @@ namespace ams::se { void ExecuteOperationSingleBlock(volatile SecurityEngineRegisters *SE, void *dst, size_t dst_size, const void *src, size_t src_size) { /* Validate sizes. */ AMS_ABORT_UNLESS(dst_size <= AesBlockSize); - AMS_ABORT_UNLESS(src_size == AesBlockSize); + AMS_ABORT_UNLESS(src_size <= AesBlockSize); /* Set the block count to 1. */ reg::Write(SE->SE_CRYPTO_LAST_BLOCK, 0); /* Create an aligned buffer. */ util::AlignedBuffer aligned; - std::memcpy(aligned, src, AesBlockSize); + std::memcpy(aligned, src, src_size); hw::FlushDataCache(aligned, AesBlockSize); hw::DataSynchronizationBarrierInnerShareable(); diff --git a/libexosphere/source/se/se_management.cpp b/libexosphere/source/se/se_management.cpp index de845c2f..8c145fd5 100644 --- a/libexosphere/source/se/se_management.cpp +++ b/libexosphere/source/se/se_management.cpp @@ -62,12 +62,6 @@ namespace ams::se { void SetPerKeySecure() { auto *SE = GetRegisters(); - /* Clear AES PerKey security. */ - SE->SE_CRYPTO_SECURITY_PERKEY = 0; - - /* Clear RSA PerKey security. */ - SE->SE_RSA_SECURITY_PERKEY = 0; - /* Update PERKEY_SETTING to secure. */ reg::ReadWrite(SE->SE_SE_SECURITY, SE_REG_BITS_ENUM(SECURITY_PERKEY_SETTING, SECURE)); } diff --git a/libexosphere/source/se/se_suspend.cpp b/libexosphere/source/se/se_suspend.cpp index 03473deb..ca5134a3 100644 --- a/libexosphere/source/se/se_suspend.cpp +++ b/libexosphere/source/se/se_suspend.cpp @@ -44,8 +44,8 @@ namespace ams::se { if (!TestRegister(SE->SE_CRYPTO_KEYTABLE_ACCESS[i], bits.crypto_keytable_access[i])) { return false; } } - /* Test RSA_SCEURITY_PERKEY */ - if (!TestRegister(SE->SE_CRYPTO_SECURITY_PERKEY, bits.rsa_security_perkey)) { return false; } + /* Test RSA_SECURITY_PERKEY */ + if (!TestRegister(SE->SE_RSA_SECURITY_PERKEY, bits.rsa_security_perkey)) { return false; } /* Check RSA_KEYTABLE_ACCESS. */ for (int i = 0; i < RsaKeySlotCount; ++i) {