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
This commit is contained in:
Jérôme Duval 2006-11-18 20:46:58 +00:00
parent c26c0b24e5
commit ea71f2e7b8
7 changed files with 434 additions and 83 deletions

View File

@ -6,6 +6,7 @@
#ifndef _ACPI_H
#define _ACPI_H
#include <device_manager.h>
#include <bus_manager.h>
#include <KernelExport.h>
@ -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 */

View File

@ -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
;

View File

@ -7,12 +7,14 @@
#include <ACPI.h>
#include <KernelExport.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#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");

View File

@ -0,0 +1,91 @@
/*
* Copyright 2006, Jérôme Duval. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#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
},
};

View File

@ -0,0 +1,210 @@
/*
* Copyright 2006, Jérôme Duval. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/
#include <stdlib.h>
#include <string.h>
#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
};

View File

@ -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 <KernelExport.h>
#include <device_manager.h>
#include <ACPI.h>
// 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__ */

View File

@ -128,8 +128,31 @@
#include <OS.h>
#ifdef _KERNEL_MODE
#include <PCI.h>
#include <KernelExport.h>
# include "pci_controller.h"
# include <KernelExport.h>
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);
}