diff --git a/exosphere/program/source/boot/secmon_boot.hpp b/exosphere/program/source/boot/secmon_boot.hpp index 469aa88..4933dee 100644 --- a/exosphere/program/source/boot/secmon_boot.hpp +++ b/exosphere/program/source/boot/secmon_boot.hpp @@ -21,6 +21,7 @@ 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 a725b78..13b8c0c 100644 --- a/exosphere/program/source/boot/secmon_boot_setup.cpp +++ b/exosphere/program/source/boot/secmon_boot_setup.cpp @@ -332,6 +332,12 @@ 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 @@ 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 852ba5a..0c2f82c 100644 --- a/exosphere/program/source/boot/secmon_main.cpp +++ b/exosphere/program/source/boot/secmon_main.cpp @@ -123,6 +123,9 @@ 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 bdb3a4f..42e3cf9 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 @@ /* 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 196c1f8..a1208ed 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 @@ 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));