/******************************************************************************* * * FUNCTION: acpi_set_firmware_waking_vector * * PARAMETERS: physical_address - Physical address of ACPI real mode * entry point. * * RETURN: Status * * DESCRIPTION: Access function for the firmware_waking_vector field in FACS * ******************************************************************************/ 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 ((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 2.0 FACS with valid X_ field */ facs->xfirmware_waking_vector = physical_address; } return_ACPI_STATUS(AE_OK); }
acpi_status acpi_ev_init_global_lock_handler(void) { acpi_status status; ACPI_FUNCTION_TRACE(ev_init_global_lock_handler); status = acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS, (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, NULL); /* * If the global lock does not exist on this platform, the attempt * to enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick) * Map to AE_OK, but mark global lock as not present. * Any attempt to actually use the global lock will be flagged * with an error. */ if (status == AE_NO_HARDWARE_RESPONSE) { ACPI_ERROR((AE_INFO, "No response from Global Lock hardware, disabling lock")); acpi_gbl_global_lock_present = FALSE; status = AE_OK; } return_ACPI_STATUS(status); }
acpi_status 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:")); info.method_count = 0; info.op_region_count = 0; info.object_count = 0; info.device_count = 0; info.table_index = table_index; info.owner_id = owner_id; /* Walk entire namespace from the supplied root */ status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, acpi_ds_init_one_object, &info, NULL); if (ACPI_FAILURE(status)) { 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->signature, owner_id, info.object_count, info.device_count, info.method_count, info.op_region_count)); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%hd Methods, %hd Regions\n", info.method_count, info.op_region_count)); return_ACPI_STATUS(AE_OK); }
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; u32 table_index; struct acpi_table_header *table; ACPI_FUNCTION_TRACE(ex_unload_table); /* * Validate the handle * Although the handle is partially validated in acpi_ex_reconfiguration(), * when it calls acpi_ex_resolve_operands(), the handle is more completely * validated here. */ if ((!ddb_handle) || (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Get the table index from the ddb_handle (acpi_size for 64-bit case) */ table_index = (u32) (acpi_size) table_desc->reference.object; /* Invoke table handler if present */ if (acpi_gbl_table_handler) { status = acpi_get_table_by_index(table_index, &table); if (ACPI_SUCCESS(status)) { (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD, table, acpi_gbl_table_handler_context); } } /* * Delete the entire namespace under this table Node * (Offset contains the table_id) */ acpi_tb_delete_namespace_by_owner(table_index); (void)acpi_tb_release_owner_id(table_index); acpi_tb_set_table_loaded_flag(table_index, FALSE); /* Table unloaded, remove a reference to the ddb_handle object */ acpi_ut_remove_reference(ddb_handle); return_ACPI_STATUS(AE_OK); }
acpi_status acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) { struct acpi_table_header *table; acpi_status status; acpi_owner_id owner_id; ACPI_FUNCTION_TRACE(tb_load_table); /* * Note: Now table is "INSTALLED", it must be validated before * using. */ status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } status = acpi_ns_load_table(table_index, parent_node); /* * This case handles the legacy option that groups all module-level * code blocks together and defers execution until all of the tables * are loaded. Execute all of these blocks at this time. * Execute any module-level code that was detected during the table * load phase. * * Note: this option is deprecated and will be eliminated in the * future. Use of this option can cause problems with AML code that * depends upon in-order immediate execution of module-level code. */ acpi_ns_exec_module_code_list(); /* * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is * responsible for discovering any new wake GPEs by running _PRW methods * that may have been loaded by this table. */ status = acpi_tb_get_owner_id(table_index, &owner_id); if (ACPI_SUCCESS(status)) { acpi_ev_update_gpes(owner_id); } /* Invoke table handler */ acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table); return_ACPI_STATUS(status); }
acpi_status acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) { struct acpi_table_header *table; acpi_status status; acpi_owner_id owner_id; ACPI_FUNCTION_TRACE(tb_load_table); /* * Note: Now table is "INSTALLED", it must be validated before * using. */ status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } status = acpi_ns_load_table(table_index, parent_node); /* Execute any module-level code that was found in the table */ if (!acpi_gbl_parse_table_as_term_list && acpi_gbl_group_module_level_code) { acpi_ns_exec_module_code_list(); } /* * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is * responsible for discovering any new wake GPEs by running _PRW methods * that may have been loaded by this table. */ status = acpi_tb_get_owner_id(table_index, &owner_id); if (ACPI_SUCCESS(status)) { acpi_ev_update_gpes(owner_id); } /* Invoke table handler if present */ if (acpi_gbl_table_handler) { (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, acpi_gbl_table_handler_context); } return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: ns_one_complete_parse * * PARAMETERS: pass_number - 1 or 2 * table_desc - The table to be parsed. * * RETURN: Status * * DESCRIPTION: Perform one complete parse of an ACPI/AML table. * ******************************************************************************/ acpi_status acpi_ns_one_complete_parse(u32 pass_number, u32 table_index, struct acpi_namespace_node *start_node) { union acpi_parse_object *parse_root; acpi_status status; u32 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(); if (!parse_root) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Create and initialize a new walk state */ 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_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); } /* Found OSDT table, enable the namespace override feature */ if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_OSDT) && pass_number == ACPI_IMODE_LOAD_PASS1) { walk_state->namespace_override = TRUE; } if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); goto cleanup; } /* start_node is the default location to load the table */ if (start_node && start_node != acpi_gbl_root_node) { status = acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD, walk_state); if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); goto cleanup; } } /* Parse the AML */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %u parse\n", pass_number)); status = acpi_ps_parse_aml(walk_state); cleanup: acpi_ps_delete_parse_tree(parse_root); return_ACPI_STATUS(status); }
acpi_status acpi_ds_initialize_objects(u32 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")); /* Set all init info to zero */ memset(&info, 0, sizeof(struct acpi_init_walk_info)); info.owner_id = owner_id; info.table_index = table_index; /* Walk entire namespace from the supplied root */ /* * We don't use acpi_walk_namespace since we do not want to acquire * the namespace reader lock. */ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, acpi_ds_init_one_object, NULL, &info, NULL); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); } status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* DSDT is always the first AML table */ if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT)) { ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "\nInitializing Namespace objects:\n")); } /* Summary of objects initialized */ ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, " "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n", table->signature, table->oem_table_id, owner_id, info.object_count, info.device_count, info.op_region_count, info.method_count, info.serial_method_count, info.non_serial_method_count, info.serialized_method_count)); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n", info.method_count, info.op_region_count)); return_ACPI_STATUS(AE_OK); }
acpi_status acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, union acpi_parse_object *op) { acpi_status status; union acpi_operand_object *obj_desc; union acpi_operand_object **operand; struct acpi_namespace_node *node; union acpi_parse_object *next_op; u32 table_index; struct acpi_table_header *table; ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); /* * This is where we evaluate the Signature string, oem_id string, * and oem_table_id string of the Data Table Region declaration */ node = op->common.node; /* next_op points to Signature string op */ next_op = op->common.value.arg; /* * Evaluate/create the Signature string, oem_id string, * and oem_table_id string operands */ status = acpi_ds_create_operands(walk_state, next_op); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* * Resolve the Signature string, oem_id string, * and oem_table_id string operands */ status = acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } operand = &walk_state->operands[0]; /* Find the ACPI table */ status = acpi_tb_find_table(operand[0]->string.pointer, operand[1]->string.pointer, operand[2]->string.pointer, &table_index); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } acpi_ut_remove_reference(operand[0]); acpi_ut_remove_reference(operand[1]); acpi_ut_remove_reference(operand[2]); status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } obj_desc = acpi_ns_get_attached_object(node); if (!obj_desc) { return_ACPI_STATUS(AE_NOT_EXIST); } obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table); obj_desc->region.length = table->length; ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", obj_desc, ACPI_FORMAT_UINT64(obj_desc->region.address), obj_desc->region.length)); /* Now the address and length are valid for this opregion */ obj_desc->region.flags |= AOPOBJ_DATA_VALID; return_ACPI_STATUS(status); }
acpi_status acpi_ds_initialize_objects(u32 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:")); /* Set all init info to zero */ ACPI_MEMSET(&info, 0, sizeof(struct acpi_init_walk_info)); info.owner_id = owner_id; info.table_index = table_index; /* Walk entire namespace from the supplied root */ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* * We don't use acpi_walk_namespace since we do not want to acquire * the namespace reader lock. */ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object, NULL, &info, NULL); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); } (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 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) - %u Objects with %u Devices %u Methods %u Regions\n", table->signature, owner_id, info.object_count, info.device_count, info.method_count, info.op_region_count)); ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n", info.method_count, info.op_region_count)); return_ACPI_STATUS(AE_OK); }
acpi_status acpi_ex_load_table_op(struct acpi_walk_state *walk_state, union acpi_operand_object **return_desc) { acpi_status status; union acpi_operand_object **operand = &walk_state->operands[0]; 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; u32 table_index; ACPI_FUNCTION_TRACE(ex_load_table_op); /* Validate lengths for the signature_string, OEMIDString, OEMtable_iD */ if ((operand[0]->string.length > ACPI_NAME_SIZE) || (operand[1]->string.length > ACPI_OEM_ID_SIZE) || (operand[2]->string.length > ACPI_OEM_TABLE_ID_SIZE)) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Find the ACPI table in the RSDT/XSDT */ status = acpi_tb_find_table(operand[0]->string.pointer, operand[1]->string.pointer, operand[2]->string.pointer, &table_index); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) { return_ACPI_STATUS(status); } /* Table not found, return an Integer=0 and AE_OK */ ddb_handle = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); if (!ddb_handle) { return_ACPI_STATUS(AE_NO_MEMORY); } ddb_handle->integer.value = 0; *return_desc = ddb_handle; return_ACPI_STATUS(AE_OK); } /* Default nodes */ start_node = walk_state->scope_info->scope.node; parent_node = acpi_gbl_root_node; /* root_path (optional parameter) */ if (operand[3]->string.length > 0) { /* * Find the node referenced by the root_path_string. This is the * location within the namespace where the table will be loaded. */ status = acpi_ns_get_node(start_node, operand[3]->string.pointer, ACPI_NS_SEARCH_PARENT, &parent_node); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } } /* parameter_path (optional parameter) */ if (operand[4]->string.length > 0) { if ((operand[4]->string.pointer[0] != '\\') && (operand[4]->string.pointer[0] != '^')) { /* * Path is not absolute, so it will be relative to the node * referenced by the root_path_string (or the NS root if omitted) */ start_node = parent_node; } /* Find the node referenced by the parameter_path_string */ status = acpi_ns_get_node(start_node, operand[4]->string.pointer, ACPI_NS_SEARCH_PARENT, ¶meter_node); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } } /* Load the table into the namespace */ status = acpi_ex_add_table(table_index, parent_node, &ddb_handle); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Parameter Data (optional) */ if (parameter_node) { /* Store the parameter data into the optional parameter object */ status = acpi_ex_store(operand[5], ACPI_CAST_PTR(union acpi_operand_object, parameter_node), walk_state); if (ACPI_FAILURE(status)) { (void)acpi_ex_unload_table(ddb_handle); return_ACPI_STATUS(status); } } status = acpi_get_table_by_index(table_index, &table); if (ACPI_SUCCESS(status)) { ACPI_INFO((AE_INFO, "Dynamic OEM Table Load - [%.4s] OemId [%.6s] OemTableId [%.8s]", table->signature, table->oem_id, table->oem_table_id)); } /* Invoke table handler if present */ if (acpi_gbl_table_handler) { (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, acpi_gbl_table_handler_context); } *return_desc = ddb_handle; return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: ns_execute_table * * PARAMETERS: table_desc - An ACPI table descriptor for table to parse * start_node - Where to enter the table into the namespace * * RETURN: Status * * DESCRIPTION: Load ACPI/AML table by executing the entire table as a * term_list. * ******************************************************************************/ acpi_status acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node) { acpi_status status; struct acpi_table_header *table; acpi_owner_id owner_id; struct acpi_evaluate_info *info = NULL; u32 aml_length; u8 *aml_start; union acpi_operand_object *method_obj = NULL; ACPI_FUNCTION_TRACE(ns_execute_table); status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Table must consist of at least a complete header */ if (table->length < sizeof(struct acpi_table_header)) { return_ACPI_STATUS(AE_BAD_HEADER); } aml_start = (u8 *)table + sizeof(struct acpi_table_header); aml_length = table->length - sizeof(struct acpi_table_header); status = acpi_tb_get_owner_id(table_index, &owner_id); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Create, initialize, and link a new temporary method object */ method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); if (!method_obj) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Allocate the evaluation information block */ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); if (!info) { status = AE_NO_MEMORY; goto cleanup; } ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Create table code block: %p\n", method_obj)); method_obj->method.aml_start = aml_start; method_obj->method.aml_length = aml_length; method_obj->method.owner_id = owner_id; method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL; info->pass_number = ACPI_IMODE_EXECUTE; info->node = start_node; info->obj_desc = method_obj; info->node_flags = info->node->flags; info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE); if (!info->full_pathname) { status = AE_NO_MEMORY; goto cleanup; } status = acpi_ps_execute_table(info); cleanup: if (info) { ACPI_FREE(info->full_pathname); info->full_pathname = NULL; } ACPI_FREE(info); acpi_ut_remove_reference(method_obj); return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: ns_one_complete_parse * * PARAMETERS: pass_number - 1 or 2 * table_desc - The table to be parsed. * * RETURN: Status * * DESCRIPTION: Perform one complete parse of an ACPI/AML table. * ******************************************************************************/ acpi_status acpi_ns_one_complete_parse(u32 pass_number, u32 table_index, struct acpi_namespace_node *start_node) { union acpi_parse_object *parse_root; acpi_status status; u32 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(); if (!parse_root) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Create and initialize a new walk state */ 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_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); goto cleanup; } /* start_node is the default location to load the table */ if (start_node && start_node != acpi_gbl_root_node) { status = acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD, walk_state); if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); goto cleanup; } } /* Parse the AML */ <<<<<<< HEAD
acpi_status acpi_ns_one_complete_parse(u32 pass_number, u32 table_index, struct acpi_namespace_node *start_node) { union acpi_parse_object *parse_root; acpi_status status; u32 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); } /* */ parse_root = acpi_ps_create_scope_op(); if (!parse_root) { return_ACPI_STATUS(AE_NO_MEMORY); } /* */ 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_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); } /* */ 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); goto cleanup; } /* */ if (start_node && start_node != acpi_gbl_root_node) { status = acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD, walk_state); if (ACPI_FAILURE(status)) { acpi_ds_delete_walk_state(walk_state); goto cleanup; } } /* */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %u parse\n", pass_number)); status = acpi_ps_parse_aml(walk_state); cleanup: acpi_ps_delete_parse_tree(parse_root); return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: ns_one_complete_parse * * PARAMETERS: pass_number - 1 or 2 * table_desc - The table to be parsed. * * RETURN: Status * * DESCRIPTION: Perform one complete parse of an ACPI/AML table. * ******************************************************************************/ acpi_status 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(); if (!parse_root) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Create and initialize a new walk state */ 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_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); } /* Parse the AML */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", (unsigned)pass_number)); status = acpi_ps_parse_aml(walk_state); acpi_ps_delete_parse_tree(parse_root); return_ACPI_STATUS(status); }