kern: implement and comment missing 23.0.0 changes

This commit is contained in:
hexkyz
2026-09-23 00:02:33 +01:00
parent 21f16ff938
commit 2d0fc65fd8
13 changed files with 68 additions and 20 deletions

View File

@@ -220,6 +220,8 @@ namespace ams::kern::arch::arm64::cpu {
virtual KInterruptTask *OnInterrupt(s32 interrupt_id) override {
MESOSPHERE_UNUSED(interrupt_id);
/* TODO: 23.0.0+ now yields here while m_target_cores doesn't have the current core id bit set. */
/* Evaluate if we should do the same. */
this->ProcessOperation();
m_target_cores &= ~(1ul << GetCurrentCoreId());
return nullptr;

View File

@@ -381,7 +381,7 @@ namespace ams::kern::arch::arm64 {
}
/* Exit the current process. */
cur_process.Exit();
cur_process.Exit(-1ll);
}
}
@@ -548,7 +548,7 @@ namespace ams::kern::arch::arm64 {
MESOSPHERE_EXCEPTION_LOG("Exception occurred. ");
/* Exit the current process. */
GetCurrentProcess().Exit();
GetCurrentProcess().Exit(-1ll);
}
/* NOTE: This function is called from ASM. */

View File

@@ -411,7 +411,10 @@ namespace ams::kern::board::nintendo::nx {
{
/* Set whether we're in debug mode. */
{
ts->is_not_debug_mode = !GetConfigBool(smc::ConfigItem::IsDebugMode);
ts->is_not_debug_mode = !GetConfigBool(smc::ConfigItem::IsDebugMode);
/* TODO: 23.0.0+ split debug mode into 2 fields. Implement this properly for better accuracy. */
ts->is_not_debug_mode2 = ts->is_not_debug_mode;
/* If we're not in debug mode, we don't want to initialize uart logging. */
ts->disable_debug_logging = ts->is_not_debug_mode;

View File

@@ -223,6 +223,8 @@ namespace ams::kern::board::nintendo::nx::smc {
KScopedInterruptDisable di;
/* Ensure we successfully show the error. */
/* NOTE: On 23.0.0+ the SMC result is discarded. */
/* The function now ends with an unconditional infinite loop and interrupts are never restored. */
MESOSPHERE_ABORT_UNLESS(ShowErrorImpl(color));
}

View File

@@ -417,7 +417,7 @@ namespace ams::kern {
/* Terminate the process. */
/* NOTE: This result is seemingly-intentionally not checked by Nintendo. */
static_cast<void>(target->Terminate());
static_cast<void>(target->Terminate(-1ll));
R_SUCCEED();
}

View File

@@ -465,7 +465,7 @@ namespace ams::kern {
}
}
void KProcess::Exit() {
void KProcess::Exit(s64 exit_tag) {
MESOSPHERE_ASSERT_THIS();
/* Determine whether we need to start terminating. */
@@ -480,6 +480,7 @@ namespace ams::kern {
MESOSPHERE_ASSERT(m_state != State_Terminated);
if (m_state == State_Running || m_state == State_RunningAttached || m_state == State_DebugBreak) {
this->ChangeState(State_Terminating);
this->SetExitTag(exit_tag);
needs_terminate = true;
}
}
@@ -500,7 +501,7 @@ namespace ams::kern {
MESOSPHERE_PANIC("Thread survived call to exit");
}
Result KProcess::Terminate() {
Result KProcess::Terminate(s64 exit_tag) {
MESOSPHERE_ASSERT_THIS();
/* Determine whether we need to start terminating */
@@ -516,6 +517,7 @@ namespace ams::kern {
if (m_state == State_Running || m_state == State_RunningAttached || m_state == State_Crashed || m_state == State_DebugBreak) {
this->ChangeState(State_Terminating);
this->SetExitTag(exit_tag);
needs_terminate = true;
}
}
@@ -783,7 +785,7 @@ namespace ams::kern {
MESOSPHERE_ASSERT(m_num_running_threads.Load() > 0);
if (const auto prev = m_num_running_threads--; prev == 1) {
static_cast<void>(this->Terminate());
static_cast<void>(this->Terminate(-1ll));
}
}

View File

@@ -28,6 +28,8 @@ namespace ams::kern {
} else {
/* Allocate dynamic mappings as necessary. */
if (m_dynamic_mappings == nullptr) {
/* 23.0.0+ now checks for IsDynamicResourceLimitsEnabled before allocating from slab heap. */
R_UNLESS(KTargetSystem::IsDynamicResourceLimitsEnabled(), svc::ResultOutOfMemory());
m_dynamic_mappings = DynamicMappings::Allocate();
R_UNLESS(m_dynamic_mappings != nullptr, svc::ResultOutOfMemory());
}

View File

@@ -70,7 +70,7 @@ namespace ams::kern::svc {
}
/* Exit the current process. */
GetCurrentProcess().Exit();
GetCurrentProcess().Exit(-1ll);
}
}

View File

@@ -25,8 +25,9 @@ namespace ams::kern::svc {
return (0 <= core_id && core_id < static_cast<int32_t>(cpu::NumVirtualCores));
}
void ExitProcess() {
GetCurrentProcess().Exit();
void ExitProcess(int64_t exit_tag) {
const uint32_t intended_kernel_major_version = GetCurrentProcess().GetIntendedKernelMajorVersion();
GetCurrentProcess().Exit(intended_kernel_major_version <= 26 ? -1ll : exit_tag);
MESOSPHERE_PANIC("Process survived call to exit");
}
@@ -357,7 +358,7 @@ namespace ams::kern::svc {
R_RETURN(process->Run(priority, static_cast<size_t>(aligned_stack_size)));
}
Result TerminateProcess(ams::svc::Handle process_handle) {
Result TerminateProcess(ams::svc::Handle process_handle, int64_t exit_tag) {
/* Get the target process. */
KProcess *process = GetCurrentProcess().GetHandleTable().GetObject<KProcess>(process_handle).ReleasePointerUnsafe();
R_UNLESS(process != nullptr, svc::ResultInvalidHandle());
@@ -367,13 +368,13 @@ namespace ams::kern::svc {
ON_SCOPE_EXIT { process->Close(); };
/* Terminate the process. */
R_TRY(process->Terminate());
R_TRY(process->Terminate(exit_tag));
} else {
/* We're terminating ourselves. Close our reference immediately. */
process->Close();
/* Exit. */
ExitProcess();
ExitProcess(exit_tag);
}
R_SUCCEED();
@@ -411,6 +412,20 @@ namespace ams::kern::svc {
}
}
break;
case ams::svc::ProcessInfoType_Unknown1:
{
/* TODO: 23.0.0+ added a new process info type. Figure out what this is. */
/* For now just call it an exit tag since it's only set during Exit or Terminate. */
int64_t exit_tag;
{
KScopedLightLock proc_lk(process->GetStateLock());
exit_tag = process->GetExitTag();
}
*out = exit_tag;
}
break;
default:
R_THROW(svc::ResultInvalidEnumValue());
}
@@ -423,7 +438,9 @@ namespace ams::kern::svc {
/* ============================= 64 ABI ============================= */
void ExitProcess64() {
return ExitProcess();
/* TODO: 23.0.0+ changed the actual SVC handler. */
/* For now just pass the default value for the exit tag. */
return ExitProcess(-1ll);
}
Result GetProcessId64(uint64_t *out_process_id, ams::svc::Handle process_handle) {
@@ -443,7 +460,9 @@ namespace ams::kern::svc {
}
Result TerminateProcess64(ams::svc::Handle process_handle) {
R_RETURN(TerminateProcess(process_handle));
/* TODO: 23.0.0+ changed the actual SVC handler. */
/* For now just pass the default value for the exit tag. */
R_RETURN(TerminateProcess(process_handle, -1ll));
}
Result GetProcessInfo64(int64_t *out_info, ams::svc::Handle process_handle, ams::svc::ProcessInfoType info_type) {
@@ -453,7 +472,9 @@ namespace ams::kern::svc {
/* ============================= 64From32 ABI ============================= */
void ExitProcess64From32() {
return ExitProcess();
/* TODO: 23.0.0+ changed the actual SVC handler. */
/* For now just pass the default value for the exit tag. */
return ExitProcess(-1ll);
}
Result GetProcessId64From32(uint64_t *out_process_id, ams::svc::Handle process_handle) {
@@ -473,7 +494,9 @@ namespace ams::kern::svc {
}
Result TerminateProcess64From32(ams::svc::Handle process_handle) {
R_RETURN(TerminateProcess(process_handle));
/* TODO: 23.0.0+ changed the actual SVC handler. */
/* For now just pass the default value for the exit tag. */
R_RETURN(TerminateProcess(process_handle, -1ll));
}
Result GetProcessInfo64From32(int64_t *out_info, ams::svc::Handle process_handle, ams::svc::ProcessInfoType info_type) {

View File

@@ -28,6 +28,8 @@ namespace ams::kern::svc {
/* ============================= 64 ABI ============================= */
void CallSecureMonitor64(ams::svc::lp64::SecureMonitorArguments *args) {
/* TODO: 23.0.0+ added a second argument to CallSecureMonitorFromUser. */
/* On NX, CallSecureMonitor64 always passes 0 for this argument. */
KSystemControl::CallSecureMonitorFromUser(args);
}