⛏️ index : haiku.git

/*
 * Copyright 2005-2008, Haiku Inc. All Rights Reserved.
 * Distributed under the terms of the MIT License
 */
#ifndef _ACPI_H
#define _ACPI_H


#include <device_manager.h>
#include <KernelExport.h>


typedef struct acpi_module_info acpi_module_info;
typedef union acpi_object_type acpi_object_type;

#define B_ACPI_MODULE_NAME "bus_managers/acpi/v1"

typedef phys_addr_t acpi_physical_address;
typedef phys_addr_t acpi_io_address;
typedef size_t acpi_size;

/* Actually a ptr to a NS Node */
typedef void *				acpi_handle;

#ifndef __ACTYPES_H__

/* Notify types */

#define ACPI_SYSTEM_NOTIFY				0x1
#define ACPI_DEVICE_NOTIFY				0x2
#define ACPI_ALL_NOTIFY					(ACPI_SYSTEM_NOTIFY | ACPI_DEVICE_NOTIFY)
#define ACPI_MAX_NOTIFY_HANDLER_TYPE	0x3

#define ACPI_MAX_SYS_NOTIFY				0x7F

/* Address Space (Operation Region) Types */

enum {
	ACPI_ADR_SPACE_SYSTEM_MEMORY	= 0,
	ACPI_ADR_SPACE_SYSTEM_IO		= 1,
	ACPI_ADR_SPACE_PCI_CONFIG		= 2,
	ACPI_ADR_SPACE_EC				= 3,
	ACPI_ADR_SPACE_SMBUS			= 4,
	ACPI_ADR_SPACE_CMOS 			= 5,
	ACPI_ADR_SPACE_PCI_BAR_TARGET	= 6,
	ACPI_ADR_SPACE_IPMI				= 7,
	ACPI_ADR_SPACE_DATA_TABLE		= 8,
	ACPI_ADR_SPACE_FIXED_HARDWARE	= 127
};

/* ACPI fixed event types */

enum {
	ACPI_EVENT_PMTIMER = 0,
	ACPI_EVENT_GLOBAL,
	ACPI_EVENT_POWER_BUTTON,
	ACPI_EVENT_SLEEP_BUTTON,
	ACPI_EVENT_RTC
};

/* ACPI Object Types */

enum {
	ACPI_TYPE_ANY = 0,
	ACPI_TYPE_INTEGER,
	ACPI_TYPE_STRING,
	ACPI_TYPE_BUFFER,
	ACPI_TYPE_PACKAGE,
	ACPI_TYPE_FIELD_UNIT,
	ACPI_TYPE_DEVICE,
	ACPI_TYPE_EVENT,
	ACPI_TYPE_METHOD,
	ACPI_TYPE_MUTEX,
	ACPI_TYPE_REGION,
	ACPI_TYPE_POWER,
	ACPI_TYPE_PROCESSOR,
	ACPI_TYPE_THERMAL,
	ACPI_TYPE_BUFFER_FIELD,
	ACPI_TYPE_DDB_HANDLE,
	ACPI_TYPE_DEBUG_OBJECT,
	ACPI_TYPE_LOCAL_REFERENCE = 0x14
};

/* ACPI control method arg type */

union acpi_object_type {
	uint32 object_type;
	struct {
		uint32 object_type;
		uint64 integer;
	} integer;
	struct {
		uint32 object_type;
		uint32 len;
		char *string; /* You have to allocate string space yourself */
	} string;
	struct {
		uint32 object_type;
		uint32 length;
		void *buffer;
	} buffer;
	struct {
		uint32 object_type;
		uint32 count;
		acpi_object_type *objects;
	} package;
	struct {
		uint32 object_type;
		uint32 actual_type;
		acpi_handle handle;
	} reference;
	struct {
		uint32 object_type;
		uint32 cpu_id;
		acpi_io_address pblk_address;
		uint32 pblk_length;
	} processor;
	struct {
		uint32 object_type;
		uint32 min_power_state;
		uint32 resource_order;
	} power_resource;
};


