From ea71f2e7b8e1a1524683029560576e8917bb2298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 18 Nov 2006 20:46:58 +0000 Subject: [PATCH] acpi now uses a simple pci layer instead of the pci bus manager added a new style module to publish acpi devices ("listdev -d" to list them) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19322 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/ACPI.h | 9 + src/add-ons/kernel/bus_managers/acpi/Jamfile | 4 + .../kernel/bus_managers/acpi/acpi_busman.c | 30 +-- .../kernel/bus_managers/acpi/acpi_device.c | 91 ++++++++ .../kernel/bus_managers/acpi/acpi_module.c | 210 ++++++++++++++++++ .../kernel/bus_managers/acpi/acpi_priv.h | 63 ++++++ .../kernel/bus_managers/acpi/oshaiku.c | 110 +++++---- 7 files changed, 434 insertions(+), 83 deletions(-) create mode 100644 src/add-ons/kernel/bus_managers/acpi/acpi_device.c create mode 100644 src/add-ons/kernel/bus_managers/acpi/acpi_module.c create mode 100644 src/add-ons/kernel/bus_managers/acpi/acpi_priv.h diff --git a/headers/os/drivers/ACPI.h b/headers/os/drivers/ACPI.h index f668bbaa26..7ce670a46d 100644 --- a/headers/os/drivers/ACPI.h +++ b/headers/os/drivers/ACPI.h @@ -6,6 +6,7 @@ #ifndef _ACPI_H #define _ACPI_H +#include #include #include @@ -121,4 +122,12 @@ struct acpi_object_type { #define B_ACPI_MODULE_NAME "bus_managers/acpi/v1" +#define ACPI_DEVICE_HID_ITEM "acpi/hid" +#define ACPI_DEVICE_PATH_ITEM "acpi/path" +#define ACPI_DEVICE_TYPE_ITEM "acpi/type" + + +typedef struct acpi_device_info *acpi_device; + + #endif /* _ACPI_H */ diff --git a/src/add-ons/kernel/bus_managers/acpi/Jamfile b/src/add-ons/kernel/bus_managers/acpi/Jamfile index e3d83d9add..69fead9a1c 100644 --- a/src/add-ons/kernel/bus_managers/acpi/Jamfile +++ b/src/add-ons/kernel/bus_managers/acpi/Jamfile @@ -4,6 +4,7 @@ SetSubDirSupportedPlatformsBeOSCompatible ; SubDirHdrs [ FDirName $(SUBDIR) include ] ; SubDirHdrs [ FDirName $(SUBDIR) include platform ] ; +SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) pci ] ; SubDirCcFlags -fno-pic -D_KERNEL_MODE ; if $(TARGET_PLATFORM) != haiku { @@ -175,6 +176,9 @@ SEARCH on [ FGristFiles $(parser_src) ] = [ FDirName $(HAIKU_TOP) src add-ons k KernelAddon acpi : oshaiku.c acpi_busman.c + acpi_module.c + acpi_device.c : libacpi_ca.a + pci_arch_bus_manager.a ; 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 5ee7674e66..e567600aea 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c @@ -7,12 +7,14 @@ #include #include + #include #include #include #include "acpi.h" #include "acpixf.h" +#include "acpi_priv.h" status_t acpi_std_ops(int32 op,...); status_t acpi_rescan_stub(void); @@ -20,27 +22,9 @@ status_t acpi_rescan_stub(void); #define TRACE(x...) dprintf("acpi: " x) #define ERROR(x...) dprintf("acpi: " x) -void enable_fixed_event (uint32 event); -void disable_fixed_event (uint32 event); -uint32 fixed_event_status (uint32 event); -void reset_fixed_event (uint32 event); -status_t install_fixed_event_handler (uint32 event, interrupt_handler *handler, void *data); -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 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); - -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 = { @@ -71,13 +55,9 @@ struct acpi_module_info acpi_module = { enter_sleep_state }; -_EXPORT module_info *modules[] = { - (module_info *) &acpi_module, - NULL -}; - -status_t acpi_std_ops(int32 op,...) +status_t +acpi_std_ops(int32 op,...) { ACPI_STATUS Status; @@ -111,7 +91,7 @@ status_t acpi_std_ops(int32 op,...) break; case B_MODULE_UNINIT: - Status = AcpiTerminate(); + /*Status = AcpiTerminate();*/ if (Status != AE_OK) ERROR("Could not bring system out of ACPI mode. Oh well.\n"); diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_device.c b/src/add-ons/kernel/bus_managers/acpi/acpi_device.c new file mode 100644 index 0000000000..b93e18da7a --- /dev/null +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_device.c @@ -0,0 +1,91 @@ +/* + * Copyright 2006, Jérôme Duval. All rights reserved. + * + * Distributed under the terms of the MIT License. + */ + +#include +#include +#include + +#include "acpi_priv.h" + +// information about one ACPI device +typedef struct acpi_device_info { + char *path; // path + device_node_handle node; + char name[32]; // name (for fast log) +} acpi_device_info; + + +static status_t +acpi_device_init_driver(device_node_handle node, void *user_cookie, void **cookie) +{ + char *path; + acpi_device_info *device; + status_t status = B_OK; + + if (gDeviceManager->get_attr_string(node, ACPI_DEVICE_PATH_ITEM, &path, false) != B_OK) + return B_ERROR; + + device = malloc(sizeof(*device)); + if (device == NULL) { + return B_NO_MEMORY; + } + + memset(device, 0, sizeof(*device)); + + device->path = path; + device->node = node; + + snprintf(device->name, sizeof(device->name), "acpi_device %s", + path); + + *cookie = device; + + return status; +} + + +static status_t +acpi_device_uninit_driver(void *cookie) +{ + acpi_device_info *device = cookie; + + free(device->path); + free(device); + return B_OK; +} + + +static status_t +acpi_device_std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + case B_MODULE_UNINIT: + return B_OK; + } + + return B_BAD_VALUE; +} + +acpi_device_module_info gACPIDeviceModule = { + { + { + ACPI_DEVICE_MODULE_NAME, + 0, + acpi_device_std_ops + }, + + NULL, // supports device + NULL, // register device (our parent registered us) + acpi_device_init_driver, + acpi_device_uninit_driver, + NULL, // removed + NULL, // cleanup + NULL, // get supported paths + }, + + +}; diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_module.c b/src/add-ons/kernel/bus_managers/acpi/acpi_module.c new file mode 100644 index 0000000000..a236cab2c2 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_module.c @@ -0,0 +1,210 @@ +/* + * Copyright 2006, Jérôme Duval. All rights reserved. + * + * Distributed under the terms of the MIT License. + */ + +#include +#include +#include "acpi_priv.h" + +device_manager_info *gDeviceManager; + +module_dependency module_dependencies[] = { + {B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager}, + {} +}; + + +static float +acpi_module_supports_device(device_node_handle parent, bool *_noConnection) +{ + char *bus; + + // make sure parent is really device root + if (gDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus, false)) + return B_ERROR; + + if (strcmp(bus, "root")) { + free(bus); + return 0.0; + } + + free(bus); + return 1.0; +} + + +static status_t +acpi_module_register_device(device_node_handle parent) +{ + + device_attr attrs[] = { + // info about ourself + { B_DRIVER_MODULE, B_STRING_TYPE, { string: ACPI_ROOT_MODULE_NAME }}, + // unique connection name + { PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: "ACPI" }}, + + // mark as being a bus + { PNP_BUS_IS_BUS, B_UINT8_TYPE, { ui8: 1 }}, + // search for device drivers once all devices are detected + //{ PNP_BUS_DEFER_PROBE, B_UINT8_TYPE, { ui8: 1 }}, + // don't scan if loaded as we own I/O resources + //{ PNP_DRIVER_NO_LIVE_RESCAN, B_UINT8_TYPE, { ui8: 1 }}, + {} + }; + + io_resource_handle *resourceHandles = NULL; + device_node_handle node; + + return gDeviceManager->register_device(parent, attrs, resourceHandles, &node); +} + + +static status_t +acpi_enumerate_child_devices(device_node_handle node, const char *root) +{ + char result[255]; + void *counter = NULL; + + dprintf("acpi_enumerate_child_devices: recursing from %s\n", root); + + while (get_next_entry(ACPI_TYPE_ANY, root, result, 255, &counter) == B_OK) { + uint32 type = get_object_type(result); + device_node_handle deviceNode; + + switch (type) { + case ACPI_TYPE_DEVICE: { + char hid[9] = ""; + get_device_hid(result, hid); + device_attr attrs[] = { + // info about device + { B_DRIVER_MODULE, B_STRING_TYPE, { string: ACPI_DEVICE_MODULE_NAME }}, + { PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: + "path: %"ACPI_DEVICE_PATH_ITEM"%" }}, + + // location on ACPI bus + { ACPI_DEVICE_PATH_ITEM, B_STRING_TYPE, { string: result }}, + + // info about the device + { ACPI_DEVICE_HID_ITEM, B_STRING_TYPE, { string: hid }}, + { ACPI_DEVICE_TYPE_ITEM, B_UINT32_TYPE, { ui32: type }}, + + // consumer specification + { B_DRIVER_BUS, B_STRING_TYPE, { string: "apci" }}, + { NULL } + }; + + if (gDeviceManager->register_device(node, attrs, NULL, &deviceNode) == B_OK) + acpi_enumerate_child_devices(deviceNode, result); + break; + } + case ACPI_TYPE_POWER: + case ACPI_TYPE_PROCESSOR: + case ACPI_TYPE_THERMAL: { + device_attr attrs[] = { + // info about device + { B_DRIVER_MODULE, B_STRING_TYPE, { string: ACPI_DEVICE_MODULE_NAME }}, + { PNP_DRIVER_CONNECTION, B_STRING_TYPE, { string: + "path: %"ACPI_DEVICE_PATH_ITEM"%" }}, + + // location on ACPI bus + { ACPI_DEVICE_PATH_ITEM, B_STRING_TYPE, { string: result }}, + + // info about the device + { ACPI_DEVICE_TYPE_ITEM, B_UINT32_TYPE, { ui32: type }}, + + // consumer specification + { B_DRIVER_BUS, B_STRING_TYPE, { string: "apci" }}, + { NULL } + }; + + if (gDeviceManager->register_device(node, attrs, NULL, &deviceNode) == B_OK) + acpi_enumerate_child_devices(deviceNode, result); + break; + } + default: + acpi_enumerate_child_devices(node, result); + break; + } + + } + + return B_OK; +} + + +static status_t +acpi_module_register_child_devices(void *cookie) +{ + device_node_handle node = cookie; + return acpi_enumerate_child_devices(node, "\\"); +} + + +static void +acpi_module_get_paths(const char ***_bus, const char ***_device) +{ + static const char *kBus[] = {"root", NULL}; + + *_bus = kBus; + *_device = NULL; +} + + +static status_t +acpi_module_init(device_node_handle node, void *user_cookie, void **_cookie) +{ + *_cookie = node; + return B_OK; +} + + +static int32 +apci_module_std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + { + module_info *module; + return get_module(B_ACPI_MODULE_NAME, &module); + // this serializes our module initialization + } + + case B_MODULE_UNINIT: + return put_module(B_ACPI_MODULE_NAME); + } + + return B_BAD_VALUE; +} + + +static struct acpi_root_info sACPIModule = { + { + { + { + ACPI_ROOT_MODULE_NAME, + 0, + apci_module_std_ops + }, + + acpi_module_supports_device, + acpi_module_register_device, + acpi_module_init, + NULL, // uninit + NULL, // removed + NULL, // cleanup + acpi_module_get_paths, + }, + + acpi_module_register_child_devices, + NULL, // rescan bus + }, + +}; + +_EXPORT module_info *modules[] = { + (module_info *) &acpi_module, + (module_info *) &sACPIModule, + NULL +}; diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h b/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h new file mode 100644 index 0000000000..6f0c38e170 --- /dev/null +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_priv.h @@ -0,0 +1,63 @@ +/* + * Copyright 2006, Jérôme Duval. All rights reserved. + * + * Distributed under the terms of the MIT License. + */ + +#ifndef __ACPI_PRIV_H__ +#define __ACPI_PRIV_H__ + +#include +#include +#include + +// name of ACPI root module +#define ACPI_ROOT_MODULE_NAME "bus_managers/acpi/root/device_v1" + +// name of ACPI device modules +#define ACPI_DEVICE_MODULE_NAME "bus_managers/acpi/device_v1" + + +extern device_manager_info *gDeviceManager; + +// Interface to one ACPI device. +typedef struct acpi_device_module_info { + driver_module_info info; + +} acpi_device_module_info; + + +// ACPI root. +typedef struct acpi_root_info { + bus_module_info info; + +} acpi_root_info; + +extern struct acpi_module_info acpi_module; + + +void enable_fixed_event (uint32 event); +void disable_fixed_event (uint32 event); + +uint32 fixed_event_status (uint32 event); +void reset_fixed_event (uint32 event); + +status_t install_fixed_event_handler (uint32 event, interrupt_handler *handler, void *data); +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 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); + +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); + + +#endif /* __ACPI_PRIV_H__ */ diff --git a/src/add-ons/kernel/bus_managers/acpi/oshaiku.c b/src/add-ons/kernel/bus_managers/acpi/oshaiku.c index c078d43f0f..13983e2b4b 100644 --- a/src/add-ons/kernel/bus_managers/acpi/oshaiku.c +++ b/src/add-ons/kernel/bus_managers/acpi/oshaiku.c @@ -128,8 +128,31 @@ #include #ifdef _KERNEL_MODE - #include - #include +# include "pci_controller.h" +# include + +void *pci_ram_address(const void *physical_address_in_system_memory); + +status_t pci_io_init(void); +uint8 pci_read_io_8(int mapped_io_addr); +void pci_write_io_8(int mapped_io_addr, uint8 value); +uint16 pci_read_io_16(int mapped_io_addr); +void pci_write_io_16(int mapped_io_addr, uint16 value); +uint32 pci_read_io_32(int mapped_io_addr); +void pci_write_io_32(int mapped_io_addr, uint32 value); + +pci_controller *gController = NULL; +void *gControllerCookie; + +status_t +pci_controller_add(pci_controller *controller, void *cookie) +{ + gController = controller; + gControllerCookie = cookie; + return B_OK; +} + + #endif #include "acpi.h" @@ -166,6 +189,11 @@ AcpiOsInitialize (void) AcpiGbl_OutputFile = NULL; #endif + if (pci_io_init() != B_OK) + return AE_ERROR; + if (pci_controller_init() != B_OK) + return AE_ERROR; + return AE_OK; } @@ -529,7 +557,7 @@ AcpiOsUnmapMemory ( { delete_area(area_for(where)); - return; + return; } @@ -1044,16 +1072,8 @@ AcpiOsReadPciConfiguration ( { #ifdef _KERNEL_MODE - - static struct pci_module_info *pci = NULL; - uint32 result; - - if (pci == NULL) - get_module(B_PCI_MODULE_NAME,(module_info **)&pci); - - result = pci->read_pci_config(PciId->Bus,PciId->Device,PciId->Function,Register,Width/8); - memcpy(Value,&result,Width); - + gController->read_pci_config(gControllerCookie, + PciId->Bus, PciId->Device, PciId->Function, Register, Width/8, Value); #endif return (AE_OK); @@ -1084,14 +1104,8 @@ AcpiOsWritePciConfiguration ( { #ifdef _KERNEL_MODE - - static struct pci_module_info *pci = NULL; - - if (pci == NULL) - get_module(B_PCI_MODULE_NAME,(module_info **)&pci); - - pci->write_pci_config(PciId->Bus,PciId->Device,PciId->Function,Register,Width/8,Value); - + gController->write_pci_config(gControllerCookie, + PciId->Bus, PciId->Device, PciId->Function, Register, Width/8, Value); #endif return (AE_OK); @@ -1131,23 +1145,18 @@ AcpiOsReadPort ( #ifdef _KERNEL_MODE - static struct pci_module_info *pci = NULL; - - if (pci == NULL) - get_module(B_PCI_MODULE_NAME,(module_info **)&pci); - switch (Width) { case 8: - *Value = pci->read_io_8(Address); + *Value = pci_read_io_8(Address); break; case 16: - *Value = pci->read_io_16(Address); + *Value = pci_read_io_16(Address); break; case 32: - *Value = pci->read_io_32(Address); + *Value = pci_read_io_32(Address); break; } @@ -1180,25 +1189,19 @@ AcpiOsWritePort ( #ifdef _KERNEL_MODE - static struct pci_module_info *pci = NULL; - - if (pci == NULL) - get_module(B_PCI_MODULE_NAME,(module_info **)&pci); - - switch (Width) - { - case 8: - pci->write_io_8(Address,Value); - break; + switch (Width) { + case 8: + pci_write_io_8(Address,Value); + break; - case 16: - pci->write_io_16(Address,Value); - break; + case 16: + pci_write_io_16(Address,Value); + break; - case 32: - pci->write_io_32(Address,Value); - break; - } + case 32: + pci_write_io_32(Address,Value); + break; + } #endif @@ -1229,12 +1232,7 @@ AcpiOsReadMemory ( #ifdef _KERNEL_MODE - static struct pci_module_info *pci = NULL; - - if (pci == NULL) - get_module(B_PCI_MODULE_NAME,(module_info **)&pci); - - memcpy(Value,pci->ram_address(ACPI_TO_POINTER(Address)),Width/8); + memcpy(Value, pci_ram_address(ACPI_TO_POINTER(Address)), Width/8); #endif @@ -1265,12 +1263,7 @@ AcpiOsWriteMemory ( #ifdef _KERNEL_MODE - static struct pci_module_info *pci = NULL; - - if (pci == NULL) - get_module(B_PCI_MODULE_NAME,(module_info **)&pci); - - memcpy(pci->ram_address(ACPI_TO_POINTER(Address)),&Value,Width/8); + memcpy(pci_ram_address(ACPI_TO_POINTER(Address)), &Value, Width/8); #endif @@ -1326,3 +1319,4 @@ AcpiOsSignal ( return (AE_OK); } +