Commit a62a7117 authored by Bob Moore's avatar Bob Moore Committed by Rafael J. Wysocki

ACPICA: Implement deferred resolution of reference package elements

ACPICA commit 0c08790c56fdf0dc081ae869495a09d8c4230854

This change defers the resolution of package elements that
are named references until after the entire namespace has been
loaded from the definition block. This allows such references
to be in fact forward references for both module level code
and control methods.

Link: https://github.com/acpica/acpica/commit/0c08790cSigned-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 7ab58197
......@@ -18,6 +18,7 @@ acpi-y := \
dsmthdat.o \
dsobject.o \
dsopcode.o \
dspkginit.o \
dsutils.o \
dswexec.o \
dswload.o \
......
......@@ -237,6 +237,11 @@ acpi_ds_initialize_objects(u32 table_index,
* dsobject - Parser/Interpreter interface - object initialization and conversion
*/
acpi_status
acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
union acpi_parse_object *op,
union acpi_operand_object **obj_desc_ptr);
acpi_status
acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
union acpi_parse_object *op,
u32 buffer_length,
......@@ -258,6 +263,14 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state,
struct acpi_namespace_node *node,
union acpi_parse_object *op);
/*
* dspkginit - Package object initialization
*/
acpi_status
acpi_ds_init_package_element(u8 object_type,
union acpi_operand_object *source_object,
union acpi_generic_state *state, void *context);
/*
* dsutils - Parser/Interpreter interface utility routines
*/
......
......@@ -605,7 +605,7 @@ struct acpi_update_state {
* Pkg state - used to traverse nested package structures
*/
struct acpi_pkg_state {
ACPI_STATE_COMMON u16 index;
ACPI_STATE_COMMON u32 index;
union acpi_operand_object *source_object;
union acpi_operand_object *dest_object;
struct acpi_walk_state *walk_state;
......
......@@ -339,11 +339,12 @@ struct acpi_object_addr_handler {
struct acpi_object_reference {
ACPI_OBJECT_COMMON_HEADER u8 class; /* Reference Class */
u8 target_type; /* Used for Index Op */
u8 reserved;
u8 resolved; /* Reference has been resolved to a value */
void *object; /* name_op=>HANDLE to obj, index_op=>union acpi_operand_object */
struct acpi_namespace_node *node; /* ref_of or Namepath */
union acpi_operand_object **where; /* Target of Index */
u8 *index_pointer; /* Used for Buffers and Strings */
u8 *aml; /* Used for deferred resolution of the ref */
u32 value; /* Used for Local/Arg/Index/ddb_handle */
};
......
......@@ -516,7 +516,7 @@ union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object
union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object,
void *external_object,
u16 index);
u32 index);
acpi_status
acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
......
This diff is collapsed.
......@@ -599,6 +599,15 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
*/
walk_state->operand_index = walk_state->num_operands;
/* Ignore if child is not valid */
if (!op->common.value.arg) {
ACPI_ERROR((AE_INFO,
"Dispatch: Missing child while executing TermArg for %X",
op->common.aml_opcode));
return_ACPI_STATUS(AE_OK);
}
status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
......
This diff is collapsed.
......@@ -69,9 +69,14 @@ void acpi_ns_check_argument_types(struct acpi_evaluate_info *info)
u8 user_arg_type;
u32 i;
/* If not a predefined name, cannot typecheck args */
if (!info->predefined) {
/*
* If not a predefined name, cannot typecheck args, because
* we have no idea what argument types are expected.
* Also, ignore typecheck if warnings/errors if this method
* has already been evaluated at least once -- in order
* to suppress repetitive messages.
*/
if (!info->predefined || (info->node->flags & ANOBJ_EVALUATED)) {
return;
}
......@@ -93,6 +98,10 @@ void acpi_ns_check_argument_types(struct acpi_evaluate_info *info)
acpi_ut_get_type_name
(user_arg_type),
acpi_ut_get_type_name(arg_type)));
/* Prevent any additional typechecking for this method */
info->node->flags |= ANOBJ_EVALUATED;
}
}
}
......@@ -121,7 +130,7 @@ acpi_ns_check_acpi_compliance(char *pathname,
u32 aml_param_count;
u32 required_param_count;
if (!predefined) {
if (!predefined || (node->flags & ANOBJ_EVALUATED)) {
return;
}
......@@ -215,6 +224,10 @@ acpi_ns_check_argument_count(char *pathname,
u32 aml_param_count;
u32 required_param_count;
if (node->flags & ANOBJ_EVALUATED) {
return;
}
if (!predefined) {
/*
* Not a predefined name. Check the incoming user argument count
......
......@@ -396,6 +396,20 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
info->package_init++;
status = acpi_ds_get_package_arguments(obj_desc);
if (ACPI_FAILURE(status)) {
break;
}
/*
* Resolve all named references in package objects (and all
* sub-packages). This action has been deferred until the entire
* namespace has been loaded, in order to support external and
* forward references from individual package elements (05/2017).
*/
status = acpi_ut_walk_package_tree(obj_desc, NULL,
acpi_ds_init_package_element,
NULL);
obj_desc->package.flags |= AOPOBJ_DATA_VALID;
break;
default:
......
......@@ -89,7 +89,14 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
{
acpi_size size;
ACPI_FUNCTION_ENTRY();
/* Validate the Node */
if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
ACPI_ERROR((AE_INFO,
"Invalid/cached reference target node: %p, descriptor type %d",
node, ACPI_GET_DESCRIPTOR_TYPE(node)));
return (0);
}
size = acpi_ns_build_normalized_path(node, NULL, 0, FALSE);
return (size);
......
......@@ -164,6 +164,11 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
INCREMENT_ARG_LIST(walk_state->arg_types);
}
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
"Final argument count: %u pass %u\n",
walk_state->arg_count,
walk_state->pass_number));
/*
* Handle executable code at "module-level". This refers to
* executable opcodes that appear outside of any control method.
......@@ -277,6 +282,11 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
AML_NAME_OP)
&& (walk_state->pass_number <=
ACPI_IMODE_LOAD_PASS2)) {
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
"Setup Package/Buffer: Pass %u, AML Ptr: %p\n",
walk_state->pass_number,
aml_op_start));
/*
* Skip parsing of Buffers and Packages because we don't have
* enough info in the first pass to parse them correctly.
......@@ -570,6 +580,10 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
/* Check for arguments that need to be processed */
ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
"Parseloop: argument count: %u\n",
walk_state->arg_count));
if (walk_state->arg_count) {
/*
* There are arguments (complex ones), push Op and
......
......@@ -224,7 +224,7 @@ acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
*
* RETURN: Status
*
* DESCRIPTION: Walk through a package
* DESCRIPTION: Walk through a package, including subpackages
*
******************************************************************************/
......@@ -236,8 +236,8 @@ acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
acpi_status status = AE_OK;
union acpi_generic_state *state_list = NULL;
union acpi_generic_state *state;
u32 this_index;
union acpi_operand_object *this_source_obj;
u32 this_index;
ACPI_FUNCTION_TRACE(ut_walk_package_tree);
......@@ -251,8 +251,10 @@ acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
/* Get one element of the package */
this_index = state->pkg.index;
this_source_obj = (union acpi_operand_object *)
this_source_obj =
state->pkg.source_object->package.elements[this_index];
state->pkg.this_target_obj =
&state->pkg.source_object->package.elements[this_index];
/*
* Check for:
......
......@@ -483,6 +483,11 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
/* A namespace node should never get here */
ACPI_ERROR((AE_INFO,
"Received a namespace node [%4.4s] "
"where an operand object is required",
ACPI_CAST_PTR(struct acpi_namespace_node,
internal_object)->name.ascii));
return_ACPI_STATUS(AE_AML_INTERNAL);
}
......
......@@ -226,7 +226,7 @@ union acpi_generic_state *acpi_ut_create_update_state(union acpi_operand_object
union acpi_generic_state *acpi_ut_create_pkg_state(void *internal_object,
void *external_object,
u16 index)
u32 index)
{
union acpi_generic_state *state;
......
......@@ -591,6 +591,10 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
return_VOID;
}
if (!acpi_gbl_global_list) {
goto exit;
}
element = acpi_gbl_global_list->list_head;
while (element) {
if ((element->component & component) &&
......@@ -602,7 +606,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
if (element->size <
sizeof(struct acpi_common_descriptor)) {
acpi_os_printf("%p Length 0x%04X %9.9s-%u "
acpi_os_printf("%p Length 0x%04X %9.9s-%4.4u "
"[Not a Descriptor - too small]\n",
descriptor, element->size,
element->module, element->line);
......@@ -612,7 +616,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
if (ACPI_GET_DESCRIPTOR_TYPE(descriptor) !=
ACPI_DESC_TYPE_CACHED) {
acpi_os_printf
("%p Length 0x%04X %9.9s-%u [%s] ",
("%p Length 0x%04X %9.9s-%4.4u [%s] ",
descriptor, element->size,
element->module, element->line,
acpi_ut_get_descriptor_name
......@@ -705,6 +709,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
element = element->next;
}
exit:
(void)acpi_ut_release_mutex(ACPI_MTX_MEMORY);
/* Print summary */
......
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