exo2: add sc7fw load, skeleton rest of suspend

This commit is contained in:
Michael Scire 2020-06-07 19:51:49 -07:00 committed by SciresM
parent 0202a95832
commit 34098f7215
3 changed files with 91 additions and 7 deletions

View file

@ -21,7 +21,8 @@ export TOPDIR := $(CURDIR)
export DEPSDIR := $(CURDIR)/$(BUILD) export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(TOPDIR)/sc7fw
CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \ CFILES := $(foreach dir,$(SOURCES),$(filter-out $(notdir $(wildcard $(dir)/*.arch.*.c)) $(notdir $(wildcard $(dir)/*.board.*.c)) $(notdir $(wildcard $(dir)/*.os.*.c)), \
$(notdir $(wildcard $(dir)/*.c)))) $(notdir $(wildcard $(dir)/*.c))))
@ -41,6 +42,8 @@ SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.arch.$(ATM
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s))) SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.board.$(ATMOSPHERE_BOARD_NAME).s)))
SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s))) SFILES += $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.os.$(ATMOSPHERE_OS_NAME).s)))
BINFILES := sc7fw.bin
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C # use CXX for linking C++ projects, CC for standard C
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@ -71,16 +74,20 @@ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib -L$(dir)/$(ATMOSPHERE_L
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
all: $(BUILD) check_libexo all: $(BUILD) check_libexo
$(BUILD): check_libexo $(BUILD): check_libexo check_sc7fw
@[ -d $@ ] || mkdir -p $@ @[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
check_libexo: check_libexo:
@$(MAKE) --no-print-directory -C ../../libraries/libexosphere arm64 @$(MAKE) --no-print-directory -C ../../libraries/libexosphere arm64
check_sc7fw:
@$(MAKE) -C $(TOPDIR)/sc7fw all
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
clean: clean:
@echo clean ... @echo clean ...
@$(MAKE) -C $(TOPDIR)/sc7fw clean
@rm -fr $(BUILD) $(OUTPUT).bin $(OUTPUT).elf *.lz4 @rm -fr $(BUILD) $(OUTPUT).bin $(OUTPUT).elf *.lz4
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------

View file

@ -20,6 +20,8 @@
#include "secmon_smc_power_management.hpp" #include "secmon_smc_power_management.hpp"
#include "secmon_smc_se_lock.hpp" #include "secmon_smc_se_lock.hpp"
#include "sc7fw_bin.h"
namespace ams::secmon { namespace ams::secmon {
/* Declare assembly functionality. */ /* Declare assembly functionality. */
@ -35,9 +37,12 @@ namespace ams::secmon::smc {
namespace { namespace {
constexpr inline uintptr_t PMC = MemoryRegionVirtualDevicePmc.GetAddress(); constexpr inline const uintptr_t PMC = MemoryRegionVirtualDevicePmc.GetAddress();
constexpr inline uintptr_t GPIO = MemoryRegionVirtualDeviceGpio.GetAddress(); constexpr inline const uintptr_t APB_MISC = MemoryRegionVirtualDeviceApbMisc.GetAddress();
constexpr inline uintptr_t CLK_RST = MemoryRegionVirtualDeviceClkRst.GetAddress(); constexpr inline const uintptr_t GPIO = MemoryRegionVirtualDeviceGpio.GetAddress();
constexpr inline const uintptr_t CLK_RST = MemoryRegionVirtualDeviceClkRst.GetAddress();
constexpr inline const uintptr_t EVP = secmon::MemoryRegionVirtualDeviceExceptionVectors.GetAddress();
constexpr inline const uintptr_t FLOW_CTLR = MemoryRegionVirtualDeviceFlowController.GetAddress();
constexpr inline uintptr_t CommonSmcStackTop = MemoryRegionVirtualTzramVolatileData.GetEndAddress() - (0x80 * (NumCores - 1)); constexpr inline uintptr_t CommonSmcStackTop = MemoryRegionVirtualTzramVolatileData.GetEndAddress() - (0x80 * (NumCores - 1));
@ -150,8 +155,75 @@ namespace ams::secmon::smc {
/* TODO */ /* TODO */
} }
void SaveSecureContextAndSuspend() { void SaveSecureContextForErista() {
/* TODO */ /* TODO */
}
void SaveSecureContextForMariko() {
/* TODO */
}
void SaveSecureContext() {
const auto soc_type = GetSocType();
if (soc_type == fuse::SocType_Erista) {
SaveSecureContextForErista();
} else /* if (soc_type == fuse::SocType_Mariko) */ {
SaveSecureContextForMariko();
}
}
void LoadAndStartSc7BpmpFirmware() {
/* Set the PMC as insecure, so that the BPMP firmware can access it. */
reg::ReadWrite(APB_MISC + APB_MISC_SECURE_REGS_APB_SLAVE_SECURITY_ENABLE_REG0_0, SLAVE_SECURITY_REG_BITS_ENUM(0, PMC, DISABLE));
/* Set the exception vectors for the bpmp. RESET should point to RESET, all others should point to generic exception/panic. */
constexpr const u32 Sc7FirmwareResetVector = static_cast<u32>(MemoryRegionPhysicalIramSc7Firmware.GetAddress() + 0x0);
constexpr const u32 Sc7FirmwarePanicVector = static_cast<u32>(MemoryRegionPhysicalIramSc7Firmware.GetAddress() + 0x4);
reg::Write(EVP + EVP_COP_RESET_VECTOR, Sc7FirmwareResetVector);
reg::Write(EVP + EVP_COP_UNDEF_VECTOR, Sc7FirmwarePanicVector);
reg::Write(EVP + EVP_COP_SWI_VECTOR, Sc7FirmwarePanicVector);
reg::Write(EVP + EVP_COP_PREFETCH_ABORT_VECTOR, Sc7FirmwarePanicVector);
reg::Write(EVP + EVP_COP_DATA_ABORT_VECTOR, Sc7FirmwarePanicVector);
reg::Write(EVP + EVP_COP_RSVD_VECTOR, Sc7FirmwarePanicVector);
reg::Write(EVP + EVP_COP_IRQ_VECTOR, Sc7FirmwarePanicVector);
reg::Write(EVP + EVP_COP_FIQ_VECTOR, Sc7FirmwarePanicVector);
/* Disable activity monitor bpmp monitoring, so that we don't panic upon bpmp wake. */
actmon::StopMonitoringBpmp();
/* Load the bpmp firmware. */
void * const sc7fw_load_address = MemoryRegionVirtualIramSc7Firmware.GetPointer<void>();
std::memcpy(sc7fw_load_address, sc7fw_bin, sc7fw_bin_size);
hw::FlushDataCache(sc7fw_load_address, sc7fw_bin_size);
hw::DataSynchronizationBarrierInnerShareable();
/* Ensure that the bpmp firmware was loaded. */
AMS_ABORT_UNLESS(crypto::IsSameBytes(sc7fw_load_address, sc7fw_bin, sc7fw_bin_size));
/* Clear BPMP reset. */
reg::Write(CLK_RST + CLK_RST_CONTROLLER_RST_DEV_L_CLR, CLK_RST_REG_BITS_ENUM(RST_DEV_L_CLR_CLR_COP_RST, ENABLE));
/* Start the bpmp. */
reg::Write(FLOW_CTLR + FLOW_CTLR_HALT_COP_EVENTS, FLOW_REG_BITS_ENUM(HALT_COP_EVENTS_MODE, FLOW_MODE_NONE));
}
void SaveSecureContextAndSuspend() {
/* Ensure there are no pending memory transactions before we continue */
FlushEntireDataCache();
hw::DataSynchronizationBarrierInnerShareable();
/* Save all secure context (security engine state + tzram). */
SaveSecureContext();
/* Load and start the sc7 firmware on the bpmp. */
LoadAndStartSc7BpmpFirmware();
/* Log our suspension. */
/* NOTE: Nintendo only does this on dev, but we will always do it. */
if (true /* !pkg1::IsProduction() */) {
log::SendText("OYASUMI\n", 8);
}
/* Finalize our powerdown and wait for an interrupt. */ /* Finalize our powerdown and wait for an interrupt. */
FinalizePowerOff(); FinalizePowerOff();

View file

@ -61,7 +61,10 @@ DEFINE_CLK_RST_REG(MISC_CLK_ENB_CFG_ALL_VISIBLE, 28, 1);
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA (0x178) #define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA (0x178)
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB (0x17C) #define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB (0x17C)
#define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC (0x1A0) #define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC (0x1A0)
#define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON (0x3e8) #define CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON (0x3E8)
/* RST_DEV_*_CLR */
#define CLK_RST_CONTROLLER_RST_DEV_L_CLR (0x304)
/* CLK_ENB_*_INDEX */ /* CLK_ENB_*_INDEX */
#define CLK_RST_CONTROLLER_CLK_ENB_I2C1_INDEX (0x0C) #define CLK_RST_CONTROLLER_CLK_ENB_I2C1_INDEX (0x0C)
@ -96,3 +99,5 @@ DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_UARTB_UARTB_CLK_SRC, 29, PLLP_OUT0,
DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_UARTC_UARTC_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT0, RESERVED4, PLLC4_OUT1, CLK_M, PLLC4_OUT2); DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_UARTC_UARTC_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT0, RESERVED4, PLLC4_OUT1, CLK_M, PLLC4_OUT2);
DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_ACTMON_ACTMON_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT0, CLK_S, PLLC4_OUT1, CLK_M, PLLC4_OUT2); DEFINE_CLK_RST_REG_THREE_BIT_ENUM(CLK_SOURCE_ACTMON_ACTMON_CLK_SRC, 29, PLLP_OUT0, PLLC2_OUT0, PLLC_OUT0, PLLC4_OUT0, CLK_S, PLLC4_OUT1, CLK_M, PLLC4_OUT2);
DEFINE_CLK_RST_REG_BIT_ENUM(RST_DEV_L_CLR_CLR_COP_RST, 1, DISABLE, ENABLE);