pm: actually implement GetBootFinishedEvent

This commit is contained in:
Michael Scire 2019-05-27 21:52:28 -07:00
parent f38965d0bd
commit d6502c174a
5 changed files with 108 additions and 84 deletions

View file

@ -35,6 +35,7 @@ static std::atomic<u64> g_debug_on_launch_tid(0);
static IEvent *g_process_event = nullptr;
static IEvent *g_debug_title_event = nullptr;
static IEvent *g_debug_application_event = nullptr;
static IEvent *g_boot_finished_event = nullptr;
static u8 g_ac_buf[4 * sizeof(LoaderProgramInfo)];
@ -46,6 +47,7 @@ void Registration::InitializeSystemResources() {
g_process_event = CreateWriteOnlySystemEvent();
g_debug_title_event = CreateWriteOnlySystemEvent();
g_debug_application_event = CreateWriteOnlySystemEvent();
g_boot_finished_event = CreateWriteOnlySystemEvent();
/* Auto-clear non-system event. */
g_process_launch_start_event = CreateHosEvent(&Registration::ProcessLaunchStartCallback);
@ -501,3 +503,19 @@ Result Registration::DisableDebug(u32 which) {
}
return ResultSuccess;
}
Handle Registration::GetDebugTitleEventHandle() {
return g_debug_title_event->GetHandle();
}
Handle Registration::GetDebugApplicationEventHandle() {
return g_debug_application_event->GetHandle();
}
Handle Registration::GetBootFinishedEventHandle() {
return g_boot_finished_event->GetHandle();
}
void Registration::SignalBootFinished() {
g_boot_finished_event->Signal();
}

View file

@ -193,6 +193,7 @@ class Registration {
static Result DisableDebug(u32 which);
static Handle GetDebugTitleEventHandle();
static Handle GetDebugApplicationEventHandle();
static Handle GetBootFinishedEventHandle();
static void HandleProcessLaunch();
static Result LaunchDebugProcess(u64 pid);
@ -200,6 +201,8 @@ class Registration {
static Result LaunchProcess(u64 title_id, FsStorageId storage_id, u64 launch_flags, u64 *out_pid);
static Result LaunchProcessByTidSid(TidSid tid_sid, u64 launch_flags, u64 *out_pid);
static void SignalBootFinished();
static bool HasApplicationProcess(std::shared_ptr<Process> *out);
};

View file

@ -86,6 +86,7 @@ Result ShellService::ClearProcessNotificationFlag(u64 pid) {
void ShellService::NotifyBootFinished() {
if (!g_has_boot_finished) {
g_has_boot_finished = true;
Registration::SignalBootFinished();
EmbeddedBoot2::Main();
}
}
@ -113,13 +114,15 @@ Result ShellService::BoostSystemThreadsResourceLimit() {
}
Result ShellService::GetUnimplementedEventHandle(Out<CopiedHandle> event) {
/* In 8.0.0, Nintendo added this command which should return an event handle. */
/* In addition, they also added code to create a new event in the global PM constructor. */
/* However, nothing signals this event, and this command currently does std::abort();. */
/* We will oblige. */
std::abort();
/* TODO: Return an event handle, once N makes this command a real thing in the future. */
/* TODO: return ResultSuccess; */
void ShellService::GetBootFinishedEvent(Out<CopiedHandle> event) {
/* In 8.0.0, Nintendo added this command, which signals that the boot sysmodule has finished. */
/* Nintendo only signals it in safe mode FIRM, and this function aborts on normal FIRM. */
/* We will signal it always, but only allow this function to succeed on safe mode. */
{
u64 is_recovery_boot = 0;
if (R_FAILED(SmcGetConfig(SplConfigItem_IsRecoveryBoot, &is_recovery_boot)) || !is_recovery_boot) {
std::abort();
}
}
event.SetValue(Registration::GetBootFinishedEventHandle());
}

View file

@ -44,7 +44,7 @@ enum ShellCmd_5X {
Shell_Cmd_5X_BoostSystemMemoryResourceLimit = 7,
Shell_Cmd_BoostSystemThreadsResourceLimit = 8,
Shell_Cmd_GetUnimplementedEventHandle = 9 /* TODO: Rename when Nintendo implements this. */
Shell_Cmd_GetBootFinishedEvent = 9,
};
class ShellService final : public IServiceObject {
@ -61,7 +61,7 @@ class ShellService final : public IServiceObject {
Result GetApplicationProcessId(Out<u64> pid);
Result BoostSystemMemoryResourceLimit(u64 sysmem_size);
Result BoostSystemThreadsResourceLimit();
Result GetUnimplementedEventHandle(Out<CopiedHandle> event);
void GetBootFinishedEvent(Out<CopiedHandle> event);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
/* 1.0.0-4.0.0 */
@ -92,6 +92,6 @@ class ShellService final : public IServiceObject {
MakeServiceCommandMeta<Shell_Cmd_BoostSystemThreadsResourceLimit, &ShellService::BoostSystemThreadsResourceLimit, FirmwareVersion_700>(),
/* 8.0.0-* */
MakeServiceCommandMeta<Shell_Cmd_GetUnimplementedEventHandle, &ShellService::GetUnimplementedEventHandle, FirmwareVersion_800>(),
MakeServiceCommandMeta<Shell_Cmd_GetBootFinishedEvent, &ShellService::GetBootFinishedEvent, FirmwareVersion_800>(),
};
};