Skip to content

Commit

Permalink
thor: Handle shutting down from userspace
Browse files Browse the repository at this point in the history
  • Loading branch information
Dennisbonke committed Oct 1, 2024
1 parent 6f76891 commit 1a6a425
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions kernel/thor/system/acpi/pm-interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,53 @@ struct PmInterfaceBusObject : private KernelBusObject {
infoLogger() << "thor: Reset using PS/2 controller failed" << frg::endlog;
#endif
panicLogger() << "thor: We do not know how to reset" << frg::endlog;
} else if(preamble.id() == bragi::message_id<managarm::hw::RebootRequest>) {
auto req = bragi::parse_head_only<managarm::hw::RebootRequest>(reqBuffer, *kernelAlloc);

if(!req) {
infoLogger() << "thor: Closing lane due to illegal HW request." << frg::endlog;
co_return Error::protocolViolation;
}

uacpi_sleep_state state = UACPI_SLEEP_STATE_S0;
switch(req->cmd()) {
case 5:
state = UACPI_SLEEP_STATE_S5;
break;
case 6: {
auto ret = uacpi_reboot();
if(uacpi_unlikely_error(ret))
infoLogger() << "thor: ACPI reset failed: " << uacpi_status_to_string(ret) << frg::endlog;

#ifdef __x86_64__
issuePs2Reset();
infoLogger() << "thor: Reset using PS/2 controller failed" << frg::endlog;
#endif
panicLogger() << "thor: We do not know how to reset" << frg::endlog;
break;
}
default:
infoLogger() << "thor: Unhandled reboot request" << frg::endlog;
co_return frg::success;
}

auto ret = uacpi_prepare_for_sleep_state(state);
if(uacpi_unlikely_error(ret))
infoLogger() << "thor: Preparing to enter sleep state S" << (int)state << " failed: " << uacpi_status_to_string(ret) << frg::endlog;

// uACPI Documentation states that you must call uacpi_enter_sleep_state with interrupts disabled.
disableInts();

ret = uacpi_enter_sleep_state(state);
if(uacpi_unlikely_error(ret))
infoLogger() << "thor: Entering sleep state S" << (int)state << " failed: " << uacpi_status_to_string(ret) << frg::endlog;

// Either reboot failed, poweroff failed, or someone is funny and thinks we can suspend.
// Either way, return succes.

// Oops, re-enable before returning.
enableInts();
co_return frg::success;
}else{
infoLogger() << "thor: Dismissing conversation due to illegal HW request." << frg::endlog;
co_await DismissSender{conversation};
Expand Down

0 comments on commit 1a6a425

Please sign in to comment.