/*
 * List of objects, used as a parameter list for control method evaluation
 */
typedef struct acpi_objects {
	uint32				count;
	acpi_object_type	*pointer;
} acpi_objects;


typedef struct acpi_data {
	acpi_size			length;		/* Length in bytes of the buffer */
	void				*pointer;	/* pointer to buffer */
} acpi_data;


enum {
	ACPI_ALLOCATE_BUFFER = (acpi_size)-1,
	ACPI_ALLOCATE_LOCAL_BUFFER = (acpi_size)-2,
};


/*
 * acpi_status should return ACPI specific error codes, not BeOS ones.
 */
typedef uint32 acpi_status;

typedef struct acpi_resource acpi_resource;

#define ACPI_REENABLE_GPE	0x80


#endif	// __ACTYPES_H__


typedef uint32 (*acpi_event_handler)(void *context);
typedef uint32 (*acpi_gpe_handler) (acpi_handle GpeDevice, uint32 GpeNumber,
	void *context);

typedef acpi_status (*acpi_adr_space_handler)(uint32 function,
	acpi_physical_address address, uint32 bitWidth, int *value,
	void *handlerContext, void *regionContext);

typedef acpi_status (*acpi_adr_space_setup)(acpi_handle regionHandle,
	uint32 function, void *handlerContext, void **regionContext);

typedef void (*acpi_notify_handler)(acpi_handle device, uint32 value,
	void *context);

typedef acpi_status (*acpi_walk_resources_callback)(acpi_resource* resource,
	void* context);

typedef acpi_status (*acpi_walk_callback) (acpi_handle object, uint32 nestingLevel,
	void *context, void** returnValue);


struct acpi_module_info {
	module_info info;

	status_t	(*get_handle)(acpi_handle parent, const char *pathname,
					acpi_handle *retHandle);
	status_t 	(*get_name)(acpi_handle handle, uint32 nameType,
					char* returnedName, size_t bufferLength);

	/* Global Lock */

	status_t	(*acquire_global_lock)(uint16 timeout, uint32 *handle);
	status_t	(*release_global_lock)(uint32 handle);

	/* Notify Handler */

	status_t	(*install_notify_handler)(acpi_handle device,
					uint32 handlerType, acpi_notify_handler handler,
					void *context);
	status_t	(*remove_notify_handler)(acpi_handle device,
					uint32 handlerType, acpi_notify_handler handler);

	/* GPE Handler */

	status_t	(*update_all_gpes)();
	status_t	(*enable_gpe)(acpi_handle handle, uint32 gpeNumber);
	status_t	(*disable_gpe)(acpi_handle handle, uint32 gpeNumber);
	status_t	(*clear_gpe)(acpi_handle handle, uint32 gpeNumber);
	status_t	(*set_gpe)(acpi_handle handle, uint32 gpeNumber,
					uint8 action);
	status_t	(*finish_gpe)(acpi_handle handle, uint32 gpeNumber);
	status_t	(*install_gpe_handler)(acpi_handle handle, uint32 gpeNumber,
					uint32 type, acpi_gpe_handler handler, void *data);
	status_t	(*remove_gpe_handler)(acpi_handle handle, uint32 gpeNumber,
					acpi_gpe_handler address);

	/* Address Space Handler */

	status_t	(*install_address_space_handler)(acpi_handle handle,
					uint32 spaceId,
					acpi_adr_space_handler handler,
					acpi_adr_space_setup setup,	void *data);
	status_t	(*remove_address_space_handler)(acpi_handle handle,
					uint32 spaceId,
					acpi_adr_space_handler handler);

	/* Fixed Event Management */

	void		(*enable_fixed_event)(uint32 event);
	void		(*disable_fixed_event)(uint32 event);

	uint32		(*fixed_event_status) (uint32 event);
					/* Returns 1 if event set, 0 otherwise */
	void		(*reset_fixed_event) (uint32 event);

	status_t	(*install_fixed_event_handler)(uint32 event,
					acpi_event_handler handler, void *data);
	status_t	(*remove_fixed_event_handler)(uint32 event,
					acpi_event_handler handler);

