diff --git a/headers/os/drivers/ACPI.h b/headers/os/drivers/ACPI.h index accf860a84..f668bbaa26 100644 --- a/headers/os/drivers/ACPI.h +++ b/headers/os/drivers/ACPI.h @@ -34,6 +34,8 @@ struct acpi_module_info { status_t (*get_device_hid) (const char *path, char *hid); uint32 (*get_object_type) (const char *path); + status_t (*get_object) (const char *path, acpi_object_type **return_value); + status_t (*get_object_typed) (const char *path, acpi_object_type **return_value, uint32 object_type); /* Control method execution and data acquisition */ 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 e7978f6685..85882b4593 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c @@ -23,6 +23,8 @@ status_t get_next_entry (uint32 object_type, const char *base, char *result, siz status_t get_device (const char *hid, uint32 index, char *result); status_t get_device_hid (const char *path, char *hid); +status_t get_object(const char *path, acpi_object_type **return_value); +status_t get_object_typed(const char *path, acpi_object_type **return_value, uint32 object_type); uint32 get_object_type (const char *path); status_t evaluate_object (const char *object, acpi_object_type *return_value, size_t buf_len); @@ -50,6 +52,8 @@ struct acpi_module_info acpi_module = { get_next_entry, get_device, get_device_hid, + get_object, + get_object_typed, get_object_type, evaluate_object, evaluate_method, @@ -251,6 +255,42 @@ uint32 get_object_type (const char *path) { return type; } +status_t get_object (const char *path, acpi_object_type **return_value) { + ACPI_HANDLE handle; + ACPI_BUFFER buffer; + ACPI_STATUS status; + + status = AcpiGetHandle(NULL, path, &handle); + if (status != AE_OK) { + return B_ENTRY_NOT_FOUND; + } + buffer.Pointer = NULL; + buffer.Length = ACPI_ALLOCATE_BUFFER; + + status = AcpiEvaluateObject(handle, NULL, NULL, &buffer); + + *return_value = buffer.Pointer; + return (status == AE_OK) ? B_OK : B_ERROR; +} + +status_t get_object_typed (const char *path, acpi_object_type **return_value, uint32 object_type) { + ACPI_HANDLE handle; + ACPI_BUFFER buffer; + ACPI_STATUS status; + + status = AcpiGetHandle(NULL, path, &handle); + if (status != AE_OK) { + return B_ENTRY_NOT_FOUND; + } + buffer.Pointer = NULL; + buffer.Length = ACPI_ALLOCATE_BUFFER; + + status = AcpiEvaluateObjectTyped(handle, NULL, NULL, &buffer, object_type); + + *return_value = buffer.Pointer; + return (status == AE_OK) ? B_OK : B_ERROR; +} + status_t evaluate_object (const char *object, acpi_object_type *return_value, size_t buf_len) { ACPI_BUFFER buffer; ACPI_STATUS status; diff --git a/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.c b/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.c index 36afe92f9e..726c8b2cc3 100644 --- a/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.c +++ b/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.c @@ -36,6 +36,7 @@ void enumerate_devices (char* parent) if (td != NULL) { td->open = 0; td->num = device_count; + dprintf("acpi_thermal: Adding thermal device from: %s\n", result); td->path = malloc(sizeof(char) * strlen(result) + 1); strcpy(td->path, result); @@ -139,6 +140,7 @@ acpi_thermal_open (const char *name, uint32 flags, void** cookie) static status_t acpi_thermal_read (void* cookie, off_t position, void *buf, size_t* num_bytes) { + int i; acpi_thermal_type therm_info; if (*num_bytes < 1) return B_IO_ERROR; @@ -149,16 +151,37 @@ acpi_thermal_read (void* cookie, off_t position, void *buf, size_t* num_bytes) sprintf((char *)buf, "ACPI Thermal Device %u\n", therm_info.devnum); *num_bytes = strlen((char *)buf); - sprintf((char *)buf + *num_bytes, " Critical Temperature: %lu.%lu K\n", (therm_info.critical_temp / 10), (therm_info.critical_temp % 10)); + sprintf((char *)buf + *num_bytes, " Critical Temperature: %lu.%lu K\n", + (therm_info.critical_temp / 10), (therm_info.critical_temp % 10)); *num_bytes = strlen((char *)buf); - sprintf((char *)buf + *num_bytes, " Current Temperature: %lu.%lu K\n", (therm_info.current_temp / 10), (therm_info.current_temp % 10)); + sprintf((char *)buf + *num_bytes, " Current Temperature: %lu.%lu K\n", + (therm_info.current_temp / 10), (therm_info.current_temp % 10)); *num_bytes = strlen((char *)buf); if (therm_info.hot_temp > 0) { - sprintf((char *)buf, "Hot Temperature: %lu.%lu K\n", (therm_info.hot_temp / 10), (therm_info.hot_temp % 10)); + sprintf((char *)buf + *num_bytes, " Hot Temperature: %lu.%lu K\n", + (therm_info.hot_temp / 10), (therm_info.hot_temp % 10)); *num_bytes = strlen((char *)buf); } + + if (therm_info.passive_package) { +/* Incomplete. + Needs to obtain acpi global lock. + acpi_object_type needs Reference entry (with Handle that can be resolved) + what you see here is _highly_ unreliable. +*/ +/* if (therm_info.passive_package->data.package.count > 0) { + sprintf((char *)buf + *num_bytes, " Passive Devices\n"); + *num_bytes = strlen((char *)buf); + for (i = 0; i < therm_info.passive_package->data.package.count; i++) { + sprintf((char *)buf + *num_bytes, " Processor: %lu\n", therm_info.passive_package->data.package.objects[i].data.processor.cpu_id); + *num_bytes = strlen((char *)buf); + } + } +*/ + free(therm_info.passive_package); + } } else { *num_bytes = 0; } @@ -178,16 +201,18 @@ acpi_thermal_control (void* cookie, uint32 op, void* arg, size_t len) status_t err = B_ERROR; thermal_dev *td = (thermal_dev *)cookie; + char objname[255]; acpi_thermal_type *att = NULL; + size_t bufsize = sizeof(acpi_object_type); acpi_object_type buf; - size_t bufsize = sizeof(buf); - + switch (op) { case drvOpGetThermalType: { dprintf("acpi_thermal: GetThermalType()\n"); att = (acpi_thermal_type *)arg; + // Read basic temperature thresholds. att->devnum = td->num; err = acpi->evaluate_method(td->path, "_CRT", &buf, bufsize, NULL, 0); att->critical_temp = buf.data.integer; @@ -201,9 +226,10 @@ acpi_thermal_control (void* cookie, uint32 op, void* arg, size_t len) } dprintf("acpi_thermal: GotBasicTemperatures()\n"); - // TODO: Fill this out - att->passive_count = 0; + // Read Passive Cooling devices att->passive_package = NULL; + sprintf(objname, "%s._PSL", td->path); + err = acpi->get_object(objname, &(att->passive_package)); att->active_count = 0; att->active_devices = NULL; diff --git a/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.h b/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.h index 2fbc7a3d39..fd9133aba1 100644 --- a/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.h +++ b/src/add-ons/kernel/drivers/power/acpi_thermal/acpi_thermal.h @@ -26,8 +26,9 @@ struct acpi_thermal_type { /* Optional HOT temp, S4 sleep threshold */ uint32 hot_temp; - /* List of acpi_objects_types assigned to the passive device list */ - uint32 passive_count; + /* acpi_objects_type evaluated from _PSL + if != NULL, client must free() + */ acpi_object_type *passive_package; /* List of acpi_thermal_active_objects that can actively manage this thermal device */