mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-15 01:26:34 +00:00
kern: refactor smc helpers to share more common logic
This commit is contained in:
parent
48e86f0406
commit
6113ffa191
5 changed files with 155 additions and 106 deletions
|
@ -16,11 +16,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <mesosphere/kern_common.hpp>
|
#include <mesosphere/kern_common.hpp>
|
||||||
#include <mesosphere/kern_select_cpu.hpp>
|
#include <mesosphere/kern_select_cpu.hpp>
|
||||||
#include <mesosphere/kern_select_interrupt_manager.hpp>
|
|
||||||
|
|
||||||
namespace ams::kern::arch::arm64::smc {
|
namespace ams::kern::arch::arm64::smc {
|
||||||
|
|
||||||
template<int SmcId, bool DisableInterrupt>
|
template<int SmcId>
|
||||||
void SecureMonitorCall(u64 *buf) {
|
void SecureMonitorCall(u64 *buf) {
|
||||||
/* Load arguments into registers. */
|
/* Load arguments into registers. */
|
||||||
register u64 x0 asm("x0") = buf[0];
|
register u64 x0 asm("x0") = buf[0];
|
||||||
|
@ -32,13 +31,10 @@ namespace ams::kern::arch::arm64::smc {
|
||||||
register u64 x6 asm("x6") = buf[6];
|
register u64 x6 asm("x6") = buf[6];
|
||||||
register u64 x7 asm("x7") = buf[7];
|
register u64 x7 asm("x7") = buf[7];
|
||||||
|
|
||||||
|
/* Backup the current thread pointer. */
|
||||||
|
const uintptr_t current_thread_pointer_value = cpu::GetCurrentThreadPointerValue();
|
||||||
|
|
||||||
/* Perform the call. */
|
/* Perform the call. */
|
||||||
if constexpr (DisableInterrupt) {
|
|
||||||
KScopedInterruptDisable di;
|
|
||||||
|
|
||||||
/* Backup the current thread pointer. */
|
|
||||||
const uintptr_t current_thread_pointer_value = cpu::GetCurrentThreadPointerValue();
|
|
||||||
|
|
||||||
__asm__ __volatile__("smc %c[smc_id]"
|
__asm__ __volatile__("smc %c[smc_id]"
|
||||||
: "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7)
|
: "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7)
|
||||||
: [smc_id]"i"(SmcId)
|
: [smc_id]"i"(SmcId)
|
||||||
|
@ -47,19 +43,6 @@ namespace ams::kern::arch::arm64::smc {
|
||||||
|
|
||||||
/* Restore the current thread pointer into X18. */
|
/* Restore the current thread pointer into X18. */
|
||||||
cpu::SetCurrentThreadPointerValue(current_thread_pointer_value);
|
cpu::SetCurrentThreadPointerValue(current_thread_pointer_value);
|
||||||
} else {
|
|
||||||
/* Backup the current thread pointer. */
|
|
||||||
const uintptr_t current_thread_pointer_value = cpu::GetCurrentThreadPointerValue();
|
|
||||||
|
|
||||||
__asm__ __volatile__("smc %c[smc_id]"
|
|
||||||
: "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3), "+r"(x4), "+r"(x5), "+r"(x6), "+r"(x7)
|
|
||||||
: [smc_id]"i"(SmcId)
|
|
||||||
: "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "cc", "memory"
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Restore the current thread pointer into X18. */
|
|
||||||
cpu::SetCurrentThreadPointerValue(current_thread_pointer_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store arguments to output. */
|
/* Store arguments to output. */
|
||||||
buf[0] = x0;
|
buf[0] = x0;
|
||||||
|
@ -78,18 +61,18 @@ namespace ams::kern::arch::arm64::smc {
|
||||||
PsciFunction_CpuOn = 0xC4000003,
|
PsciFunction_CpuOn = 0xC4000003,
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int SmcId, bool DisableInterrupt>
|
template<int SmcId>
|
||||||
u64 PsciCall(PsciFunction function, u64 x1 = 0, u64 x2 = 0, u64 x3 = 0, u64 x4 = 0, u64 x5 = 0, u64 x6 = 0, u64 x7 = 0) {
|
u64 PsciCall(PsciFunction function, u64 x1 = 0, u64 x2 = 0, u64 x3 = 0, u64 x4 = 0, u64 x5 = 0, u64 x6 = 0, u64 x7 = 0) {
|
||||||
ams::svc::lp64::SecureMonitorArguments args = { { function, x1, x2, x3, x4, x5, x6, x7 } };
|
ams::svc::lp64::SecureMonitorArguments args = { { function, x1, x2, x3, x4, x5, x6, x7 } };
|
||||||
|
|
||||||
SecureMonitorCall<SmcId, DisableInterrupt>(args.r);
|
SecureMonitorCall<SmcId>(args.r);
|
||||||
|
|
||||||
return args.r[0];
|
return args.r[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int SmcId, bool DisableInterrupt>
|
template<int SmcId>
|
||||||
u64 CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg) {
|
u64 CpuOn(u64 core_id, uintptr_t entrypoint, uintptr_t arg) {
|
||||||
return PsciCall<SmcId, DisableInterrupt>(PsciFunction_CpuOn, core_id, entrypoint, arg);
|
return PsciCall<SmcId>(PsciFunction_CpuOn, core_id, entrypoint, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,7 +296,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
/* TODO: Move this into a header for the MC in general. */
|
/* TODO: Move this into a header for the MC in general. */
|
||||||
constexpr u32 MemoryControllerConfigurationRegister = 0x70019050;
|
constexpr u32 MemoryControllerConfigurationRegister = 0x70019050;
|
||||||
u32 config_value;
|
u32 config_value;
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(smc::init::ReadWriteRegister(&config_value, MemoryControllerConfigurationRegister, 0, 0));
|
smc::init::ReadWriteRegister(std::addressof(config_value), MemoryControllerConfigurationRegister, 0, 0);
|
||||||
return static_cast<size_t>(config_value & 0x3FFF) << 20;
|
return static_cast<size_t>(config_value & 0x3FFF) << 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,7 +387,7 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
}
|
}
|
||||||
|
|
||||||
void KSystemControl::Init::CpuOnImpl(u64 core_id, uintptr_t entrypoint, uintptr_t arg) {
|
void KSystemControl::Init::CpuOnImpl(u64 core_id, uintptr_t entrypoint, uintptr_t arg) {
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn<smc::SmcId_Supervisor, false>(core_id, entrypoint, arg)) == 0);
|
MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn<smc::SmcId_Supervisor>(core_id, entrypoint, arg)) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Randomness for Initialization. */
|
/* Randomness for Initialization. */
|
||||||
|
@ -601,8 +601,9 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
|
|
||||||
if (g_call_smc_on_panic) {
|
if (g_call_smc_on_panic) {
|
||||||
/* If we should, instruct the secure monitor to display a panic screen. */
|
/* If we should, instruct the secure monitor to display a panic screen. */
|
||||||
smc::Panic(0xF00);
|
smc::ShowError(0xF00);
|
||||||
}
|
}
|
||||||
|
|
||||||
AMS_INFINITE_LOOP();
|
AMS_INFINITE_LOOP();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace ams::kern::board::nintendo::nx::smc {
|
||||||
enum FunctionId : u32 {
|
enum FunctionId : u32 {
|
||||||
FunctionId_GetConfig = 0xC3000004,
|
FunctionId_GetConfig = 0xC3000004,
|
||||||
FunctionId_GenerateRandomBytes = 0xC3000005,
|
FunctionId_GenerateRandomBytes = 0xC3000005,
|
||||||
FunctionId_Panic = 0xC3000006,
|
FunctionId_ShowError = 0xC3000006,
|
||||||
FunctionId_ConfigureCarveout = 0xC3000007,
|
FunctionId_ConfigureCarveout = 0xC3000007,
|
||||||
FunctionId_ReadWriteRegister = 0xC3000008,
|
FunctionId_ReadWriteRegister = 0xC3000008,
|
||||||
|
|
||||||
|
@ -51,122 +51,187 @@ namespace ams::kern::board::nintendo::nx::smc {
|
||||||
FunctionId_SetConfig = 0xC3000409,
|
FunctionId_SetConfig = 0xC3000409,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr size_t GenerateRandomBytesSizeMax = sizeof(::ams::svc::lp64::SecureMonitorArguments) - sizeof(::ams::svc::lp64::SecureMonitorArguments{}.r[0]);
|
||||||
|
|
||||||
/* Global lock for generate random bytes. */
|
/* Global lock for generate random bytes. */
|
||||||
constinit KSpinLock g_generate_random_lock;
|
constinit KSpinLock g_generate_random_lock;
|
||||||
|
|
||||||
|
bool TryGetConfigImpl(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
||||||
|
/* Create the arguments .*/
|
||||||
|
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast<u32>(config_item) } };
|
||||||
|
|
||||||
|
/* Call into the secure monitor. */
|
||||||
|
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor>(args.r);
|
||||||
|
|
||||||
|
/* If successful, copy the output. */
|
||||||
|
const bool success = static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
||||||
|
if (AMS_LIKELY(success)) {
|
||||||
|
for (size_t i = 0; i < num_qwords && i < 7; i++) {
|
||||||
|
out[i] = args.r[1 + i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetConfigImpl(ConfigItem config_item, u64 value) {
|
||||||
|
/* Create the arguments .*/
|
||||||
|
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_SetConfig, static_cast<u32>(config_item), 0, value } };
|
||||||
|
|
||||||
|
/* Call into the secure monitor. */
|
||||||
|
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor>(args.r);
|
||||||
|
|
||||||
|
/* Return whether the call was successful. */
|
||||||
|
return static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadWriteRegisterImpl(u32 *out, u64 address, u32 mask, u32 value) {
|
||||||
|
/* Create the arguments .*/
|
||||||
|
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ReadWriteRegister, address, mask, value } };
|
||||||
|
|
||||||
|
/* Call into the secure monitor. */
|
||||||
|
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor>(args.r);
|
||||||
|
|
||||||
|
/* Unconditionally write the output. */
|
||||||
|
*out = static_cast<u32>(args.r[1]);
|
||||||
|
|
||||||
|
/* Return whether the call was successful. */
|
||||||
|
return static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GenerateRandomBytesImpl(void *dst, size_t size) {
|
||||||
|
/* Create the arguments. */
|
||||||
|
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } };
|
||||||
|
|
||||||
|
/* Call into the secure monitor. */
|
||||||
|
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor>(args.r);
|
||||||
|
|
||||||
|
/* If successful, copy the output. */
|
||||||
|
const bool success = static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
||||||
|
if (AMS_LIKELY(success)) {
|
||||||
|
std::memcpy(dst, std::addressof(args.r[1]), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigureCarveoutImpl(size_t which, uintptr_t address, size_t size) {
|
||||||
|
/* Create the arguments .*/
|
||||||
|
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ConfigureCarveout, static_cast<u64>(which), static_cast<u64>(address), static_cast<u64>(size) } };
|
||||||
|
|
||||||
|
/* Call into the secure monitor. */
|
||||||
|
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor>(args.r);
|
||||||
|
|
||||||
|
/* Return whether the call was successful. */
|
||||||
|
return static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShowErrorImpl(u32 color) {
|
||||||
|
/* Create the arguments .*/
|
||||||
|
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ShowError, color } };
|
||||||
|
|
||||||
|
/* Call into the secure monitor. */
|
||||||
|
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor>(args.r);
|
||||||
|
|
||||||
|
/* Return whether the call was successful. */
|
||||||
|
return static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallSecureMonitorFromUserImpl(ams::svc::lp64::SecureMonitorArguments *args) {
|
||||||
|
/* Call into the secure monitor. */
|
||||||
|
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_User>(args->r);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SMC functionality needed for init. */
|
/* SMC functionality needed for init. */
|
||||||
namespace init {
|
namespace init {
|
||||||
|
|
||||||
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
||||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast<u32>(config_item) } };
|
/* Ensure we successfully get the config. */
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(TryGetConfigImpl(out, num_qwords, config_item));
|
||||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, false>(args.r);
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS((static_cast<SmcResult>(args.r[0]) == SmcResult::Success));
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num_qwords && i < 7; i++) {
|
|
||||||
out[i] = args.r[1 + i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateRandomBytes(void *dst, size_t size) {
|
void GenerateRandomBytes(void *dst, size_t size) {
|
||||||
/* Call SmcGenerateRandomBytes() */
|
/* Check that the size is valid. */
|
||||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } };
|
MESOSPHERE_INIT_ABORT_UNLESS(0 < size && size <= GenerateRandomBytesSizeMax);
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.r[0]));
|
|
||||||
|
|
||||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, false>(args.r);
|
/* Ensure we successfully generate the random bytes. */
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS((static_cast<SmcResult>(args.r[0]) == SmcResult::Success));
|
MESOSPHERE_INIT_ABORT_UNLESS(GenerateRandomBytesImpl(dst, size));
|
||||||
|
|
||||||
/* Copy output. */
|
|
||||||
std::memcpy(dst, std::addressof(args.r[1]), size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value) {
|
void ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value) {
|
||||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ReadWriteRegister, address, mask, value } };
|
/* Ensure we successfully access the register. */
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(ReadWriteRegisterImpl(out, address, mask, value));
|
||||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, false>(args.r);
|
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS((static_cast<SmcResult>(args.r[0]) == SmcResult::Success));
|
|
||||||
|
|
||||||
*out = args.r[1];
|
|
||||||
|
|
||||||
return static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TryGetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
bool TryGetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
||||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GetConfig, static_cast<u32>(config_item) } };
|
/* Disable interrupts. */
|
||||||
|
KScopedInterruptDisable di;
|
||||||
|
|
||||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
/* Get the config. */
|
||||||
if (AMS_UNLIKELY(static_cast<SmcResult>(args.r[0]) != SmcResult::Success)) {
|
return TryGetConfigImpl(out, num_qwords, config_item);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num_qwords && i < 7; i++) {
|
|
||||||
out[i] = args.r[1 + i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item) {
|
||||||
|
/* Ensure we successfully get the config. */
|
||||||
MESOSPHERE_ABORT_UNLESS(TryGetConfig(out, num_qwords, config_item));
|
MESOSPHERE_ABORT_UNLESS(TryGetConfig(out, num_qwords, config_item));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetConfig(ConfigItem config_item, u64 value) {
|
bool SetConfig(ConfigItem config_item, u64 value) {
|
||||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_SetConfig, static_cast<u32>(config_item), 0, value } };
|
/* Disable interrupts. */
|
||||||
|
KScopedInterruptDisable di;
|
||||||
|
|
||||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
/* Set the config. */
|
||||||
|
return SetConfigImpl(config_item, value);
|
||||||
return static_cast<SmcResult>(args.r[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) {
|
||||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ReadWriteRegister, address, mask, value } };
|
/* Disable interrupts. */
|
||||||
|
KScopedInterruptDisable di;
|
||||||
|
|
||||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
/* Access the register. */
|
||||||
|
return ReadWriteRegisterImpl(out, address, mask, value);
|
||||||
*out = static_cast<u32>(args.r[1]);
|
|
||||||
return static_cast<SmcResult>(args.r[0]) == SmcResult::Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureCarveout(size_t which, uintptr_t address, size_t size) {
|
void ConfigureCarveout(size_t which, uintptr_t address, size_t size) {
|
||||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_ConfigureCarveout, static_cast<u64>(which), static_cast<u64>(address), static_cast<u64>(size) } };
|
/* Disable interrupts. */
|
||||||
|
KScopedInterruptDisable di;
|
||||||
|
|
||||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
/* Ensure that we successfully configure the carveout. */
|
||||||
|
MESOSPHERE_ABORT_UNLESS(ConfigureCarveoutImpl(which, address, size));
|
||||||
MESOSPHERE_ABORT_UNLESS((static_cast<SmcResult>(args.r[0]) == SmcResult::Success));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateRandomBytes(void *dst, size_t size) {
|
void GenerateRandomBytes(void *dst, size_t size) {
|
||||||
/* Setup for call. */
|
/* Check that the size is valid. */
|
||||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_GenerateRandomBytes, size } };
|
MESOSPHERE_ABORT_UNLESS(0 < size && size <= GenerateRandomBytesSizeMax);
|
||||||
MESOSPHERE_ABORT_UNLESS(size <= sizeof(args) - sizeof(args.r[0]));
|
|
||||||
|
|
||||||
/* Make call. */
|
/* Disable interrupts. */
|
||||||
{
|
KScopedInterruptDisable di;
|
||||||
KScopedInterruptDisable intr_disable;
|
|
||||||
|
/* Acquire the exclusive right to generate random bytes. */
|
||||||
KScopedSpinLock lk(g_generate_random_lock);
|
KScopedSpinLock lk(g_generate_random_lock);
|
||||||
|
|
||||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
/* Ensure we successfully generate the random bytes. */
|
||||||
}
|
MESOSPHERE_ABORT_UNLESS(GenerateRandomBytesImpl(dst, size));
|
||||||
MESOSPHERE_ABORT_UNLESS((static_cast<SmcResult>(args.r[0]) == SmcResult::Success));
|
|
||||||
|
|
||||||
/* Copy output. */
|
|
||||||
std::memcpy(dst, std::addressof(args.r[1]), size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NORETURN Panic(u32 color) {
|
void ShowError(u32 color) {
|
||||||
ams::svc::lp64::SecureMonitorArguments args = { { FunctionId_Panic, color } };
|
/* Disable interrupts. */
|
||||||
|
KScopedInterruptDisable di;
|
||||||
|
|
||||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_Supervisor, true>(args.r);
|
/* Ensure we successfully show the error. */
|
||||||
|
MESOSPHERE_ABORT_UNLESS(ShowErrorImpl(color));
|
||||||
AMS_INFINITE_LOOP();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args) {
|
void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args) {
|
||||||
::ams::kern::arch::arm64::smc::SecureMonitorCall<SmcId_User, true>(args->r);
|
/* Disable interrupts. */
|
||||||
|
KScopedInterruptDisable di;
|
||||||
|
|
||||||
|
/* Perform the call. */
|
||||||
|
CallSecureMonitorFromUserImpl(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -111,7 +111,7 @@ namespace ams::kern::board::nintendo::nx::smc {
|
||||||
|
|
||||||
bool SetConfig(ConfigItem config_item, u64 value);
|
bool SetConfig(ConfigItem config_item, u64 value);
|
||||||
|
|
||||||
void NORETURN Panic(u32 color);
|
void ShowError(u32 color);
|
||||||
|
|
||||||
void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args);
|
void CallSecureMonitorFromUser(ams::svc::lp64::SecureMonitorArguments *args);
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ namespace ams::kern::board::nintendo::nx::smc {
|
||||||
|
|
||||||
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item);
|
void GetConfig(u64 *out, size_t num_qwords, ConfigItem config_item);
|
||||||
void GenerateRandomBytes(void *dst, size_t size);
|
void GenerateRandomBytes(void *dst, size_t size);
|
||||||
bool ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value);
|
void ReadWriteRegister(u32 *out, u64 address, u32 mask, u32 value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace ams::kern {
|
||||||
|
|
||||||
void KSystemControlBase::Init::CpuOnImpl(u64 core_id, uintptr_t entrypoint, uintptr_t arg) {
|
void KSystemControlBase::Init::CpuOnImpl(u64 core_id, uintptr_t entrypoint, uintptr_t arg) {
|
||||||
#if defined(ATMOSPHERE_ARCH_ARM64)
|
#if defined(ATMOSPHERE_ARCH_ARM64)
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn<0, false>(core_id, entrypoint, arg)) == 0);
|
MESOSPHERE_INIT_ABORT_UNLESS((::ams::kern::arch::arm64::smc::CpuOn<0>(core_id, entrypoint, arg)) == 0);
|
||||||
#else
|
#else
|
||||||
AMS_INFINITE_LOOP();
|
AMS_INFINITE_LOOP();
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue