exo2: implement main through sync-for-pk21-load

This commit is contained in:
Michael Scire 2020-05-12 01:18:10 -07:00 committed by SciresM
parent e11fad6598
commit 9ddcbe9dc3
13 changed files with 138 additions and 6 deletions

View file

@ -19,6 +19,7 @@
namespace ams::secmon::boot { namespace ams::secmon::boot {
void MakePageTable(); void MakePageTable();
void UnmapPhysicalIdentityMapping();
void InitializeColdBoot(); void InitializeColdBoot();

View file

@ -14,9 +14,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <exosphere.hpp> #include <exosphere.hpp>
#include "secmon_boot_cache.hpp"
namespace ams::secmon::boot { namespace ams::secmon::boot {
/* TODO */ #include "../secmon_cache_impl.inc"
} }

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <exosphere.hpp>
namespace ams::secmon::boot {
#include "../secmon_cache.inc"
}

View file

@ -15,6 +15,7 @@
*/ */
#include <exosphere.hpp> #include <exosphere.hpp>
#include "secmon_boot.hpp" #include "secmon_boot.hpp"
#include "secmon_boot_cache.hpp"
#include "secmon_boot_functions.hpp" #include "secmon_boot_functions.hpp"
namespace ams::secmon::boot { namespace ams::secmon::boot {
@ -104,4 +105,30 @@ namespace ams::secmon::boot {
SYSCTR0_REG_BITS_ENUM(CNTCR_EN, ENABLE)); 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<u32>() - (0x004 / sizeof(*gpu_magic));
u32 *tsec_magic = MemoryRegionDramGpuCarveout.GetEndPointer<u32>() - (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();
}
} }

View file

@ -27,4 +27,6 @@ namespace ams::secmon::boot {
void EnableTsc(u64 initial_tsc_value); void EnableTsc(u64 initial_tsc_value);
void WriteGpuCarveoutMagicNumbers();
} }

View file

@ -15,6 +15,7 @@
*/ */
#include <exosphere.hpp> #include <exosphere.hpp>
#include "secmon_boot.hpp" #include "secmon_boot.hpp"
#include "secmon_boot_cache.hpp"
#include "../secmon_setup.hpp" #include "../secmon_setup.hpp"
#include "../secmon_key_storage.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() { void InitializeColdBoot() {
/* Ensure that the system counters are valid. */ /* Ensure that the system counters are valid. */
ValidateSystemCounters(); ValidateSystemCounters();
@ -334,4 +354,16 @@ namespace ams::secmon::boot {
SaveSecurityEngineAesKeySlotTestVector(); SaveSecurityEngineAesKeySlotTestVector();
} }
} void UnmapPhysicalIdentityMapping() {
/* Get the tables. */
u64 * const l1 = MemoryRegionPhysicalTzramL1PageTable.GetPointer<u64>();
u64 * const l2_l3 = MemoryRegionPhysicalTzramL2L3PageTable.GetPointer<u64>();
/* Unmap. */
UnmapPhysicalIdentityMappingImpl(l1, l2_l3, l2_l3);
/* Ensure the mappings are consistent. */
secmon::boot::EnsureMappingConsistency();
}
}

View file

@ -89,6 +89,36 @@ namespace ams::secmon {
secmon::boot::EnableTsc(bc.data.GetInitialTscValue() & TscMask); 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);
} }
} }

View file

@ -144,4 +144,4 @@ namespace ams::secmon::boot {
MakePageTablesImpl(l1, l2_l3, l2_l3); MakePageTablesImpl(l1, l2_l3, l2_l3);
} }
} }

View file

@ -19,4 +19,4 @@ void InvalidateEntireDataCache();
void EnsureMappingConsistency(); void EnsureMappingConsistency();
void EnsureMappingConsistency(uintptr_t address); void EnsureMappingConsistency(uintptr_t address);
void EnsureInstructionConsistency(); void EnsureInstructionConsistency();

View file

@ -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() { void SetupCpuCoreContext() {
/* Get the tsc frequency. */ /* Get the tsc frequency. */
const u32 tsc_frequency = reg::Read(MemoryRegionVirtualDeviceSysCtr0.GetAddress() + SYSCTR0_CNTFID0); const u32 tsc_frequency = reg::Read(MemoryRegionVirtualDeviceSysCtr0.GetAddress() + SYSCTR0_CNTFID0);

View file

@ -31,6 +31,8 @@ namespace ams::secmon {
void SetupSocSecurity(); void SetupSocSecurity();
void SetupSocProtections(); void SetupSocProtections();
void SetupPmcAndMcSecure();
void Setup1(); void Setup1();
void SaveSecurityEngineAesKeySlotTestVector(); void SaveSecurityEngineAesKeySlotTestVector();

View file

@ -74,6 +74,9 @@ namespace ams::secmon {
constexpr inline const MemoryRegion MemoryRegionPhysical = MemoryRegion(UINT64_C( 0x40000000), 1_GB); 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 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)); constexpr inline const MemoryRegion MemoryRegionDramDefaultKernelCarveout = MemoryRegion(UINT64_C(0x80060000), UINT64_C(0x1FFE0000));
static_assert(MemoryRegionDram.Contains(MemoryRegionDramDefaultKernelCarveout)); 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 MemoryRegionPhysicalTzramFullProgramImage = MemoryRegion(UINT64_C(0x7C010800), 0xD800);
constexpr inline const MemoryRegion MemoryRegionPhysicalIramBootCodeImage = MemoryRegion(UINT64_C(0x40032000), 0xC000); 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);
} }

View file

@ -16,7 +16,7 @@
#pragma once #pragma once
#include <vapours.hpp> #include <vapours.hpp>
#define SYSCTR0_CNTCR (0x00C) #define SYSCTR0_CNTCR (0x000)
#define SYSCTR0_CNTCV0 (0x008) #define SYSCTR0_CNTCV0 (0x008)
#define SYSCTR0_CNTCV1 (0x00C) #define SYSCTR0_CNTCV1 (0x00C)
#define SYSCTR0_CNTFID0 (0x020) #define SYSCTR0_CNTFID0 (0x020)