Commit 8afca009 authored by Andy Grover's avatar Andy Grover

ACPI interpreter update

parent e31ad404
/*******************************************************************************
*
* Module Name: dbdisasm - parser op tree display routines
* $Revision: 66 $
* $Revision: 67 $
*
******************************************************************************/
......@@ -674,7 +674,8 @@ acpi_db_display_opcode (
(walk_state) &&
(walk_state->results) &&
(walk_state->results->results.num_results)) {
acpi_db_decode_internal_object (walk_state->results->results.obj_desc [walk_state->results->results.num_results-1]);
acpi_db_decode_internal_object (
walk_state->results->results.obj_desc [walk_state->results->results.num_results-1]);
}
#endif
break;
......
/*******************************************************************************
*
* Module Name: dbdisply - debug display commands
* $Revision: 75 $
* $Revision: 76 $
*
******************************************************************************/
......@@ -300,6 +300,11 @@ acpi_db_decode_internal_object (
return;
}
if (ACPI_GET_DESCRIPTOR_TYPE (obj_desc) != ACPI_DESC_TYPE_OPERAND) {
acpi_os_printf ("%p", obj_desc);
return;
}
acpi_os_printf (" %s", acpi_ut_get_object_type_name (obj_desc));
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
......@@ -336,12 +341,45 @@ acpi_db_decode_internal_object (
default:
/* No additional display for other types */
acpi_os_printf ("%p", obj_desc);
break;
}
}
/*******************************************************************************
*
* FUNCTION: Acpi_db_decode_node
*
* PARAMETERS: Node - Object to be displayed
*
* RETURN: None
*
* DESCRIPTION: Short display of a namespace node
*
******************************************************************************/
void
acpi_db_decode_node (
acpi_namespace_node *node)
{
acpi_os_printf ("<Node> Name %4.4s Type-%s",
node->name.ascii, acpi_ut_get_type_name (node->type));
if (node->flags & ANOBJ_METHOD_ARG) {
acpi_os_printf (" [Method Arg]");
}
if (node->flags & ANOBJ_METHOD_LOCAL) {
acpi_os_printf (" [Method Local]");
}
acpi_db_decode_internal_object (acpi_ns_get_attached_object (node));
}
/*******************************************************************************
*
* FUNCTION: Acpi_db_display_internal_object
......@@ -381,16 +419,7 @@ acpi_db_display_internal_object (
case ACPI_DESC_TYPE_NAMED:
acpi_os_printf ("<Node> Name %4.4s Type-%s",
((acpi_namespace_node *)obj_desc)->name.ascii,
acpi_ut_get_type_name (((acpi_namespace_node *) obj_desc)->type));
if (((acpi_namespace_node *) obj_desc)->flags & ANOBJ_METHOD_ARG) {
acpi_os_printf (" [Method Arg]");
}
if (((acpi_namespace_node *) obj_desc)->flags & ANOBJ_METHOD_LOCAL) {
acpi_os_printf (" [Method Local]");
}
acpi_db_decode_node ((acpi_namespace_node *) obj_desc);
break;
......@@ -406,8 +435,10 @@ acpi_db_display_internal_object (
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case INTERNAL_TYPE_REFERENCE:
switch (obj_desc->reference.opcode) {
case AML_LOCAL_OP:
acpi_os_printf ("[Local%d] ", obj_desc->reference.offset);
if (walk_state) {
obj_desc = walk_state->local_variables[obj_desc->reference.offset].object;
......@@ -416,7 +447,9 @@ acpi_db_display_internal_object (
}
break;
case AML_ARG_OP:
acpi_os_printf ("[Arg%d] ", obj_desc->reference.offset);
if (walk_state) {
obj_desc = walk_state->arguments[obj_desc->reference.offset].object;
......@@ -425,24 +458,51 @@ acpi_db_display_internal_object (
}
break;
case AML_DEBUG_OP:
acpi_os_printf ("[Debug] ");
break;
case AML_INDEX_OP:
acpi_os_printf ("[Index] ");
acpi_db_decode_internal_object (obj_desc->reference.object);
break;
case AML_REF_OF_OP:
acpi_os_printf ("[Reference] ");
/* Reference can be to a Node or an Operand object */
switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc->reference.object)) {
case ACPI_DESC_TYPE_NAMED:
acpi_db_decode_node (obj_desc->reference.object);
break;
case ACPI_DESC_TYPE_OPERAND:
acpi_db_decode_internal_object (obj_desc->reference.object);
break;
default:
break;
}
break;
default:
acpi_os_printf ("Unknown Reference opcode %X\n",
obj_desc->reference.opcode);
break;
}
break;
default:
acpi_os_printf ("<Obj> ");
acpi_os_printf (" ");
acpi_db_decode_internal_object (obj_desc);
......
/*******************************************************************************
*
* Module Name: dbexec - debugger control method execution
* $Revision: 41 $
* $Revision: 42 $
*
******************************************************************************/
......@@ -223,6 +223,9 @@ acpi_db_execute (
acpi_gbl_db_method_info.args = args;
acpi_gbl_db_method_info.flags = flags;
return_obj.pointer = NULL;
return_obj.length = ACPI_ALLOCATE_BUFFER;
acpi_db_execute_setup (&acpi_gbl_db_method_info);
status = acpi_db_execute_method (&acpi_gbl_db_method_info, &return_obj);
......@@ -260,6 +263,10 @@ acpi_db_execute (
acpi_gbl_db_method_info.pathname, return_obj.pointer, return_obj.length);
acpi_db_dump_object (return_obj.pointer, 1);
}
else {
acpi_os_printf ("No return object from execution of %s\n",
acpi_gbl_db_method_info.pathname);
}
}
acpi_db_set_output_destination (ACPI_DB_CONSOLE_OUTPUT);
......
......@@ -2,7 +2,7 @@
*
* Module Name: dbfileio - Debugger file I/O commands. These can't usually
* be used when running the debugger in Ring 0 (Kernel mode)
* $Revision: 63 $
* $Revision: 64 $
*
******************************************************************************/
......@@ -279,9 +279,13 @@ ae_local_load_table (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Install the new table into the local data structures */
table_info.pointer = table_ptr;
status = acpi_tb_recognize_table (&table_info, ACPI_TABLE_SECONDARY);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Install the new table into the local data structures */
status = acpi_tb_install_table (&table_info);
if (ACPI_FAILURE (status)) {
......
/******************************************************************************
*
* Module Name: dsmethod - Parser/Interpreter interface - control method parsing
* $Revision: 86 $
* $Revision: 87 $
*
*****************************************************************************/
......@@ -290,7 +290,7 @@ acpi_ds_call_control_method (
/* Create and init a Root Node */
op = acpi_ps_alloc_op (AML_SCOPE_OP);
op = acpi_ps_create_scope_op ();
if (!op) {
status = AE_NO_MEMORY;
goto cleanup;
......
/******************************************************************************
*
* Module Name: dsobject - Dispatcher object management routines
* $Revision: 103 $
* $Revision: 104 $
*
*****************************************************************************/
......@@ -368,6 +368,8 @@ acpi_ds_init_object_from_op (
obj_desc->reference.opcode = AML_LOCAL_OP;
obj_desc->reference.offset = opcode - AML_LOCAL_OP;
acpi_ds_method_data_get_node (AML_LOCAL_OP, obj_desc->reference.offset,
walk_state, (acpi_namespace_node **) &obj_desc->reference.object);
break;
......
/******************************************************************************
*
* Module Name: dswload - Dispatcher namespace load callbacks
* $Revision: 66 $
* $Revision: 67 $
*
*****************************************************************************/
......@@ -448,12 +448,6 @@ acpi_ds_load2_end_op (
if (op->common.aml_opcode == AML_SCOPE_OP) {
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"Ending scope Op=%p State=%p\n", op, walk_state));
if (op->named.name == ACPI_UINT16_MAX) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unnamed scope! Op=%p State=%p\n",
op, walk_state));
return (AE_OK);
}
}
......
/******************************************************************************
*
* Module Name: exconfig - Namespace reconfiguration (Load/Unload opcodes)
* $Revision: 66 $
* $Revision: 67 $
*
*****************************************************************************/
......@@ -138,6 +138,7 @@ acpi_ex_load_table_op (
ACPI_FUNCTION_TRACE ("Ex_load_table_op");
#if 0
/*
* Make sure that the signature does not match one of the tables that
* is already loaded.
......@@ -148,6 +149,7 @@ acpi_ex_load_table_op (
return_ACPI_STATUS (AE_ALREADY_EXISTS);
}
#endif
/* Find the ACPI table */
......
/******************************************************************************
*
* Module Name: exdump - Interpreter debug output routines
* $Revision: 155 $
* $Revision: 156 $
*
*****************************************************************************/
......@@ -121,6 +121,13 @@ acpi_ex_dump_operand (
break;
case AML_REF_OF_OP:
acpi_os_printf ("Reference: (Ref_of) %p\n",
obj_desc->reference.object);
break;
case AML_ARG_OP:
acpi_os_printf ("Reference: Arg%d",
......@@ -157,10 +164,12 @@ acpi_ex_dump_operand (
case AML_INT_NAMEPATH_OP:
acpi_os_printf ("Reference.Node->Name %X\n",
obj_desc->reference.node->name.integer);
break;
default:
/* unknown opcode */
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
* $Revision: 106 $
* $Revision: 107 $
*
*****************************************************************************/
......@@ -41,6 +41,7 @@
*
* PARAMETERS: Obj_desc - Create a reference to this object
* Return_desc - Where to store the reference
* Walk_state - Current state
*
* RETURN: Status
*
......@@ -55,65 +56,75 @@ acpi_ex_get_object_reference (
acpi_operand_object **return_desc,
acpi_walk_state *walk_state)
{
acpi_status status = AE_OK;
acpi_operand_object *reference_obj;
acpi_operand_object *referenced_obj;
ACPI_FUNCTION_TRACE_PTR ("Ex_get_object_reference", obj_desc);
*return_desc = NULL;
switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
case ACPI_DESC_TYPE_OPERAND:
if (ACPI_GET_OBJECT_TYPE (obj_desc) != INTERNAL_TYPE_REFERENCE) {
*return_desc = NULL;
status = AE_TYPE;
goto cleanup;
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
/*
* Not a Name -- an indirect name pointer would have
* been converted to a direct name pointer in Acpi_ex_resolve_operands
* Must be a reference to a Local or Arg
*/
switch (obj_desc->reference.opcode) {
case AML_LOCAL_OP:
case AML_ARG_OP:
status = acpi_ds_method_data_get_node (obj_desc->reference.opcode,
obj_desc->reference.offset, walk_state,
ACPI_CAST_INDIRECT_PTR (acpi_namespace_node, return_desc));
/* The referenced object is the pseudo-node for the local/arg */
referenced_obj = obj_desc->reference.object;
break;
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(Internal) Unknown Ref subtype %02x\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference subtype %X\n",
obj_desc->reference.opcode));
*return_desc = NULL;
status = AE_AML_INTERNAL;
goto cleanup;
return_ACPI_STATUS (AE_AML_INTERNAL);
}
break;
case ACPI_DESC_TYPE_NAMED:
/* Must be a named object; Just return the Node */
*return_desc = obj_desc;
/*
* A named reference that has already been resolved to a Node
*/
referenced_obj = obj_desc;
break;
default:
*return_desc = NULL;
status = AE_TYPE;
break;
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type %X in %p\n",
ACPI_GET_DESCRIPTOR_TYPE (obj_desc), obj_desc));
return_ACPI_STATUS (AE_TYPE);
}
cleanup:
/* Create a new reference object */
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p Ref=%p\n", obj_desc, *return_desc));
return_ACPI_STATUS (status);
reference_obj = acpi_ut_create_internal_object (INTERNAL_TYPE_REFERENCE);
if (!reference_obj) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
reference_obj->reference.opcode = AML_REF_OF_OP;
reference_obj->reference.object = referenced_obj;
*return_desc = reference_obj;
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Object %p Type [%s], returning Reference %p\n",
obj_desc, acpi_ut_get_object_type_name (obj_desc), *return_desc));
return_ACPI_STATUS (AE_OK);
}
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exoparg1 - AML execution - opcodes with 1 argument
* $Revision: 139 $
* $Revision: 140 $
*
*****************************************************************************/
......@@ -355,7 +355,7 @@ acpi_ex_opcode_1A_1T_1R (
goto cleanup;
}
/* Get the object reference and store it */
/* Get the object reference, store it, and remove our reference */
status = acpi_ex_get_object_reference (operand[0], &return_desc2, walk_state);
if (ACPI_FAILURE (status)) {
......@@ -363,6 +363,7 @@ acpi_ex_opcode_1A_1T_1R (
}
status = acpi_ex_store (return_desc2, operand[1], walk_state);
acpi_ut_remove_reference (return_desc2);
/* The object exists in the namespace, return TRUE */
......@@ -733,6 +734,15 @@ acpi_ex_opcode_1A_0T_1R (
operand[0] = temp_desc;
break;
case AML_REF_OF_OP:
/* Get the object to which the reference refers */
temp_desc = operand[0]->reference.object;
acpi_ut_remove_reference (operand[0]);
operand[0] = temp_desc;
break;
default:
/* Must be an Index op - handled below */
......
/******************************************************************************
*
* Module Name: exoparg2 - AML execution - opcodes with 2 arguments
* $Revision: 108 $
* $Revision: 109 $
*
*****************************************************************************/
......@@ -359,7 +359,8 @@ acpi_ex_opcode_2A_1T_1R (
/* Object to be indexed is a Package */
if (index >= operand[0]->package.count) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value beyond package end\n"));
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond package end (%X)\n",
index, operand[0]->package.count));
status = AE_AML_PACKAGE_LIMIT;
goto cleanup;
}
......@@ -401,7 +402,8 @@ acpi_ex_opcode_2A_1T_1R (
/* Object to be indexed is a Buffer */
if (index >= operand[0]->buffer.length) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value beyond end of buffer\n"));
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond end of buffer (%X)\n",
index, operand[0]->buffer.length));
status = AE_AML_BUFFER_LIMIT;
goto cleanup;
}
......@@ -522,7 +524,8 @@ acpi_ex_opcode_2A_0T_1R (
default:
ACPI_REPORT_ERROR (("Acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n", walk_state->opcode));
ACPI_REPORT_ERROR (("Acpi_ex_opcode_2A_0T_1R: Unknown opcode %X\n",
walk_state->opcode));
status = AE_AML_BAD_OPCODE;
goto cleanup;
}
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exresnte - AML Interpreter object resolution
* $Revision: 56 $
* $Revision: 57 $
*
*****************************************************************************/
......@@ -219,7 +219,7 @@ acpi_ex_resolve_node_to_value (
/* No named references are allowed here */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported reference opcode %X\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X\n",
source_desc->reference.opcode));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exresolv - AML Interpreter object resolution
* $Revision: 114 $
* $Revision: 115 $
*
*****************************************************************************/
......@@ -227,9 +227,11 @@ acpi_ex_resolve_object_to_value (
break;
case AML_REF_OF_OP:
case AML_DEBUG_OP:
/* Just leave the object as-is */
break;
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exresop - AML Interpreter operand/object resolution
* $Revision: 53 $
* $Revision: 54 $
*
*****************************************************************************/
......@@ -204,6 +204,7 @@ acpi_ex_resolve_operands (
case AML_DEBUG_OP:
case AML_NAME_OP:
case AML_INDEX_OP:
case AML_REF_OF_OP:
case AML_ARG_OP:
case AML_LOCAL_OP:
......
......@@ -2,7 +2,7 @@
/******************************************************************************
*
* Module Name: exstore - AML Interpreter object store support
* $Revision: 167 $
* $Revision: 168 $
*
*****************************************************************************/
......@@ -130,6 +130,7 @@ acpi_ex_store (
*/
switch (ref_desc->reference.opcode) {
case AML_NAME_OP:
case AML_REF_OF_OP:
/* Storing an object into a Name "container" */
......
/******************************************************************************
*
* Name: acconfig.h - Global configuration constants
* $Revision: 104 $
* $Revision: 105 $
*
*****************************************************************************/
......@@ -54,7 +54,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20020611
#define ACPI_CA_VERSION 0x20020702
/* Version of ACPI supported */
......
/******************************************************************************
*
* Name: acdebug.h - ACPI/AML debugger
* $Revision: 61 $
* $Revision: 62 $
*
*****************************************************************************/
......@@ -212,6 +212,10 @@ void
acpi_db_decode_internal_object (
acpi_operand_object *obj_desc);
void
acpi_db_decode_node (
acpi_namespace_node *node);
u32
acpi_db_block_type (
acpi_parse_object *op);
......
/******************************************************************************
*
* Name: acglobal.h - Declarations for global variables
* $Revision: 125 $
* $Revision: 126 $
*
*****************************************************************************/
......@@ -72,6 +72,7 @@ extern u32 acpi_gbl_nesting_level;
*
*/
ACPI_EXTERN u32 acpi_gbl_table_flags;
ACPI_EXTERN u32 acpi_gbl_rsdt_table_count;
ACPI_EXTERN RSDP_DESCRIPTOR *acpi_gbl_RSDP;
ACPI_EXTERN xsdt_descriptor *acpi_gbl_XSDT;
ACPI_EXTERN FADT_DESCRIPTOR *acpi_gbl_FADT;
......
/******************************************************************************
*
* Name: aclocal.h - Internal data types used across the ACPI subsystem
* $Revision: 167 $
* $Revision: 168 $
*
*****************************************************************************/
......@@ -33,10 +33,6 @@ typedef void* acpi_mutex;
typedef u32 ACPI_MUTEX_HANDLE;
#define ACPI_MEMORY_MODE 0x01
#define ACPI_LOGICAL_ADDRESSING 0x00
#define ACPI_PHYSICAL_ADDRESSING 0x01
/* Total number of aml opcodes defined */
#define AML_NUM_OPCODES 0x7E
......
/******************************************************************************
*
* Module Name: acparser.h - AML Parser subcomponent prototypes and defines
* $Revision: 59 $
* $Revision: 60 $
*
*****************************************************************************/
......@@ -266,6 +266,10 @@ acpi_ps_delete_completed_op (
/* psutils - parser utilities */
acpi_parse_object *
acpi_ps_create_scope_op (
void);
void
acpi_ps_init_op (
acpi_parse_object *op,
......
......@@ -43,6 +43,10 @@ acpi_status
acpi_enable_subsystem (
u32 flags);
acpi_status
acpi_initialize_objects (
u32 flags);
acpi_status
acpi_terminate (
void);
......
/******************************************************************************
*
* Name: actables.h - ACPI table management
* $Revision: 41 $
* $Revision: 42 $
*
*****************************************************************************/
......@@ -43,8 +43,7 @@ acpi_tb_handle_to_object (
acpi_status
acpi_tb_convert_to_xsdt (
acpi_table_desc *table_info,
u32 *number_of_tables);
acpi_table_desc *table_info);
acpi_status
acpi_tb_convert_table_fadt (
......@@ -63,13 +62,31 @@ acpi_tb_get_table_count (
* tbget - Table "get" routines
*/
void
acpi_tb_table_override (
acpi_status
acpi_tb_get_table (
ACPI_POINTER *address,
acpi_table_desc *table_info);
acpi_status
acpi_tb_get_table_with_override (
acpi_tb_get_table_header (
ACPI_POINTER *address,
acpi_table_header *return_header);
acpi_status
acpi_tb_get_table_body (
ACPI_POINTER *address,
acpi_table_header *header,
acpi_table_desc *table_info);
acpi_status
acpi_tb_get_this_table (
ACPI_POINTER *address,
acpi_table_header *header,
acpi_table_desc *table_info);
acpi_status
acpi_tb_table_override (
acpi_table_header *header,
acpi_table_desc *table_info);
acpi_status
......@@ -78,11 +95,6 @@ acpi_tb_get_table_ptr (
u32 instance,
acpi_table_header **table_ptr_loc);
acpi_status
acpi_tb_get_table (
ACPI_POINTER *address,
acpi_table_desc *table_info);
acpi_status
acpi_tb_verify_rsdp (
ACPI_POINTER *address);
......@@ -96,20 +108,19 @@ acpi_tb_validate_rsdt (
acpi_table_header *table_ptr);
acpi_status
acpi_tb_get_table_pointer (
ACPI_POINTER *address,
u32 flags,
ACPI_SIZE *size,
acpi_table_header **table_ptr);
/*
* tbgetall - Get all firmware ACPI tables
*/
acpi_tb_get_required_tables (
void);
acpi_status
acpi_tb_get_all_tables (
u32 number_of_tables);
acpi_tb_get_primary_table (
ACPI_POINTER *address,
acpi_table_desc *table_info);
acpi_status
acpi_tb_get_secondary_table (
ACPI_POINTER *address,
acpi_string signature,
acpi_table_desc *table_info);
/*
* tbinstall - Table installation
......@@ -122,11 +133,13 @@ acpi_tb_install_table (
acpi_status
acpi_tb_match_signature (
NATIVE_CHAR *signature,
acpi_table_desc *table_info);
acpi_table_desc *table_info,
u8 search_type);
acpi_status
acpi_tb_recognize_table (
acpi_table_desc *table_info);
acpi_table_desc *table_info,
u8 search_type);
acpi_status
acpi_tb_init_table_descriptor (
......@@ -165,7 +178,7 @@ acpi_tb_free_acpi_tables_of_type (
acpi_status
acpi_tb_get_table_rsdt (
u32 *number_of_tables);
void);
u8 *
acpi_tb_scan_memory_for_rsdp (
......@@ -189,12 +202,6 @@ acpi_tb_find_table (
NATIVE_CHAR *oem_table_id,
acpi_table_header **table_ptr);
acpi_status
acpi_tb_map_acpi_table (
ACPI_PHYSICAL_ADDRESS physical_address,
ACPI_SIZE *size,
acpi_table_header **logical_address);
acpi_status
acpi_tb_verify_table_checksum (
acpi_table_header *table_header);
......
/******************************************************************************
*
* Name: actbl.h - Table data structures defined in ACPI specification
* $Revision: 52 $
* $Revision: 53 $
*
*****************************************************************************/
......@@ -185,9 +185,15 @@ typedef struct /* Smart Battery Description Table */
/* Definitions for the Flags bitfield member of ACPI_TABLE_SUPPORT */
#define ACPI_TABLE_SINGLE 0
#define ACPI_TABLE_MULTIPLE 1
#define ACPI_TABLE_EXECUTABLE 2
#define ACPI_TABLE_SINGLE 0x00
#define ACPI_TABLE_MULTIPLE 0x01
#define ACPI_TABLE_EXECUTABLE 0x02
#define ACPI_TABLE_ROOT 0x00
#define ACPI_TABLE_PRIMARY 0x10
#define ACPI_TABLE_SECONDARY 0x20
#define ACPI_TABLE_OTHER 0x30
#define ACPI_TABLE_TYPE_MASK 0x30
/* Data about each known table type */
......
/******************************************************************************
*
* Name: actypes.h - Common data types for the entire ACPI subsystem
* $Revision: 237 $
* $Revision: 238 $
*
*****************************************************************************/
......@@ -209,8 +209,18 @@ typedef struct acpi_pointer
/* Pointer_types for above */
#define ACPI_LOGICAL_POINTER 0x01
#define ACPI_PHYSICAL_POINTER 0x02
#define ACPI_PHYSICAL_POINTER 0x01
#define ACPI_LOGICAL_POINTER 0x02
/* Processor mode */
#define ACPI_PHYSICAL_ADDRESSING 0x04
#define ACPI_LOGICAL_ADDRESSING 0x08
#define ACPI_MEMORY_MODE 0x0C
#define ACPI_PHYSMODE_PHYSPTR ACPI_PHYSICAL_ADDRESSING | ACPI_PHYSICAL_POINTER
#define ACPI_LOGMODE_PHYSPTR ACPI_LOGICAL_ADDRESSING | ACPI_PHYSICAL_POINTER
#define ACPI_LOGMODE_LOGPTR ACPI_LOGICAL_ADDRESSING | ACPI_LOGICAL_POINTER
/*
......
/******************************************************************************
*
* Module Name: aslresource.h - ASL resource descriptors
* $Revision: 19 $
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2002, R. Byron Moore
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASLRESOURCE_H
#define __ASLRESOURCE_H
#define ASL_RESNAME_ADDRESS "_ADR"
#define ASL_RESNAME_ALIGNMENT "_ALN"
#define ASL_RESNAME_ADDRESSSPACE "_ASI"
#define ASL_RESNAME_BASEADDRESS "_BAS"
#define ASL_RESNAME_BUSMASTER "_BM_" /* Master(1), Slave(0) */
#define ASL_RESNAME_DECODE "_DEC"
#define ASL_RESNAME_DMA "_DMA"
#define ASL_RESNAME_DMATYPE "_TYP" /* Compatible(0), A(1), B(2), F(3) */
#define ASL_RESNAME_GRANULARITY "_GRA"
#define ASL_RESNAME_INTERRUPT "_INT"
#define ASL_RESNAME_INTERRUPTLEVEL "_LL_" /* Active_lo(1), Active_hi(0) */
#define ASL_RESNAME_INTERRUPTSHARE "_SHR" /* Shareable(1), No_share(0) */
#define ASL_RESNAME_INTERRUPTTYPE "_HE_" /* Edge(1), Level(0) */
#define ASL_RESNAME_LENGTH "_LEN"
#define ASL_RESNAME_MEMATTRIBUTES "_MTP" /* Memory(0), Reserved(1), ACPI(2), NVS(3) */
#define ASL_RESNAME_MEMTYPE "_MEM" /* Non_cache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */
#define ASL_RESNAME_MAXADDR "_MAX"
#define ASL_RESNAME_MINADDR "_MIN"
#define ASL_RESNAME_MAXTYPE "_MAF"
#define ASL_RESNAME_MINTYPE "_MIF"
#define ASL_RESNAME_REGISTERBITOFFSET "_RBO"
#define ASL_RESNAME_REGISTERBITWIDTH "_RBW"
#define ASL_RESNAME_RANGETYPE "_RNG"
#define ASL_RESNAME_READWRITETYPE "_RW_" /* Read_only(0), Writeable (1) */
#define ASL_RESNAME_TRANSLATION "_TRA"
#define ASL_RESNAME_TRANSTYPE "_TRS" /* Sparse(1), Dense(0) */
#define ASL_RESNAME_TYPE "_TTP" /* Translation(1), Static (0) */
#define ASL_RESNAME_XFERTYPE "_SIZ" /* 8(0), 8_and16(1), 16(2) */
/* Default sizes for "small" resource descriptors */
#define ASL_RDESC_IRQ_SIZE 0x02
#define ASL_RDESC_DMA_SIZE 0x02
#define ASL_RDESC_ST_DEPEND_SIZE 0x00
#define ASL_RDESC_END_DEPEND_SIZE 0x00
#define ASL_RDESC_IO_SIZE 0x07
#define ASL_RDESC_FIXED_IO_SIZE 0x03
#define ASL_RDESC_END_TAG_SIZE 0x01
typedef struct asl_resource_node
{
u32 buffer_length;
void *buffer;
struct asl_resource_node *next;
} ASL_RESOURCE_NODE;
/*
* Resource descriptors defined in the ACPI specification
*/
#pragma pack(1)
typedef struct asl_irq_format_desc
{
u8 descriptor_type;
u16 irq_mask;
u8 flags;
} ASL_IRQ_FORMAT_DESC;
#pragma pack(1)
typedef struct asl_irq_noflags_desc
{
u8 descriptor_type;
u16 irq_mask;
} ASL_IRQ_NOFLAGS_DESC;
#pragma pack(1)
typedef struct asl_dma_format_desc
{
u8 descriptor_type;
u8 dma_channel_mask;
u8 flags;
} ASL_DMA_FORMAT_DESC;
#pragma pack(1)
typedef struct asl_start_dependent_desc
{
u8 descriptor_type;
u8 flags;
} ASL_START_DEPENDENT_DESC;
#pragma pack(1)
typedef struct asl_start_dependent_noprio_desc
{
u8 descriptor_type;
} ASL_START_DEPENDENT_NOPRIO_DESC;
#pragma pack(1)
typedef struct asl_end_dependent_desc
{
u8 descriptor_type;
} ASL_END_DEPENDENT_DESC;
#pragma pack(1)
typedef struct asl_io_port_desc
{
u8 descriptor_type;
u8 information;
u16 address_min;
u16 address_max;
u8 alignment;
u8 length;
} ASL_IO_PORT_DESC;
#pragma pack(1)
typedef struct asl_fixed_io_port_desc
{
u8 descriptor_type;
u16 base_address;
u8 length;
} ASL_FIXED_IO_PORT_DESC;
#pragma pack(1)
typedef struct asl_small_vendor_desc
{
u8 descriptor_type;
u8 vendor_defined[7];
} ASL_SMALL_VENDOR_DESC;
#pragma pack(1)
typedef struct asl_end_tag_desc
{
u8 descriptor_type;
u8 checksum;
} ASL_END_TAG_DESC;
/* LARGE descriptors */
#pragma pack(1)
typedef struct asl_memory_24_desc
{
u8 descriptor_type;
u16 length;
u8 information;
u16 address_min;
u16 address_max;
u16 alignment;
u16 range_length;
} ASL_MEMORY_24_DESC;
#pragma pack(1)
typedef struct asl_large_vendor_desc
{
u8 descriptor_type;
u16 length;
u8 vendor_defined[1];
} ASL_LARGE_VENDOR_DESC;
#pragma pack(1)
typedef struct asl_memory_32_desc
{
u8 descriptor_type;
u16 length;
u8 information;
u32 address_min;
u32 address_max;
u32 alignment;
u32 range_length;
} ASL_MEMORY_32_DESC;
#pragma pack(1)
typedef struct asl_fixed_memory_32_desc
{
u8 descriptor_type;
u16 length;
u8 information;
u32 base_address;
u32 range_length;
} ASL_FIXED_MEMORY_32_DESC;
#pragma pack(1)
typedef struct asl_qword_address_desc
{
u8 descriptor_type;
u16 length;
u8 resource_type;
u8 flags;
u8 specific_flags;
u64 granularity;
u64 address_min;
u64 address_max;
u64 translation_offset;
u64 address_length;
u8 optional_fields[2];
} ASL_QWORD_ADDRESS_DESC;
#pragma pack(1)
typedef struct asl_dword_address_desc
{
u8 descriptor_type;
u16 length;
u8 resource_type;
u8 flags;
u8 specific_flags;
u32 granularity;
u32 address_min;
u32 address_max;
u32 translation_offset;
u32 address_length;
u8 optional_fields[2];
} ASL_DWORD_ADDRESS_DESC;
#pragma pack(1)
typedef struct asl_word_address_desc
{
u8 descriptor_type;
u16 length;
u8 resource_type;
u8 flags;
u8 specific_flags;
u16 granularity;
u16 address_min;
u16 address_max;
u16 translation_offset;
u16 address_length;
u8 optional_fields[2];
} ASL_WORD_ADDRESS_DESC;
#pragma pack(1)
typedef struct asl_extended_xrupt_desc
{
u8 descriptor_type;
u16 length;
u8 flags;
u8 table_length;
u32 interrupt_number[1];
/* Res_source_index, Res_source optional fields follow */
} ASL_EXTENDED_XRUPT_DESC;
#pragma pack(1)
typedef struct asl_general_register_desc
{
u8 descriptor_type;
u16 length;
u8 address_space_id;
u8 bit_width;
u8 bit_offset;
u8 reserved;
u64 address;
} ASL_GENERAL_REGISTER_DESC;
/* Union of all resource descriptors, sow we can allocate the worst case */
typedef union asl_resource_desc
{
ASL_IRQ_FORMAT_DESC irq;
ASL_DMA_FORMAT_DESC dma;
ASL_START_DEPENDENT_DESC std;
ASL_END_DEPENDENT_DESC end;
ASL_IO_PORT_DESC iop;
ASL_FIXED_IO_PORT_DESC fio;
ASL_SMALL_VENDOR_DESC smv;
ASL_END_TAG_DESC et;
ASL_MEMORY_24_DESC M24;
ASL_LARGE_VENDOR_DESC lgv;
ASL_MEMORY_32_DESC M32;
ASL_FIXED_MEMORY_32_DESC F32;
ASL_QWORD_ADDRESS_DESC qas;
ASL_DWORD_ADDRESS_DESC das;
ASL_WORD_ADDRESS_DESC was;
ASL_EXTENDED_XRUPT_DESC exx;
ASL_GENERAL_REGISTER_DESC grg;
u32 U32_item;
u16 U16_item;
u8 U8item;
} ASL_RESOURCE_DESC;
#define NEXT_RESOURCE_DESC(a,b) (ASL_RESOURCE_DESC *) (((char *) (a)) + sizeof(b))
#define DEFAULT_RESOURCE_DESC_SIZE (sizeof (ASL_RESOURCE_DESC) + sizeof (ASL_END_TAG_DESC))
/*
* Resource utilities
*/
ASL_RESOURCE_NODE *
rs_allocate_resource_node (
u32 size);
void
rs_create_bit_field (
acpi_parse_object *op,
char *name,
u32 byte_offset,
u32 bit_offset);
void
rs_create_byte_field (
acpi_parse_object *op,
char *name,
u32 byte_offset);
void
rs_set_flag_bits (
u8 *flags,
acpi_parse_object *op,
u8 position,
u8 default);
acpi_parse_object *
rs_complete_node_and_get_next (
acpi_parse_object *op);
ASL_RESOURCE_NODE *
rs_do_one_resource_descriptor (
acpi_parse_object *descriptor_type_op,
u32 current_byte_offset);
u32
rs_link_descriptor_chain (
ASL_RESOURCE_NODE **previous_rnode,
ASL_RESOURCE_NODE *rnode);
/*
* Small descriptors
*/
ASL_RESOURCE_NODE *
rs_do_dma_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_end_dependent_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_fixed_io_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_interrupt_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_io_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_irq_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_irq_no_flags_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_memory24_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_memory32_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_memory32_fixed_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_start_dependent_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_start_dependent_no_pri_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_vendor_small_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
/*
* Large descriptors
*/
u32
rs_get_string_data_length (
acpi_parse_object *initializer_op);
ASL_RESOURCE_NODE *
rs_do_dword_io_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_dword_memory_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_qword_io_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_qword_memory_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_word_io_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_word_bus_number_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_vendor_large_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
ASL_RESOURCE_NODE *
rs_do_general_register_descriptor (
acpi_parse_object *op,
u32 current_byte_offset);
#endif
/******************************************************************************
*
* Name: aclinux.h - OS specific defines, etc.
* $Revision: 25 $
* $Revision: 26 $
*
*****************************************************************************/
......
......@@ -2,7 +2,7 @@
*
* Module Name: nseval - Object evaluation interfaces -- includes control
* method lookup and execution.
* $Revision: 116 $
* $Revision: 117 $
*
******************************************************************************/
......@@ -485,7 +485,8 @@ acpi_ns_get_object_value (
if (ACPI_SUCCESS (status)) {
status = AE_CTRL_RETURN_VALUE;
*return_obj_desc = ACPI_CAST_PTR (acpi_operand_object, resolved_node);
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning obj %p\n", resolved_node));
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
*return_obj_desc, acpi_ut_get_object_type_name (*return_obj_desc)));
}
}
......
/******************************************************************************
*
* Module Name: nsload - namespace loading/expanding/contracting procedures
* $Revision: 55 $
* $Revision: 56 $
*
*****************************************************************************/
......@@ -115,12 +115,11 @@ acpi_ns_one_complete_parse (
/* Create and init a Root Node */
parse_root = acpi_ps_alloc_op (AML_SCOPE_OP);
parse_root = acpi_ps_create_scope_op ();
if (!parse_root) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
parse_root->named.name = ACPI_ROOT_NAME;
/* Create and initialize a new walk state */
......
/*******************************************************************************
*
* Module Name: nsnames - Name manipulation and search
* $Revision: 77 $
* $Revision: 78 $
*
******************************************************************************/
......@@ -179,7 +179,7 @@ acpi_ns_get_pathname_length (
size = 0;
next_node = node;
while (next_node != acpi_gbl_root_node) {
while (next_node && (next_node != acpi_gbl_root_node)) {
size += PATH_SEGMENT_LENGTH;
next_node = acpi_ns_get_parent_node (next_node);
}
......
/******************************************************************************
*
* Module Name: psparse - Parser top level AML parse routines
* $Revision: 127 $
* $Revision: 128 $
*
*****************************************************************************/
......@@ -581,6 +581,10 @@ acpi_ps_parse_loop (
pre_op.common.value.arg = NULL;
pre_op.common.aml_opcode = walk_state->opcode;
/*
* Get and append arguments until we find the node that contains
* the name (the type ARGP_NAME).
*/
while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME) {
arg = acpi_ps_get_next_arg (parser_state,
GET_CURRENT_ARG_TYPE (walk_state->arg_types),
......
/******************************************************************************
*
* Module Name: psutils - Parser miscellaneous utilities (Parser only)
* $Revision: 51 $
* $Revision: 52 $
*
*****************************************************************************/
......@@ -27,11 +27,42 @@
#include "acpi.h"
#include "acparser.h"
#include "amlcode.h"
#include "acnamesp.h"
#define _COMPONENT ACPI_PARSER
ACPI_MODULE_NAME ("psutils")
/*******************************************************************************
*
* FUNCTION: Acpi_ps_create_scope_op
*
* PARAMETERS: None
*
* RETURN: Scope_op
*
* DESCRIPTION: Create a Scope and associated namepath op with the root name
*
******************************************************************************/
acpi_parse_object *
acpi_ps_create_scope_op (
void)
{
acpi_parse_object *scope_op;
scope_op = acpi_ps_alloc_op (AML_SCOPE_OP);
if (!scope_op) {
return (NULL);
}
scope_op->named.name = ACPI_ROOT_NAME;
return (scope_op);
}
/*******************************************************************************
*
* FUNCTION: Acpi_ps_init_op
......
/******************************************************************************
*
* Module Name: psxface - Parser external interfaces
* $Revision: 64 $
* $Revision: 65 $
*
*****************************************************************************/
......@@ -108,7 +108,7 @@ acpi_psx_execute (
/* Create and init a Root Node */
op = acpi_ps_alloc_op (AML_SCOPE_OP);
op = acpi_ps_create_scope_op ();
if (!op) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
......@@ -149,7 +149,7 @@ acpi_psx_execute (
/* Create and init a Root Node */
op = acpi_ps_alloc_op (AML_SCOPE_OP);
op = acpi_ps_create_scope_op ();
if (!op) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
......
/*******************************************************************************
*
* Module Name: rscreate - Create resource lists/tables
* $Revision: 57 $
* $Revision: 58 $
*
******************************************************************************/
......@@ -39,7 +39,6 @@
*
* PARAMETERS: Byte_stream_buffer - Pointer to the resource byte stream
* Output_buffer - Pointer to the user's buffer
* Output_buffer_length - Pointer to the size of Output_buffer
*
* RETURN: Status - AE_OK if okay, else a valid acpi_status code
* If Output_buffer is not large enough, Output_buffer_length
......@@ -116,7 +115,6 @@ acpi_rs_create_resource_list (
* PARAMETERS: Package_object - Pointer to an acpi_operand_object
* package
* Output_buffer - Pointer to the user's buffer
* Output_buffer_length - Size of Output_buffer
*
* RETURN: Status AE_OK if okay, else a valid acpi_status code.
* If the Output_buffer is too small, the error will be
......
/*******************************************************************************
*
* Module Name: rsio - IO and DMA resource descriptors
* $Revision: 20 $
* $Revision: 21 $
*
******************************************************************************/
......@@ -410,6 +410,7 @@ acpi_rs_dma_resource (
if (i == 0) {
/* Zero channels is invalid! */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found Zero DMA channels in resource list\n"));
return_ACPI_STATUS (AE_BAD_DATA);
}
output_struct->data.dma.number_of_channels = i;
......@@ -432,6 +433,7 @@ acpi_rs_dma_resource (
output_struct->data.dma.transfer = temp8 & 0x03;
if (0x03 == output_struct->data.dma.transfer) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid DMA.Transfer preference (3)\n"));
return_ACPI_STATUS (AE_BAD_DATA);
}
......
/*******************************************************************************
*
* Module Name: rsirq - IRQ resource descriptors
* $Revision: 28 $
* $Revision: 29 $
*
******************************************************************************/
......@@ -99,6 +99,7 @@ acpi_rs_irq_resource (
if (i == 0) {
/* Zero interrupts is invalid! */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found Zero interrupt levels in resource list\n"));
return_ACPI_STATUS (AE_BAD_DATA);
}
output_struct->data.irq.number_of_interrupts = i;
......@@ -133,6 +134,7 @@ acpi_rs_irq_resource (
* are allowed (ACPI spec v1.0b ection 6.4.2.1),
* so an error will occur if we reach this point
*/
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid interrupt polarity/trigger in resource list\n"));
return_ACPI_STATUS (AE_BAD_DATA);
}
}
......
/*******************************************************************************
*
* Module Name: rslist - Linked list utilities
* $Revision: 30 $
* $Revision: 31 $
*
******************************************************************************/
......@@ -471,6 +471,8 @@ acpi_rs_list_to_byte_stream (
* If we get here, everything is out of sync,
* so exit with an error
*/
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid descriptor type (%X) in resource list\n",
linked_list->id));
status = AE_BAD_DATA;
break;
......
/******************************************************************************
*
* Module Name: tbconvrt - ACPI Table conversion utilities
* $Revision: 41 $
* $Revision: 42 $
*
*****************************************************************************/
......@@ -90,8 +90,7 @@ acpi_tb_get_table_count (
acpi_status
acpi_tb_convert_to_xsdt (
acpi_table_desc *table_info,
u32 *number_of_tables)
acpi_table_desc *table_info)
{
ACPI_SIZE table_size;
u32 i;
......@@ -101,13 +100,10 @@ acpi_tb_convert_to_xsdt (
ACPI_FUNCTION_ENTRY ();
/* Get the number of tables defined in the RSDT or XSDT */
*number_of_tables = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info->pointer);
/* Compute size of the converted XSDT */
table_size = ((ACPI_SIZE) *number_of_tables * sizeof (u64)) + sizeof (acpi_table_header);
table_size = ((ACPI_SIZE) acpi_gbl_rsdt_table_count * sizeof (u64)) +
sizeof (acpi_table_header);
/* Allocate an XSDT */
......@@ -123,7 +119,7 @@ acpi_tb_convert_to_xsdt (
/* Copy the table pointers */
for (i = 0; i < *number_of_tables; i++) {
for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
if (acpi_gbl_RSDP->revision < 2) {
ACPI_STORE_ADDRESS (new_table->table_offset_entry[i],
((RSDT_DESCRIPTOR_REV1 *) table_info->pointer)->table_offset_entry[i]);
......
/******************************************************************************
*
* Module Name: tbget - ACPI Table get* routines
* $Revision: 77 $
* $Revision: 78 $
*
*****************************************************************************/
......@@ -34,777 +34,438 @@
/*******************************************************************************
*
* FUNCTION: Acpi_tb_table_override
* FUNCTION: Acpi_tb_get_table
*
* PARAMETERS: *Table_info - Info for current table
* PARAMETERS: Address - Address of table to retrieve. Can be
* Logical or Physical
* Table_info - Where table info is returned
*
* RETURN: None
*
* DESCRIPTION: Attempts override of current table with a new one if provided
* by the host OS.
* DESCRIPTION: Get entire table of unknown size.
*
******************************************************************************/
void
acpi_tb_table_override (
acpi_status
acpi_tb_get_table (
ACPI_POINTER *address,
acpi_table_desc *table_info)
{
acpi_table_header *new_table;
acpi_status status;
ACPI_POINTER address;
acpi_table_desc new_table_info;
ACPI_FUNCTION_TRACE ("Acpi_tb_table_override");
status = acpi_os_table_override (table_info->pointer, &new_table);
if (ACPI_FAILURE (status)) {
/* Some severe error from the OSL, but we basically ignore it */
acpi_table_header header;
ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
acpi_format_exception (status)));
return_VOID;
}
if (!new_table) {
/* No table override */
ACPI_FUNCTION_TRACE ("Tb_get_table");
return_VOID;
}
/*
* We have a new table to override the old one. Get a copy of
* the new one. We know that the new table has a logical pointer.
* Get the header in order to get signature and table size
*/
address.pointer_type = ACPI_LOGICAL_POINTER;
address.pointer.logical = new_table;
status = acpi_tb_get_table (&address, &new_table_info);
status = acpi_tb_get_table_header (address, &header);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not copy ACPI table override\n"));
return_VOID;
return_ACPI_STATUS (status);
}
/*
* Delete the original table
*/
acpi_tb_delete_single_table (table_info);
/* Copy the table info */
/* Get the entire table */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Successful table override [%4.4s]\n",
((acpi_table_header *) new_table_info.pointer)->signature));
status = acpi_tb_get_table_body (address, &header, table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get ACPI table (size %X), %s\n",
header.length, acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
ACPI_MEMCPY (table_info, &new_table_info, sizeof (acpi_table_desc));
return_VOID;
return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table_with_override
* FUNCTION: Acpi_tb_get_table_header
*
* PARAMETERS: Address - Physical or logical address of table
* *Table_info - Where the table info is returned
* PARAMETERS: Address - Address of table to retrieve. Can be
* Logical or Physical
* Return_header - Where the table header is returned
*
* RETURN: Status
*
* DESCRIPTION: Gets and installs the table with possible table override by OS.
* DESCRIPTION: Get an ACPI table header. Works in both physical or virtual
* addressing mode. Works with both physical or logical pointers.
* Table is either copied or mapped, depending on the pointer
* type and mode of the processor.
*
******************************************************************************/
acpi_status
acpi_tb_get_table_with_override (
acpi_tb_get_table_header (
ACPI_POINTER *address,
acpi_table_desc *table_info)
acpi_table_header *return_header)
{
acpi_status status;
acpi_status status = AE_OK;
acpi_table_header *header = NULL;
ACPI_FUNCTION_TRACE ("Acpi_tb_get_table_with_override");
ACPI_FUNCTION_TRACE ("Tb_get_table_header");
status = acpi_tb_get_table (address, table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get ACPI table, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/*
* Attempt override. It either happens or it doesn't, no status
* Flags contains the current processor mode (Virtual or Physical addressing)
* The Pointer_type is either Logical or Physical
*/
acpi_tb_table_override (table_info);
switch (address->pointer_type) {
case ACPI_PHYSMODE_PHYSPTR:
case ACPI_LOGMODE_LOGPTR:
/* Install the table */
/* Pointer matches processor mode, copy the header */
status = acpi_tb_install_table (table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not install ACPI table, %s\n",
acpi_format_exception (status)));
}
ACPI_MEMCPY (return_header, address->pointer.logical, sizeof (acpi_table_header));
break;
return_ACPI_STATUS (status);
}
case ACPI_LOGMODE_PHYSPTR:
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table_ptr
*
* PARAMETERS: Table_type - one of the defined table types
* Instance - Which table of this type
* Table_ptr_loc - pointer to location to place the pointer for
* return
*
* RETURN: Status
*
* DESCRIPTION: This function is called to get the pointer to an ACPI table.
*
******************************************************************************/
/* Create a logical address for the physical pointer*/
acpi_status
acpi_tb_get_table_ptr (
acpi_table_type table_type,
u32 instance,
acpi_table_header **table_ptr_loc)
{
acpi_table_desc *table_desc;
u32 i;
status = acpi_os_map_memory (address->pointer.physical, sizeof (acpi_table_header),
(void **) &header);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not map memory at %p for length %X\n",
address->pointer.physical, sizeof (acpi_table_header)));
return_ACPI_STATUS (status);
}
/* Copy header and delete mapping */
ACPI_FUNCTION_TRACE ("Tb_get_table_ptr");
ACPI_MEMCPY (return_header, header, sizeof (acpi_table_header));
acpi_os_unmap_memory (header, sizeof (acpi_table_header));
break;
if (!acpi_gbl_DSDT) {
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
default:
if (table_type > ACPI_TABLE_MAX) {
ACPI_REPORT_ERROR (("Invalid address flags %X\n",
address->pointer_type));
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* For all table types (Single/Multiple), the first
* instance is always in the list head.
*/
if (instance == 1) {
/*
* Just pluck the pointer out of the global table!
* Will be null if no table is present
*/
*table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer;
return_ACPI_STATUS (AE_OK);
}
/*
* Check for instance out of range
*/
if (instance > acpi_gbl_acpi_tables[table_type].count) {
return_ACPI_STATUS (AE_NOT_EXIST);
}
/* Walk the list to get the desired table
* Since the if (Instance == 1) check above checked for the
* first table, setting Table_desc equal to the .Next member
* is actually pointing to the second table. Therefore, we
* need to walk from the 2nd table until we reach the Instance
* that the user is looking for and return its table pointer.
*/
table_desc = acpi_gbl_acpi_tables[table_type].next;
for (i = 2; i < instance; i++) {
table_desc = table_desc->next;
}
/* We are now pointing to the requested table's descriptor */
*table_ptr_loc = table_desc->pointer;
return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table
* FUNCTION: Acpi_tb_get_table_body
*
* PARAMETERS: Address - Physical address of table to retrieve
* *Table_info - Where the table info is returned
* PARAMETERS: Address - Address of table to retrieve. Can be
* Logical or Physical
* Header - Header of the table to retrieve
* Table_info - Where the table info is returned
*
* RETURN: Status
*
* DESCRIPTION: Maps the physical address of table into a logical address
* DESCRIPTION: Get an entire ACPI table with support to allow the host OS to
* replace the table with a newer version (table override.)
* Works in both physical or virtual
* addressing mode. Works with both physical or logical pointers.
* Table is either copied or mapped, depending on the pointer
* type and mode of the processor.
*
******************************************************************************/
acpi_status
acpi_tb_get_table (
acpi_tb_get_table_body (
ACPI_POINTER *address,
acpi_table_header *header,
acpi_table_desc *table_info)
{
acpi_table_header *table_header = NULL;
acpi_table_header *full_table = NULL;
ACPI_SIZE size;
u8 allocation;
acpi_status status = AE_OK;
acpi_status status;
ACPI_FUNCTION_TRACE ("Tb_get_table");
ACPI_FUNCTION_TRACE ("Tb_get_table_body");
if (!table_info || !address) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
switch (address->pointer_type) {
case ACPI_LOGICAL_POINTER:
/*
* Getting data from a buffer, not BIOS tables
*/
table_header = address->pointer.logical;
/* Allocate buffer for the entire table */
full_table = ACPI_MEM_ALLOCATE (table_header->length);
if (!full_table) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Copy the entire table (including header) to the local buffer */
size = (ACPI_SIZE) table_header->length;
ACPI_MEMCPY (full_table, table_header, size);
/* Save allocation type */
allocation = ACPI_MEM_ALLOCATED;
break;
case ACPI_PHYSICAL_POINTER:
/*
* Not reading from a buffer, just map the table's physical memory
* into our address space.
* Attempt table override.
*/
size = SIZE_IN_HEADER;
status = acpi_tb_table_override (header, table_info);
if (ACPI_SUCCESS (status)) {
/* Table was overridden by the host OS */
status = acpi_tb_map_acpi_table (address->pointer.physical, &size, &full_table);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Save allocation type */
allocation = ACPI_MEM_MAPPED;
break;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Return values */
table_info->pointer = full_table;
table_info->length = size;
table_info->allocation = allocation;
table_info->base_pointer = full_table;
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
full_table->signature,
ACPI_HIDWORD (address->pointer.physical),
ACPI_LODWORD (address->pointer.physical), full_table));
/* No override, get the original table */
status = acpi_tb_get_this_table (address, header, table_info);
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_all_tables
*
* PARAMETERS: Number_of_tables - Number of tables to get
*
* RETURN: Status
* FUNCTION: Acpi_tb_table_override
*
* DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must
* already be loaded and validated.
* PARAMETERS: Header - Pointer to table header
* Table_info - Return info if table is overridden
*
* Get the minimum set of ACPI tables, namely:
* RETURN: None
*
* 1) FADT (via RSDT in loop below)
* 2) FACS (via FADT)
* 3) DSDT (via FADT)
* DESCRIPTION: Attempts override of current table with a new one if provided
* by the host OS.
*
******************************************************************************/
acpi_status
acpi_tb_get_all_tables (
u32 number_of_tables)
acpi_tb_table_override (
acpi_table_header *header,
acpi_table_desc *table_info)
{
acpi_status status = AE_OK;
u32 index;
acpi_table_desc table_info;
acpi_table_header *new_table;
acpi_status status;
ACPI_POINTER address;
ACPI_FUNCTION_TRACE ("Tb_get_all_tables");
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Number of tables: %d\n", number_of_tables));
/*
* Loop through all table pointers found in RSDT.
* This will NOT include the FACS and DSDT - we must get
* them after the loop.
*
* The ONLY table we are interested in getting here is the FADT.
*/
for (index = 0; index < number_of_tables; index++) {
/* Clear the Table_info each time */
ACPI_MEMSET (&table_info, 0, sizeof (acpi_table_desc));
/* Get the table via the XSDT */
address.pointer_type = acpi_gbl_table_flags;
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_XSDT->table_offset_entry[index]);
ACPI_FUNCTION_TRACE ("Tb_table_override");
status = acpi_tb_get_table (&address, &table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Recognize and install the table */
status = acpi_tb_install_table (&table_info);
if (ACPI_FAILURE (status)) {
/*
* Unrecognized or unsupported table, delete it and ignore the
* error. Just get as many tables as we can, later we will
* determine if there are enough tables to continue.
*/
(void) acpi_tb_uninstall_table (&table_info);
status = AE_OK;
}
}
if (!acpi_gbl_FADT) {
ACPI_REPORT_ERROR (("No FADT present in R/XSDT\n"));
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
/*
* Convert the FADT to a common format. This allows earlier revisions of the
* table to coexist with newer versions, using common access code.
* The OSL will examine the header and decide whether to override this
* table. If it decides to override, a table will be returned in New_table,
* which we will then copy.
*/
status = acpi_tb_convert_table_fadt ();
status = acpi_os_table_override (header, &new_table);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
return_ACPI_STATUS (status);
}
/*
* Get the FACS (must have the FADT first, from loop above)
* Acpi_tb_get_table_facs will fail if FADT pointer is not valid
*/
address.pointer_type = acpi_gbl_table_flags;
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_FADT->Xfirmware_ctrl);
/* Some severe error from the OSL, but we basically ignore it */
status = acpi_tb_get_table (&address, &table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get the FACS, %s\n",
ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/* Install the FACS */
status = acpi_tb_install_table (&table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not install the FACS, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
if (!new_table) {
/* No table override */
/*
* Create the common FACS pointer table
* (Contains pointers to the original table)
*/
status = acpi_tb_build_common_facs (&table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
/*
* Get/install the DSDT (We know that the FADT is valid now)
* We have a new table to override the old one. Get a copy of
* the new one. We know that the new table has a logical pointer.
*/
address.pointer_type = acpi_gbl_table_flags;
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_FADT->Xdsdt);
address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
address.pointer.logical = new_table;
status = acpi_tb_get_table_with_override (&address, &table_info);
status = acpi_tb_get_this_table (&address, new_table, table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get the DSDT\n"));
ACPI_REPORT_ERROR (("Could not copy override ACPI table, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/* Set Integer Width (32/64) based upon DSDT revision */
acpi_ut_set_integer_width (acpi_gbl_DSDT->revision);
/* Dump the entire DSDT */
ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
"Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, acpi_gbl_integer_bit_width));
ACPI_DUMP_BUFFER ((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length);
/* Copy the table info */
/* Always delete the RSDP mapping, we are done with it */
ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
table_info->pointer->signature));
acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP);
return_ACPI_STATUS (status);
return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_verify_rsdp
* FUNCTION: Acpi_tb_get_this_table
*
* PARAMETERS: Number_of_tables - Where the table count is placed
* PARAMETERS: Address - Address of table to retrieve. Can be
* Logical or Physical
* Header - Header of the table to retrieve
* Table_info - Where the table info is returned
*
* RETURN: Status
*
* DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
* DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual
* addressing mode. Works with both physical or logical pointers.
* Table is either copied or mapped, depending on the pointer
* type and mode of the processor.
*
******************************************************************************/
acpi_status
acpi_tb_verify_rsdp (
ACPI_POINTER *address)
acpi_tb_get_this_table (
ACPI_POINTER *address,
acpi_table_header *header,
acpi_table_desc *table_info)
{
acpi_table_desc table_info;
acpi_status status;
RSDP_DESCRIPTOR *rsdp;
acpi_table_header *full_table = NULL;
u8 allocation;
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE ("Tb_verify_rsdp");
ACPI_FUNCTION_TRACE ("Tb_get_this_table");
switch (address->pointer_type) {
case ACPI_LOGICAL_POINTER:
rsdp = address->pointer.logical;
break;
case ACPI_PHYSICAL_POINTER:
/*
* Obtain access to the RSDP structure
* Flags contains the current processor mode (Virtual or Physical addressing)
* The Pointer_type is either Logical or Physical
*/
status = acpi_os_map_memory (address->pointer.physical, sizeof (RSDP_DESCRIPTOR),
(void **) &rsdp);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
break;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* The signature and checksum must both be correct
*/
if (ACPI_STRNCMP ((NATIVE_CHAR *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
/* Nope, BAD Signature */
status = AE_BAD_SIGNATURE;
goto cleanup;
}
/* Check the standard checksum */
if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
status = AE_BAD_CHECKSUM;
goto cleanup;
}
/* Check extended checksum if table version >= 2 */
if (rsdp->revision >= 2) {
if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) {
status = AE_BAD_CHECKSUM;
goto cleanup;
}
}
/* The RSDP supplied is OK */
table_info.pointer = ACPI_CAST_PTR (acpi_table_header, rsdp);
table_info.length = sizeof (RSDP_DESCRIPTOR);
table_info.allocation = ACPI_MEM_MAPPED;
table_info.base_pointer = rsdp;
/* Save the table pointers and allocation info */
status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/* Save the RSDP in a global for easy access */
acpi_gbl_RSDP = ACPI_CAST_PTR (RSDP_DESCRIPTOR, table_info.pointer);
return_ACPI_STATUS (status);
/* Error exit */
cleanup:
if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) {
acpi_os_unmap_memory (rsdp, sizeof (RSDP_DESCRIPTOR));
}
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_rsdt_address
*
* PARAMETERS: None
*
* RETURN: RSDT physical address
*
* DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
* version of the RSDP
*
******************************************************************************/
void
acpi_tb_get_rsdt_address (
ACPI_POINTER *out_address)
{
ACPI_FUNCTION_ENTRY ();
switch (address->pointer_type) {
case ACPI_PHYSMODE_PHYSPTR:
case ACPI_LOGMODE_LOGPTR:
out_address->pointer_type = acpi_gbl_table_flags;
/* Pointer matches processor mode, copy the table to a new buffer */
/*
* For RSDP revision 0 or 1, we use the RSDT.
* For RSDP revision 2 (and above), we use the XSDT
*/
if (acpi_gbl_RSDP->revision < 2) {
out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address;
}
else {
out_address->pointer.value = ACPI_GET_ADDRESS (acpi_gbl_RSDP->xsdt_physical_address);
full_table = ACPI_MEM_ALLOCATE (header->length);
if (!full_table) {
ACPI_REPORT_ERROR (("Could not allocate table memory for [%4.4s] length %X\n",
header->signature, header->length));
return_ACPI_STATUS (AE_NO_MEMORY);
}
}
/* Copy the entire table (including header) to the local buffer */
/*******************************************************************************
*
* FUNCTION: Acpi_tb_validate_rsdt
*
* PARAMETERS: Table_ptr - Addressable pointer to the RSDT.
*
* RETURN: Status
*
* DESCRIPTION: Validate signature for the RSDT or XSDT
*
******************************************************************************/
ACPI_MEMCPY (full_table, address->pointer.logical, header->length);
acpi_status
acpi_tb_validate_rsdt (
acpi_table_header *table_ptr)
{
int no_match;
/* Save allocation type */
allocation = ACPI_MEM_ALLOCATED;
break;
ACPI_FUNCTION_NAME ("Tb_validate_rsdt");
case ACPI_LOGMODE_PHYSPTR:
/*
* For RSDP revision 0 or 1, we use the RSDT.
* For RSDP revision 2 and above, we use the XSDT
* Just map the table's physical memory
* into our address space.
*/
if (acpi_gbl_RSDP->revision < 2) {
no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG,
sizeof (RSDT_SIG) -1);
}
else {
no_match = ACPI_STRNCMP ((char *) table_ptr, XSDT_SIG,
sizeof (XSDT_SIG) -1);
status = acpi_os_map_memory (address->pointer.physical, (ACPI_SIZE) header->length,
(void **) &full_table);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %p for length %X\n",
header->signature, address->pointer.physical, header->length));
return (status);
}
if (no_match) {
/* Invalid RSDT or XSDT signature */
/* Save allocation type */
ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
allocation = ACPI_MEM_MAPPED;
break;
ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR,
"RSDT/XSDT signature at %X (%p) is invalid\n",
acpi_gbl_RSDP->rsdt_physical_address,
(void *) (NATIVE_UINT) acpi_gbl_RSDP->rsdt_physical_address));
default:
return (AE_BAD_SIGNATURE);
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid address flags %X\n",
address->pointer_type));
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table_pointer
*
* PARAMETERS: Physical_address - Address from RSDT
* Flags - virtual or physical addressing
* Table_ptr - Addressable address (output)
*
* RETURN: Status
*
* DESCRIPTION: Create an addressable pointer to an ACPI table
*
******************************************************************************/
acpi_status
acpi_tb_get_table_pointer (
ACPI_POINTER *address,
u32 flags,
ACPI_SIZE *size,
acpi_table_header **table_ptr)
{
acpi_status status = AE_OK;
ACPI_FUNCTION_ENTRY ();
/*
* What mode is the processor in? (Virtual or Physical addressing)
* Validate checksum for _most_ tables,
* even the ones whose signature we don't recognize
*/
if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
/* Incoming pointer can be either logical or physical */
switch (address->pointer_type) {
case ACPI_PHYSICAL_POINTER:
*size = SIZE_IN_HEADER;
status = acpi_tb_map_acpi_table (address->pointer.physical, size, table_ptr);
break;
case ACPI_LOGICAL_POINTER:
if (table_info->type != ACPI_TABLE_FACS) {
status = acpi_tb_verify_table_checksum (full_table);
*table_ptr = address->pointer.logical;
*size = 0;
break;
#if (!ACPI_CHECKSUM_ABORT)
if (ACPI_FAILURE (status)) {
/* Ignore the error if configuration says so */
default:
return (AE_BAD_PARAMETER);
status = AE_OK;
}
#endif
}
else {
/* In Physical addressing mode, all pointers must be physical */
switch (address->pointer_type) {
case ACPI_PHYSICAL_POINTER:
*size = 0;
*table_ptr = address->pointer.logical;
break;
case ACPI_LOGICAL_POINTER:
/* Return values */
status = AE_BAD_PARAMETER;
break;
table_info->pointer = full_table;
table_info->length = (ACPI_SIZE) header->length;
table_info->allocation = allocation;
table_info->base_pointer = full_table;
default:
return (AE_BAD_PARAMETER);
}
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
full_table->signature,
ACPI_HIDWORD (address->pointer.physical),
ACPI_LODWORD (address->pointer.physical), full_table));
return (status);
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table_rsdt
* FUNCTION: Acpi_tb_get_table_ptr
*
* PARAMETERS: Number_of_tables - Where the table count is placed
* PARAMETERS: Table_type - one of the defined table types
* Instance - Which table of this type
* Table_ptr_loc - pointer to location to place the pointer for
* return
*
* RETURN: Status
*
* DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
* DESCRIPTION: This function is called to get the pointer to an ACPI table.
*
******************************************************************************/
acpi_status
acpi_tb_get_table_rsdt (
u32 *number_of_tables)
acpi_tb_get_table_ptr (
acpi_table_type table_type,
u32 instance,
acpi_table_header **table_ptr_loc)
{
acpi_table_desc table_info;
acpi_status status;
ACPI_POINTER address;
acpi_table_desc *table_desc;
u32 i;
ACPI_FUNCTION_TRACE ("Tb_get_table_rsdt");
ACPI_FUNCTION_TRACE ("Tb_get_table_ptr");
/* Get the RSDT/XSDT from the RSDP */
acpi_tb_get_rsdt_address (&address);
status = acpi_tb_get_table (&address, &table_info);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the R/XSDT, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
if (!acpi_gbl_DSDT) {
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
acpi_gbl_RSDP,
ACPI_HIDWORD (address.pointer.value),
ACPI_LODWORD (address.pointer.value)));
/* Check the RSDT or XSDT signature */
status = acpi_tb_validate_rsdt (table_info.pointer);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
if (table_type > ACPI_TABLE_MAX) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* Valid RSDT signature, verify the checksum. If it fails, just
* print a warning and ignore it.
* For all table types (Single/Multiple), the first
* instance is always in the list head.
*/
status = acpi_tb_verify_table_checksum (table_info.pointer);
/* Convert and/or copy to an XSDT structure */
status = acpi_tb_convert_to_xsdt (&table_info, number_of_tables);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
if (instance == 1) {
/*
* Just pluck the pointer out of the global table!
* Will be null if no table is present
*/
*table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer;
return_ACPI_STATUS (AE_OK);
}
/* Save the table pointers and allocation info */
/*
* Check for instance out of range
*/
if (instance > acpi_gbl_acpi_tables[table_type].count) {
return_ACPI_STATUS (AE_NOT_EXIST);
}
status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
/* Walk the list to get the desired table
* Since the if (Instance == 1) check above checked for the
* first table, setting Table_desc equal to the .Next member
* is actually pointing to the second table. Therefore, we
* need to walk from the 2nd table until we reach the Instance
* that the user is looking for and return its table pointer.
*/
table_desc = acpi_gbl_acpi_tables[table_type].next;
for (i = 2; i < instance; i++) {
table_desc = table_desc->next;
}
acpi_gbl_XSDT = (xsdt_descriptor *) table_info.pointer;
/* We are now pointing to the requested table's descriptor */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
return_ACPI_STATUS (status);
}
*table_ptr_loc = table_desc->pointer;
return_ACPI_STATUS (AE_OK);
}
/******************************************************************************
*
* Module Name: tbgetall - Get all required ACPI tables
* $Revision: 1 $
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2002, R. Byron Moore
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "acpi.h"
#include "actables.h"
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbgetall")
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_primary_table
*
* PARAMETERS: Address - Physical address of table to retrieve
* *Table_info - Where the table info is returned
*
* RETURN: Status
*
* DESCRIPTION: Maps the physical address of table into a logical address
*
******************************************************************************/
acpi_status
acpi_tb_get_primary_table (
ACPI_POINTER *address,
acpi_table_desc *table_info)
{
acpi_status status;
acpi_table_header header;
ACPI_FUNCTION_TRACE ("Tb_get_primary_table");
/* Ignore a NULL address in the RSDT */
if (!address->pointer.value) {
return_ACPI_STATUS (AE_OK);
}
/*
* Get the header in order to get signature and table size
*/
status = acpi_tb_get_table_header (address, &header);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Clear the Table_info */
ACPI_MEMSET (table_info, 0, sizeof (acpi_table_desc));
/*
* Check the table signature and make sure it is recognized.
* Also checks the header checksum
*/
table_info->pointer = &header;
status = acpi_tb_recognize_table (table_info, ACPI_TABLE_PRIMARY);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Get the entire table */
status = acpi_tb_get_table_body (address, &header, table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Install the table */
status = acpi_tb_install_table (table_info);
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_secondary_table
*
* PARAMETERS: Address - Physical address of table to retrieve
* *Table_info - Where the table info is returned
*
* RETURN: Status
*
* DESCRIPTION: Maps the physical address of table into a logical address
*
******************************************************************************/
acpi_status
acpi_tb_get_secondary_table (
ACPI_POINTER *address,
acpi_string signature,
acpi_table_desc *table_info)
{
acpi_status status;
acpi_table_header header;
ACPI_FUNCTION_TRACE_STR ("Tb_get_secondary_table", signature);
/* Get the header in order to match the signature */
status = acpi_tb_get_table_header (address, &header);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Signature must match request */
if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
ACPI_REPORT_ERROR (("Incorrect table signature - wanted [%s] found [%4.4s]\n",
signature, header.signature));
return_ACPI_STATUS (AE_BAD_SIGNATURE);
}
/*
* Check the table signature and make sure it is recognized.
* Also checks the header checksum
*/
table_info->pointer = &header;
status = acpi_tb_recognize_table (table_info, ACPI_TABLE_SECONDARY);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Get the entire table */
status = acpi_tb_get_table_body (address, &header, table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Install the table */
status = acpi_tb_install_table (table_info);
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_required_tables
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must
* already be loaded and validated.
*
* Get the minimum set of ACPI tables, namely:
*
* 1) FADT (via RSDT in loop below)
* 2) FACS (via FADT)
* 3) DSDT (via FADT)
*
******************************************************************************/
acpi_status
acpi_tb_get_required_tables (
void)
{
acpi_status status = AE_OK;
u32 i;
acpi_table_desc table_info;
ACPI_POINTER address;
ACPI_FUNCTION_TRACE ("Tb_get_required_tables");
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
acpi_gbl_rsdt_table_count));
address.pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
/*
* Loop through all table pointers found in RSDT.
* This will NOT include the FACS and DSDT - we must get
* them after the loop.
*
* The only tables we are interested in getting here is the FADT and
* any SSDTs.
*/
for (i = 0; i < acpi_gbl_rsdt_table_count; i++) {
/* Get the table addresss from the common internal XSDT */
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_XSDT->table_offset_entry[i]);
/*
* Get the tables needed by this subsystem (FADT and any SSDTs).
* NOTE: All other tables are completely ignored at this time.
*/
acpi_tb_get_primary_table (&address, &table_info);
}
/* We must have a FADT to continue */
if (!acpi_gbl_FADT) {
ACPI_REPORT_ERROR (("No FADT present in RSDT/XSDT\n"));
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
/*
* Convert the FADT to a common format. This allows earlier revisions of the
* table to coexist with newer versions, using common access code.
*/
status = acpi_tb_convert_table_fadt ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
return_ACPI_STATUS (status);
}
/*
* Get the FACS (Pointed to by the FADT)
*/
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_FADT->Xfirmware_ctrl);
status = acpi_tb_get_secondary_table (&address, FACS_SIG, &table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get/install the FACS, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/*
* Create the common FACS pointer table
* (Contains pointers to the original table)
*/
status = acpi_tb_build_common_facs (&table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/*
* Get/install the DSDT (Pointed to by the FADT)
*/
address.pointer.value = ACPI_GET_ADDRESS (acpi_gbl_FADT->Xdsdt);
status = acpi_tb_get_secondary_table (&address, DSDT_SIG, &table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not get/install the DSDT\n"));
return_ACPI_STATUS (status);
}
/* Set Integer Width (32/64) based upon DSDT revision */
acpi_ut_set_integer_width (acpi_gbl_DSDT->revision);
/* Dump the entire DSDT */
ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
"Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
acpi_gbl_DSDT->length, acpi_gbl_DSDT->length, acpi_gbl_integer_bit_width));
ACPI_DUMP_BUFFER ((u8 *) acpi_gbl_DSDT, acpi_gbl_DSDT->length);
/* Always delete the RSDP mapping, we are done with it */
acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP);
return_ACPI_STATUS (status);
}
/******************************************************************************
*
* Module Name: tbinstal - ACPI table installation and removal
* $Revision: 61 $
* $Revision: 62 $
*
*****************************************************************************/
......@@ -49,7 +49,8 @@
acpi_status
acpi_tb_match_signature (
NATIVE_CHAR *signature,
acpi_table_desc *table_info)
acpi_table_desc *table_info,
u8 search_type)
{
NATIVE_UINT i;
......@@ -61,6 +62,10 @@ acpi_tb_match_signature (
* Search for a signature match among the known table types
*/
for (i = 0; i < NUM_ACPI_TABLES; i++) {
if ((acpi_gbl_acpi_table_data[i].flags & ACPI_TABLE_TYPE_MASK) != search_type) {
continue;
}
if (!ACPI_STRNCMP (signature, acpi_gbl_acpi_table_data[i].signature,
acpi_gbl_acpi_table_data[i].sig_length)) {
/* Found a signature match, return index if requested */
......@@ -69,13 +74,18 @@ acpi_tb_match_signature (
table_info->type = (u8) i;
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Signature match %4.4s\n",
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Table [%4.4s] matched and is a required ACPI table\n",
(char *) acpi_gbl_acpi_table_data[i].signature));
return_ACPI_STATUS (AE_OK);
}
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Table [%4.4s] is not a required ACPI table - ignored\n",
(char *) signature));
return_ACPI_STATUS (AE_TABLE_NOT_SUPPORTED);
}
......@@ -84,7 +94,7 @@ acpi_tb_match_signature (
*
* FUNCTION: Acpi_tb_install_table
*
* PARAMETERS: Table_info - Return value from Acpi_tb_get_table
* PARAMETERS: Table_info - Return value from Acpi_tb_get_table_body
*
* RETURN: Status
*
......@@ -103,25 +113,22 @@ acpi_tb_install_table (
ACPI_FUNCTION_TRACE ("Tb_install_table");
/*
* Check the table signature and make sure it is recognized
* Also checks the header checksum
*/
status = acpi_tb_recognize_table (table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Lock tables while installing */
status = acpi_ut_acquire_mutex (ACPI_MTX_TABLES);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not acquire table mutex for [%4.4s], %s\n",
table_info->pointer->signature, acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
/* Install the table into the global data structure */
status = acpi_tb_init_table_descriptor (table_info->type, table_info);
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Could not install ACPI table [%s], %s\n",
table_info->pointer->signature, acpi_format_exception (status)));
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n",
acpi_gbl_acpi_table_data[table_info->type].name, table_info->pointer));
......@@ -135,7 +142,7 @@ acpi_tb_install_table (
*
* FUNCTION: Acpi_tb_recognize_table
*
* PARAMETERS: Table_info - Return value from Acpi_tb_get_table
* PARAMETERS: Table_info - Return value from Acpi_tb_get_table_body
*
* RETURN: Status
*
......@@ -153,7 +160,8 @@ acpi_tb_install_table (
acpi_status
acpi_tb_recognize_table (
acpi_table_desc *table_info)
acpi_table_desc *table_info,
u8 search_type)
{
acpi_table_header *table_header;
acpi_status status;
......@@ -177,7 +185,7 @@ acpi_tb_recognize_table (
* This can be any one of many valid ACPI tables, it just isn't one of
* the tables that is consumed by the core subsystem
*/
status = acpi_tb_match_signature (table_header->signature, table_info);
status = acpi_tb_match_signature (table_header->signature, table_info, search_type);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
......@@ -191,22 +199,6 @@ acpi_tb_recognize_table (
table_info->length = (ACPI_SIZE) table_header->length;
/*
* Validate checksum for _most_ tables,
* even the ones whose signature we don't recognize
*/
if (table_info->type != ACPI_TABLE_FACS) {
status = acpi_tb_verify_table_checksum (table_header);
#if (!ACPI_CHECKSUM_ABORT)
if (ACPI_FAILURE (status)) {
/* Ignore the error if configuration says so */
status = AE_OK;
}
#endif
}
return_ACPI_STATUS (status);
}
......
/******************************************************************************
*
* Module Name: tbrsdt - ACPI RSDT table utilities
* $Revision: 1 $
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2002, R. Byron Moore
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "acpi.h"
#include "actables.h"
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbrsdt")
/*******************************************************************************
*
* FUNCTION: Acpi_tb_verify_rsdp
*
* PARAMETERS: Address - RSDP (Pointer to RSDT)
*
* RETURN: Status
*
* DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
*
******************************************************************************/
acpi_status
acpi_tb_verify_rsdp (
ACPI_POINTER *address)
{
acpi_table_desc table_info;
acpi_status status;
RSDP_DESCRIPTOR *rsdp;
ACPI_FUNCTION_TRACE ("Tb_verify_rsdp");
switch (address->pointer_type) {
case ACPI_LOGICAL_POINTER:
rsdp = address->pointer.logical;
break;
case ACPI_PHYSICAL_POINTER:
/*
* Obtain access to the RSDP structure
*/
status = acpi_os_map_memory (address->pointer.physical, sizeof (RSDP_DESCRIPTOR),
(void **) &rsdp);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
break;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
* The signature and checksum must both be correct
*/
if (ACPI_STRNCMP ((NATIVE_CHAR *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
/* Nope, BAD Signature */
status = AE_BAD_SIGNATURE;
goto cleanup;
}
/* Check the standard checksum */
if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
status = AE_BAD_CHECKSUM;
goto cleanup;
}
/* Check extended checksum if table version >= 2 */
if (rsdp->revision >= 2) {
if (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0) {
status = AE_BAD_CHECKSUM;
goto cleanup;
}
}
/* The RSDP supplied is OK */
table_info.pointer = ACPI_CAST_PTR (acpi_table_header, rsdp);
table_info.length = sizeof (RSDP_DESCRIPTOR);
table_info.allocation = ACPI_MEM_MAPPED;
table_info.base_pointer = rsdp;
/* Save the table pointers and allocation info */
status = acpi_tb_init_table_descriptor (ACPI_TABLE_RSDP, &table_info);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/* Save the RSDP in a global for easy access */
acpi_gbl_RSDP = ACPI_CAST_PTR (RSDP_DESCRIPTOR, table_info.pointer);
return_ACPI_STATUS (status);
/* Error exit */
cleanup:
if (acpi_gbl_table_flags & ACPI_PHYSICAL_POINTER) {
acpi_os_unmap_memory (rsdp, sizeof (RSDP_DESCRIPTOR));
}
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_rsdt_address
*
* PARAMETERS: None
*
* RETURN: RSDT physical address
*
* DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
* version of the RSDP
*
******************************************************************************/
void
acpi_tb_get_rsdt_address (
ACPI_POINTER *out_address)
{
ACPI_FUNCTION_ENTRY ();
out_address->pointer_type = acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
/*
* For RSDP revision 0 or 1, we use the RSDT.
* For RSDP revision 2 (and above), we use the XSDT
*/
if (acpi_gbl_RSDP->revision < 2) {
out_address->pointer.value = acpi_gbl_RSDP->rsdt_physical_address;
}
else {
out_address->pointer.value = ACPI_GET_ADDRESS (acpi_gbl_RSDP->xsdt_physical_address);
}
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_validate_rsdt
*
* PARAMETERS: Table_ptr - Addressable pointer to the RSDT.
*
* RETURN: Status
*
* DESCRIPTION: Validate signature for the RSDT or XSDT
*
******************************************************************************/
acpi_status
acpi_tb_validate_rsdt (
acpi_table_header *table_ptr)
{
int no_match;
ACPI_FUNCTION_NAME ("Tb_validate_rsdt");
/*
* For RSDP revision 0 or 1, we use the RSDT.
* For RSDP revision 2 and above, we use the XSDT
*/
if (acpi_gbl_RSDP->revision < 2) {
no_match = ACPI_STRNCMP ((char *) table_ptr, RSDT_SIG,
sizeof (RSDT_SIG) -1);
}
else {
no_match = ACPI_STRNCMP ((char *) table_ptr, XSDT_SIG,
sizeof (XSDT_SIG) -1);
}
if (no_match) {
/* Invalid RSDT or XSDT signature */
ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
ACPI_DUMP_BUFFER (acpi_gbl_RSDP, 20);
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR,
"RSDT/XSDT signature at %X (%p) is invalid\n",
acpi_gbl_RSDP->rsdt_physical_address,
(void *) (NATIVE_UINT) acpi_gbl_RSDP->rsdt_physical_address));
return (AE_BAD_SIGNATURE);
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_get_table_rsdt
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
*
******************************************************************************/
acpi_status
acpi_tb_get_table_rsdt (
void)
{
acpi_table_desc table_info;
acpi_status status;
ACPI_POINTER address;
ACPI_FUNCTION_TRACE ("Tb_get_table_rsdt");
/* Get the RSDT/XSDT via the RSDP */
acpi_tb_get_rsdt_address (&address);
status = acpi_tb_get_table (&address, &table_info);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n",
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"RSDP located at %p, points to RSDT physical=%8.8X%8.8X \n",
acpi_gbl_RSDP,
ACPI_HIDWORD (address.pointer.value),
ACPI_LODWORD (address.pointer.value)));
/* Check the RSDT or XSDT signature */
status = acpi_tb_validate_rsdt (table_info.pointer);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/*
* Valid RSDT signature, verify the checksum. If it fails, just
* print a warning and ignore it.
*/
status = acpi_tb_verify_table_checksum (table_info.pointer);
/* Get the number of tables defined in the RSDT or XSDT */
acpi_gbl_rsdt_table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, table_info.pointer);
/* Convert and/or copy to an XSDT structure */
status = acpi_tb_convert_to_xsdt (&table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
/* Save the table pointers and allocation info */
status = acpi_tb_init_table_descriptor (ACPI_TABLE_XSDT, &table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
acpi_gbl_XSDT = (xsdt_descriptor *) table_info.pointer;
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
return_ACPI_STATUS (status);
}
/******************************************************************************
*
* Module Name: tbutils - Table manipulation utilities
* $Revision: 54 $
* $Revision: 55 $
*
*****************************************************************************/
......@@ -121,7 +121,8 @@ acpi_tb_validate_table_header (
"Table signature at %p [%p] has invalid characters\n",
table_header, &signature));
ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n", (char *) &signature));
ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n",
(char *) &signature));
ACPI_DUMP_BUFFER (table_header, sizeof (acpi_table_header));
return (AE_BAD_SIGNATURE);
}
......@@ -133,7 +134,8 @@ acpi_tb_validate_table_header (
"Invalid length in table header %p name %4.4s\n",
table_header, (char *) &signature));
ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n", table_header->length));
ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n",
table_header->length));
ACPI_DUMP_BUFFER (table_header, sizeof (acpi_table_header));
return (AE_BAD_HEADER);
}
......@@ -142,91 +144,6 @@ acpi_tb_validate_table_header (
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_map_acpi_table
*
* PARAMETERS: Physical_address - Physical address of table to map
* *Size - Size of the table. If zero, the size
* from the table header is used.
* Actual size is returned here.
* **Logical_address - Logical address of mapped table
*
* RETURN: Logical address of the mapped table.
*
* DESCRIPTION: Maps the physical address of table into a logical address
*
******************************************************************************/
acpi_status
acpi_tb_map_acpi_table (
ACPI_PHYSICAL_ADDRESS physical_address,
ACPI_SIZE *size,
acpi_table_header **logical_address)
{
acpi_table_header *table;
ACPI_SIZE table_size = *size;
acpi_status status = AE_OK;
ACPI_FUNCTION_NAME ("Tb_map_acpi_table");
/* If size is zero, look at the table header to get the actual size */
if ((*size) == 0) {
/* Get the table header so we can extract the table length */
status = acpi_os_map_memory (physical_address, sizeof (acpi_table_header),
(void **) &table);
if (ACPI_FAILURE (status)) {
return (status);
}
/* Extract the full table length before we delete the mapping */
table_size = (ACPI_SIZE) table->length;
#if 0
/* We don't want to validate the header here. */
/*
* Validate the header and delete the mapping.
* We will create a mapping for the full table below.
*/
status = acpi_tb_validate_table_header (table);
#endif
/* Always unmap the memory for the header */
acpi_os_unmap_memory (table, sizeof (acpi_table_header));
#if 0
/* Exit if header invalid */
if (ACPI_FAILURE (status)) {
return (status);
}
#endif
}
/* Map the physical memory for the correct length */
status = acpi_os_map_memory (physical_address, table_size,
(void **) &table);
if (ACPI_FAILURE (status)) {
return (status);
}
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Mapped memory for ACPI table, length=%d(%X) at %p\n",
table_size, table_size, table));
*size = table_size;
*logical_address = table;
return (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_tb_verify_table_checksum
......
......@@ -2,7 +2,7 @@
*
* Module Name: tbxface - Public interfaces to the ACPI subsystem
* ACPI table oriented interfaces
* $Revision: 57 $
* $Revision: 58 $
*
*****************************************************************************/
......@@ -52,7 +52,6 @@ acpi_load_tables (void)
{
ACPI_POINTER rsdp_address;
acpi_status status;
u32 number_of_tables = 0;
ACPI_FUNCTION_TRACE ("Acpi_load_tables");
......@@ -81,16 +80,16 @@ acpi_load_tables (void)
/* Get the RSDT via the RSDP */
status = acpi_tb_get_table_rsdt (&number_of_tables);
status = acpi_tb_get_table_rsdt ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Acpi_load_tables: Could not load RSDT: %s\n",
acpi_format_exception (status)));
goto error_exit;
}
/* Now get the rest of the tables */
/* Now get the tables needed by this subsystem (FADT, DSDT, etc.) */
status = acpi_tb_get_all_tables (number_of_tables);
status = acpi_tb_get_required_tables ();
if (ACPI_FAILURE (status)) {
ACPI_REPORT_ERROR (("Acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %s\n",
acpi_format_exception (status)));
......@@ -154,10 +153,10 @@ acpi_load_table (
/* Copy the table to a local buffer */
address.pointer_type = ACPI_LOGICAL_POINTER;
address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
address.pointer.logical = table_ptr;
status = acpi_tb_get_table (&address, &table_info);
status = acpi_tb_get_table_body (&address, table_ptr, &table_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
......@@ -166,7 +165,7 @@ acpi_load_table (
status = acpi_tb_install_table (&table_info);
if (ACPI_FAILURE (status)) {
/* Free table allocated by Acpi_tb_get_table */
/* Free table allocated by Acpi_tb_get_table_body */
acpi_tb_delete_single_table (&table_info);
return_ACPI_STATUS (status);
......
/******************************************************************************
*
* Module Name: tbxfroot - Find the root ACPI table (RSDT)
* $Revision: 63 $
* $Revision: 64 $
*
*****************************************************************************/
......@@ -63,9 +63,9 @@ acpi_tb_find_table (
/* Validate string lengths */
if ((ACPI_STRLEN (signature) > 4) ||
(ACPI_STRLEN (oem_id) > 6) ||
(ACPI_STRLEN (oem_table_id) > 8)) {
if ((ACPI_STRLEN (signature) > ACPI_NAME_SIZE) ||
(ACPI_STRLEN (oem_id) > sizeof (table->oem_id)) ||
(ACPI_STRLEN (oem_table_id) > sizeof (table->oem_table_id))) {
return_ACPI_STATUS (AE_AML_STRING_LIMIT);
}
......@@ -96,7 +96,7 @@ acpi_tb_find_table (
* PARAMETERS: Signature - Any ACPI table signature
* Instance - the non zero instance of the table, allows
* support for multiple tables of the same type
* Flags - 0: Physical/Virtual support
* Flags - Physical/Virtual support
* Ret_buffer - pointer to a structure containing a buffer to
* receive the table
*
......@@ -120,11 +120,10 @@ acpi_get_firmware_table (
{
ACPI_POINTER rsdp_address;
ACPI_POINTER address;
acpi_table_header *rsdt_ptr = NULL;
acpi_table_header *table_ptr;
acpi_status status;
ACPI_SIZE rsdt_size = 0;
ACPI_SIZE table_size;
acpi_table_header header;
acpi_table_desc table_info;
acpi_table_desc rsdt_info;
u32 table_count;
u32 i;
u32 j;
......@@ -147,6 +146,8 @@ acpi_get_firmware_table (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
rsdt_info.pointer = NULL;
if (!acpi_gbl_RSDP) {
/* Get the RSDP */
......@@ -175,15 +176,13 @@ acpi_get_firmware_table (
if (ACPI_STRNCMP ((NATIVE_CHAR *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
/* Nope, BAD Signature */
status = AE_BAD_SIGNATURE;
goto cleanup;
return_ACPI_STATUS (AE_BAD_SIGNATURE);
}
if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
/* Nope, BAD Checksum */
status = AE_BAD_CHECKSUM;
goto cleanup;
return_ACPI_STATUS (AE_BAD_CHECKSUM);
}
}
......@@ -197,63 +196,65 @@ acpi_get_firmware_table (
ACPI_HIDWORD (address.pointer.value),
ACPI_LODWORD (address.pointer.value)));
status = acpi_tb_get_table_pointer (&address, flags, &rsdt_size, &rsdt_ptr);
/* Insert Processor_mode flags */
address.pointer_type |= flags;
status = acpi_tb_get_table (&address, &rsdt_info);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
status = acpi_tb_validate_rsdt (rsdt_ptr);
status = acpi_tb_validate_rsdt (rsdt_info.pointer);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/* Get the number of table pointers within the RSDT */
table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_ptr);
table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info.pointer);
address.pointer_type = acpi_gbl_table_flags | flags;
/*
* Search the RSDT/XSDT for the correct instance of the
* requested table
*/
for (i = 0, j = 0; i < table_count; i++) {
/* Get the next table pointer */
/* Get the next table pointer, handle RSDT vs. XSDT */
address.pointer_type = acpi_gbl_table_flags;
if (acpi_gbl_RSDP->revision < 2) {
address.pointer.value = ((RSDT_DESCRIPTOR *) rsdt_ptr)->table_offset_entry[i];
address.pointer.value = ((RSDT_DESCRIPTOR *) rsdt_info.pointer)->table_offset_entry[i];
}
else {
address.pointer.value = ACPI_GET_ADDRESS (
((xsdt_descriptor *) rsdt_ptr)->table_offset_entry[i]);
((xsdt_descriptor *) rsdt_info.pointer)->table_offset_entry[i]);
}
/* Get addressibility if necessary */
/* Get the table header */
status = acpi_tb_get_table_pointer (&address, flags, &table_size, &table_ptr);
status = acpi_tb_get_table_header (&address, &header);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/* Compare table signatures and table instance */
if (!ACPI_STRNCMP ((char *) table_ptr, signature, ACPI_STRLEN (signature))) {
if (!ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
/* An instance of the table was found */
j++;
if (j >= instance) {
/* Found the correct instance */
/* Found the correct instance, get the entire table */
*table_pointer = table_ptr;
status = acpi_tb_get_table_body (&address, &header, &table_info);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
}
/* Delete table mapping if using virtual addressing */
if ((table_size) &&
((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING)) {
acpi_os_unmap_memory (table_ptr, table_size);
*table_pointer = table_info.pointer;
goto cleanup;
}
}
}
......@@ -263,9 +264,7 @@ acpi_get_firmware_table (
cleanup:
if (rsdt_size) {
acpi_os_unmap_memory (rsdt_ptr, rsdt_size);
}
acpi_os_unmap_memory (rsdt_info.pointer, (ACPI_SIZE) rsdt_info.pointer->length);
return_ACPI_STATUS (status);
}
......
/******************************************************************************
*
* Module Name: utcopy - Internal to external object translation utilities
* $Revision: 101 $
* $Revision: 103 $
*
*****************************************************************************/
......@@ -286,19 +286,21 @@ acpi_ut_copy_ipackage_to_epackage (
/*
* Free space begins right after the first package
*/
info.length = 0;
info.length = ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
info.free_space = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
info.object_space = 0;
info.num_packages = 1;
info.free_space = buffer + ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
external_object->type = ACPI_GET_OBJECT_TYPE (internal_object);
external_object->package.count = internal_object->package.count;
external_object->package.elements = ACPI_CAST_PTR (acpi_object, info.free_space);
/*
* Build an array of ACPI_OBJECTS in the buffer
* Leave room for an array of ACPI_OBJECTS in the buffer
* and move the free space past it
*/
info.length += (ACPI_SIZE) external_object->package.count *
ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
info.free_space += external_object->package.count *
ACPI_ROUND_UP_TO_NATIVE_WORD (sizeof (acpi_object));
......@@ -517,7 +519,6 @@ acpi_ut_copy_epackage_to_ipackage (
external_object->package.count = internal_object->package.count;
external_object->package.elements = (acpi_object *)free_space;
/*
* Build an array of ACPI_OBJECTS in the buffer
* and move the free space past it
......
/******************************************************************************
*
* Module Name: utglobal - Global variables for the ACPI subsystem
* $Revision: 163 $
* $Revision: 164 $
*
*****************************************************************************/
......@@ -286,15 +286,15 @@ acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
ACPI_TABLE_SUPPORT acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] =
{
/*********** Name, Signature, Global typed pointer Signature size, How many allowed?, Contains valid AML? */
/* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof (RSDP_SIG)-1, ACPI_TABLE_SINGLE},
/* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void **) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE},
/* FADT 2 */ {FADT_SIG, FADT_SIG, (void **) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_SINGLE},
/* FACS 3 */ {FACS_SIG, FACS_SIG, (void **) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SINGLE},
/* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof (PSDT_SIG)-1, ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
/* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof (SSDT_SIG)-1, ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
/* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof (RSDT_SIG)-1, ACPI_TABLE_SINGLE},
/*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */
/* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof (RSDP_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE},
/* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void **) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE},
/* FADT 2 */ {FADT_SIG, FADT_SIG, (void **) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE},
/* FACS 3 */ {FACS_SIG, FACS_SIG, (void **) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE},
/* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof (PSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
/* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof (SSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
/* XSDT 6 */ {XSDT_SIG, XSDT_SIG, NULL, sizeof (RSDT_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE},
};
......
/******************************************************************************
*
* Module Name: utxface - External interfaces for "global" ACPI functions
* $Revision: 96 $
* $Revision: 97 $
*
*****************************************************************************/
......@@ -192,6 +192,31 @@ acpi_enable_subsystem (
}
}
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
* FUNCTION: Acpi_initialize_objects
*
* PARAMETERS: Flags - Init/enable Options
*
* RETURN: Status
*
* DESCRIPTION: Completes namespace initialization by initializing device
* objects and executing AML code for Regions, buffers, etc.
*
******************************************************************************/
acpi_status
acpi_initialize_objects (
u32 flags)
{
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE ("Acpi_initialize_objects");
/*
* Initialize all device objects in the namespace
* This runs the _STA and _INI methods.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment