Commit f3d2e786 authored by Bob Moore's avatar Bob Moore Committed by Len Brown

ACPICA: Implement simplified Table Manager

The Table Manager component has been completely
redesigned and reimplemented. The new design is much
simpler, and reduces the overall code and data size of
the kernel-resident ACPICA by approximately 5%. Also,
it is now possible to obtain the ACPI tables very early
during kernel initialization, even before dynamic memory
management is initialized.
Signed-off-by: default avatarAlexey Starikovskiy <alexey.y.starikovskiy@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 2e42005b
......@@ -44,6 +44,7 @@
#include <acpi/acpi.h>
#include <acpi/acdispat.h>
#include <acpi/acnamesp.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME("dsinit")
......@@ -90,7 +91,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
* We are only interested in NS nodes owned by the table that
* was just loaded
*/
if (node->owner_id != info->table_desc->owner_id) {
if (node->owner_id != info->owner_id) {
return (AE_OK);
}
......@@ -150,14 +151,21 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
******************************************************************************/
acpi_status
acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
acpi_ds_initialize_objects(acpi_native_uint table_index,
struct acpi_namespace_node * start_node)
{
acpi_status status;
struct acpi_init_walk_info info;
struct acpi_table_header *table;
acpi_owner_id owner_id;
ACPI_FUNCTION_TRACE(ds_initialize_objects);
status = acpi_tb_get_owner_id(table_index, &owner_id);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
"**** Starting initialization of namespace objects ****\n"));
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:"));
......@@ -166,7 +174,8 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
info.op_region_count = 0;
info.object_count = 0;
info.device_count = 0;
info.table_desc = table_desc;
info.table_index = table_index;
info.owner_id = owner_id;
/* Walk entire namespace from the supplied root */
......@@ -176,10 +185,14 @@ acpi_ds_initialize_objects(struct acpi_table_desc * table_desc,
ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
}
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
"\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
table_desc->pointer->signature,
table_desc->owner_id, info.object_count,
table->signature, owner_id, info.object_count,
info.device_count, info.method_count,
info.op_region_count));
......
......@@ -70,13 +70,6 @@ acpi_status acpi_ev_initialize_events(void)
ACPI_FUNCTION_TRACE(ev_initialize_events);
/* Make sure we have ACPI tables */
if (!acpi_gbl_DSDT) {
ACPI_WARNING((AE_INFO, "No ACPI tables present!"));
return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
/*
* Initialize the Fixed and General Purpose Events. This is done prior to
* enabling SCIs to prevent interrupts from occurring before the handlers are
......
......@@ -529,7 +529,7 @@ static struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32
/* Install new interrupt handler if not SCI_INT */
if (interrupt_number != acpi_gbl_FADT->sci_int) {
if (interrupt_number != acpi_gbl_FADT.sci_interrupt) {
status = acpi_os_install_interrupt_handler(interrupt_number,
acpi_ev_gpe_xrupt_handler,
gpe_xrupt);
......@@ -567,7 +567,7 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
/* We never want to remove the SCI interrupt handler */
if (gpe_xrupt->interrupt_number == acpi_gbl_FADT->sci_int) {
if (gpe_xrupt->interrupt_number == acpi_gbl_FADT.sci_interrupt) {
gpe_xrupt->gpe_block_list_head = NULL;
return_ACPI_STATUS(AE_OK);
}
......@@ -803,17 +803,17 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
(gpe_block->block_address.address
+ i + gpe_block->register_count));
this_register->status_address.address_space_id =
gpe_block->block_address.address_space_id;
this_register->enable_address.address_space_id =
gpe_block->block_address.address_space_id;
this_register->status_address.register_bit_width =
this_register->status_address.space_id =
gpe_block->block_address.space_id;
this_register->enable_address.space_id =
gpe_block->block_address.space_id;
this_register->status_address.bit_width =
ACPI_GPE_REGISTER_WIDTH;
this_register->enable_address.register_bit_width =
this_register->enable_address.bit_width =
ACPI_GPE_REGISTER_WIDTH;
this_register->status_address.register_bit_offset =
this_register->status_address.bit_offset =
ACPI_GPE_REGISTER_WIDTH;
this_register->enable_address.register_bit_offset =
this_register->enable_address.bit_offset =
ACPI_GPE_REGISTER_WIDTH;
/* Init the event_info for each GPE within this register */
......@@ -1109,11 +1109,12 @@ acpi_status acpi_ev_gpe_initialize(void)
* If EITHER the register length OR the block address are zero, then that
* particular block is not supported.
*/
if (acpi_gbl_FADT->gpe0_blk_len && acpi_gbl_FADT->xgpe0_blk.address) {
if (acpi_gbl_FADT.gpe0_block_length &&
acpi_gbl_FADT.xgpe0_block.address) {
/* GPE block 0 exists (has both length and address > 0) */
register_count0 = (u16) (acpi_gbl_FADT->gpe0_blk_len / 2);
register_count0 = (u16) (acpi_gbl_FADT.gpe0_block_length / 2);
gpe_number_max =
(register_count0 * ACPI_GPE_REGISTER_WIDTH) - 1;
......@@ -1121,9 +1122,9 @@ acpi_status acpi_ev_gpe_initialize(void)
/* Install GPE Block 0 */
status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
&acpi_gbl_FADT->xgpe0_blk,
&acpi_gbl_FADT.xgpe0_block,
register_count0, 0,
acpi_gbl_FADT->sci_int,
acpi_gbl_FADT.sci_interrupt,
&acpi_gbl_gpe_fadt_blocks[0]);
if (ACPI_FAILURE(status)) {
......@@ -1132,20 +1133,21 @@ acpi_status acpi_ev_gpe_initialize(void)
}
}
if (acpi_gbl_FADT->gpe1_blk_len && acpi_gbl_FADT->xgpe1_blk.address) {
if (acpi_gbl_FADT.gpe1_block_length &&
acpi_gbl_FADT.xgpe1_block.address) {
/* GPE block 1 exists (has both length and address > 0) */
register_count1 = (u16) (acpi_gbl_FADT->gpe1_blk_len / 2);
register_count1 = (u16) (acpi_gbl_FADT.gpe1_block_length / 2);
/* Check for GPE0/GPE1 overlap (if both banks exist) */
if ((register_count0) &&
(gpe_number_max >= acpi_gbl_FADT->gpe1_base)) {
(gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
ACPI_ERROR((AE_INFO,
"GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
gpe_number_max, acpi_gbl_FADT->gpe1_base,
acpi_gbl_FADT->gpe1_base +
gpe_number_max, acpi_gbl_FADT.gpe1_base,
acpi_gbl_FADT.gpe1_base +
((register_count1 *
ACPI_GPE_REGISTER_WIDTH) - 1)));
......@@ -1157,10 +1159,11 @@ acpi_status acpi_ev_gpe_initialize(void)
status =
acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
&acpi_gbl_FADT->xgpe1_blk,
&acpi_gbl_FADT.xgpe1_block,
register_count1,
acpi_gbl_FADT->gpe1_base,
acpi_gbl_FADT->sci_int,
acpi_gbl_FADT.gpe1_base,
acpi_gbl_FADT.
sci_interrupt,
&acpi_gbl_gpe_fadt_blocks
[1]);
......@@ -1173,7 +1176,7 @@ acpi_status acpi_ev_gpe_initialize(void)
* GPE0 and GPE1 do not have to be contiguous in the GPE number
* space. However, GPE0 always starts at GPE number zero.
*/
gpe_number_max = acpi_gbl_FADT->gpe1_base +
gpe_number_max = acpi_gbl_FADT.gpe1_base +
((register_count1 * ACPI_GPE_REGISTER_WIDTH) - 1);
}
}
......
......@@ -63,6 +63,10 @@ static const char *acpi_notify_value_names[] = {
};
#endif
/* Pointer to FACS needed for the Global Lock */
static struct acpi_table_facs *facs = NULL;
/* Local prototypes */
static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
......@@ -306,7 +310,7 @@ static u32 acpi_ev_global_lock_handler(void *context)
* If we don't get it now, it will be marked pending and we will
* take another interrupt when it becomes free.
*/
ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired);
ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
if (acquired) {
/* Got the lock, now wake all threads waiting for it */
......@@ -342,6 +346,13 @@ acpi_status acpi_ev_init_global_lock_handler(void)
ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
status =
acpi_get_table(ACPI_SIG_FACS, 0,
(struct acpi_table_header **)&facs);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
acpi_gbl_global_lock_present = TRUE;
status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
acpi_ev_global_lock_handler,
......@@ -414,7 +425,7 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
/* Attempt to acquire the actual hardware lock */
ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired);
ACPI_ACQUIRE_GLOBAL_LOCK(facs, acquired);
if (acquired) {
/* We got the lock */
......@@ -438,6 +449,7 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
*/
status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
ACPI_WAIT_FOREVER);
return_ACPI_STATUS(status);
}
......@@ -472,8 +484,7 @@ acpi_status acpi_ev_release_global_lock(void)
/* Allow any thread to release the lock */
ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock,
pending);
ACPI_RELEASE_GLOBAL_LOCK(facs, pending);
/*
* If the pending bit was set, we must write GBL_RLS to the control
......
......@@ -142,9 +142,10 @@ u32 acpi_ev_install_sci_handler(void)
ACPI_FUNCTION_TRACE(ev_install_sci_handler);
status = acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT->sci_int,
acpi_ev_sci_xrupt_handler,
acpi_gbl_gpe_xrupt_list_head);
status =
acpi_os_install_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
acpi_ev_sci_xrupt_handler,
acpi_gbl_gpe_xrupt_list_head);
return_ACPI_STATUS(status);
}
......@@ -175,8 +176,9 @@ acpi_status acpi_ev_remove_sci_handler(void)
/* Just let the OS remove the handler and disable the level */
status = acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT->sci_int,
acpi_ev_sci_xrupt_handler);
status =
acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt,
acpi_ev_sci_xrupt_handler);
return_ACPI_STATUS(status);
}
......@@ -65,13 +65,6 @@ acpi_status acpi_enable(void)
ACPI_FUNCTION_TRACE(acpi_enable);
/* Make sure we have the FADT */
if (!acpi_gbl_FADT) {
ACPI_WARNING((AE_INFO, "No FADT information present!"));
return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
ACPI_DEBUG_PRINT((ACPI_DB_INIT,
"System is already in ACPI mode\n"));
......@@ -111,11 +104,6 @@ acpi_status acpi_disable(void)
ACPI_FUNCTION_TRACE(acpi_disable);
if (!acpi_gbl_FADT) {
ACPI_WARNING((AE_INFO, "No FADT information present!"));
return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
ACPI_DEBUG_PRINT((ACPI_DB_INIT,
"System is already in legacy (non-ACPI) mode\n"));
......
......@@ -54,7 +54,7 @@ ACPI_MODULE_NAME("exconfig")
/* Local prototypes */
static acpi_status
acpi_ex_add_table(struct acpi_table_header *table,
acpi_ex_add_table(acpi_native_uint table_index,
struct acpi_namespace_node *parent_node,
union acpi_operand_object **ddb_handle);
......@@ -74,12 +74,11 @@ acpi_ex_add_table(struct acpi_table_header *table,
******************************************************************************/
static acpi_status
acpi_ex_add_table(struct acpi_table_header *table,
acpi_ex_add_table(acpi_native_uint table_index,
struct acpi_namespace_node *parent_node,
union acpi_operand_object **ddb_handle)
{
acpi_status status;
struct acpi_table_desc table_info;
union acpi_operand_object *obj_desc;
ACPI_FUNCTION_TRACE(ex_add_table);
......@@ -98,42 +97,16 @@ acpi_ex_add_table(struct acpi_table_header *table,
/* Install the new table into the local data structures */
ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc));
table_info.type = ACPI_TABLE_ID_SSDT;
table_info.pointer = table;
table_info.length = (acpi_size) table->length;
table_info.allocation = ACPI_MEM_ALLOCATED;
status = acpi_tb_install_table(&table_info);
obj_desc->reference.object = table_info.installed_desc;
if (ACPI_FAILURE(status)) {
if (status == AE_ALREADY_EXISTS) {
/* Table already exists, just return the handle */
return_ACPI_STATUS(AE_OK);
}
goto cleanup;
}
obj_desc->reference.object = ACPI_CAST_PTR(void, table_index);
/* Add the table to the namespace */
status = acpi_ns_load_table(table_info.installed_desc, parent_node);
status = acpi_ns_load_table(table_index, parent_node);
if (ACPI_FAILURE(status)) {
/* Uninstall table on error */
(void)acpi_tb_uninstall_table(table_info.installed_desc);
goto cleanup;
acpi_ut_remove_reference(obj_desc);
*ddb_handle = NULL;
}
return_ACPI_STATUS(AE_OK);
cleanup:
acpi_ut_remove_reference(obj_desc);
*ddb_handle = NULL;
return_ACPI_STATUS(status);
}
......@@ -156,11 +129,12 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
{
acpi_status status;
union acpi_operand_object **operand = &walk_state->operands[0];
struct acpi_table_header *table;
acpi_native_uint table_index;
struct acpi_namespace_node *parent_node;
struct acpi_namespace_node *start_node;
struct acpi_namespace_node *parameter_node = NULL;
union acpi_operand_object *ddb_handle;
struct acpi_table_header *table;
ACPI_FUNCTION_TRACE(ex_load_table_op);
......@@ -182,7 +156,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
status = acpi_tb_find_table(operand[0]->string.pointer,
operand[1]->string.pointer,
operand[2]->string.pointer, &table);
operand[2]->string.pointer, &table_index);
if (ACPI_FAILURE(status)) {
if (status != AE_NOT_FOUND) {
return_ACPI_STATUS(status);
......@@ -245,7 +219,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
/* Load the table into the namespace */
status = acpi_ex_add_table(table, parent_node, &ddb_handle);
status = acpi_ex_add_table(table_index, parent_node, &ddb_handle);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
......@@ -266,9 +240,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
}
}
ACPI_INFO((AE_INFO,
"Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]",
table->signature, table->oem_id, table->oem_table_id));
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_SUCCESS(status)) {
ACPI_INFO((AE_INFO,
"Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]",
table->signature, table->oem_id,
table->oem_table_id));
}
*return_desc = ddb_handle;
return_ACPI_STATUS(status);
......@@ -298,6 +276,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
union acpi_operand_object *ddb_handle;
union acpi_operand_object *buffer_desc = NULL;
struct acpi_table_header *table_ptr = NULL;
acpi_native_uint table_index;
acpi_physical_address address;
struct acpi_table_header table_header;
acpi_integer temp;
......@@ -420,8 +399,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* The table must be either an SSDT or a PSDT */
if ((!ACPI_COMPARE_NAME(table_ptr->signature, PSDT_SIG)) &&
(!ACPI_COMPARE_NAME(table_ptr->signature, SSDT_SIG))) {
if ((!ACPI_COMPARE_NAME(table_ptr->signature, ACPI_SIG_PSDT)) &&
(!ACPI_COMPARE_NAME(table_ptr->signature, ACPI_SIG_SSDT))) {
ACPI_ERROR((AE_INFO,
"Table has invalid signature [%4.4s], must be SSDT or PSDT",
table_ptr->signature));
......@@ -429,9 +408,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
goto cleanup;
}
/* Install the new table into the local data structures */
/*
* Install the new table into the local data structures
*/
status = acpi_tb_add_table(table_ptr, &table_index);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle);
status =
acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle);
if (ACPI_FAILURE(status)) {
/* On error, table_ptr was deallocated above */
......@@ -477,7 +463,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
{
acpi_status status = AE_OK;
union acpi_operand_object *table_desc = ddb_handle;
struct acpi_table_desc *table_info;
acpi_native_uint table_index;
ACPI_FUNCTION_TRACE(ex_unload_table);
......@@ -493,19 +479,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Get the actual table descriptor from the ddb_handle */
/* Get the table index from the ddb_handle */
table_info = (struct acpi_table_desc *)table_desc->reference.object;
table_index = (acpi_native_uint) table_desc->reference.object;
/*
* Delete the entire namespace under this table Node
* (Offset contains the table_id)
*/
acpi_ns_delete_namespace_by_owner(table_info->owner_id);
/* Delete the table itself */
acpi_tb_delete_namespace_by_owner(table_index);
acpi_tb_release_owner_id(table_index);
(void)acpi_tb_uninstall_table(table_info->installed_desc);
acpi_tb_set_table_loaded_flag(table_index, FALSE);
/* Delete the table descriptor (ddb_handle) */
......
......@@ -359,8 +359,9 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
union acpi_operand_object **operand = &walk_state->operands[0];
union acpi_operand_object *obj_desc;
struct acpi_namespace_node *node;
struct acpi_table_header *table;
union acpi_operand_object *region_obj2;
acpi_native_uint table_index;
struct acpi_table_header *table;
ACPI_FUNCTION_TRACE(ex_create_table_region);
......@@ -380,7 +381,7 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
status = acpi_tb_find_table(operand[1]->string.pointer,
operand[2]->string.pointer,
operand[3]->string.pointer, &table);
operand[3]->string.pointer, &table_index);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
......@@ -395,6 +396,11 @@ acpi_status acpi_ex_create_table_region(struct acpi_walk_state *walk_state)
region_obj2 = obj_desc->common.next_object;
region_obj2->extra.region_context = NULL;
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Init the region from the operands */
obj_desc->region.space_id = REGION_DATA_TABLE;
......@@ -553,7 +559,8 @@ acpi_ex_create_method(u8 * aml_start,
obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
if (!obj_desc) {
return_ACPI_STATUS(AE_NO_MEMORY);
status = AE_NO_MEMORY;
goto exit;
}
/* Save the method's AML pointer and length */
......@@ -597,6 +604,7 @@ acpi_ex_create_method(u8 * aml_start,
acpi_ut_remove_reference(obj_desc);
exit:
/* Remove a reference to the operand */
acpi_ut_remove_reference(operand[1]);
......
......@@ -257,14 +257,13 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD,
" Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n",
" Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n",
acpi_ut_get_region_name(rgn_desc->region.
space_id),
rgn_desc->region.space_id,
obj_desc->common_field.access_byte_width,
obj_desc->common_field.base_byte_offset,
field_datum_byte_offset,
ACPI_FORMAT_UINT64(address)));
field_datum_byte_offset, (void *)address));
/* Invoke the appropriate address_space/op_region handler */
......
......@@ -155,16 +155,15 @@ acpi_ex_system_memory_space_handler(u32 function,
/* Create a new mapping starting at the address given */
status = acpi_os_map_memory(address, window_size,
(void **)&mem_info->
mapped_logical_address);
if (ACPI_FAILURE(status)) {
mem_info->mapped_logical_address =
acpi_os_map_memory((acpi_native_uint) address, window_size);
if (!mem_info->mapped_logical_address) {
ACPI_ERROR((AE_INFO,
"Could not map memory at %8.8X%8.8X, size %X",
ACPI_FORMAT_UINT64(address),
(u32) window_size));
mem_info->mapped_length = 0;
return_ACPI_STATUS(status);
return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Save the physical address and mapping size */
......
......@@ -65,13 +65,6 @@ acpi_status acpi_hw_initialize(void)
ACPI_FUNCTION_TRACE(hw_initialize);
/* We must have the ACPI tables by the time we get here */
if (!acpi_gbl_FADT) {
ACPI_ERROR((AE_INFO, "No FADT is present"));
return_ACPI_STATUS(AE_NO_ACPI_TABLES);
}
/* Sanity check the FADT for valid values */
status = acpi_ut_validate_fadt();
......@@ -106,7 +99,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
* ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
* system does not support mode transition.
*/
if (!acpi_gbl_FADT->smi_cmd) {
if (!acpi_gbl_FADT.smi_command) {
ACPI_ERROR((AE_INFO,
"No SMI_CMD in FADT, mode transition failed"));
return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
......@@ -119,7 +112,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
* we make sure both the numbers are zero to determine these
* transitions are not supported.
*/
if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) {
if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
ACPI_ERROR((AE_INFO,
"No ACPI mode transition supported in this system (enable/disable both zero)"));
return_ACPI_STATUS(AE_OK);
......@@ -130,9 +123,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
/* BIOS should have disabled ALL fixed and GP events */
status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd,
(u32) acpi_gbl_FADT->acpi_enable,
8);
status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.acpi_enable, 8);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Attempting to enable ACPI mode\n"));
break;
......@@ -143,8 +135,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
* BIOS should clear all fixed status bits and restore fixed event
* enable bits to default
*/
status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd,
(u32) acpi_gbl_FADT->acpi_disable,
status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.acpi_disable,
8);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Attempting to enable Legacy (non-ACPI) mode\n"));
......@@ -204,7 +196,7 @@ u32 acpi_hw_get_mode(void)
* ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
* system does not support mode transition.
*/
if (!acpi_gbl_FADT->smi_cmd) {
if (!acpi_gbl_FADT.smi_command) {
return_UINT32(ACPI_SYS_MODE_ACPI);
}
......
......@@ -73,7 +73,7 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags)
ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
ACPI_BITMASK_ALL_FIXED_STATUS,
(u16) acpi_gbl_FADT->xpm1a_evt_blk.address));
(u16) acpi_gbl_FADT.xpm1a_event_block.address));
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
......@@ -86,10 +86,10 @@ acpi_status acpi_hw_clear_acpi_status(u32 flags)
/* Clear the fixed events */
if (acpi_gbl_FADT->xpm1b_evt_blk.address) {
if (acpi_gbl_FADT.xpm1b_event_block.address) {
status =
acpi_hw_low_level_write(16, ACPI_BITMASK_ALL_FIXED_STATUS,
&acpi_gbl_FADT->xpm1b_evt_blk);
&acpi_gbl_FADT.xpm1b_event_block);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
......@@ -422,8 +422,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags)
ACPI_DEBUG_PRINT((ACPI_DB_IO,
"PM2 control: Read %X from %8.8X%8.8X\n",
register_value,
ACPI_FORMAT_UINT64(acpi_gbl_FADT->
xpm2_cnt_blk.address)));
ACPI_FORMAT_UINT64(acpi_gbl_FADT.
xpm2_control_block.
address)));
ACPI_REGISTER_INSERT_VALUE(register_value,
bit_reg_info->bit_position,
......@@ -433,8 +434,9 @@ acpi_status acpi_set_register(u32 register_id, u32 value, u32 flags)
ACPI_DEBUG_PRINT((ACPI_DB_IO,
"About to write %4.4X to %8.8X%8.8X\n",
register_value,
ACPI_FORMAT_UINT64(acpi_gbl_FADT->
xpm2_cnt_blk.address)));
ACPI_FORMAT_UINT64(acpi_gbl_FADT.
xpm2_control_block.
address)));
status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
ACPI_REGISTER_PM2_CONTROL,
......@@ -495,7 +497,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
status =
acpi_hw_low_level_read(16, &value1,
&acpi_gbl_FADT->xpm1a_evt_blk);
&acpi_gbl_FADT.xpm1a_event_block);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
......@@ -504,7 +506,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
status =
acpi_hw_low_level_read(16, &value2,
&acpi_gbl_FADT->xpm1b_evt_blk);
&acpi_gbl_FADT.xpm1b_event_block);
value1 |= value2;
break;
......@@ -527,14 +529,14 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
status =
acpi_hw_low_level_read(16, &value1,
&acpi_gbl_FADT->xpm1a_cnt_blk);
&acpi_gbl_FADT.xpm1a_control_block);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
status =
acpi_hw_low_level_read(16, &value2,
&acpi_gbl_FADT->xpm1b_cnt_blk);
&acpi_gbl_FADT.xpm1b_control_block);
value1 |= value2;
break;
......@@ -542,19 +544,20 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
status =
acpi_hw_low_level_read(8, &value1,
&acpi_gbl_FADT->xpm2_cnt_blk);
&acpi_gbl_FADT.xpm2_control_block);
break;
case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
status =
acpi_hw_low_level_read(32, &value1,
&acpi_gbl_FADT->xpm_tmr_blk);
&acpi_gbl_FADT.xpm_timer_block);
break;
case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
status = acpi_os_read_port(acpi_gbl_FADT->smi_cmd, &value1, 8);
status =
acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
break;
default:
......@@ -635,7 +638,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
status =
acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT->xpm1a_evt_blk);
&acpi_gbl_FADT.xpm1a_event_block);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
......@@ -644,7 +647,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
status =
acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT->xpm1b_evt_blk);
&acpi_gbl_FADT.xpm1b_event_block);
break;
case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
......@@ -682,49 +685,50 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
status =
acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT->xpm1a_cnt_blk);
&acpi_gbl_FADT.xpm1a_control_block);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
status =
acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT->xpm1b_cnt_blk);
&acpi_gbl_FADT.xpm1b_control_block);
break;
case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */
status =
acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT->xpm1a_cnt_blk);
&acpi_gbl_FADT.xpm1a_control_block);
break;
case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */
status =
acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT->xpm1b_cnt_blk);
&acpi_gbl_FADT.xpm1b_control_block);
break;
case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
status =
acpi_hw_low_level_write(8, value,
&acpi_gbl_FADT->xpm2_cnt_blk);
&acpi_gbl_FADT.xpm2_control_block);
break;
case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
status =
acpi_hw_low_level_write(32, value,
&acpi_gbl_FADT->xpm_tmr_blk);
&acpi_gbl_FADT.xpm_timer_block);
break;
case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
/* SMI_CMD is currently always in IO space */
status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd, value, 8);
status =
acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
break;
default:
......@@ -783,7 +787,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
* Two address spaces supported: Memory or IO.
* PCI_Config is not supported here because the GAS struct is insufficient
*/
switch (reg->address_space_id) {
switch (reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
status = acpi_os_read_memory((acpi_physical_address) address,
......@@ -798,8 +802,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
default:
ACPI_ERROR((AE_INFO,
"Unsupported address space: %X",
reg->address_space_id));
"Unsupported address space: %X", reg->space_id));
return (AE_BAD_PARAMETER);
}
......@@ -807,7 +810,7 @@ acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
"Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
*value, width,
ACPI_FORMAT_UINT64(address),
acpi_ut_get_region_name(reg->address_space_id)));
acpi_ut_get_region_name(reg->space_id)));
return (status);
}
......@@ -854,7 +857,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
* Two address spaces supported: Memory or IO.
* PCI_Config is not supported here because the GAS struct is insufficient
*/
switch (reg->address_space_id) {
switch (reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
status = acpi_os_write_memory((acpi_physical_address) address,
......@@ -869,8 +872,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
default:
ACPI_ERROR((AE_INFO,
"Unsupported address space: %X",
reg->address_space_id));
"Unsupported address space: %X", reg->space_id));
return (AE_BAD_PARAMETER);
}
......@@ -878,7 +880,7 @@ acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
"Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
value, width,
ACPI_FORMAT_UINT64(address),
acpi_ut_get_region_name(reg->address_space_id)));
acpi_ut_get_region_name(reg->space_id)));
return (status);
}
......@@ -43,6 +43,7 @@
*/
#include <acpi/acpi.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_HARDWARE
ACPI_MODULE_NAME("hwsleep")
......@@ -62,17 +63,32 @@ ACPI_MODULE_NAME("hwsleep")
acpi_status
acpi_set_firmware_waking_vector(acpi_physical_address physical_address)
{
struct acpi_table_facs *facs;
acpi_status status;
ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector);
/* Get the FACS */
status =
acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
(struct acpi_table_header **)&facs);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Set the vector */
if (acpi_gbl_common_fACS.vector_width == 32) {
*(ACPI_CAST_PTR
(u32, acpi_gbl_common_fACS.firmware_waking_vector))
= (u32) physical_address;
if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
/*
* ACPI 1.0 FACS or short table or optional X_ field is zero
*/
facs->firmware_waking_vector = (u32) physical_address;
} else {
*acpi_gbl_common_fACS.firmware_waking_vector = physical_address;
/*
* ACPI 2.0 FACS with valid X_ field
*/
facs->xfirmware_waking_vector = physical_address;
}
return_ACPI_STATUS(AE_OK);
......@@ -97,6 +113,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
acpi_status
acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
{
struct acpi_table_facs *facs;
acpi_status status;
ACPI_FUNCTION_TRACE(acpi_get_firmware_waking_vector);
......@@ -104,16 +122,29 @@ acpi_get_firmware_waking_vector(acpi_physical_address * physical_address)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Get the FACS */
status =
acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
(struct acpi_table_header **)&facs);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Get the vector */
if (acpi_gbl_common_fACS.vector_width == 32) {
*physical_address = (acpi_physical_address)
*
(ACPI_CAST_PTR
(u32, acpi_gbl_common_fACS.firmware_waking_vector));
if ((facs->length < 32) || (!(facs->xfirmware_waking_vector))) {
/*
* ACPI 1.0 FACS or short table or optional X_ field is zero
*/
*physical_address =
(acpi_physical_address) facs->firmware_waking_vector;
} else {
/*
* ACPI 2.0 FACS with valid X_ field
*/
*physical_address =
*acpi_gbl_common_fACS.firmware_waking_vector;
(acpi_physical_address) facs->xfirmware_waking_vector;
}
return_ACPI_STATUS(AE_OK);
......@@ -429,8 +460,8 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
ACPI_FLUSH_CPU_CACHE();
status = acpi_os_write_port(acpi_gbl_FADT->smi_cmd,
(u32) acpi_gbl_FADT->S4bios_req, 8);
status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.S4bios_request, 8);
do {
acpi_os_stall(1000);
......
......@@ -66,7 +66,7 @@ acpi_status acpi_get_timer_resolution(u32 * resolution)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
if (acpi_gbl_FADT->tmr_val_ext == 0) {
if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {
*resolution = 24;
} else {
*resolution = 32;
......@@ -98,7 +98,8 @@ acpi_status acpi_get_timer(u32 * ticks)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
status = acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT->xpm_tmr_blk);
status =
acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block);
return_ACPI_STATUS(status);
}
......@@ -153,7 +154,7 @@ acpi_get_timer_duration(u32 start_ticks, u32 end_ticks, u32 * time_elapsed)
if (start_ticks < end_ticks) {
delta_ticks = end_ticks - start_ticks;
} else if (start_ticks > end_ticks) {
if (acpi_gbl_FADT->tmr_val_ext == 0) {
if ((acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) == 0) {
/* 24-bit Timer */
......
......@@ -44,13 +44,12 @@
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acdispat.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nsload")
/* Local prototypes */
static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type);
#ifdef ACPI_FUTURE_IMPLEMENTATION
acpi_status acpi_ns_unload_namespace(acpi_handle handle);
......@@ -62,7 +61,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
*
* FUNCTION: acpi_ns_load_table
*
* PARAMETERS: table_desc - Descriptor for table to be loaded
* PARAMETERS: table_index - Index for table to be loaded
* Node - Owning NS node
*
* RETURN: Status
......@@ -72,42 +71,13 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle);
******************************************************************************/
acpi_status
acpi_ns_load_table(struct acpi_table_desc *table_desc,
acpi_ns_load_table(acpi_native_uint table_index,
struct acpi_namespace_node *node)
{
acpi_status status;
ACPI_FUNCTION_TRACE(ns_load_table);
/* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */
if (!
(acpi_gbl_table_data[table_desc->type].
flags & ACPI_TABLE_EXECUTABLE)) {
/* Just ignore this table */
return_ACPI_STATUS(AE_OK);
}
/* Check validity of the AML start and length */
if (!table_desc->aml_start) {
ACPI_ERROR((AE_INFO, "Null AML pointer"));
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "AML block at %p\n",
table_desc->aml_start));
/* Ignore table if there is no AML contained within */
if (!table_desc->aml_length) {
ACPI_WARNING((AE_INFO, "Zero-length AML block in table [%4.4s]",
table_desc->pointer->signature));
return_ACPI_STATUS(AE_OK);
}
/*
* Parse the table and load the namespace with all named
* objects found within. Control methods are NOT parsed
......@@ -117,15 +87,34 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc,
* to another control method, we can't continue parsing
* because we don't know how many arguments to parse next!
*/
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* If table already loaded into namespace, just return */
if (acpi_tb_is_table_loaded(table_index)) {
status = AE_ALREADY_EXISTS;
goto unlock;
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"**** Loading table into namespace ****\n"));
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
status = acpi_tb_allocate_owner_id(table_index);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
goto unlock;
}
status = acpi_ns_parse_table(table_index, node->child);
if (ACPI_SUCCESS(status)) {
acpi_tb_set_table_loaded_flag(table_index, TRUE);
} else {
acpi_tb_release_owner_id(table_index);
}
status = acpi_ns_parse_table(table_desc, node->child);
unlock:
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
......@@ -141,7 +130,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc,
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"**** Begin Table Method Parsing and Object Initialization ****\n"));
status = acpi_ds_initialize_objects(table_desc, node);
status = acpi_ds_initialize_objects(table_index, node);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"**** Completed Table Method Parsing and Object Initialization ****\n"));
......@@ -149,99 +138,7 @@ acpi_ns_load_table(struct acpi_table_desc *table_desc,
return_ACPI_STATUS(status);
}
/*******************************************************************************
*
* FUNCTION: acpi_ns_load_table_by_type
*
* PARAMETERS: table_type - Id of the table type to load
*
* RETURN: Status
*
* DESCRIPTION: Load an ACPI table or tables into the namespace. All tables
* of the given type are loaded. The mechanism allows this
* routine to be called repeatedly.
*
******************************************************************************/
static acpi_status acpi_ns_load_table_by_type(acpi_table_type table_type)
{
u32 i;
acpi_status status;
struct acpi_table_desc *table_desc;
ACPI_FUNCTION_TRACE(ns_load_table_by_type);
status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/*
* Table types supported are:
* DSDT (one), SSDT/PSDT (multiple)
*/
switch (table_type) {
case ACPI_TABLE_ID_DSDT:
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace load: DSDT\n"));
table_desc = acpi_gbl_table_lists[ACPI_TABLE_ID_DSDT].next;
/* If table already loaded into namespace, just return */
if (table_desc->loaded_into_namespace) {
goto unlock_and_exit;
}
/* Now load the single DSDT */
status = acpi_ns_load_table(table_desc, acpi_gbl_root_node);
if (ACPI_SUCCESS(status)) {
table_desc->loaded_into_namespace = TRUE;
}
break;
case ACPI_TABLE_ID_SSDT:
case ACPI_TABLE_ID_PSDT:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Namespace load: %d SSDT or PSDTs\n",
acpi_gbl_table_lists[table_type].count));
/*
* Traverse list of SSDT or PSDT tables
*/
table_desc = acpi_gbl_table_lists[table_type].next;
for (i = 0; i < acpi_gbl_table_lists[table_type].count; i++) {
/*
* Only attempt to load table into namespace if it is not
* already loaded!
*/
if (!table_desc->loaded_into_namespace) {
status =
acpi_ns_load_table(table_desc,
acpi_gbl_root_node);
if (ACPI_FAILURE(status)) {
break;
}
table_desc->loaded_into_namespace = TRUE;
}
table_desc = table_desc->next;
}
break;
default:
status = AE_SUPPORT;
break;
}
unlock_and_exit:
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
return_ACPI_STATUS(status);
}
#ifdef ACPI_OBSOLETE_FUNCTIONS
/*******************************************************************************
*
* FUNCTION: acpi_load_namespace
......@@ -288,6 +185,7 @@ acpi_status acpi_ns_load_namespace(void)
return_ACPI_STATUS(status);
}
#endif
#ifdef ACPI_FUTURE_IMPLEMENTATION
/*******************************************************************************
......
......@@ -45,6 +45,7 @@
#include <acpi/acnamesp.h>
#include <acpi/acparser.h>
#include <acpi/acdispat.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nsparse")
......@@ -62,14 +63,24 @@ ACPI_MODULE_NAME("nsparse")
*
******************************************************************************/
acpi_status
acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc)
acpi_ns_one_complete_parse(acpi_native_uint pass_number,
acpi_native_uint table_index)
{
union acpi_parse_object *parse_root;
acpi_status status;
acpi_native_uint aml_length;
u8 *aml_start;
struct acpi_walk_state *walk_state;
struct acpi_table_header *table;
acpi_owner_id owner_id;
ACPI_FUNCTION_TRACE(ns_one_complete_parse);
status = acpi_tb_get_owner_id(table_index, &owner_id);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Create and init a Root Node */
parse_root = acpi_ps_create_scope_op();
......@@ -79,19 +90,34 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc)
/* Create and initialize a new walk state */
walk_state = acpi_ds_create_walk_state(table_desc->owner_id,
NULL, NULL, NULL);
walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL);
if (!walk_state) {
acpi_ps_free_op(parse_root);
return_ACPI_STATUS(AE_NO_MEMORY);
}
status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
table_desc->aml_start,
table_desc->aml_length, NULL,
pass_number);
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_FAILURE(status)) {
acpi_ds_delete_walk_state(walk_state);
acpi_ps_free_op(parse_root);
return_ACPI_STATUS(status);
}
/* Table must consist of at least a complete header */
if (table->length < sizeof(struct acpi_table_header)) {
status = AE_BAD_HEADER;
} else {
aml_start = (u8 *) table + sizeof(struct acpi_table_header);
aml_length = table->length - sizeof(struct acpi_table_header);
status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
aml_start, aml_length, NULL,
(u8) pass_number);
}
if (ACPI_FAILURE(status)) {
acpi_ds_delete_walk_state(walk_state);
acpi_ps_delete_parse_tree(parse_root);
return_ACPI_STATUS(status);
}
......@@ -119,7 +145,7 @@ acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc)
******************************************************************************/
acpi_status
acpi_ns_parse_table(struct acpi_table_desc *table_desc,
acpi_ns_parse_table(acpi_native_uint table_index,
struct acpi_namespace_node *start_node)
{
acpi_status status;
......@@ -137,7 +163,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc,
* performs another complete parse of the AML..
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
status = acpi_ns_one_complete_parse(1, table_desc);
status = acpi_ns_one_complete_parse(1, table_index);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
......@@ -152,7 +178,7 @@ acpi_ns_parse_table(struct acpi_table_desc *table_desc,
* parse objects are all cached.
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
status = acpi_ns_one_complete_parse(2, table_desc);
status = acpi_ns_one_complete_parse(2, table_index);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
......
......@@ -770,13 +770,6 @@ void acpi_ns_terminate(void)
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n"));
/*
* 2) Now we can delete the ACPI tables
*/
acpi_tb_delete_all_tables();
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n"));
return_VOID;
}
......
This diff is collapsed.
/******************************************************************************
*
* Module Name: tbfind - find table
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2006, R. Byron Moore
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include <acpi/acpi.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME("tbfind")
/*******************************************************************************
*
* FUNCTION: acpi_tb_find_table
*
* PARAMETERS: Signature - String with ACPI table signature
* oem_id - String with the table OEM ID
* oem_table_id - String with the OEM Table ID
* table_index - Where the table index is returned
*
* RETURN: Status and table index
*
* DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
* Signature, OEM ID and OEM Table ID. Returns an index that can
* be used to get the table header or entire table.
*
******************************************************************************/
acpi_status
acpi_tb_find_table(char *signature,
char *oem_id,
char *oem_table_id, acpi_native_uint * table_index)
{
acpi_native_uint i;
acpi_status status;
ACPI_FUNCTION_TRACE(tb_find_table);
for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
if (ACPI_MEMCMP(&(acpi_gbl_root_table_list.tables[i].signature),
signature, ACPI_NAME_SIZE)) {
/* Not the requested table */
continue;
}
/* Table with matching signature has been found */
if (!acpi_gbl_root_table_list.tables[i].pointer) {
/* Table is not currently mapped, map it */
status =
acpi_tb_verify_table(&acpi_gbl_root_table_list.
tables[i]);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
if (!acpi_gbl_root_table_list.tables[i].pointer) {
continue;
}
}
/* Check for table match on all IDs */
if (!ACPI_MEMCMP
(acpi_gbl_root_table_list.tables[i].pointer->signature,
signature, ACPI_NAME_SIZE) && (!oem_id[0]
||
!ACPI_MEMCMP
(acpi_gbl_root_table_list.
tables[i].pointer->oem_id,
oem_id, ACPI_OEM_ID_SIZE))
&& (!oem_table_id[0]
|| !ACPI_MEMCMP(acpi_gbl_root_table_list.tables[i].
pointer->oem_table_id, oem_table_id,
ACPI_OEM_TABLE_ID_SIZE))) {
*table_index = i;
ACPI_DEBUG_PRINT((ACPI_DB_TABLES,
"Found table [%4.4s]\n", signature));
return_ACPI_STATUS(AE_OK);
}
}
return_ACPI_STATUS(AE_NOT_FOUND);
}
This diff is collapsed.
/******************************************************************************
*
* Module Name: tbgetall - Get all required ACPI tables
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2006, R. Byron Moore
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include <acpi/acpi.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME("tbgetall")
/* Local prototypes */
static acpi_status
acpi_tb_get_primary_table(struct acpi_pointer *address,
struct acpi_table_desc *table_info);
static acpi_status
acpi_tb_get_secondary_table(struct acpi_pointer *address,
acpi_string signature,
struct acpi_table_desc *table_info);
/*******************************************************************************
*
* 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
*
******************************************************************************/
static acpi_status
acpi_tb_get_primary_table(struct acpi_pointer *address,
struct acpi_table_desc *table_info)
{
acpi_status status;
struct 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(struct 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
*
******************************************************************************/
static acpi_status
acpi_tb_get_secondary_table(struct acpi_pointer *address,
acpi_string signature,
struct acpi_table_desc *table_info)
{
acpi_status status;
struct 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_COMPARE_NAME(header.signature, signature)) {
ACPI_ERROR((AE_INFO,
"Incorrect table signature - wanted [%s] found [%4.4s]",
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;
struct acpi_table_desc table_info;
struct 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 address from the common internal XSDT */
address.pointer.value = 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.
*/
status = acpi_tb_get_primary_table(&address, &table_info);
if ((status != AE_OK) && (status != AE_TABLE_NOT_SUPPORTED)) {
ACPI_WARNING((AE_INFO,
"%s, while getting table at %8.8X%8.8X",
acpi_format_exception(status),
ACPI_FORMAT_UINT64(address.pointer.
value)));
}
}
/* We must have a FADT to continue */
if (!acpi_gbl_FADT) {
ACPI_ERROR((AE_INFO, "No FADT present in RSDT/XSDT"));
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_ERROR((AE_INFO,
"Could not convert FADT to internal common format"));
return_ACPI_STATUS(status);
}
/* Get the FACS (Pointed to by the FADT) */
address.pointer.value = acpi_gbl_FADT->xfirmware_ctrl;
status = acpi_tb_get_secondary_table(&address, FACS_SIG, &table_info);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not get/install the FACS"));
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_gbl_FADT->Xdsdt;
status = acpi_tb_get_secondary_table(&address, DSDT_SIG, &table_info);
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO, "Could not get/install the DSDT"));
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(ACPI_CAST_PTR(u8, acpi_gbl_DSDT),
acpi_gbl_DSDT->length);
/* Always delete the RSDP mapping, we are done with it */
acpi_tb_delete_tables_by_type(ACPI_TABLE_ID_RSDP);
return_ACPI_STATUS(status);
}
This diff is collapsed.
/******************************************************************************
*
* Module Name: tbrsdt - ACPI RSDT table utilities
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2006, R. Byron Moore
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include <acpi/acpi.h>
#include <acpi/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(struct acpi_pointer *address)
{
struct acpi_table_desc table_info;
acpi_status status;
struct 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(struct rsdp_descriptor),
ACPI_CAST_PTR(void, &rsdp));
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
break;
default:
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
/* Verify RSDP signature and checksum */
status = acpi_tb_validate_rsdp(rsdp);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* RSDP is ok. Init the table info */
table_info.pointer = ACPI_CAST_PTR(struct acpi_table_header, rsdp);
table_info.length = sizeof(struct rsdp_descriptor);
if (address->pointer_type == ACPI_PHYSICAL_POINTER) {
table_info.allocation = ACPI_MEM_MAPPED;
} else {
table_info.allocation = ACPI_MEM_NOT_ALLOCATED;
}
/* Save the table pointers and allocation info */
status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_RSDP, &table_info);
if (ACPI_FAILURE(status)) {
goto cleanup;
}
/* Save the RSDP in a global for easy access */
acpi_gbl_RSDP =
ACPI_CAST_PTR(struct 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(struct rsdp_descriptor));
}
return_ACPI_STATUS(status);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_get_rsdt_address
*
* PARAMETERS: out_address - Where the address is returned
*
* RETURN: None, Address
*
* DESCRIPTION: Extract the address of either the RSDT or XSDT, depending on the
* version of the RSDP and whether the XSDT pointer is valid
*
******************************************************************************/
void acpi_tb_get_rsdt_address(struct acpi_pointer *out_address)
{
ACPI_FUNCTION_ENTRY();
out_address->pointer_type =
acpi_gbl_table_flags | ACPI_LOGICAL_ADDRESSING;
/* Use XSDT if it is present */
if ((acpi_gbl_RSDP->revision >= 2) &&
acpi_gbl_RSDP->xsdt_physical_address) {
out_address->pointer.value =
acpi_gbl_RSDP->xsdt_physical_address;
acpi_gbl_root_table_type = ACPI_TABLE_TYPE_XSDT;
} else {
/* No XSDT, use the RSDT */
out_address->pointer.value =
acpi_gbl_RSDP->rsdt_physical_address;
acpi_gbl_root_table_type = ACPI_TABLE_TYPE_RSDT;
}
}
/*******************************************************************************
*
* 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(struct acpi_table_header *table_ptr)
{
char *signature;
ACPI_FUNCTION_ENTRY();
/* Validate minimum length */
if (table_ptr->length < sizeof(struct acpi_table_header)) {
ACPI_ERROR((AE_INFO,
"RSDT/XSDT length (%X) is smaller than minimum (%zX)",
table_ptr->length,
sizeof(struct acpi_table_header)));
return (AE_INVALID_TABLE_LENGTH);
}
/* Search for appropriate signature, RSDT or XSDT */
if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
signature = RSDT_SIG;
} else {
signature = XSDT_SIG;
}
if (!ACPI_COMPARE_NAME(table_ptr->signature, signature)) {
/* Invalid RSDT or XSDT signature */
ACPI_ERROR((AE_INFO,
"Invalid signature where RSDP indicates RSDT/XSDT should be located. RSDP:"));
ACPI_DUMP_BUFFER(acpi_gbl_RSDP, 20);
ACPI_ERROR((AE_INFO,
"RSDT/XSDT signature at %X is invalid",
acpi_gbl_RSDP->rsdt_physical_address));
if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
ACPI_ERROR((AE_INFO, "Looking for RSDT"));
} else {
ACPI_ERROR((AE_INFO, "Looking for XSDT"));
}
ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48);
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)
{
struct acpi_table_desc table_info;
acpi_status status;
struct acpi_pointer address;
ACPI_FUNCTION_TRACE(tb_get_table_rsdt);
/* Get the RSDT/XSDT via the RSDP */
acpi_tb_get_rsdt_address(&address);
table_info.type = ACPI_TABLE_ID_XSDT;
status = acpi_tb_get_table(&address, &table_info);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not get the RSDT/XSDT"));
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_FORMAT_UINT64(address.pointer.value)));
/* Check the RSDT or XSDT signature */
status = acpi_tb_validate_rsdt(table_info.pointer);
if (ACPI_FAILURE(status)) {
goto error_cleanup;
}
/* 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)) {
goto error_cleanup;
}
/* Save the table pointers and allocation info */
status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info);
if (ACPI_FAILURE(status)) {
goto error_cleanup;
}
acpi_gbl_XSDT =
ACPI_CAST_PTR(struct xsdt_descriptor, table_info.pointer);
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
return_ACPI_STATUS(status);
error_cleanup:
/* Free table allocated by acpi_tb_get_table */
acpi_tb_delete_single_table(&table_info);
return_ACPI_STATUS(status);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -46,8 +46,9 @@
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
ACPI_EXPORT_SYMBOL(acpi_gbl_FADT)
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME("utglobal")
ACPI_MODULE_NAME("utglobal")
/*******************************************************************************
*
......@@ -280,53 +281,6 @@ char acpi_ut_hex_to_ascii_char(acpi_integer integer, u32 position)
return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
}
/*******************************************************************************
*
* Table name globals
*
* NOTE: This table includes ONLY the ACPI tables that the subsystem consumes.
* it is NOT an exhaustive list of all possible ACPI tables. All ACPI tables
* that are not used by the subsystem are simply ignored.
*
* Do NOT add any table to this list that is not consumed directly by this
* subsystem (No MADT, ECDT, SBST, etc.)
*
******************************************************************************/
struct acpi_table_list acpi_gbl_table_lists[ACPI_TABLE_ID_MAX + 1];
struct acpi_table_support acpi_gbl_table_data[ACPI_TABLE_ID_MAX + 1] = {
/*********** 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}
,
};
/******************************************************************************
*
* Event and Hardware globals
......@@ -751,13 +705,6 @@ void acpi_ut_init_globals(void)
return;
}
/* ACPI table structure */
for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) {
acpi_gbl_table_lists[i].next = NULL;
acpi_gbl_table_lists[i].count = 0;
}
/* Mutex locked flags */
for (i = 0; i < ACPI_NUM_MUTEX; i++) {
......@@ -784,14 +731,6 @@ void acpi_ut_init_globals(void)
acpi_gbl_exception_handler = NULL;
acpi_gbl_init_handler = NULL;
/* Global "typed" ACPI table pointers */
acpi_gbl_RSDP = NULL;
acpi_gbl_XSDT = NULL;
acpi_gbl_FACS = NULL;
acpi_gbl_FADT = NULL;
acpi_gbl_DSDT = NULL;
/* Global Lock support */
acpi_gbl_global_lock_semaphore = NULL;
......@@ -801,8 +740,6 @@ void acpi_ut_init_globals(void)
/* Miscellaneous variables */
acpi_gbl_table_flags = ACPI_PHYSICAL_POINTER;
acpi_gbl_rsdp_original_location = 0;
acpi_gbl_cm_single_step = FALSE;
acpi_gbl_db_terminate_threads = FALSE;
acpi_gbl_shutdown = FALSE;
......
......@@ -44,6 +44,7 @@
#include <acpi/acpi.h>
#include <acpi/acnamesp.h>
#include <acpi/acevents.h>
#include <acpi/actables.h>
#define _COMPONENT ACPI_UTILITIES
ACPI_MODULE_NAME("utinit")
......@@ -73,8 +74,8 @@ acpi_ut_fadt_register_error(char *register_name, u32 value, u8 offset)
{
ACPI_WARNING((AE_INFO,
"Invalid FADT value %s=%X at offset %X FADT=%p",
register_name, value, offset, acpi_gbl_FADT));
"Invalid FADT value %s=%X at offset %X in FADT=%p",
register_name, value, offset, &acpi_gbl_FADT));
}
/******************************************************************************
......@@ -96,62 +97,70 @@ acpi_status acpi_ut_validate_fadt(void)
* Verify Fixed ACPI Description Table fields,
* but don't abort on any problems, just display error
*/
if (acpi_gbl_FADT->pm1_evt_len < 4) {
if (acpi_gbl_FADT.pm1_event_length < 4) {
acpi_ut_fadt_register_error("PM1_EVT_LEN",
(u32) acpi_gbl_FADT->pm1_evt_len,
ACPI_FADT_OFFSET(pm1_evt_len));
(u32) acpi_gbl_FADT.
pm1_event_length,
ACPI_FADT_OFFSET(pm1_event_length));
}
if (!acpi_gbl_FADT->pm1_cnt_len) {
if (!acpi_gbl_FADT.pm1_control_length) {
acpi_ut_fadt_register_error("PM1_CNT_LEN", 0,
ACPI_FADT_OFFSET(pm1_cnt_len));
ACPI_FADT_OFFSET
(pm1_control_length));
}
if (!acpi_gbl_FADT->xpm1a_evt_blk.address) {
if (!acpi_gbl_FADT.xpm1a_event_block.address) {
acpi_ut_fadt_register_error("X_PM1a_EVT_BLK", 0,
ACPI_FADT_OFFSET(xpm1a_evt_blk.
ACPI_FADT_OFFSET(xpm1a_event_block.
address));
}
if (!acpi_gbl_FADT->xpm1a_cnt_blk.address) {
if (!acpi_gbl_FADT.xpm1a_control_block.address) {
acpi_ut_fadt_register_error("X_PM1a_CNT_BLK", 0,
ACPI_FADT_OFFSET(xpm1a_cnt_blk.
address));
ACPI_FADT_OFFSET
(xpm1a_control_block.address));
}
if (!acpi_gbl_FADT->xpm_tmr_blk.address) {
if (!acpi_gbl_FADT.xpm_timer_block.address) {
acpi_ut_fadt_register_error("X_PM_TMR_BLK", 0,
ACPI_FADT_OFFSET(xpm_tmr_blk.
ACPI_FADT_OFFSET(xpm_timer_block.
address));
}
if ((acpi_gbl_FADT->xpm2_cnt_blk.address &&
!acpi_gbl_FADT->pm2_cnt_len)) {
if ((acpi_gbl_FADT.xpm2_control_block.address &&
!acpi_gbl_FADT.pm2_control_length)) {
acpi_ut_fadt_register_error("PM2_CNT_LEN",
(u32) acpi_gbl_FADT->pm2_cnt_len,
ACPI_FADT_OFFSET(pm2_cnt_len));
(u32) acpi_gbl_FADT.
pm2_control_length,
ACPI_FADT_OFFSET
(pm2_control_length));
}
if (acpi_gbl_FADT->pm_tm_len < 4) {
if (acpi_gbl_FADT.pm_timer_length < 4) {
acpi_ut_fadt_register_error("PM_TM_LEN",
(u32) acpi_gbl_FADT->pm_tm_len,
ACPI_FADT_OFFSET(pm_tm_len));
(u32) acpi_gbl_FADT.pm_timer_length,
ACPI_FADT_OFFSET(pm_timer_length));
}
/* Length of GPE blocks must be a multiple of 2 */
if (acpi_gbl_FADT->xgpe0_blk.address &&
(acpi_gbl_FADT->gpe0_blk_len & 1)) {
if (acpi_gbl_FADT.xgpe0_block.address &&
(acpi_gbl_FADT.gpe0_block_length & 1)) {
acpi_ut_fadt_register_error("(x)GPE0_BLK_LEN",
(u32) acpi_gbl_FADT->gpe0_blk_len,
ACPI_FADT_OFFSET(gpe0_blk_len));
(u32) acpi_gbl_FADT.
gpe0_block_length,
ACPI_FADT_OFFSET
(gpe0_block_length));
}
if (acpi_gbl_FADT->xgpe1_blk.address &&
(acpi_gbl_FADT->gpe1_blk_len & 1)) {
if (acpi_gbl_FADT.xgpe1_block.address &&
(acpi_gbl_FADT.gpe1_block_length & 1)) {
acpi_ut_fadt_register_error("(x)GPE1_BLK_LEN",
(u32) acpi_gbl_FADT->gpe1_blk_len,
ACPI_FADT_OFFSET(gpe1_blk_len));
(u32) acpi_gbl_FADT.
gpe1_block_length,
ACPI_FADT_OFFSET
(gpe1_block_length));
}
return (AE_OK);
......@@ -178,7 +187,6 @@ static void acpi_ut_terminate(void)
ACPI_FUNCTION_TRACE(ut_terminate);
/* Free global tables, etc. */
/* Free global GPE blocks and related info structures */
gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
......@@ -239,6 +247,10 @@ void acpi_ut_subsystem_shutdown(void)
acpi_ns_terminate();
/* Delete the ACPI tables */
acpi_tb_terminate();
/* Close the globals */
acpi_ut_terminate();
......
......@@ -67,9 +67,9 @@ u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
/* These are the only tables that contain executable AML */
if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) ||
ACPI_COMPARE_NAME(table->signature, PSDT_SIG) ||
ACPI_COMPARE_NAME(table->signature, SSDT_SIG)) {
if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) ||
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) ||
ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) {
return (TRUE);
}
......@@ -418,7 +418,7 @@ u32 acpi_ut_dword_byte_swap(u32 value)
void acpi_ut_set_integer_width(u8 revision)
{
if (revision <= 1) {
if (revision < 2) {
/* 32-bit case */
......
......@@ -398,7 +398,6 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
{
struct acpi_system_info *info_ptr;
acpi_status status;
u32 i;
ACPI_FUNCTION_TRACE(acpi_get_system_info);
......@@ -431,9 +430,7 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
/* Timer resolution - 24 or 32 bits */
if (!acpi_gbl_FADT) {
info_ptr->timer_resolution = 0;
} else if (acpi_gbl_FADT->tmr_val_ext == 0) {
if (acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) {
info_ptr->timer_resolution = 24;
} else {
info_ptr->timer_resolution = 32;
......@@ -449,13 +446,6 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer)
info_ptr->debug_layer = acpi_dbg_layer;
info_ptr->debug_level = acpi_dbg_level;
/* Current status of the ACPI tables, per table type */
info_ptr->num_table_types = ACPI_TABLE_ID_MAX + 1;
for (i = 0; i < (ACPI_TABLE_ID_MAX + 1); i++) {
info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count;
}
return_ACPI_STATUS(AE_OK);
}
......
......@@ -63,7 +63,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20060721
#define ACPI_CA_VERSION 0x20060823
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
......@@ -115,6 +115,10 @@
#define ACPI_NUM_OWNERID_MASKS 8
/* Size of the root table array is increased by this increment */
#define ACPI_ROOT_TABLE_SIZE_INCREMENT 4
/******************************************************************************
*
* ACPI Specification constants (Do not change unless the specification changes)
......@@ -152,6 +156,11 @@
#define ACPI_PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */
#define ACPI_PATH_SEPARATOR '.'
/* Sizes for ACPI table headers */
#define ACPI_OEM_ID_SIZE 6
#define ACPI_OEM_TABLE_ID_SIZE 8
/* Constants used in searching for the RSDP in low memory */
#define ACPI_EBDA_PTR_LOCATION 0x0000040E /* Physical Address */
......
......@@ -210,7 +210,7 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state);
* dsinit
*/
acpi_status
acpi_ds_initialize_objects(struct acpi_table_desc *table_desc,
acpi_ds_initialize_objects(acpi_native_uint table_index,
struct acpi_namespace_node *start_node);
/*
......
This diff is collapsed.
This diff is collapsed.
......@@ -82,7 +82,7 @@ acpi_status acpi_ns_initialize_devices(void);
acpi_status acpi_ns_load_namespace(void);
acpi_status
acpi_ns_load_table(struct acpi_table_desc *table_desc,
acpi_ns_load_table(acpi_native_uint table_index,
struct acpi_namespace_node *node);
/*
......@@ -106,11 +106,12 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type,
* nsparse - table parsing
*/
acpi_status
acpi_ns_parse_table(struct acpi_table_desc *table_desc,
struct acpi_namespace_node *scope);
acpi_ns_parse_table(acpi_native_uint table_index,
struct acpi_namespace_node *start_node);
acpi_status
acpi_ns_one_complete_parse(u8 pass_number, struct acpi_table_desc *table_desc);
acpi_ns_one_complete_parse(acpi_native_uint pass_number,
acpi_native_uint table_index);
/*
* nsaccess - Top-level namespace access
......
This diff is collapsed.
This diff is collapsed.
......@@ -139,7 +139,8 @@ struct acpi_init_walk_info {
u16 buffer_init;
u16 package_init;
u16 object_count;
struct acpi_table_desc *table_desc;
acpi_owner_id owner_id;
acpi_native_uint table_index;
};
struct acpi_get_devices_info {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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