mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-30 18:34:38 +01:00
ams: expose reboot payload for kernel panic
This commit is contained in:
parent
8d46d901d9
commit
48b4dd48a4
@ -96,10 +96,6 @@ namespace ams::secmon {
|
|||||||
util::ClearMemory(reinterpret_cast<void *>(address + size / 2), size / 2);
|
util::ClearMemory(reinterpret_cast<void *>(address + size / 2), size / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsPhysicalMemoryAddress(uintptr_t address) {
|
|
||||||
return (address - MemoryRegionDram.GetAddress()) < GetPhysicalMemorySize();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearBootCodeHigh() {
|
void ClearBootCodeHigh() {
|
||||||
@ -130,6 +126,10 @@ namespace ams::secmon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsPhysicalMemoryAddress(uintptr_t address) {
|
||||||
|
return (address - MemoryRegionDram.GetAddress()) < GetPhysicalMemorySize();
|
||||||
|
}
|
||||||
|
|
||||||
void UnmapTzram() {
|
void UnmapTzram() {
|
||||||
/* Get the tables. */
|
/* Get the tables. */
|
||||||
u64 * const l1 = MemoryRegionVirtualTzramL1PageTable.GetPointer<u64>();
|
u64 * const l1 = MemoryRegionVirtualTzramL1PageTable.GetPointer<u64>();
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
namespace ams::secmon {
|
namespace ams::secmon {
|
||||||
|
|
||||||
|
bool IsPhysicalMemoryAddress(uintptr_t address);
|
||||||
size_t GetPhysicalMemorySize();
|
size_t GetPhysicalMemorySize();
|
||||||
|
|
||||||
void UnmapTzram();
|
void UnmapTzram();
|
||||||
|
@ -141,6 +141,9 @@ namespace ams::secmon::smc {
|
|||||||
{ 0xC3000006, Restriction_Normal, SmcShowError },
|
{ 0xC3000006, Restriction_Normal, SmcShowError },
|
||||||
{ 0xC3000007, Restriction_Normal, SmcSetKernelCarveoutRegion },
|
{ 0xC3000007, Restriction_Normal, SmcSetKernelCarveoutRegion },
|
||||||
{ 0xC3000008, Restriction_Normal, SmcReadWriteRegister },
|
{ 0xC3000008, Restriction_Normal, SmcReadWriteRegister },
|
||||||
|
|
||||||
|
/* NOTE: Atmosphere extension for mesosphere. This ID is subject to change at any time. */
|
||||||
|
{ 0xC3000409, Restriction_Normal, SmcSetConfig },
|
||||||
};
|
};
|
||||||
|
|
||||||
constinit HandlerInfo g_ams_handlers[] = {
|
constinit HandlerInfo g_ams_handlers[] = {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
#include <exosphere.hpp>
|
#include <exosphere.hpp>
|
||||||
#include "../secmon_error.hpp"
|
#include "../secmon_error.hpp"
|
||||||
|
#include "../secmon_map.hpp"
|
||||||
#include "../secmon_misc.hpp"
|
#include "../secmon_misc.hpp"
|
||||||
#include "../secmon_page_mapper.hpp"
|
#include "../secmon_page_mapper.hpp"
|
||||||
#include "../secmon_user_power_management.hpp"
|
#include "../secmon_user_power_management.hpp"
|
||||||
@ -157,6 +158,8 @@ namespace ams::secmon::smc {
|
|||||||
return value.value;
|
return value.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constinit u64 g_payload_address = 0;
|
||||||
|
|
||||||
SmcResult GetConfig(SmcArguments &args, bool kern) {
|
SmcResult GetConfig(SmcArguments &args, bool kern) {
|
||||||
switch (static_cast<ConfigItem>(args.r[1])) {
|
switch (static_cast<ConfigItem>(args.r[1])) {
|
||||||
case ConfigItem::DisableProgramVerification:
|
case ConfigItem::DisableProgramVerification:
|
||||||
@ -267,6 +270,14 @@ namespace ams::secmon::smc {
|
|||||||
/* NOTE: This may return values other than 1 in the future. */
|
/* NOTE: This may return values other than 1 in the future. */
|
||||||
args.r[1] = (GetEmummcConfiguration().IsEmummcActive() ? 1 : 0);
|
args.r[1] = (GetEmummcConfiguration().IsEmummcActive() ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
|
case ConfigItem::ExospherePayloadAddress:
|
||||||
|
/* Gets the physical address of the reboot payload buffer, if one exists. */
|
||||||
|
if (g_payload_address != 0) {
|
||||||
|
args.r[1] = g_payload_address;
|
||||||
|
} else {
|
||||||
|
return SmcResult::NotInitialized;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return SmcResult::InvalidArgument;
|
return SmcResult::InvalidArgument;
|
||||||
}
|
}
|
||||||
@ -309,6 +320,17 @@ namespace ams::secmon::smc {
|
|||||||
return SmcResult::NotImplemented;
|
return SmcResult::NotImplemented;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ConfigItem::ExospherePayloadAddress:
|
||||||
|
if (g_payload_address == 0) {
|
||||||
|
if (secmon::IsPhysicalMemoryAddress(args.r[2])) {
|
||||||
|
g_payload_address = args.r[2];
|
||||||
|
} else {
|
||||||
|
return SmcResult::InvalidArgument;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return SmcResult::Busy;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return SmcResult::InvalidArgument;
|
return SmcResult::InvalidArgument;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ namespace ams::secmon::smc {
|
|||||||
ExosphereBlankProdInfo = 65005,
|
ExosphereBlankProdInfo = 65005,
|
||||||
ExosphereAllowCalWrites = 65006,
|
ExosphereAllowCalWrites = 65006,
|
||||||
ExosphereEmummcType = 65007,
|
ExosphereEmummcType = 65007,
|
||||||
|
ExospherePayloadAddress = 65008,
|
||||||
};
|
};
|
||||||
|
|
||||||
SmcResult SmcGetConfigUser(SmcArguments &args);
|
SmcResult SmcGetConfigUser(SmcArguments &args);
|
||||||
|
@ -534,10 +534,14 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
|
|
||||||
void KSystemControl::StopSystem(void *arg) {
|
void KSystemControl::StopSystem(void *arg) {
|
||||||
if (arg != nullptr) {
|
if (arg != nullptr) {
|
||||||
|
/* Get the address of the legacy IRAM region. */
|
||||||
|
const KVirtualAddress iram_address = KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_LegacyLpsIram) + 64_KB;
|
||||||
|
constexpr size_t RebootPayloadSize = 0x2E000;
|
||||||
|
|
||||||
/* NOTE: Atmosphere extension; if we received an exception context from Panic(), */
|
/* NOTE: Atmosphere extension; if we received an exception context from Panic(), */
|
||||||
/* generate a fatal error report using it. */
|
/* generate a fatal error report using it. */
|
||||||
const KExceptionContext *e_ctx = static_cast<const KExceptionContext *>(arg);
|
const KExceptionContext *e_ctx = static_cast<const KExceptionContext *>(arg);
|
||||||
auto *f_ctx = GetPointer<::ams::impl::FatalErrorContext>(KMemoryLayout::GetDeviceVirtualAddress(KMemoryRegionType_LegacyLpsIram) + 0x3E000);
|
auto *f_ctx = GetPointer<::ams::impl::FatalErrorContext>(iram_address + RebootPayloadSize);
|
||||||
|
|
||||||
/* Clear the fatal context. */
|
/* Clear the fatal context. */
|
||||||
std::memset(f_ctx, 0xCC, sizeof(*f_ctx));
|
std::memset(f_ctx, 0xCC, sizeof(*f_ctx));
|
||||||
@ -581,8 +585,27 @@ namespace ams::kern::board::nintendo::nx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger a reboot to rcm. */
|
/* Try to get a payload address. */
|
||||||
smc::init::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToRcm);
|
const KMemoryRegion *cached_region = nullptr;
|
||||||
|
u64 reboot_payload_paddr = 0;
|
||||||
|
if (smc::TryGetConfig(std::addressof(reboot_payload_paddr), 1, smc::ConfigItem::ExospherePayloadAddress) && KMemoryLayout::IsLinearMappedPhysicalAddress(cached_region, reboot_payload_paddr, RebootPayloadSize)) {
|
||||||
|
/* If we have a payload, reboot to it. */
|
||||||
|
const KVirtualAddress reboot_payload = KMemoryLayout::GetLinearVirtualAddress(KPhysicalAddress(reboot_payload_paddr));
|
||||||
|
|
||||||
|
/* Clear IRAM. */
|
||||||
|
std::memset(GetVoidPointer(iram_address), 0xCC, RebootPayloadSize);
|
||||||
|
|
||||||
|
/* Copy the payload to iram. */
|
||||||
|
for (size_t i = 0; i < RebootPayloadSize / sizeof(u32); ++i) {
|
||||||
|
GetPointer<volatile u32>(iram_address)[i] = GetPointer<volatile u32>(reboot_payload)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reboot. */
|
||||||
|
smc::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToPayload);
|
||||||
|
} else {
|
||||||
|
/* If we don't have a payload, reboot to rcm. */
|
||||||
|
smc::SetConfig(smc::ConfigItem::ExosphereNeedsReboot, smc::UserRebootType_ToRcm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_call_smc_on_panic) {
|
if (g_call_smc_on_panic) {
|
||||||
|
@ -37,6 +37,9 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
FunctionId_Panic = 0xC3000006,
|
FunctionId_Panic = 0xC3000006,
|
||||||
FunctionId_ConfigureCarveout = 0xC3000007,
|
FunctionId_ConfigureCarveout = 0xC3000007,
|
||||||
FunctionId_ReadWriteRegister = 0xC3000008,
|
FunctionId_ReadWriteRegister = 0xC3000008,
|
||||||
|
|
||||||
|
/* NOTE: Atmosphere extension for mesosphere. This ID is subject to change at any time. */
|
||||||
|
FunctionId_SetConfig = 0xC3000409,
|
||||||
};
|
};
|
||||||
|
|
||||||
void CallPrivilegedSecureMonitorFunction(SecureMonitorArguments &args) {
|
void CallPrivilegedSecureMonitorFunction(SecureMonitorArguments &args) {
|
||||||
@ -140,35 +143,6 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
args.x[7] = x7;
|
args.x[7] = x7;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallUserSecureMonitorFunctionForInit(SecureMonitorArguments &args) {
|
|
||||||
/* Load arguments into registers. */
|
|
||||||
register u64 x0 asm("x0") = args.x[0];
|
|
||||||
register u64 x1 asm("x1") = args.x[1];
|
|
||||||
register u64 x2 asm("x2") = args.x[2];
|
|
||||||
register u64 x3 asm("x3") = args.x[3];
|
|
||||||
register u64 x4 asm("x4") = args.x[4];
|
|
||||||
register u64 x5 asm("x5") = args.x[5];
|
|
||||||
register u64 x6 asm("x6") = args.x[6];
|
|
||||||
register u64 x7 asm("x7") = args.x[7];
|
|
||||||
|
|
||||||
/* Actually make the call. */
|
|
||||||
__asm__ __volatile__("smc #0"
|
|
||||||
: "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7)
|
|
||||||
:
|
|
||||||
: "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "cc", "memory"
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Store arguments to output. */
|
|
||||||
args.x[0] = x0;
|
|
||||||
args.x[1] = x1;
|
|
||||||
args.x[2] = x2;
|
|
||||||
args.x[3] = x3;
|
|
||||||
args.x[4] = x4;
|
|
||||||
args.x[5] = x5;
|
|
||||||
args.x[6] = x6;
|
|
||||||
args.x[7] = x7;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Global lock for generate random bytes. */
|
/* Global lock for generate random bytes. */
|
||||||
KSpinLock g_generate_random_lock;
|
KSpinLock g_generate_random_lock;
|
||||||
|
|
||||||
@ -210,21 +184,30 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
return static_cast<SmcResult>(args.x[0]) == SmcResult::Success;
|
return static_cast<SmcResult>(args.x[0]) == SmcResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetConfig(ConfigItem config_item, u64 value) {
|
|
||||||
SecureMonitorArguments args = { UserFunctionId_SetConfig, static_cast<u32>(config_item), 0, value };
|
|
||||||
CallUserSecureMonitorFunctionForInit(args);
|
|
||||||
return static_cast<SmcResult>(args.x[0]) == SmcResult::Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
bool TryGetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
||||||
SecureMonitorArguments args = { FunctionId_GetConfig, static_cast<u32>(config_item) };
|
SecureMonitorArguments args = { FunctionId_GetConfig, static_cast<u32>(config_item) };
|
||||||
CallPrivilegedSecureMonitorFunction(args);
|
CallPrivilegedSecureMonitorFunction(args);
|
||||||
MESOSPHERE_ABORT_UNLESS((static_cast<SmcResult>(args.x[0]) == SmcResult::Success));
|
if (static_cast<SmcResult>(args.x[0]) != SmcResult::Success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < num_qwords && i < 7; i++) {
|
for (size_t i = 0; i < num_qwords && i < 7; i++) {
|
||||||
out[i] = args.x[1 + i];
|
out[i] = args.x[1 + i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
||||||
|
MESOSPHERE_ABORT_UNLESS(TryGetConfig(out, num_qwords, config_item));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetConfig(ConfigItem config_item, u64 value) {
|
||||||
|
SecureMonitorArguments args = { FunctionId_SetConfig, static_cast<u32>(config_item), 0, value };
|
||||||
|
CallPrivilegedSecureMonitorFunction(args);
|
||||||
|
return static_cast<SmcResult>(args.x[0]) == SmcResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value) {
|
bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value) {
|
||||||
|
@ -60,6 +60,10 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
ExosphereNeedsShutdown = 65002,
|
ExosphereNeedsShutdown = 65002,
|
||||||
ExosphereGitCommitHash = 65003,
|
ExosphereGitCommitHash = 65003,
|
||||||
ExosphereHasRcmBugPatch = 65004,
|
ExosphereHasRcmBugPatch = 65004,
|
||||||
|
ExosphereBlankProdInfo = 65005,
|
||||||
|
ExosphereAllowCalWrites = 65006,
|
||||||
|
ExosphereEmummcType = 65007,
|
||||||
|
ExospherePayloadAddress = 65008,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SmcResult {
|
enum class SmcResult {
|
||||||
@ -89,12 +93,14 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
UserRebootType_ToPayload = 2,
|
UserRebootType_ToPayload = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TODO: Rest of Secure Monitor API. */
|
|
||||||
void GenerateRandomBytes(void *dst, size_t size);
|
void GenerateRandomBytes(void *dst, size_t size);
|
||||||
|
bool TryGetConfig(u64 *out, size_t num_qwords, ConfigItem config_item);
|
||||||
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item);
|
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item);
|
||||||
bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value);
|
bool ReadWriteRegister(u32 *out, ams::svc::PhysicalAddress address, u32 mask, u32 value);
|
||||||
void ConfigureCarveout(size_t which, uintptr_t address, size_t size);
|
void ConfigureCarveout(size_t which, uintptr_t address, size_t size);
|
||||||
|
|
||||||
|
bool SetConfig(ConfigItem config_item, u64 value);
|
||||||
|
|
||||||
void CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg);
|
void CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg);
|
||||||
|
|
||||||
void NORETURN Panic(u32 color);
|
void NORETURN Panic(u32 color);
|
||||||
@ -108,8 +114,6 @@ namespace ams::kern::board::nintendo::nx::smc {
|
|||||||
void GenerateRandomBytes(void *dst, size_t size);
|
void GenerateRandomBytes(void *dst, size_t size);
|
||||||
bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value);
|
bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value);
|
||||||
|
|
||||||
bool SetConfig(ConfigItem config_item, u64 value);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -29,7 +29,7 @@ namespace ams::spl::smc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Functions. */
|
/* Functions. */
|
||||||
Result SetConfig(spl::ConfigItem which, const u64 *value, size_t num_qwords);
|
Result SetConfig(spl::ConfigItem which, const void *address, const u64 *value, size_t num_qwords);
|
||||||
Result GetConfig(u64 *out, size_t num_qwords, spl::ConfigItem which);
|
Result GetConfig(u64 *out, size_t num_qwords, spl::ConfigItem which);
|
||||||
Result GetResult(Result *out, AsyncOperationKey op);
|
Result GetResult(Result *out, AsyncOperationKey op);
|
||||||
Result GetResultData(Result *out, void *out_buf, size_t out_buf_size, AsyncOperationKey op);
|
Result GetResultData(Result *out, void *out_buf, size_t out_buf_size, AsyncOperationKey op);
|
||||||
@ -59,8 +59,12 @@ namespace ams::spl::smc {
|
|||||||
Result AtmosphereGetEmummcConfig(void *out_config, void *out_paths, u32 storage_id);
|
Result AtmosphereGetEmummcConfig(void *out_config, void *out_paths, u32 storage_id);
|
||||||
|
|
||||||
/* Helpers. */
|
/* Helpers. */
|
||||||
|
inline Result SetConfig(spl::ConfigItem which, const u64 *value, size_t num_qwords) {
|
||||||
|
return SetConfig(which, nullptr, value, num_qwords);
|
||||||
|
}
|
||||||
|
|
||||||
inline Result SetConfig(spl::ConfigItem which, const u64 value) {
|
inline Result SetConfig(spl::ConfigItem which, const u64 value) {
|
||||||
return SetConfig(which, &value, 1);
|
return SetConfig(which, std::addressof(value), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -222,6 +222,7 @@ namespace ams::spl {
|
|||||||
ExosphereBlankProdInfo = 65005,
|
ExosphereBlankProdInfo = 65005,
|
||||||
ExosphereAllowCalWrites = 65006,
|
ExosphereAllowCalWrites = 65006,
|
||||||
ExosphereEmummcType = 65007,
|
ExosphereEmummcType = 65007,
|
||||||
|
ExospherePayloadAddress = 65008,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -235,3 +236,4 @@ constexpr inline SplConfigItem SplConfigItem_ExosphereHasRcmBugPatch = static_ca
|
|||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereBlankProdInfo = static_cast<SplConfigItem>(65005);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereBlankProdInfo = static_cast<SplConfigItem>(65005);
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereAllowCalWrites = static_cast<SplConfigItem>(65006);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereAllowCalWrites = static_cast<SplConfigItem>(65006);
|
||||||
constexpr inline SplConfigItem SplConfigItem_ExosphereEmummcType = static_cast<SplConfigItem>(65007);
|
constexpr inline SplConfigItem SplConfigItem_ExosphereEmummcType = static_cast<SplConfigItem>(65007);
|
||||||
|
constexpr inline SplConfigItem SplConfigItem_ExospherePayloadAddress = static_cast<SplConfigItem>(65008);
|
||||||
|
@ -17,12 +17,12 @@
|
|||||||
|
|
||||||
namespace ams::spl::smc {
|
namespace ams::spl::smc {
|
||||||
|
|
||||||
Result SetConfig(spl::ConfigItem which, const u64 *value, size_t num_qwords) {
|
Result SetConfig(spl::ConfigItem which, const void *address, const u64 *value, size_t num_qwords) {
|
||||||
SecmonArgs args;
|
SecmonArgs args;
|
||||||
|
|
||||||
args.X[0] = static_cast<u64>(FunctionId::SetConfig);
|
args.X[0] = static_cast<u64>(FunctionId::SetConfig);
|
||||||
args.X[1] = static_cast<u64>(which);
|
args.X[1] = static_cast<u64>(which);
|
||||||
args.X[2] = 0;
|
args.X[2] = reinterpret_cast<u64>(address);
|
||||||
for (size_t i = 0; i < std::min(size_t(4), num_qwords); i++) {
|
for (size_t i = 0; i < std::min(size_t(4), num_qwords); i++) {
|
||||||
args.X[3 + i] = value[i];
|
args.X[3 + i] = value[i];
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,9 @@ namespace ams::mitm::bpc {
|
|||||||
/* Copy in payload. */
|
/* Copy in payload. */
|
||||||
std::memcpy(g_reboot_payload, payload, payload_size);
|
std::memcpy(g_reboot_payload, payload, payload_size);
|
||||||
|
|
||||||
|
/* Note to the secure monitor that we have a payload. */
|
||||||
|
spl::smc::SetConfig(spl::ConfigItem::ExospherePayloadAddress, g_reboot_payload, nullptr, 0);
|
||||||
|
|
||||||
/* NOTE: Preferred reboot type may be overrwritten when parsed from settings during boot. */
|
/* NOTE: Preferred reboot type may be overrwritten when parsed from settings during boot. */
|
||||||
g_reboot_type = RebootType::ToPayload;
|
g_reboot_type = RebootType::ToPayload;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user