* Divided enter_sleep_state() to have a prepare_sleep_state() that accepts a

wake vector (not tested at all).
* Removed disabling interrupts when entering the sleep state - looks like
  ACPI still needs memory then.
* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27403 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-09-10 19:24:37 +00:00
parent 7adf6ce100
commit a181d013aa
5 changed files with 436 additions and 406 deletions
+69 -50
View File
@@ -1,57 +1,64 @@
/* ACPI Bus Manger Interface /*
* Copyright 2005, Haiku Inc. All Rights Reserved. * Copyright 2005-2008, Haiku Inc. All Rights Reserved.
* Distributed under the terms of the MIT License * Distributed under the terms of the MIT License
*/ */
#ifndef _ACPI_H #ifndef _ACPI_H
#define _ACPI_H #define _ACPI_H
#include <device_manager.h> #include <device_manager.h>
#include <bus_manager.h>
#include <KernelExport.h> #include <KernelExport.h>
typedef struct acpi_module_info acpi_module_info; typedef struct acpi_module_info acpi_module_info;
typedef struct acpi_object_type acpi_object_type; typedef struct acpi_object_type acpi_object_type;
#define B_ACPI_MODULE_NAME "bus_managers/acpi/v1"
struct acpi_module_info { struct acpi_module_info {
bus_manager_info binfo; module_info info;
/* Fixed Event Management */ /* Fixed Event Management */
void (*enable_fixed_event) (uint32 event); void (*enable_fixed_event)(uint32 event);
void (*disable_fixed_event) (uint32 event); void (*disable_fixed_event)(uint32 event);
uint32 (*fixed_event_status) (uint32 event); uint32 (*fixed_event_status) (uint32 event);
/* Returns 1 if event set, 0 otherwise */ /* Returns 1 if event set, 0 otherwise */
void (*reset_fixed_event) (uint32 event); void (*reset_fixed_event) (uint32 event);
status_t (*install_fixed_event_handler) (uint32 event, interrupt_handler *handler, void *data); status_t (*install_fixed_event_handler)(uint32 event,
status_t (*remove_fixed_event_handler) (uint32 event, interrupt_handler *handler); interrupt_handler *handler, void *data);
status_t (*remove_fixed_event_handler)(uint32 event,
interrupt_handler *handler);
/* Namespace Access */ /* Namespace Access */
status_t (*get_next_entry) (uint32 object_type, const char *base, char *result, size_t len, void **counter); status_t (*get_next_entry)(uint32 objectType, const char *base,
status_t (*get_device) (const char *hid, uint32 index, char *result); char *result, size_t length, void **_counter);
status_t (*get_device)(const char *hid, uint32 index, char *result,
status_t (*get_device_hid) (const char *path, char *hid); size_t resultLength);
uint32 (*get_object_type) (const char *path);
status_t (*get_object) (const char *path, acpi_object_type **return_value); status_t (*get_device_hid)(const char *path, char *hid);
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 (*get_object)(const char *path,
acpi_object_type **_returnValue);
status_t (*get_object_typed)(const char *path,
acpi_object_type **_returnValue, uint32 objectType);
/* Control method execution and data acquisition */ /* Control method execution and data acquisition */
status_t (*evaluate_object) (const char *object, acpi_object_type *return_value, size_t buf_len); status_t (*evaluate_object)(const char *object,
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_object_type *returnValue, size_t bufferLength);
status_t (*evaluate_method)(const char *object, const char *method,
acpi_object_type *returnValue, size_t bufferLength,
acpi_object_type *args, int numArgs);
/* Power state setting */ /* Power state setting */
status_t (*enter_sleep_state) (uint8 state); status_t (*prepare_sleep_state)(uint8 state, void (*wakeFunc)(void),
/* Sleep state values: size_t size);
0: On (Working) status_t (*enter_sleep_state)(uint8 state);
1: Sleep
2: Software Off
3: Mechanical Off
4: Hibernate
5: Software Off */
}; };
@@ -107,7 +114,7 @@ struct acpi_object_type {
} package; } package;
struct { struct {
uint32 cpu_id; uint32 cpu_id;
int pblk_address; int pblk_address;
size_t pblk_length; size_t pblk_length;
} processor; } processor;
@@ -118,13 +125,23 @@ struct acpi_object_type {
} data; } data;
}; };
#endif #endif // __ACTYPES_H__
#define B_ACPI_MODULE_NAME "bus_managers/acpi/v1" /* Sleep states */
#define ACPI_DEVICE_HID_ITEM "acpi/hid" enum {
#define ACPI_DEVICE_PATH_ITEM "acpi/path" ACPI_POWER_STATE_ON = 0,
#define ACPI_DEVICE_TYPE_ITEM "acpi/type" ACPI_POWER_STATE_SLEEP_S1,
ACPI_POWER_STATE_SLEEP_S2,
ACPI_POWER_STATE_SLEEP_S3,
ACPI_POWER_STATE_HIBERNATE,
ACPI_POWER_STATE_OFF
};
#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; typedef struct acpi_device_info *acpi_device;
@@ -134,13 +151,15 @@ typedef struct acpi_device_module_info {
driver_module_info info; driver_module_info info;
/* Namespace Access */ /* Namespace Access */
uint32 (*get_object_type) (acpi_device device); uint32 (*get_object_type)(acpi_device device);
status_t (*get_object) (acpi_device device, const char *path, acpi_object_type **return_value); status_t (*get_object)(acpi_device device, const char *path,
acpi_object_type **_returnValue);
/* Control method execution and data acquisition */ /* Control method execution and data acquisition */
status_t (*evaluate_method) (acpi_device device, const char *method, acpi_object_type *return_value, size_t buf_len, acpi_object_type *args, int num_args); status_t (*evaluate_method)(acpi_device device, const char *method,
acpi_object_type *returnValue, size_t bufferLength,
acpi_object_type *args, int numArgs);
} acpi_device_module_info; } acpi_device_module_info;
#endif /* _ACPI_H */ #endif /* _ACPI_H */
+263 -259
View File
@@ -1,66 +1,72 @@
/* /*
* Copyright 2008, Axel Dörfler, [email protected].
* Copyright 2006, Bryan Varner. All rights reserved. * Copyright 2006, Bryan Varner. All rights reserved.
* Copyright 2005, Nathan Whitehorn. All rights reserved. * Copyright 2005, Nathan Whitehorn. All rights reserved.
* *
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ACPI.h> #include <ACPI.h>
#include <dpc.h> #include <dpc.h>
#include <PCI.h>
#include <KernelExport.h> #include <KernelExport.h>
#include <PCI.h>
#include <malloc.h>
#include <safemode.h> #include <safemode.h>
#include <stdio.h>
#include <string.h>
#include "acpi.h" #include "acpi.h"
#include "acpixf.h" #include "acpixf.h"
#include "acpi_priv.h" #include "acpi_priv.h"
status_t acpi_std_ops(int32 op,...);
status_t acpi_rescan_stub(void);
#define TRACE(x...) dprintf("acpi: " x) #define TRACE(x...) dprintf("acpi: " x)
#define ERROR(x...) dprintf("acpi: " x) #define ERROR(x...) dprintf("acpi: " x)
extern dpc_module_info *gDPC;
void *gDPChandle = NULL;
extern pci_module_info *gPCIManager; extern dpc_module_info* gDPC;
void* gDPCHandle = NULL;
struct acpi_module_info acpi_module = { extern pci_module_info* gPCIManager;
{
{
B_ACPI_MODULE_NAME,
B_KEEP_LOADED,
acpi_std_ops
},
acpi_rescan_stub
},
enable_fixed_event,
disable_fixed_event,
fixed_event_status,
reset_fixed_event,
install_fixed_event_handler,
remove_fixed_event_handler,
get_next_entry,
get_device,
get_device_hid,
get_object_type,
get_object,
get_object_typed,
evaluate_object,
evaluate_method,
enter_sleep_state
};
status_t static ACPI_STATUS
acpi_std_ops(int32 op,...) get_device_by_hid_callback(ACPI_HANDLE object, UINT32 depth, void* context,
void** _returnValue)
{
uint32* counter = (uint32*)context;
ACPI_STATUS status;
ACPI_BUFFER buffer;
*_returnValue = NULL;
if (counter[0] == counter[1]) {
buffer.Length = 254;
buffer.Pointer = malloc(255);
status = AcpiGetName(object, ACPI_FULL_PATHNAME, &buffer);
if (status != AE_OK) {
free(buffer.Pointer);
return AE_CTRL_TERMINATE;
}
((char*)buffer.Pointer)[buffer.Length] = '\0';
*_returnValue = buffer.Pointer;
return AE_CTRL_TERMINATE;
}
counter[1]++;
return AE_OK;
}
// #pragma mark - ACPI bus manager API
static status_t
acpi_std_ops(int32 op,...)
{ {
switch (op) { switch (op) {
case B_MODULE_INIT: case B_MODULE_INIT:
@@ -110,7 +116,7 @@ acpi_std_ops(int32 op,...)
} }
#endif #endif
if (gDPC->new_dpc_queue(&gDPChandle, "acpi_task", B_NORMAL_PRIORITY) != B_OK) { if (gDPC->new_dpc_queue(&gDPCHandle, "acpi_task", B_NORMAL_PRIORITY) != B_OK) {
ERROR("AcpiInitializeSubsystem failed (new_dpc_queue() failed!)\n"); ERROR("AcpiInitializeSubsystem failed (new_dpc_queue() failed!)\n");
goto err; goto err;
} }
@@ -151,7 +157,7 @@ acpi_std_ops(int32 op,...)
/* Phew. Now in ACPI mode */ /* Phew. Now in ACPI mode */
TRACE("ACPI initialized\n"); TRACE("ACPI initialized\n");
return B_OK; return B_OK;
err: err:
#ifndef __HAIKU__ #ifndef __HAIKU__
put_module(B_DPC_MODULE_NAME); put_module(B_DPC_MODULE_NAME);
@@ -166,9 +172,9 @@ acpi_std_ops(int32 op,...)
ERROR("Could not bring system out of ACPI mode. Oh well.\n"); ERROR("Could not bring system out of ACPI mode. Oh well.\n");
/* This isn't so terrible. We'll just fail silently */ /* This isn't so terrible. We'll just fail silently */
if (gDPChandle != NULL) { if (gDPCHandle != NULL) {
gDPC->delete_dpc_queue(gDPChandle); gDPC->delete_dpc_queue(gDPCHandle);
gDPChandle = NULL; gDPCHandle = NULL;
} }
#ifndef __HAIKU__ #ifndef __HAIKU__
@@ -187,304 +193,302 @@ acpi_std_ops(int32 op,...)
} }
status_t void
acpi_rescan_stub(void)
{
return B_OK;
}
void
enable_fixed_event(uint32 event) enable_fixed_event(uint32 event)
{ {
AcpiEnableEvent(event,0); AcpiEnableEvent(event, 0);
} }
void void
disable_fixed_event(uint32 event) disable_fixed_event(uint32 event)
{ {
AcpiDisableEvent(event,0); AcpiDisableEvent(event, 0);
} }
uint32 uint32
fixed_event_status(uint32 event) fixed_event_status(uint32 event)
{ {
ACPI_EVENT_STATUS status = 0; ACPI_EVENT_STATUS status = 0;
AcpiGetEventStatus(event,&status); AcpiGetEventStatus(event, &status);
return (status/* & ACPI_EVENT_FLAG_SET*/); return status/* & ACPI_EVENT_FLAG_SET*/;
} }
void void
reset_fixed_event(uint32 event) reset_fixed_event(uint32 event)
{ {
AcpiClearEvent(event); AcpiClearEvent(event);
} }
status_t status_t
install_fixed_event_handler (uint32 event, interrupt_handler *handler, void *data) install_fixed_event_handler(uint32 event, interrupt_handler* handler,
void *data)
{ {
return ((AcpiInstallFixedEventHandler(event,handler,data) == AE_OK) ? B_OK : B_ERROR); return AcpiInstallFixedEventHandler(event, (void*)handler, data) == AE_OK
? B_OK : B_ERROR;
} }
status_t status_t
remove_fixed_event_handler (uint32 event, interrupt_handler *handler) remove_fixed_event_handler(uint32 event, interrupt_handler* handler)
{ {
return ((AcpiRemoveFixedEventHandler(event,handler) == AE_OK) ? B_OK : B_ERROR); return AcpiRemoveFixedEventHandler(event, (void*)handler) == AE_OK
? B_OK : B_ERROR;
} }
status_t status_t
get_next_entry (uint32 object_type, const char *base, char *result, size_t len, void **counter) get_next_entry(uint32 objectType, const char *base, char *result,
size_t length, void **counter)
{ {
ACPI_STATUS result_status; ACPI_HANDLE parent, child, newChild;
ACPI_HANDLE parent,child,new_child;
ACPI_BUFFER buffer; ACPI_BUFFER buffer;
ACPI_STATUS status;
if ((base == NULL) || (strcmp(base,"\\") == 0)) {
if (base == NULL || !strcmp(base, "\\")) {
parent = ACPI_ROOT_OBJECT; parent = ACPI_ROOT_OBJECT;
} else { } else {
result_status = AcpiGetHandle(NULL,base,&parent); status = AcpiGetHandle(NULL, (char*)base, &parent);
if (result_status != AE_OK) if (status != AE_OK)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
} }
child = *counter; child = *counter;
result_status = AcpiGetNextObject(object_type,parent,child,&new_child); status = AcpiGetNextObject(objectType, parent, child, &newChild);
if (result_status != AE_OK) if (status != AE_OK)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
*counter = new_child; *counter = newChild;
buffer.Length = len; buffer.Length = length;
buffer.Pointer = result; buffer.Pointer = result;
result_status = AcpiGetName(new_child,ACPI_FULL_PATHNAME,&buffer); status = AcpiGetName(newChild, ACPI_FULL_PATHNAME, &buffer);
if (result_status != AE_OK) if (status != AE_OK)
return B_NO_MEMORY; /* Corresponds to AE_BUFFER_OVERFLOW */ return B_NO_MEMORY; /* Corresponds to AE_BUFFER_OVERFLOW */
return B_OK; return B_OK;
} }
static ACPI_STATUS status_t
get_device_by_hid_callback(ACPI_HANDLE object, UINT32 depth, void *context, void **return_val) get_device(const char* hid, uint32 index, char* result, size_t resultLength)
{
ACPI_STATUS result;
ACPI_BUFFER buffer;
uint32 *counter = (uint32 *)(context);
*return_val = NULL;
if (counter[0] == counter[1]) {
buffer.Length = 254;
buffer.Pointer = malloc(255);
result = AcpiGetName(object,ACPI_FULL_PATHNAME,&buffer);
if (result != AE_OK) {
free(buffer.Pointer);
return AE_CTRL_TERMINATE;
}
((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; ACPI_STATUS status;
uint32 counter[2] = {index,0}; uint32 counter[2] = {index, 0};
char *result2 = NULL; char *buffer = NULL;
status = AcpiGetDevices((char *)hid,&get_device_by_hid_callback,counter,&result2); status = AcpiGetDevices((char*)hid, (void*)&get_device_by_hid_callback,
if ((status != AE_OK) || (result2 == NULL)) counter, (void**)&buffer);
if (status != AE_OK || buffer == NULL)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
strcpy(result,result2); strlcpy(result, buffer, resultLength);
free(result2); free(buffer);
return B_OK; return B_OK;
} }
status_t status_t
get_device_hid (const char *path, char *hid) get_device_hid(const char *path, char *hid)
{ {
ACPI_HANDLE handle; ACPI_HANDLE handle;
ACPI_OBJECT info; ACPI_OBJECT info;
ACPI_BUFFER info_buffer; ACPI_BUFFER infoBuffer;
if (AcpiGetHandle(NULL,path,&handle) != AE_OK) if (AcpiGetHandle(NULL, (char*)path, &handle) != AE_OK)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
info_buffer.Pointer = &info; infoBuffer.Pointer = &info;
info_buffer.Length = sizeof(ACPI_OBJECT); infoBuffer.Length = sizeof(ACPI_OBJECT);
info.String.Pointer = hid; info.String.Pointer = hid;
info.String.Length = 9; info.String.Length = 9;
info.String.Type = ACPI_TYPE_STRING; info.String.Type = ACPI_TYPE_STRING;
if (AcpiEvaluateObject(handle,"_HID",NULL,&info_buffer) != AE_OK)
return B_BAD_TYPE;
if (info.Type == ACPI_TYPE_INTEGER) {
uint32 EisaId = AcpiUtDwordByteSwap (info.Integer.Value);
hid[0] = (char) ('@' + (((unsigned long) EisaId >> 26) & 0x1f)); if (AcpiEvaluateObject(handle, "_HID", NULL, &infoBuffer) != AE_OK)
hid[1] = (char) ('@' + ((EisaId >> 21) & 0x1f)); return B_BAD_TYPE;
hid[2] = (char) ('@' + ((EisaId >> 16) & 0x1f));
hid[3] = AcpiUtHexToAsciiChar ((ACPI_INTEGER) EisaId, 12); if (info.Type == ACPI_TYPE_INTEGER) {
hid[4] = AcpiUtHexToAsciiChar ((ACPI_INTEGER) EisaId, 8); uint32 eisaId = AcpiUtDwordByteSwap(info.Integer.Value);
hid[5] = AcpiUtHexToAsciiChar ((ACPI_INTEGER) EisaId, 4);
hid[6] = AcpiUtHexToAsciiChar ((ACPI_INTEGER) EisaId, 0); hid[0] = (char) ('@' + ((eisaId >> 26) & 0x1f));
hid[1] = (char) ('@' + ((eisaId >> 21) & 0x1f));
hid[2] = (char) ('@' + ((eisaId >> 16) & 0x1f));
hid[3] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 12);
hid[4] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 8);
hid[5] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 4);
hid[6] = AcpiUtHexToAsciiChar((ACPI_INTEGER)eisaId, 0);
hid[7] = 0; hid[7] = 0;
} }
hid[ACPI_DEVICE_ID_LENGTH] = '\0'; hid[ACPI_DEVICE_ID_LENGTH] = '\0';
return B_OK; return B_OK;
} }
uint32 uint32
get_object_type (const char *path) get_object_type(const char* path)
{ {
ACPI_HANDLE handle; ACPI_HANDLE handle;
ACPI_OBJECT_TYPE type; ACPI_OBJECT_TYPE type;
if (AcpiGetHandle(NULL,path,&handle) != AE_OK) if (AcpiGetHandle(NULL, (char*)path, &handle) != AE_OK)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
AcpiGetType(handle,&type); AcpiGetType(handle, &type);
return type; return type;
} }
status_t status_t
get_object (const char *path, acpi_object_type **return_value) get_object(const char* path, acpi_object_type** _returnValue)
{ {
ACPI_HANDLE handle; ACPI_HANDLE handle;
ACPI_BUFFER buffer; ACPI_BUFFER buffer;
ACPI_STATUS status; 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 = AcpiGetHandle(NULL, (char*)path, &handle);
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;
buffer.Pointer = return_value;
buffer.Length = 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;
}
void
waking_vector(void)
{
//--- This should do something ---
}
status_t
enter_sleep_state (uint8 state)
{
ACPI_STATUS status;
cpu_status cpu;
physical_entry wake_vector;
lock_memory(&waking_vector,sizeof(waking_vector),0);
get_memory_map(&waking_vector,sizeof(waking_vector),&wake_vector,1);
status = AcpiSetFirmwareWakingVector(wake_vector.address);
if (status != AE_OK) if (status != AE_OK)
return B_ERROR; return B_ENTRY_NOT_FOUND;
buffer.Pointer = NULL;
buffer.Length = ACPI_ALLOCATE_BUFFER;
status = AcpiEvaluateObject(handle, NULL, NULL, &buffer);
*_returnValue = buffer.Pointer;
return status == AE_OK ? B_OK : B_ERROR;
}
status_t
get_object_typed(const char* path, acpi_object_type** _returnValue,
uint32 objectType)
{
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, objectType);
*_returnValue = buffer.Pointer;
return status == AE_OK ? B_OK : B_ERROR;
}
status_t
evaluate_object(const char* object, acpi_object_type* returnValue,
size_t bufferLength)
{
ACPI_BUFFER buffer;
ACPI_STATUS status;
buffer.Pointer = returnValue;
buffer.Length = bufferLength;
status = AcpiEvaluateObject(NULL, object, NULL, returnValue != NULL
? &buffer : NULL);
return status == AE_OK ? B_OK : B_ERROR;
}
status_t
evaluate_method(const char* object, const char* method,
acpi_object_type *returnValue, size_t bufferLength, acpi_object_type *args,
int numArgs)
{
ACPI_BUFFER buffer;
ACPI_STATUS status;
ACPI_OBJECT_LIST acpiArgs;
ACPI_HANDLE handle;
if (AcpiGetHandle(NULL, object, &handle) != AE_OK)
return B_ENTRY_NOT_FOUND;
buffer.Pointer = returnValue;
buffer.Length = bufferLength;
acpiArgs.Count = numArgs;
acpiArgs.Pointer = args;
status = AcpiEvaluateObject(handle, method, args != NULL ? &acpiArgs : NULL,
returnValue != NULL ? &buffer : NULL);
return status == AE_OK ? B_OK : B_ERROR;
}
static status_t
prepare_sleep_state(uint8 state, void (*wakeFunc)(void), size_t size)
{
ACPI_STATUS status;
if (state != ACPI_POWER_STATE_OFF) {
physical_entry wakeVector;
lock_memory(&wakeFunc, size, 0);
get_memory_map(&wakeFunc, size, &wakeVector, 1);
status = AcpiSetFirmwareWakingVector(wakeVector.address);
if (status != AE_OK)
return B_ERROR;
}
status = AcpiEnterSleepStatePrep(state); status = AcpiEnterSleepStatePrep(state);
if (status != AE_OK) if (status != AE_OK)
return B_ERROR; 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; return B_OK;
} }
static status_t
enter_sleep_state(uint8 state)
{
ACPI_STATUS status;
status = AcpiEnterSleepState(state);
if (status != AE_OK)
return B_ERROR;
/*status = AcpiLeaveSleepState(state);
if (status != AE_OK)
return B_ERROR;*/
return B_OK;
}
struct acpi_module_info gACPIModule = {
{
B_ACPI_MODULE_NAME,
B_KEEP_LOADED,
acpi_std_ops
},
enable_fixed_event,
disable_fixed_event,
fixed_event_status,
reset_fixed_event,
install_fixed_event_handler,
remove_fixed_event_handler,
get_next_entry,
get_device,
get_device_hid,
get_object_type,
get_object,
get_object_typed,
evaluate_object,
evaluate_method,
prepare_sleep_state,
enter_sleep_state
};
@@ -43,29 +43,29 @@ acpi_module_supports_device(device_node *parent)
if (strcmp(bus, "root")) if (strcmp(bus, "root"))
return 0.0; return 0.0;
return 1.0; return 1.0;
} }
static status_t static status_t
acpi_module_register_device(device_node *parent) acpi_module_register_device(device_node *parent)
{ {
device_attr attrs[] = { device_attr attrs[] = {
{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "ACPI" }}, { B_DEVICE_PRETTY_NAME, B_STRING_TYPE, { string: "ACPI" }},
{ B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: B_KEEP_DRIVER_LOADED }}, { B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: B_KEEP_DRIVER_LOADED }},
{} {}
}; };
io_resource *resources = NULL; io_resource *resources = NULL;
return gDeviceManager->register_node(parent, ACPI_ROOT_MODULE_NAME, attrs, resources, NULL); return gDeviceManager->register_node(parent, ACPI_ROOT_MODULE_NAME, attrs, resources, NULL);
} }
static status_t static status_t
acpi_enumerate_child_devices(device_node *node, const char *root) acpi_enumerate_child_devices(device_node *node, const char *root)
{ {
char result[255]; char result[255];
@@ -86,25 +86,25 @@ acpi_enumerate_child_devices(device_node *node, const char *root)
acpi_enumerate_child_devices(node, result); acpi_enumerate_child_devices(node, result);
continue; continue;
} }
switch (type) { switch (type) {
case ACPI_TYPE_DEVICE: { case ACPI_TYPE_DEVICE: {
char hid[9] = ""; char hid[9] = "";
device_attr attrs[] = { device_attr attrs[] = {
// info about device // info about device
{ B_DEVICE_BUS, B_STRING_TYPE, { string: "acpi" }}, { B_DEVICE_BUS, B_STRING_TYPE, { string: "acpi" }},
// location on ACPI bus // location on ACPI bus
{ ACPI_DEVICE_PATH_ITEM, B_STRING_TYPE, { string: result }}, { ACPI_DEVICE_PATH_ITEM, B_STRING_TYPE, { string: result }},
// info about the device // info about the device
{ ACPI_DEVICE_HID_ITEM, B_STRING_TYPE, { string: hid }}, { ACPI_DEVICE_HID_ITEM, B_STRING_TYPE, { string: hid }},
{ ACPI_DEVICE_TYPE_ITEM, B_UINT32_TYPE, { ui32: type }}, { ACPI_DEVICE_TYPE_ITEM, B_UINT32_TYPE, { ui32: type }},
// consumer specification // consumer specification
/*{ B_DRIVER_MAPPING, B_STRING_TYPE, { string: /*{ B_DRIVER_MAPPING, B_STRING_TYPE, { string:
"hid_%" ACPI_DEVICE_HID_ITEM "%" }}, "hid_%" ACPI_DEVICE_HID_ITEM "%" }},
{ B_DRIVER_MAPPING "/0", B_STRING_TYPE, { string: { B_DRIVER_MAPPING "/0", B_STRING_TYPE, { string:
"type_%" ACPI_DEVICE_TYPE_ITEM "%" }},*/ "type_%" ACPI_DEVICE_TYPE_ITEM "%" }},*/
{ B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: B_FIND_CHILD_ON_DEMAND|B_FIND_MULTIPLE_CHILDREN }}, { B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: B_FIND_CHILD_ON_DEMAND|B_FIND_MULTIPLE_CHILDREN }},
{ NULL } { NULL }
@@ -122,20 +122,20 @@ acpi_enumerate_child_devices(device_node *node, const char *root)
device_attr attrs[] = { device_attr attrs[] = {
// info about device // info about device
{ B_DEVICE_BUS, B_STRING_TYPE, { string: "acpi" }}, { B_DEVICE_BUS, B_STRING_TYPE, { string: "acpi" }},
// location on ACPI bus // location on ACPI bus
{ ACPI_DEVICE_PATH_ITEM, B_STRING_TYPE, { string: result }}, { ACPI_DEVICE_PATH_ITEM, B_STRING_TYPE, { string: result }},
// info about the device // info about the device
{ ACPI_DEVICE_TYPE_ITEM, B_UINT32_TYPE, { ui32: type }}, { ACPI_DEVICE_TYPE_ITEM, B_UINT32_TYPE, { ui32: type }},
// consumer specification // consumer specification
/*{ B_DRIVER_MAPPING, B_STRING_TYPE, { string: /*{ B_DRIVER_MAPPING, B_STRING_TYPE, { string:
"type_%" ACPI_DEVICE_TYPE_ITEM "%" }},*/ "type_%" ACPI_DEVICE_TYPE_ITEM "%" }},*/
{ B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: B_FIND_CHILD_ON_DEMAND|B_FIND_MULTIPLE_CHILDREN }}, { B_DEVICE_FLAGS, B_UINT32_TYPE, { ui32: B_FIND_CHILD_ON_DEMAND|B_FIND_MULTIPLE_CHILDREN }},
{ NULL } { NULL }
}; };
if (gDeviceManager->register_node(node, ACPI_DEVICE_MODULE_NAME, attrs, NULL, &deviceNode) == B_OK) if (gDeviceManager->register_node(node, ACPI_DEVICE_MODULE_NAME, attrs, NULL, &deviceNode) == B_OK)
acpi_enumerate_child_devices(deviceNode, result); acpi_enumerate_child_devices(deviceNode, result);
break; break;
@@ -151,12 +151,12 @@ acpi_enumerate_child_devices(device_node *node, const char *root)
} }
static status_t static status_t
acpi_module_register_child_devices(void *cookie) acpi_module_register_child_devices(void *cookie)
{ {
status_t err; status_t err;
device_node *node = cookie; device_node *node = cookie;
err = gDeviceManager->publish_device(node, "acpi/namespace", ACPI_NS_DUMP_DEVICE_MODULE_NAME); err = gDeviceManager->publish_device(node, "acpi/namespace", ACPI_NS_DUMP_DEVICE_MODULE_NAME);
if (err != B_OK) { if (err != B_OK) {
return err; return err;
@@ -195,11 +195,11 @@ apci_module_std_ops(int32 op, ...)
return put_module(B_ACPI_MODULE_NAME); return put_module(B_ACPI_MODULE_NAME);
} }
return B_BAD_VALUE; return B_BAD_VALUE;
} }
static struct acpi_root_info sACPIModule = { static struct acpi_root_info sACPIRootModule = {
{ {
{ {
ACPI_ROOT_MODULE_NAME, ACPI_ROOT_MODULE_NAME,
@@ -230,13 +230,12 @@ static struct acpi_root_info sACPIModule = {
get_object_typed, get_object_typed,
evaluate_object, evaluate_object,
evaluate_method, evaluate_method,
}; };
_EXPORT module_info *modules[] = { _EXPORT module_info *modules[] = {
(module_info *) &acpi_module, (module_info *)&gACPIModule,
(module_info *) &sACPIModule, (module_info *)&sACPIRootModule,
(module_info *) &acpi_ns_dump_module, (module_info *)&acpi_ns_dump_module,
(module_info *) &gACPIDeviceModule, (module_info *)&gACPIDeviceModule,
NULL NULL
}; };
@@ -1,9 +1,7 @@
/* /*
* Copyright 2006, Jérôme Duval. All rights reserved. * Copyright 2006, Jérôme Duval. All rights reserved.
*
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef __ACPI_PRIV_H__ #ifndef __ACPI_PRIV_H__
#define __ACPI_PRIV_H__ #define __ACPI_PRIV_H__
@@ -24,70 +22,80 @@
extern device_manager_info *gDeviceManager; extern device_manager_info *gDeviceManager;
// ACPI root. // ACPI root.
typedef struct acpi_root_info { typedef struct acpi_root_info {
driver_module_info info; driver_module_info info;
/* Fixed Event Management */ /* Fixed Event Management */
void (*enable_fixed_event) (uint32 event); void (*enable_fixed_event) (uint32 event);
void (*disable_fixed_event) (uint32 event); void (*disable_fixed_event) (uint32 event);
uint32 (*fixed_event_status) (uint32 event); uint32 (*fixed_event_status) (uint32 event);
/* Returns 1 if event set, 0 otherwise */ /* Returns 1 if event set, 0 otherwise */
void (*reset_fixed_event) (uint32 event); void (*reset_fixed_event) (uint32 event);
status_t (*install_fixed_event_handler) (uint32 event, interrupt_handler *handler, void *data); status_t (*install_fixed_event_handler)(uint32 event,
status_t (*remove_fixed_event_handler) (uint32 event, interrupt_handler *handler); interrupt_handler *handler, void *data);
status_t (*remove_fixed_event_handler)(uint32 event,
interrupt_handler *handler);
/* Namespace Access */ /* Namespace Access */
status_t (*get_next_entry) (uint32 object_type, const char *base, char *result, size_t len, void **counter); status_t (*get_next_entry)(uint32 object_type, const char *base,
status_t (*get_device) (const char *hid, uint32 index, char *result); 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); size_t resultLength);
uint32 (*get_object_type) (const char *path);
status_t (*get_object) (const char *path, acpi_object_type **return_value); status_t (*get_device_hid)(const char *path, char *hid);
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 (*get_object)(const char *path,
acpi_object_type **_returnValue);
status_t (*get_object_typed)(const char *path,
acpi_object_type **_returnValue, uint32 objectType);
/* Control method execution and data acquisition */ /* Control method execution and data acquisition */
status_t (*evaluate_object) (const char *object, acpi_object_type *return_value, size_t buf_len); status_t (*evaluate_object)(const char *object,
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_object_type *returnValue, size_t bufferLength);
status_t (*evaluate_method)(const char *object, const char *method,
acpi_object_type *returnValue, size_t bufferLength,
acpi_object_type *args, int numArgs);
} acpi_root_info; } acpi_root_info;
extern struct acpi_module_info acpi_module; extern struct acpi_module_info gACPIModule;
extern struct device_module_info acpi_ns_dump_module; extern struct device_module_info acpi_ns_dump_module;
extern acpi_device_module_info gACPIDeviceModule; extern acpi_device_module_info gACPIDeviceModule;
void enable_fixed_event (uint32 event); void enable_fixed_event(uint32 event);
void disable_fixed_event (uint32 event); void disable_fixed_event(uint32 event);
uint32 fixed_event_status (uint32 event); uint32 fixed_event_status(uint32 event);
void reset_fixed_event (uint32 event); void reset_fixed_event(uint32 event);
status_t install_fixed_event_handler (uint32 event, interrupt_handler *handler, void *data); status_t install_fixed_event_handler(uint32 event, interrupt_handler *handler,
status_t remove_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 length, void **counter);
status_t get_device(const char *hid, uint32 index, char *result,
size_t resultLength);
status_t get_next_entry (uint32 object_type, const char *base, char *result, size_t len, void **counter); status_t get_device_hid(const char *path, char *hid);
status_t get_device (const char *hid, uint32 index, char *result); uint32 get_object_type(const char *path);
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(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 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);
status_t evaluate_object(const char *object, acpi_object_type *returnValue,
size_t bufferLength);
status_t evaluate_method(const char *object, const char *method,
acpi_object_type *returnValue, size_t bufferLength, acpi_object_type *args,
int numArgs);
#endif /* __ACPI_PRIV_H__ */ #endif /* __ACPI_PRIV_H__ */
+27 -27
View File
@@ -133,7 +133,7 @@
extern pci_module_info *gPCIManager; extern pci_module_info *gPCIManager;
#include <dpc.h> #include <dpc.h>
extern dpc_module_info *gDPC; extern dpc_module_info *gDPC;
extern void *gDPChandle; extern void *gDPCHandle;
#endif #endif
#include "acpi.h" #include "acpi.h"
@@ -171,7 +171,7 @@ AcpiOsInitialize (void)
#else #else
AcpiGbl_OutputFile = NULL; AcpiGbl_OutputFile = NULL;
#endif #endif
return AE_OK; return AE_OK;
} }
@@ -456,10 +456,10 @@ AcpiOsGetLine (
char *Buffer) char *Buffer)
{ {
UINT32 i = 0; UINT32 i = 0;
#ifndef _KERNEL_MODE #ifndef _KERNEL_MODE
UINT8 Temp; UINT8 Temp;
for (i = 0; ; i++) for (i = 0; ; i++)
{ {
scanf ("%1c", &Temp); scanf ("%1c", &Temp);
@@ -537,7 +537,7 @@ AcpiOsUnmapMemory (
void *where, void *where,
ACPI_SIZE length) ACPI_SIZE length)
{ {
delete_area(area_for(where)); delete_area(area_for(where));
return; return;
} }
@@ -636,7 +636,7 @@ AcpiOsDeleteSemaphore (
} }
delete_sem((sem_id)(Handle)); delete_sem((sem_id)(Handle));
return AE_OK; return AE_OK;
} }
@@ -704,10 +704,10 @@ ACPI_STATUS
AcpiOsCreateLock ( AcpiOsCreateLock (
ACPI_HANDLE *OutHandle) ACPI_HANDLE *OutHandle)
{ {
*OutHandle = (ACPI_HANDLE)malloc(sizeof(spinlock)); *OutHandle = (ACPI_HANDLE)malloc(sizeof(spinlock));
*((spinlock *)(*OutHandle)) = 1; *((spinlock *)(*OutHandle)) = 1;
return AE_OK; return AE_OK;
} }
@@ -724,22 +724,22 @@ AcpiOsAcquireLock (
ACPI_HANDLE Handle) ACPI_HANDLE Handle)
{ {
/*cpu_status cpu; /*cpu_status cpu;
if (Flags == ACPI_NOT_ISR) if (Flags == ACPI_NOT_ISR)
cpu = disable_interrupts(); cpu = disable_interrupts();
acquire_spinlock ((spinlock *)(Handle)); acquire_spinlock ((spinlock *)(Handle));
if (Flags == ACPI_NOT_ISR) if (Flags == ACPI_NOT_ISR)
restore_interrupts(cpu);*/ restore_interrupts(cpu);*/
/* Why aren't we using real spinlocks? Well, they seem to cause /* Why aren't we using real spinlocks? Well, they seem to cause
kernel hangs at boot, at least on Dano. I don't really know kernel hangs at boot, at least on Dano. I don't really know
why, as they should be equivalent to this. Maybe in sysinit2 why, as they should be equivalent to this. Maybe in sysinit2
interrupts are already off, and the double disable interrupts interrupts are already off, and the double disable interrupts
call is hanging the system? I'm not sure how to detect that call is hanging the system? I'm not sure how to detect that
though. Anyway, this works, even if it's stupid. */ though. Anyway, this works, even if it's stupid. */
while (_atomic_test_and_set(((spinlock *)(Handle)),0,1) <= 0); while (_atomic_test_and_set(((spinlock *)(Handle)),0,1) <= 0);
return (0); return (0);
} }
@@ -751,15 +751,15 @@ AcpiOsReleaseLock (
ACPI_CPU_FLAGS Flags) ACPI_CPU_FLAGS Flags)
{ {
/*cpu_status cpu; /*cpu_status cpu;
if (Flags == ACPI_NOT_ISR) if (Flags == ACPI_NOT_ISR)
cpu = disable_interrupts(); cpu = disable_interrupts();
release_spinlock ((spinlock *)(Handle)); release_spinlock ((spinlock *)(Handle));
if (Flags == ACPI_NOT_ISR) if (Flags == ACPI_NOT_ISR)
restore_interrupts(cpu);*/ restore_interrupts(cpu);*/
atomic_add(((spinlock *)(Handle)),1); atomic_add(((spinlock *)(Handle)),1);
} }
@@ -787,7 +787,7 @@ AcpiOsInstallInterruptHandler (
{ {
#ifdef _KERNEL_MODE #ifdef _KERNEL_MODE
install_io_interrupt_handler(InterruptNumber,(interrupt_handler)ServiceRoutine,Context,0); install_io_interrupt_handler(InterruptNumber,(interrupt_handler)ServiceRoutine,Context,0);
/* It so happens that the Haiku and ACPI-CA interrupt handler routines /* It so happens that the Haiku and ACPI-CA interrupt handler routines
return the same values with the same meanings */ return the same values with the same meanings */
@@ -820,7 +820,7 @@ dprintf("AcpiOsRemoveInterruptHandler()\n");
remove_io_interrupt_handler(InterruptNumber,(interrupt_handler)ServiceRoutine,NULL); remove_io_interrupt_handler(InterruptNumber,(interrupt_handler)ServiceRoutine,NULL);
/* Crap. We don't get the Context argument back. */ /* Crap. We don't get the Context argument back. */
#warning Sketchy code! #warning Sketchy code!
#endif #endif
return AE_OK; return AE_OK;
@@ -859,8 +859,8 @@ AcpiOsExecute (
break; break;
} }
err = gDPC->queue_dpc(gDPChandle, Function, Context); err = gDPC->queue_dpc(gDPCHandle, Function, Context);
if (err != B_OK) if (err != B_OK)
return AE_ERROR; return AE_ERROR;
return AE_OK; return AE_OK;
@@ -1053,7 +1053,7 @@ AcpiOsReadPciConfiguration (
case 2: *(UINT16*)Value = val; case 2: *(UINT16*)Value = val;
case 4: *(UINT32*)Value = val; case 4: *(UINT32*)Value = val;
} }
#endif #endif
return (AE_OK); return (AE_OK);
} }
@@ -1083,10 +1083,10 @@ AcpiOsWritePciConfiguration (
{ {
#ifdef _KERNEL_MODE #ifdef _KERNEL_MODE
gPCIManager->write_pci_config( gPCIManager->write_pci_config(
PciId->Bus, PciId->Device, PciId->Function, Register, Width/8, Value); PciId->Bus, PciId->Device, PciId->Function, Register, Width/8, Value);
#endif #endif
return (AE_OK); return (AE_OK);
} }
@@ -1121,7 +1121,7 @@ AcpiOsReadPort (
UINT32 *Value, UINT32 *Value,
UINT32 Width) UINT32 Width)
{ {
#ifdef _KERNEL_MODE #ifdef _KERNEL_MODE
switch (Width) switch (Width)
@@ -1138,7 +1138,7 @@ AcpiOsReadPort (
*Value = gPCIManager->read_io_32(Address); *Value = gPCIManager->read_io_32(Address);
break; break;
} }
#endif #endif
return (AE_OK); return (AE_OK);
@@ -1212,7 +1212,7 @@ AcpiOsReadMemory (
#ifdef _KERNEL_MODE #ifdef _KERNEL_MODE
memcpy(Value, gPCIManager->ram_address(ACPI_TO_POINTER(Address)), Width/8); memcpy(Value, gPCIManager->ram_address(ACPI_TO_POINTER(Address)), Width/8);
#endif #endif
return (AE_OK); return (AE_OK);