From ce2d7d5ac8d220cb661fd12529fd5c88f5d80d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Mon, 21 Oct 2013 21:59:57 +0200 Subject: [PATCH] acpi: use walk_resources to find embedded controller I/O ports. * export walk_resources and use it * removed SmallResourceData * added embedded controller module for x86_64 --- headers/os/drivers/ACPI.h | 12 ++ .../kernel/bus_managers/acpi/ACPIPrivate.h | 10 ++ .../kernel/bus_managers/acpi/BusManager.cpp | 10 ++ .../kernel/bus_managers/acpi/Device.cpp | 9 ++ .../bus_managers/acpi/EmbeddedController.cpp | 52 ++++---- src/add-ons/kernel/bus_managers/acpi/Jamfile | 1 - .../kernel/bus_managers/acpi/Module.cpp | 3 +- .../bus_managers/acpi/SmallResourceData.cpp | 114 ------------------ .../bus_managers/acpi/SmallResourceData.h | 61 ---------- 9 files changed, 72 insertions(+), 200 deletions(-) delete mode 100644 src/add-ons/kernel/bus_managers/acpi/SmallResourceData.cpp delete mode 100644 src/add-ons/kernel/bus_managers/acpi/SmallResourceData.h diff --git a/headers/os/drivers/ACPI.h b/headers/os/drivers/ACPI.h index 2ff47aa36e..d601af7501 100644 --- a/headers/os/drivers/ACPI.h +++ b/headers/os/drivers/ACPI.h @@ -142,6 +142,8 @@ enum { */ typedef uint32 acpi_status; +typedef struct acpi_resource acpi_resource; + #endif // __ACTYPES_H__ @@ -159,6 +161,9 @@ typedef acpi_status (*acpi_adr_space_setup)(acpi_handle regionHandle, typedef void (*acpi_notify_handler)(acpi_handle device, uint32 value, void *context); +typedef acpi_status (*acpi_walk_resources_callback)(acpi_resource* resource, + void* context); + struct acpi_module_info { module_info info; @@ -251,6 +256,9 @@ struct acpi_module_info { acpi_data *retBuffer); status_t (*set_current_resources)(acpi_handle busDeviceHandle, acpi_data *buffer); + status_t (*walk_resources)(acpi_handle busDeviceHandle, + char *method, acpi_walk_resources_callback callback, + void* context); /* Power state setting */ @@ -317,6 +325,10 @@ typedef struct acpi_device_module_info { /* Control method execution and data acquisition */ status_t (*evaluate_method)(acpi_device device, const char *method, acpi_objects *args, acpi_data *returnValue); + + /* Resource Management */ + status_t (*walk_resources)(acpi_device device, char *method, + acpi_walk_resources_callback callback, void* context); } acpi_device_module_info; diff --git a/src/add-ons/kernel/bus_managers/acpi/ACPIPrivate.h b/src/add-ons/kernel/bus_managers/acpi/ACPIPrivate.h index 86ca25d8d0..68084efde1 100644 --- a/src/add-ons/kernel/bus_managers/acpi/ACPIPrivate.h +++ b/src/add-ons/kernel/bus_managers/acpi/ACPIPrivate.h @@ -39,6 +39,11 @@ typedef struct acpi_device_cookie { } acpi_device_cookie; +typedef struct acpi_resource acpi_resource; +typedef acpi_status (*acpi_walk_resources_callback)(acpi_resource* resource, + void* context); + + // ACPI root. typedef struct acpi_root_info { driver_module_info info; @@ -131,6 +136,9 @@ typedef struct acpi_root_info { acpi_data *retBuffer); status_t (*set_current_resources)(acpi_handle busDeviceHandle, acpi_data *buffer); + status_t (*walk_resources)(acpi_handle busDeviceHandle, + char *method, acpi_walk_resources_callback callback, + void* context); /* Power state setting */ @@ -217,6 +225,8 @@ status_t get_possible_resources(acpi_handle busDeviceHandle, acpi_data* returnValue); status_t set_current_resources(acpi_handle busDeviceHandle, acpi_data* buffer); +status_t walk_resources(acpi_handle busDeviceHandle, char* method, + acpi_walk_resources_callback callback, void* context); status_t prepare_sleep_state(uint8 state, void (*wakeFunc)(void), size_t size); status_t enter_sleep_state(uint8 state); diff --git a/src/add-ons/kernel/bus_managers/acpi/BusManager.cpp b/src/add-ons/kernel/bus_managers/acpi/BusManager.cpp index ce2a605c7f..b44d3a7377 100644 --- a/src/add-ons/kernel/bus_managers/acpi/BusManager.cpp +++ b/src/add-ons/kernel/bus_managers/acpi/BusManager.cpp @@ -624,6 +624,15 @@ set_current_resources(acpi_handle busDeviceHandle, acpi_data *buffer) } +status_t +walk_resources(acpi_handle busDeviceHandle, char* method, + acpi_walk_resources_callback callback, void* context) +{ + return AcpiWalkResources(busDeviceHandle, method, + (ACPI_WALK_RESOURCE_CALLBACK)callback, context); +} + + status_t prepare_sleep_state(uint8 state, void (*wakeFunc)(void), size_t size) { @@ -770,6 +779,7 @@ struct acpi_module_info gACPIModule = { get_current_resources, get_possible_resources, set_current_resources, + walk_resources, prepare_sleep_state, enter_sleep_state, reboot, diff --git a/src/add-ons/kernel/bus_managers/acpi/Device.cpp b/src/add-ons/kernel/bus_managers/acpi/Device.cpp index 77d1cc1d93..136f86633b 100644 --- a/src/add-ons/kernel/bus_managers/acpi/Device.cpp +++ b/src/add-ons/kernel/bus_managers/acpi/Device.cpp @@ -74,6 +74,14 @@ acpi_evaluate_method(acpi_device device, const char *method, } +static status_t +acpi_walk_resources(acpi_device device, char *method, + acpi_walk_resources_callback callback, void* context) +{ + return walk_resources(device->handle, method, callback, context); +} + + static status_t acpi_device_init_driver(device_node *node, void **cookie) { @@ -154,4 +162,5 @@ acpi_device_module_info gACPIDeviceModule = { acpi_get_object_type, acpi_get_object, acpi_evaluate_method, + acpi_walk_resources }; diff --git a/src/add-ons/kernel/bus_managers/acpi/EmbeddedController.cpp b/src/add-ons/kernel/bus_managers/acpi/EmbeddedController.cpp index e504a705ea..40dc31c017 100644 --- a/src/add-ons/kernel/bus_managers/acpi/EmbeddedController.cpp +++ b/src/add-ons/kernel/bus_managers/acpi/EmbeddedController.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2013, Jérôme Duval, korli@users.berlios.de. * Copyright (c) 2009 Clemens Zeidler * Copyright (c) 2003-2007 Nate Lawson * Copyright (c) 2000 Michael Smith @@ -40,8 +41,6 @@ #include #include -#include "SmallResourceData.h" - #define ACPI_EC_DRIVER_NAME "drivers/power/acpi_embedded_controller/driver_v1" @@ -143,6 +142,25 @@ acpi_PkgInt32(acpi_object_type* res, int idx, uint32* dst) } +acpi_status +embedded_controller_io_ports_parse_callback(ACPI_RESOURCE* resource, + void* _context) +{ + acpi_ec_cookie* sc = (acpi_ec_cookie*)_context; + if (resource->Type != ACPI_RESOURCE_TYPE_IO) + return AE_OK; + if (sc->ec_data_pci_address == 0) { + sc->ec_data_pci_address = resource->Data.Io.Minimum; + } else if (sc->ec_csr_pci_address == 0) { + sc->ec_csr_pci_address = resource->Data.Io.Minimum; + } else { + return AE_CTRL_TERMINATE; + } + + return AE_OK; +} + + // #pragma mark - @@ -282,13 +300,6 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie) (void**)&sc->ec_handle); gDeviceManager->put_node(parent); - SmallResourceData resourceData(sc->ec_acpi, sc->ec_handle, "_CRS"); - if (resourceData.InitCheck() != B_OK) { - TRACE("failed to read _CRS resource\n") ; - return B_ERROR; - } - io_port portData; - if (get_module(B_ACPI_MODULE_NAME, (module_info**)&sc->ec_acpi_module) != B_OK) return B_ERROR; @@ -313,7 +324,7 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie) // and GPE bit, similar to _PRW. status = sc->ec_acpi->evaluate_method(sc->ec_handle, "_GPE", NULL, &buf); if (status != B_OK) { - TRACE("can't evaluate _GPE\n"); + ERROR("can't evaluate _GPE\n"); goto error; } @@ -337,22 +348,19 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie) goto error; break; default: - TRACE("_GPE has invalid type %i\n", int(obj->object_type)); + ERROR("_GPE has invalid type %i\n", int(obj->object_type)); goto error; } sc->ec_suspending = FALSE; // Attach bus resources for data and command/status ports. - if (resourceData.ReadIOPort(&portData) != B_OK) + status = sc->ec_acpi->walk_resources(sc->ec_handle, "_CRS", + embedded_controller_io_ports_parse_callback, sc); + if (status != B_OK) { + ERROR("Error while getting IO ports addresses\n"); goto error; - - sc->ec_data_pci_address = portData.minimumBase; - - if (resourceData.ReadIOPort(&portData) != B_OK) - goto error; - - sc->ec_csr_pci_address = portData.minimumBase; + } // Install a handler for this EC's GPE bit. We want edge-triggered // behavior. @@ -369,14 +377,14 @@ embedded_controller_init_driver(device_node* dev, void** _driverCookie) status = sc->ec_acpi->install_address_space_handler(sc->ec_handle, ACPI_ADR_SPACE_EC, &EcSpaceHandler, &EcSpaceSetup, sc); if (status != B_OK) { - TRACE("can't install address space handler\n"); + ERROR("can't install address space handler\n"); goto error; } // Enable runtime GPEs for the handler. status = sc->ec_acpi_module->enable_gpe(sc->ec_gpehandle, sc->ec_gpebit); if (status != B_OK) { - TRACE("AcpiEnableGpe failed.\n"); + ERROR("AcpiEnableGpe failed.\n"); goto error; } @@ -519,7 +527,7 @@ EcGpeQueryHandler(void* context) // that may arise from running the query from causing another query // to be queued, we clear the pending flag only after running it. int sci_enqueued = sc->ec_sci_pending; - acpi_status acpi_status; + acpi_status acpi_status = AE_ERROR; for (uint8 retry = 0; retry < 2; retry++) { acpi_status = EcCommand(sc, EC_COMMAND_QUERY); if (acpi_status == AE_OK) diff --git a/src/add-ons/kernel/bus_managers/acpi/Jamfile b/src/add-ons/kernel/bus_managers/acpi/Jamfile index efee40f5eb..2313b59c4c 100644 --- a/src/add-ons/kernel/bus_managers/acpi/Jamfile +++ b/src/add-ons/kernel/bus_managers/acpi/Jamfile @@ -207,7 +207,6 @@ KernelAddon acpi : Device.cpp NamespaceDump.cpp EmbeddedController.cpp - SmallResourceData.cpp : libacpi_ca.a ; diff --git a/src/add-ons/kernel/bus_managers/acpi/Module.cpp b/src/add-ons/kernel/bus_managers/acpi/Module.cpp index aa64bdf224..dd639787a4 100644 --- a/src/add-ons/kernel/bus_managers/acpi/Module.cpp +++ b/src/add-ons/kernel/bus_managers/acpi/Module.cpp @@ -221,6 +221,7 @@ static struct acpi_root_info sACPIRootModule = { get_current_resources, get_possible_resources, set_current_resources, + walk_resources, prepare_sleep_state, enter_sleep_state, reboot, @@ -233,9 +234,7 @@ module_info* modules[] = { (module_info*)&sACPIRootModule, (module_info*)&acpi_ns_dump_module, (module_info*)&gACPIDeviceModule, -#ifndef __x86_64__ (module_info*)&embedded_controller_driver_module, (module_info*)&embedded_controller_device_module, -#endif NULL }; diff --git a/src/add-ons/kernel/bus_managers/acpi/SmallResourceData.cpp b/src/add-ons/kernel/bus_managers/acpi/SmallResourceData.cpp deleted file mode 100644 index 8fdd388486..0000000000 --- a/src/add-ons/kernel/bus_managers/acpi/SmallResourceData.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2009, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Clemens Zeidler, haiku@clemens-zeidler.de - */ - -#include "SmallResourceData.h" - -#include - -//#define TRACE_SMALLRESOURCEDATA -#ifdef TRACE_SMALLRESOURCEDATA -# define TRACE(x...) dprintf("Small Resource Data: "x) -#else -# define TRACE(x...) -#endif - - -void -io_port::Print() -{ - dprintf("io_port:\n"); - int i = (deviceAddresses16Bit ? 1 : 0); - dprintf("deviceAddresses16Bit %i\n", i); - dprintf("minimumBase %i\n", minimumBase); - dprintf("maximumBase %i\n", maximumBase); - dprintf("minimumBaseAlignment %i\n", minimumBaseAlignment); - dprintf("contigiuousIOPorts %i\n", contigiuousIOPorts); -} - - -SmallResourceData::SmallResourceData(acpi_device_module_info* acpi, - acpi_device acpiCookie, const char* method) -{ - acpi_data buffer; - buffer.pointer = NULL; - buffer.length = ACPI_ALLOCATE_BUFFER; - - fStatus = acpi->evaluate_method(acpiCookie, method, NULL, &buffer); - - if (fStatus != B_OK) - return; - - fBuffer = (acpi_object_type*)buffer.pointer; - - if (fBuffer[0].object_type != ACPI_TYPE_BUFFER) { - fStatus = B_ERROR; - return; - } - - fResourcePointer = (int8*)fBuffer[0].data.buffer.buffer; - fBufferSize = fBuffer[0].data.buffer.length; - fRemainingBufferSize = fBufferSize; - - // ToDo: Check checksum of the endtag. The sum of all databytes + checksum - // is zero. See section 6.4.2.8. -} - - -SmallResourceData::~SmallResourceData() -{ - if (InitCheck() == B_OK) - free(fBuffer); -} - - -status_t -SmallResourceData::InitCheck() -{ - return fStatus; -} - - -int8 -SmallResourceData::GetType() -{ - return *fResourcePointer; -} - - -status_t -SmallResourceData::ReadIOPort(io_port* ioPort) -{ - const size_t packageSize = 8; - - if (fRemainingBufferSize < packageSize) - return B_ERROR; - if (fResourcePointer[0] != kIOPort) - return B_ERROR; - - ioPort->deviceAddresses16Bit = (fResourcePointer[1] == 1); - - int16 tmp; - tmp = fResourcePointer[3]; - tmp = tmp << 8; - tmp |= fResourcePointer[2]; - ioPort->minimumBase = tmp; - - tmp = fResourcePointer[5]; - tmp = tmp << 8; - tmp |= fResourcePointer[4]; - ioPort->maximumBase = tmp; - - ioPort->minimumBaseAlignment = fResourcePointer[6]; - ioPort->contigiuousIOPorts = fResourcePointer[7]; - - fResourcePointer += packageSize; - fRemainingBufferSize -= packageSize; - TRACE("SmallResourceData: remaining buffer size %i\n", - int(fRemainingBufferSize)); - return B_OK; -} diff --git a/src/add-ons/kernel/bus_managers/acpi/SmallResourceData.h b/src/add-ons/kernel/bus_managers/acpi/SmallResourceData.h deleted file mode 100644 index 0da2b191ff..0000000000 --- a/src/add-ons/kernel/bus_managers/acpi/SmallResourceData.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2009, Haiku, Inc. All Rights Reserved. - * Distributed under the terms of the MIT License. - * - * Authors: - * Clemens Zeidler, haiku@clemens-zeidler.de - */ - -#ifndef SMALLRESOURCEDATA_H -#define SMALLRESOURCEDATA_H - -#include -#include - - -enum resource_type -{ - kIOPort = 0x47, - kEndTag = 0x78 -}; - - -struct io_port -{ - void Print(); - //! The logical device decodes 16-bit addresses. - bool deviceAddresses16Bit; - - uint16 minimumBase; - uint16 maximumBase; - uint8 minimumBaseAlignment; - uint8 contigiuousIOPorts; -}; - - -/*! ToDo: implement also the other resource data, see acpi section 6.2.4 */ -class SmallResourceData -{ -public: - SmallResourceData(acpi_device_module_info* acpi, - acpi_device acpiCookie, const char* method); - ~SmallResourceData(); - - status_t InitCheck(); - - int8 GetType(); - /*! Get resource data and jump to the next resource. */ - status_t ReadIOPort(io_port* ioPort); - -private: - acpi_object_type* fBuffer; - size_t fBufferSize; - size_t fRemainingBufferSize; - - int8* fResourcePointer; - - status_t fStatus; -}; - - -#endif