	/* Namespace Access */

	status_t	(*get_next_entry)(uint32 objectType, const char *base,
					char *result, size_t length, void **_counter);
	status_t	(*get_next_object)(uint32 objectType, acpi_handle parent,
					acpi_handle* currentChild);
	status_t	(*walk_namespace)(acpi_handle busDeviceHandle,
					uint32 objectType, uint32 maxDepth,
					acpi_walk_callback descendingCallback,
					acpi_walk_callback ascendingCallback, void* context,
					void** returnValue);

	status_t	(*get_device)(const char *hid, uint32 index, char *result,
					size_t resultLength);

	status_t	(*get_device_info)(const char *path, char** hid,
					char** cidList, size_t cidListLength, char** uid, char** cls);
	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);
	status_t	(*ns_handle_to_pathname)(acpi_handle targetHandle,
					acpi_data *buffer);

	/* Control method execution and data acquisition */

	status_t	(*evaluate_object)(acpi_handle handle, const char* object,
					acpi_objects *args, acpi_object_type *returnValue, size_t bufferLength);
	status_t	(*evaluate_method)(acpi_handle handle, const char *method,
					acpi_objects *args, acpi_data *returnValue);

	/* Resource Management */

	status_t	(*get_irq_routing_table)(acpi_handle busDeviceHandle,
					acpi_data *retBuffer);
	status_t	(*get_current_resources)(acpi_handle busDeviceHandle,
					acpi_data *retBuffer);
	status_t	(*get_possible_resources)(acpi_handle busDeviceHandle,
					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 */

	status_t	(*prepare_sleep_state)(uint8 state, void (*wakeFunc)(void),
					size_t size);
	status_t	(*enter_sleep_state)(uint8 state);
	status_t	(*reboot)(void);

	/* Table Access */
	status_t	(*get_table)(const char *signature, uint32 instance,
					void **tableHeader);

	/* Register Access */
	status_t	(*read_bit_register)(uint32 regid, uint32 *val);
	status_t	(*write_bit_register)(uint32 regid, uint32 val);
};


/* Sleep states */

enum {
	ACPI_POWER_STATE_ON = 0,
	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_ADDR_ITEM	"acpi/addr"
#define ACPI_DEVICE_CID_ITEM	"acpi/cid"
#define ACPI_DEVICE_HANDLE_ITEM	"acpi/handle"
#define ACPI_DEVICE_HID_ITEM	"acpi/hid"
#define ACPI_DEVICE_PATH_ITEM	"acpi/path"
#define ACPI_DEVICE_TYPE_ITEM	"acpi/type"
#define ACPI_DEVICE_UID_ITEM	"acpi/uid"


typedef struct acpi_device_cookie *acpi_device;

//	Interface to one ACPI device.
typedef struct acpi_device_module_info {
	driver_module_info info;

	/* Notify Handler */

	status_t	(*install_notify_handler)(acpi_device device,
					uint32 handlerType, acpi_notify_handler handler,
					void *context);
	status_t	(*remove_notify_handler)(acpi_device device,
					uint32 handlerType, acpi_notify_handler handler);

	/* Address Space Handler */
	status_t	(*install_address_space_handler)(acpi_device device,
					uint32 spaceId,
					acpi_adr_space_handler handler,
					acpi_adr_space_setup setup,	void *data);
	status_t	(*remove_address_space_handler)(acpi_device device,
					uint32 spaceId,
					acpi_adr_space_handler handler);

	/* Namespace Access */
	uint32		(*get_object_type)(acpi_device device);
	status_t	(*get_object)(acpi_device device, const char *path,
					acpi_object_type **_returnValue);
	status_t	(*walk_namespace)(acpi_device device,
					uint32 objectType, uint32 maxDepth,
					acpi_walk_callback descendingCallback,
					acpi_walk_callback ascendingCallback,
					void* context, void** returnValue);

	/* 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;


#endif	/* _ACPI_H */