From cb7c6a5d8ae2029812ab34027716d34dce21cd15 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 15 Nov 2020 08:35:57 -0800 Subject: [PATCH] exo: load mariko-only program during boot --- exosphere/program/source/boot/secmon_boot.hpp | 1 + .../program/source/boot/secmon_boot_setup.cpp | 32 +++++++++++++++++++ exosphere/program/source/boot/secmon_main.cpp | 3 ++ .../source/boot/secmon_make_page_table.cpp | 3 ++ .../exosphere/secmon/secmon_memory_layout.hpp | 3 ++ 5 files changed, 42 insertions(+) diff --git a/exosphere/program/source/boot/secmon_boot.hpp b/exosphere/program/source/boot/secmon_boot.hpp index 469aa8884..4933dee3a 100644 --- a/exosphere/program/source/boot/secmon_boot.hpp +++ b/exosphere/program/source/boot/secmon_boot.hpp @@ -21,6 +21,7 @@ namespace ams::secmon::boot { void MakePageTable(); void UnmapPhysicalIdentityMapping(); void UnmapDram(); + void LoadMarikoProgram(); void InitializeColdBoot(); diff --git a/exosphere/program/source/boot/secmon_boot_setup.cpp b/exosphere/program/source/boot/secmon_boot_setup.cpp index a725b7846..13b8c0c64 100644 --- a/exosphere/program/source/boot/secmon_boot_setup.cpp +++ b/exosphere/program/source/boot/secmon_boot_setup.cpp @@ -332,6 +332,12 @@ namespace ams::secmon::boot { InvalidateL1Entries(l1, MemoryRegionDram.GetAddress(), MemoryRegionDram.GetSize()); } + constexpr void UnmapMarikoProgramImpl(u64 *l1, u64 *l2, u64 *l3) { + /* Unmap the L1 entry corresponding to to the Dram entries. */ + AMS_UNUSED(l1, l2); + InvalidateL3Entries(l3, MemoryRegionVirtualTzramMarikoProgram.GetAddress(), MemoryRegionVirtualTzramMarikoProgram.GetSize()); + } + } void InitializeColdBoot() { @@ -387,4 +393,30 @@ namespace ams::secmon::boot { secmon::boot::EnsureMappingConsistency(); } + void LoadMarikoProgram() { + void * const mariko_program_dst = MemoryRegionVirtualTzramMarikoProgram.GetPointer(); + void * const mariko_program_src = MemoryRegionPhysicalMarikoProgramImage.GetPointer(); + const size_t mariko_program_size = MemoryRegionVirtualTzramMarikoProgram.GetSize(); + + if (fuse::GetSocType() == fuse::SocType_Mariko) { + /* On Mariko, we want to load the mariko program image into mariko tzram. */ + std::memcpy(mariko_program_dst, mariko_program_src, mariko_program_size); + hw::FlushDataCache(mariko_program_dst, mariko_program_size); + } else { + /* On Erista, we don't have mariko-only-tzram, so unmap it. */ + u64 * const l1 = MemoryRegionVirtualTzramL1PageTable.GetPointer(); + u64 * const l2_l3 = MemoryRegionVirtualTzramL2L3PageTable.GetPointer(); + + UnmapMarikoProgramImpl(l1, l2_l3, l2_l3); + } + + /* Clear the Mariko program image from DRAM. */ + util::ClearMemory(mariko_program_src, mariko_program_size); + hw::FlushDataCache(mariko_program_src, mariko_program_size); + hw::DataSynchronizationBarrierInnerShareable(); + + /* Ensure the mappings are consistent. */ + secmon::boot::EnsureMappingConsistency(); + } + } diff --git a/exosphere/program/source/boot/secmon_main.cpp b/exosphere/program/source/boot/secmon_main.cpp index 852ba5ad9..0c2f82caf 100644 --- a/exosphere/program/source/boot/secmon_main.cpp +++ b/exosphere/program/source/boot/secmon_main.cpp @@ -123,6 +123,9 @@ namespace ams::secmon { std::memcpy(dst, src, size); } + /* Load the mariko program image. */ + secmon::boot::LoadMarikoProgram(); + /* Setup the GPU carveout's magic numbers. */ secmon::boot::WriteGpuCarveoutMagicNumbers(); diff --git a/exosphere/program/source/boot/secmon_make_page_table.cpp b/exosphere/program/source/boot/secmon_make_page_table.cpp index bdb3a4ff9..42e3cf97b 100644 --- a/exosphere/program/source/boot/secmon_make_page_table.cpp +++ b/exosphere/program/source/boot/secmon_make_page_table.cpp @@ -125,6 +125,9 @@ namespace ams::secmon::boot { /* Map the program region as rwx. */ SetL3BlockEntry(l3, MemoryRegionVirtualTzramProgram.GetAddress(), MemoryRegionPhysicalTzramProgram.GetAddress(), MemoryRegionVirtualTzramProgram.GetSize(), MappingAttributesEl3SecureRwCode); + /* Map the mariko program region as rwx. */ + SetL3BlockEntry(l3, MemoryRegionVirtualTzramMarikoProgram.GetAddress(), MemoryRegionPhysicalTzramMarikoProgram.GetAddress(), MemoryRegionPhysicalTzramMarikoProgram.GetSize(), MappingAttributesEl3SecureRwCode); + /* Map the boot code region. */ SetL3BlockEntry(l3, MemoryRegionVirtualTzramBootCode.GetAddress(), MemoryRegionPhysicalTzramBootCode.GetAddress(), MemoryRegionVirtualTzramBootCode.GetSize(), MappingAttributesEl3SecureRwCode); diff --git a/libraries/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp b/libraries/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp index 196c1f873..a1208ede6 100644 --- a/libraries/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp +++ b/libraries/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp @@ -199,6 +199,9 @@ namespace ams::secmon { constexpr inline const MemoryRegion MemoryRegionPhysicalTzramMarikoProgram(UINT64_C(0x7C020000), 0x20000); static_assert(MemoryRegionPhysicalTzramMariko.Contains(MemoryRegionPhysicalTzramMarikoProgram)); + constexpr inline const MemoryRegion MemoryRegionPhysicalMarikoProgramImage(UINT64_C(0x80020000), 0x20000); + static_assert(MemoryRegionDram.Contains(MemoryRegionPhysicalMarikoProgramImage)); + constexpr inline const MemoryRegion MemoryRegionVirtualTzramProgramMain(UINT64_C(0x1F00C0800), 0xB800); static_assert(MemoryRegionVirtualTzramProgram.Contains(MemoryRegionVirtualTzramProgramMain));