Skip to content

Commit f207a96

Browse files
acpi shutdown support
1 parent 7183f4e commit f207a96

2 files changed

Lines changed: 47 additions & 11 deletions

File tree

include/acpi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,6 @@ bool pm_timer_is_32_bit(void);
261261
*/
262262
void acpi_claim_deferred_irqs(void);
263263

264+
bool power_button_init(void);
265+
266+
bool shutdown(void);

src/acpi.c

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <stdatomic.h>
88
#include "uacpi/context.h"
99
#include "uacpi/tables.h"
10+
#include "uacpi/sleep.h"
11+
#include "uacpi/event.h"
1012

1113
volatile struct limine_rsdp_request rsdp_request = {
1214
.id = LIMINE_RSDP_REQUEST,
@@ -657,6 +659,7 @@ void acpi_claim_deferred_irqs(void) {
657659
}
658660
}
659661
uacpi_claim_phase = true;
662+
power_button_init();
660663
}
661664

662665
uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request *req) {
@@ -677,7 +680,6 @@ uacpi_status uacpi_kernel_handle_firmware_request(uacpi_firmware_request *req) {
677680

678681

679682
void async_run_gpe_handler(uacpi_handle gpe) {
680-
// No GPE support yet
681683
}
682684

683685
uacpi_status uacpi_kernel_schedule_work(uacpi_work_type type, uacpi_work_handler handler, uacpi_handle ctx) {
@@ -735,22 +737,53 @@ static uacpi_iteration_decision resource_callback(void *user, uacpi_resource *re
735737
}
736738

737739
static uacpi_iteration_decision device_callback(void *user, uacpi_namespace_node *node, uacpi_u32 depth) {
738-
(void)user;
739-
(void)depth;
740-
741740
uacpi_resources *resources = NULL;
742-
if (uacpi_get_current_resources(node, &resources) != UACPI_STATUS_OK || !resources)
741+
if (uacpi_get_current_resources(node, &resources) != UACPI_STATUS_OK || !resources) {
743742
return UACPI_ITERATION_DECISION_CONTINUE;
744-
743+
}
745744
uacpi_for_each_resource(resources, resource_callback, NULL);
746-
747745
uacpi_free_resources(resources);
748746
return UACPI_ITERATION_DECISION_CONTINUE;
749747
}
750748

751749
void enumerate_all_gsis(void) {
752-
uacpi_namespace_for_each_child(
753-
uacpi_namespace_root(), device_callback,
754-
NULL, UACPI_OBJECT_DEVICE_BIT, UACPI_MAX_DEPTH_ANY, NULL
755-
);
750+
uacpi_namespace_for_each_child(uacpi_namespace_root(), device_callback, NULL, UACPI_OBJECT_DEVICE_BIT, UACPI_MAX_DEPTH_ANY, NULL);
756751
}
752+
753+
bool shutdown(void) {
754+
dprintf("uACPI shutdown process started...\n");
755+
uacpi_status ret = uacpi_prepare_for_sleep_state(UACPI_SLEEP_STATE_S5);
756+
if (uacpi_unlikely_error(ret)) {
757+
dprintf("[uACPI] Failed to prepare for sleep: %s", uacpi_status_to_string(ret));
758+
return false;
759+
}
760+
761+
dprintf("Entering S5 sleep state...\n");
762+
interrupts_off();
763+
ret = uacpi_enter_sleep_state(UACPI_SLEEP_STATE_S5);
764+
if (uacpi_unlikely_error(ret)) {
765+
dprintf("[uACPI] Failed to enter sleep: %s", uacpi_status_to_string(ret));
766+
return false;
767+
}
768+
return true;
769+
}
770+
771+
/*
772+
* This handler will be called by uACPI from an interrupt context,
773+
* whenever a power button press is detected.
774+
*/
775+
static uacpi_interrupt_ret handle_power_button(uacpi_handle ctx) {
776+
dprintf("uACPI power button event triggered\n");
777+
shutdown();
778+
return UACPI_INTERRUPT_HANDLED;
779+
}
780+
781+
bool power_button_init(void) {
782+
uacpi_status ret = uacpi_install_fixed_event_handler(UACPI_FIXED_EVENT_POWER_BUTTON, handle_power_button, UACPI_NULL);
783+
if (uacpi_unlikely_error(ret)) {
784+
dprintf("[uACPI] Failed to install power button event callback: %s", uacpi_status_to_string(ret));
785+
return false;
786+
}
787+
dprintf("uACPI power button event installed\n");
788+
return true;
789+
}

0 commit comments

Comments
 (0)