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
1113volatile 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
662665uacpi_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
679682void async_run_gpe_handler (uacpi_handle gpe ) {
680- // No GPE support yet
681683}
682684
683685uacpi_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
737739static 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
751749void 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