From 6d92b10268dd05503fe53e55450c6fdfc629161c Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Fri, 18 Mar 2005 00:41:53 +0000 Subject: [PATCH] Upgraded the bus manager interface. It's now capable enough to start actually doing interesting things, like power management, thermal stuff, and hyperthreading. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@11891 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/ACPI.h | 48 ++++++++- .../kernel/bus_managers/acpi/acpi_busman.c | 97 ++++++++++++++++++- .../acpi/include/platform/achaiku.h | 5 + 3 files changed, 145 insertions(+), 5 deletions(-) diff --git a/headers/os/drivers/ACPI.h b/headers/os/drivers/ACPI.h index 98f6bbce8b..accf860a84 100644 --- a/headers/os/drivers/ACPI.h +++ b/headers/os/drivers/ACPI.h @@ -10,7 +10,7 @@ #include typedef struct acpi_module_info acpi_module_info; -typedef struct acpi_object_info acpi_object_info; +typedef struct acpi_object_type acpi_object_type; struct acpi_module_info { bus_manager_info binfo; @@ -30,12 +30,25 @@ struct acpi_module_info { /* Namespace Access */ status_t (*get_next_entry) (uint32 object_type, const char *base, char *result, size_t len, void **counter); + status_t (*get_device) (const char *hid, uint32 index, char *result); + status_t (*get_device_hid) (const char *path, char *hid); uint32 (*get_object_type) (const char *path); /* Control method execution and data acquisition */ - status_t (*evaluate_object) (const char *object, void *return_value, size_t buf_len); + status_t (*evaluate_object) (const char *object, acpi_object_type *return_value, size_t buf_len); + status_t (*evaluate_method) (const char *object, const char *method, acpi_object_type *return_value, size_t buf_len, acpi_object_type *args, int num_args); + /* Power state setting */ + + status_t (*enter_sleep_state) (uint8 state); + /* Sleep state values: + 0: On (Working) + 1: Sleep + 2: Software Off + 3: Mechanical Off + 4: Hibernate + 5: Software Off */ }; @@ -71,6 +84,37 @@ enum { ACPI_TYPE_BUFFER_FIELD }; +/* ACPI control method arg type */ + +struct acpi_object_type { + uint32 object_type; + union { + uint32 integer; + struct { + uint32 len; + char *string; /* You have to allocate string space yourself */ + } string; + struct { + size_t length; + void *buffer; + } buffer; + struct { + uint32 count; + acpi_object_type *objects; + } package; + struct { + uint32 cpu_id; + + int pblk_address; + size_t pblk_length; + } processor; + struct { + uint32 min_power_state; + uint32 resource_order; + } power_resource; + } data; +}; + #endif #define B_ACPI_MODULE_NAME "bus_managers/acpi/v1" diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c index de1ba9237d..c56e8c1bda 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "acpi.h" #include "acpixf.h" @@ -18,10 +19,15 @@ status_t install_fixed_event_handler (uint32 event, interrupt_handler *handler, status_t remove_fixed_event_handler (uint32 event, interrupt_handler *handler); status_t get_next_entry (uint32 object_type, const char *base, char *result, size_t len, void **counter); +status_t get_device (const char *hid, uint32 index, char *result); + status_t get_device_hid (const char *path, char *hid); uint32 get_object_type (const char *path); -status_t evaluate_object (const char *object, void *return_value, size_t buf_len); +status_t evaluate_object (const char *object, acpi_object_type *return_value, size_t buf_len); +status_t evaluate_method (const char *object, const char *method, acpi_object_type *return_value, size_t buf_len, acpi_object_type *args, int num_args); + +status_t enter_sleep_state (uint8 state); struct acpi_module_info acpi_module = { { @@ -41,8 +47,12 @@ struct acpi_module_info acpi_module = { install_fixed_event_handler, remove_fixed_event_handler, get_next_entry, + get_device, get_device_hid, - get_object_type + get_object_type, + evaluate_object, + evaluate_method, + enter_sleep_state }; _EXPORT module_info *modules[] = { @@ -155,6 +165,44 @@ status_t get_next_entry (uint32 object_type, const char *base, char *result, siz return B_OK; } +static ACPI_STATUS get_device_by_hid_callback(ACPI_HANDLE object, UINT32 depth, void *context, void **return_val) { + ACPI_STATUS result; + ACPI_BUFFER buffer; + uint32 *counter = (uint32 *)(context); + + buffer.Length = 255; + buffer.Pointer = malloc(255); + + *return_val = NULL; + + if (counter[0] == counter[1]) { + result = AcpiGetName(object,ACPI_FULL_PATHNAME,&buffer); + if (result != AE_OK) + return result; + + ((char*)(buffer.Pointer))[buffer.Length] = '\0'; + *return_val = buffer.Pointer; + return AE_CTRL_TERMINATE; + } + + counter[1]++; + return AE_OK; +} + +status_t get_device (const char *hid, uint32 index, char *result) { + ACPI_STATUS status; + uint32 counter[2] = {index,0}; + char *result2; + + status = AcpiGetDevices((char *)hid,&get_device_by_hid_callback,counter,&result2); + if ((status != AE_OK) || (result2 == NULL)) + return B_ENTRY_NOT_FOUND; + + strcpy(result,result2); + free(result2); + return B_OK; +} + status_t get_device_hid (const char *path, char *hid) { ACPI_HANDLE handle; ACPI_DEVICE_INFO info; @@ -180,7 +228,7 @@ uint32 get_object_type (const char *path) { return type; } -status_t evaluate_object (const char *object, void *return_value, size_t buf_len) { +status_t evaluate_object (const char *object, acpi_object_type *return_value, size_t buf_len) { ACPI_BUFFER buffer; ACPI_STATUS status; @@ -190,3 +238,46 @@ status_t evaluate_object (const char *object, void *return_value, size_t buf_len status = AcpiEvaluateObject(NULL,object,NULL,(return_value != NULL) ? &buffer : NULL); return (status == AE_OK) ? B_OK : B_ERROR; } + +status_t evaluate_method (const char *object, const char *method, acpi_object_type *return_value, size_t buf_len, acpi_object_type *args, int num_args) { + ACPI_BUFFER buffer; + ACPI_STATUS status; + ACPI_OBJECT_LIST acpi_args; + ACPI_HANDLE handle; + + if (AcpiGetHandle(NULL,object,&handle) != AE_OK) + return B_ENTRY_NOT_FOUND; + + buffer.Pointer = return_value; + buffer.Length = buf_len; + + acpi_args.Count = num_args; + acpi_args.Pointer = args; + + status = AcpiEvaluateObject(handle,method,(args != NULL) ? &acpi_args : NULL,(return_value != NULL) ? &buffer : NULL); + return (status == AE_OK) ? B_OK : B_ERROR; +} + +status_t enter_sleep_state (uint8 state) { + ACPI_STATUS status; + cpu_status cpu; + + status = AcpiEnterSleepStatePrep(state); + if (status != AE_OK) + return B_ERROR; + + /* NOT SMP SAFE (!!!!!!!!!!!) */ + + cpu = disable_interrupts(); + status = AcpiEnterSleepState(state); + restore_interrupts(cpu); + + if (status != AE_OK) + return B_ERROR; + + status = AcpiLeaveSleepState(state); + if (status != AE_OK) + return B_ERROR; + + return B_OK; +} diff --git a/src/add-ons/kernel/bus_managers/acpi/include/platform/achaiku.h b/src/add-ons/kernel/bus_managers/acpi/include/platform/achaiku.h index 5a21ac6463..b7cf44abce 100644 --- a/src/add-ons/kernel/bus_managers/acpi/include/platform/achaiku.h +++ b/src/add-ons/kernel/bus_managers/acpi/include/platform/achaiku.h @@ -150,6 +150,10 @@ #define ACPI_INTERNAL_XFACE #define ACPI_INTERNAL_VAR_XFACE + +#define ACPI_FLUSH_CPU_CACHE() +/* Implement ACPI_FLUSH_CPU_CACHE to do something! */ + #ifdef ACPI_DEBUG #define ACPI_DEBUG_OUTPUT #define ACPI_DBG_TRACK_ALLOCATIONS @@ -170,6 +174,7 @@ /* Not building kernel code, so use libc */ #define ACPI_USE_STANDARD_HEADERS +#define ACPI_FLUSH_CPU_CACHE() #define __cli() #define __sti()