diff --git a/exosphere2/program/source/boot/secmon_boot.hpp b/exosphere2/program/source/boot/secmon_boot.hpp
index d82c67cac..1214b8850 100644
--- a/exosphere2/program/source/boot/secmon_boot.hpp
+++ b/exosphere2/program/source/boot/secmon_boot.hpp
@@ -19,6 +19,7 @@
namespace ams::secmon::boot {
void MakePageTable();
+ void UnmapPhysicalIdentityMapping();
void InitializeColdBoot();
diff --git a/exosphere2/program/source/boot/secmon_boot_cache.cpp b/exosphere2/program/source/boot/secmon_boot_cache.cpp
index ad0649c3e..f2d1f8e22 100644
--- a/exosphere2/program/source/boot/secmon_boot_cache.cpp
+++ b/exosphere2/program/source/boot/secmon_boot_cache.cpp
@@ -14,9 +14,10 @@
* along with this program. If not, see .
*/
#include
+#include "secmon_boot_cache.hpp"
namespace ams::secmon::boot {
- /* TODO */
+ #include "../secmon_cache_impl.inc"
}
\ No newline at end of file
diff --git a/exosphere2/program/source/boot/secmon_boot_cache.hpp b/exosphere2/program/source/boot/secmon_boot_cache.hpp
new file mode 100644
index 000000000..60d5b4208
--- /dev/null
+++ b/exosphere2/program/source/boot/secmon_boot_cache.hpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+#include
+
+namespace ams::secmon::boot {
+
+ #include "../secmon_cache.inc"
+
+}
\ No newline at end of file
diff --git a/exosphere2/program/source/boot/secmon_boot_functions.cpp b/exosphere2/program/source/boot/secmon_boot_functions.cpp
index a9488e44e..537c78c5a 100644
--- a/exosphere2/program/source/boot/secmon_boot_functions.cpp
+++ b/exosphere2/program/source/boot/secmon_boot_functions.cpp
@@ -15,6 +15,7 @@
*/
#include
#include "secmon_boot.hpp"
+#include "secmon_boot_cache.hpp"
#include "secmon_boot_functions.hpp"
namespace ams::secmon::boot {
@@ -104,4 +105,30 @@ namespace ams::secmon::boot {
SYSCTR0_REG_BITS_ENUM(CNTCR_EN, ENABLE));
}
+ void WriteGpuCarveoutMagicNumbers() {
+ /* Define the magic numbers. */
+ constexpr u32 GpuMagicNumber = 0xC0EDBBCC;
+ constexpr u32 SkuInfo = 0x83;
+ constexpr u32 HdcpMicroCodeVersion = 0x2;
+ constexpr u32 ChipIdErista = 0x210;
+ constexpr u32 ChipIdMariko = 0x214;
+
+ /* Get our pointers. */
+ u32 *gpu_magic = MemoryRegionDramGpuCarveout.GetEndPointer() - (0x004 / sizeof(*gpu_magic));
+ u32 *tsec_magic = MemoryRegionDramGpuCarveout.GetEndPointer() - (0x100 / sizeof(*tsec_magic));
+
+ /* Write the gpu magic number. */
+ gpu_magic[0] = GpuMagicNumber;
+
+ /* Write the tsec magic numbers. */
+ tsec_magic[0] = SkuInfo;
+ tsec_magic[1] = HdcpMicroCodeVersion;
+ tsec_magic[2] = (false /* TODO: IsMariko */) ? ChipIdMariko : ChipIdErista;
+
+ /* Flush the magic numbers. */
+ hw::FlushDataCache(gpu_magic, 1 * sizeof(u32));
+ hw::FlushDataCache(tsec_magic, 3 * sizeof(u32));
+ hw::DataSynchronizationBarrierInnerShareable();
+ }
+
}
\ No newline at end of file
diff --git a/exosphere2/program/source/boot/secmon_boot_functions.hpp b/exosphere2/program/source/boot/secmon_boot_functions.hpp
index 83ac091db..97b5a105d 100644
--- a/exosphere2/program/source/boot/secmon_boot_functions.hpp
+++ b/exosphere2/program/source/boot/secmon_boot_functions.hpp
@@ -27,4 +27,6 @@ namespace ams::secmon::boot {
void EnableTsc(u64 initial_tsc_value);
+ void WriteGpuCarveoutMagicNumbers();
+
}
\ No newline at end of file
diff --git a/exosphere2/program/source/boot/secmon_boot_setup.cpp b/exosphere2/program/source/boot/secmon_boot_setup.cpp
index 06b411f87..c9255a529 100644
--- a/exosphere2/program/source/boot/secmon_boot_setup.cpp
+++ b/exosphere2/program/source/boot/secmon_boot_setup.cpp
@@ -15,6 +15,7 @@
*/
#include
#include "secmon_boot.hpp"
+#include "secmon_boot_cache.hpp"
#include "../secmon_setup.hpp"
#include "../secmon_key_storage.hpp"
@@ -308,6 +309,25 @@ namespace ams::secmon::boot {
}
+ namespace {
+
+ using namespace ams::mmu;
+
+ constexpr void UnmapPhysicalIdentityMappingImpl(u64 *l1, u64 *l2, u64 *l3) {
+ /* Invalidate the L3 entries for the tzram and iram boot code regions. */
+ InvalidateL3Entries(l3, MemoryRegionPhysicalTzram.GetAddress(), MemoryRegionPhysicalTzram.GetSize());
+ InvalidateL3Entries(l3, MemoryRegionPhysicalIramBootCode.GetAddress(), MemoryRegionPhysicalIramBootCode.GetSize());
+
+ /* Unmap the L2 entries corresponding to those L3 entries. */
+ InvalidateL2Entries(l2, MemoryRegionPhysicalIramL2.GetAddress(), MemoryRegionPhysicalIramL2.GetSize());
+ InvalidateL2Entries(l2, MemoryRegionPhysicalTzramL2.GetAddress(), MemoryRegionPhysicalTzramL2.GetSize());
+
+ /* Unmap the L1 entry corresponding to to those L2 entries. */
+ InvalidateL1Entries(l1, MemoryRegionPhysical.GetAddress(), MemoryRegionPhysical.GetSize());
+ }
+
+ }
+
void InitializeColdBoot() {
/* Ensure that the system counters are valid. */
ValidateSystemCounters();
@@ -334,4 +354,16 @@ namespace ams::secmon::boot {
SaveSecurityEngineAesKeySlotTestVector();
}
-}
\ No newline at end of file
+ void UnmapPhysicalIdentityMapping() {
+ /* Get the tables. */
+ u64 * const l1 = MemoryRegionPhysicalTzramL1PageTable.GetPointer();
+ u64 * const l2_l3 = MemoryRegionPhysicalTzramL2L3PageTable.GetPointer();
+
+ /* Unmap. */
+ UnmapPhysicalIdentityMappingImpl(l1, l2_l3, l2_l3);
+
+ /* Ensure the mappings are consistent. */
+ secmon::boot::EnsureMappingConsistency();
+ }
+
+}
diff --git a/exosphere2/program/source/boot/secmon_main.cpp b/exosphere2/program/source/boot/secmon_main.cpp
index 93b9f9c93..0b09e8ecc 100644
--- a/exosphere2/program/source/boot/secmon_main.cpp
+++ b/exosphere2/program/source/boot/secmon_main.cpp
@@ -89,6 +89,36 @@ namespace ams::secmon {
secmon::boot::EnableTsc(bc.data.GetInitialTscValue() & TscMask);
}
+
+ /* Wait for NX Bootloader to initialize DRAM. */
+ secmon::boot::WaitForNxBootloader(secmon_params, pkg1::BootloaderState_InitializedDram);
+
+ /* Secure the PMC and MC. */
+ secmon::SetupPmcAndMcSecure();
+
+ /* Copy warmboot to dram. */
+ {
+ /* Define warmboot extents. */
+ const void * const src = MemoryRegionPhysicalIramWarmbootBin.GetPointer();
+ void * const dst = MemoryRegionVirtualDramSecureDataStoreWarmbootFirmware.GetPointer();
+ const size_t size = MemoryRegionPhysicalIramWarmbootBin.GetSize();
+
+ /* Ensure we copy the correct data. */
+ hw::FlushDataCache(src, size);
+ hw::DataSynchronizationBarrierInnerShareable();
+
+ /* Copy warmboot.bin to its secure dram location. */
+ std::memcpy(dst, src, size);
+ }
+
+ /* Unmap the identity mapping. */
+ secmon::boot::UnmapPhysicalIdentityMapping();
+
+ /* Setup the GPU carveout's magic numbers. */
+ secmon::boot::WriteGpuCarveoutMagicNumbers();
+
+ /* Wait for NX bootloader to load Package2. */
+ secmon::boot::WaitForNxBootloader(secmon_params, pkg1::BootloaderState_LoadedPackage2);
}
}
\ No newline at end of file
diff --git a/exosphere2/program/source/boot/secmon_make_page_table.cpp b/exosphere2/program/source/boot/secmon_make_page_table.cpp
index dfde30d16..876bc54c0 100644
--- a/exosphere2/program/source/boot/secmon_make_page_table.cpp
+++ b/exosphere2/program/source/boot/secmon_make_page_table.cpp
@@ -144,4 +144,4 @@ namespace ams::secmon::boot {
MakePageTablesImpl(l1, l2_l3, l2_l3);
}
-}
\ No newline at end of file
+}
diff --git a/exosphere2/program/source/secmon_cache.inc b/exosphere2/program/source/secmon_cache.inc
index 1ee25f79a..ea57c0f4e 100644
--- a/exosphere2/program/source/secmon_cache.inc
+++ b/exosphere2/program/source/secmon_cache.inc
@@ -19,4 +19,4 @@ void InvalidateEntireDataCache();
void EnsureMappingConsistency();
void EnsureMappingConsistency(uintptr_t address);
-void EnsureInstructionConsistency();
\ No newline at end of file
+void EnsureInstructionConsistency();
diff --git a/exosphere2/program/source/secmon_setup.cpp b/exosphere2/program/source/secmon_setup.cpp
index 7bb95aa63..296f66d68 100644
--- a/exosphere2/program/source/secmon_setup.cpp
+++ b/exosphere2/program/source/secmon_setup.cpp
@@ -840,6 +840,16 @@ namespace ams::secmon {
}
+ void SetupPmcAndMcSecure() {
+ /* Set the PMC secure. */
+ reg::ReadWrite(APB_MISC + APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0, SLAVE_SECURITY_REG_BITS_ENUM(0, PMC, ENABLE));
+
+ /* Set the MC secure. */
+ reg::ReadWrite(APB_MISC + APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG1_0, SLAVE_SECURITY_REG_BITS_ENUM(1, MC0, ENABLE),
+ SLAVE_SECURITY_REG_BITS_ENUM(1, MC1, ENABLE),
+ SLAVE_SECURITY_REG_BITS_ENUM(1, MCB, ENABLE));
+ }
+
void SetupCpuCoreContext() {
/* Get the tsc frequency. */
const u32 tsc_frequency = reg::Read(MemoryRegionVirtualDeviceSysCtr0.GetAddress() + SYSCTR0_CNTFID0);
diff --git a/exosphere2/program/source/secmon_setup.hpp b/exosphere2/program/source/secmon_setup.hpp
index 623e10e74..c3c468fee 100644
--- a/exosphere2/program/source/secmon_setup.hpp
+++ b/exosphere2/program/source/secmon_setup.hpp
@@ -31,6 +31,8 @@ namespace ams::secmon {
void SetupSocSecurity();
void SetupSocProtections();
+ void SetupPmcAndMcSecure();
+
void Setup1();
void SaveSecurityEngineAesKeySlotTestVector();
diff --git a/libraries/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp b/libraries/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp
index 1e25108c5..d521efadc 100644
--- a/libraries/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp
+++ b/libraries/libexosphere/include/exosphere/secmon/secmon_memory_layout.hpp
@@ -74,6 +74,9 @@ namespace ams::secmon {
constexpr inline const MemoryRegion MemoryRegionPhysical = MemoryRegion(UINT64_C( 0x40000000), 1_GB);
constexpr inline const MemoryRegion MemoryRegionDram = MemoryRegion(UINT64_C( 0x80000000), 2_GB);
+ constexpr inline const MemoryRegion MemoryRegionDramGpuCarveout = MemoryRegion(UINT64_C(0x80020000), UINT64_C(0x40000));
+ static_assert(MemoryRegionDram.Contains(MemoryRegionDramGpuCarveout));
+
constexpr inline const MemoryRegion MemoryRegionDramDefaultKernelCarveout = MemoryRegion(UINT64_C(0x80060000), UINT64_C(0x1FFE0000));
static_assert(MemoryRegionDram.Contains(MemoryRegionDramDefaultKernelCarveout));
@@ -274,6 +277,7 @@ namespace ams::secmon {
constexpr inline const MemoryRegion MemoryRegionPhysicalTzramFullProgramImage = MemoryRegion(UINT64_C(0x7C010800), 0xD800);
constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootCodeImage = MemoryRegion(UINT64_C(0x40032000), 0xC000);
- constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootConfig = MemoryRegion(UINT64_C(0x4003F800), 0x400);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramWarmbootBin = MemoryRegion(UINT64_C(0x4003E000), 0x17F0);
+ constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootConfig = MemoryRegion(UINT64_C(0x4003F800), 0x400);
}
diff --git a/libraries/libexosphere/include/exosphere/tegra/tegra_sysctr0.hpp b/libraries/libexosphere/include/exosphere/tegra/tegra_sysctr0.hpp
index d7e7fd497..650067eb6 100644
--- a/libraries/libexosphere/include/exosphere/tegra/tegra_sysctr0.hpp
+++ b/libraries/libexosphere/include/exosphere/tegra/tegra_sysctr0.hpp
@@ -16,7 +16,7 @@
#pragma once
#include
-#define SYSCTR0_CNTCR (0x00C)
+#define SYSCTR0_CNTCR (0x000)
#define SYSCTR0_CNTCV0 (0x008)
#define SYSCTR0_CNTCV1 (0x00C)
#define SYSCTR0_CNTFID0 (0x020)