Commit adbd7582 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] ACPICA 20041105 from Bob Moore

Implemented support for FADT revision 2.  This was an
interim table (between ACPI 1.0 and ACPI 2.0) that adds
support for the FADT reset register.

Implemented optional support to allow uninitialized LocalX
and ArgX variables in a control method.  The variables
are initialized to an Integer object with a value
of zero.  This support is enabled by setting the
acpi_gbl_enable_interpreter_slack flag to TRUE,
which is default unless booted with "acpi=strict".

Implemented support for Integer objects for the SizeOf
operator.  Either 4 or 8 is returned, depending on the
current integer size (32-bit or 64-bit, depending on the
parent table revision).

Fixed a problem in the implementation of the SizeOf and
ObjectType operators where the operand was resolved to
a value too early, causing incorrect return values for
some objects.

Fixed some possible memory leaks during exceptional conditions.
parent 2f294db8
...@@ -448,7 +448,22 @@ acpi_ds_method_data_get_value ( ...@@ -448,7 +448,22 @@ acpi_ds_method_data_get_value (
* was referenced by the method (via the ASL) * was referenced by the method (via the ASL)
* before it was initialized. Either case is an error. * before it was initialized. Either case is an error.
*/ */
switch (opcode) {
/* If slack enabled, init the local_x/arg_x to an Integer of value zero */
if (acpi_gbl_enable_interpreter_slack) {
object = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
if (!object) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
object->integer.value = 0;
node->object = object;
}
/* Otherwise, return the error */
else switch (opcode) {
case AML_ARG_OP: case AML_ARG_OP:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at node %p\n", ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at node %p\n",
......
...@@ -426,7 +426,9 @@ acpi_ds_exec_end_op ( ...@@ -426,7 +426,9 @@ acpi_ds_exec_end_op (
(walk_state->operands[0]->common.type == ACPI_TYPE_LOCAL_REFERENCE) && (walk_state->operands[0]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
(walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) && (walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
(walk_state->operands[0]->reference.opcode == (walk_state->operands[0]->reference.opcode ==
walk_state->operands[1]->reference.opcode)) { walk_state->operands[1]->reference.opcode) &&
(walk_state->operands[0]->reference.offset ==
walk_state->operands[1]->reference.offset)) {
status = AE_OK; status = AE_OK;
} }
else { else {
......
...@@ -182,18 +182,20 @@ acpi_ds_load1_begin_op ( ...@@ -182,18 +182,20 @@ acpi_ds_load1_begin_op (
*/ */
status = acpi_ns_lookup (walk_state->scope_info, path, object_type, status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node)); ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
if (ACPI_FAILURE (status)) {
#ifdef _ACPI_ASL_COMPILER #ifdef _ACPI_ASL_COMPILER
if (status == AE_NOT_FOUND) { if (status == AE_NOT_FOUND) {
/*
* Table disassembly:
* Target of Scope() not found. Generate an External for it, and
* insert the name into the namespace.
*/
acpi_dm_add_to_external_list (path); acpi_dm_add_to_external_list (path);
status = AE_OK; status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
} ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
else {
ACPI_REPORT_NSERROR (path, status);
} }
#else
ACPI_REPORT_NSERROR (path, status);
#endif #endif
if (ACPI_FAILURE (status)) {
ACPI_REPORT_NSERROR (path, status);
return (status); return (status);
} }
......
...@@ -867,6 +867,7 @@ acpi_ds_create_walk_state ( ...@@ -867,6 +867,7 @@ acpi_ds_create_walk_state (
status = acpi_ds_result_stack_push (walk_state); status = acpi_ds_result_stack_push (walk_state);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
return_PTR (NULL); return_PTR (NULL);
} }
......
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
* *
* PARAMETERS: *obj_desc - Pointer to entry to be dumped * PARAMETERS: *obj_desc - Pointer to entry to be dumped
* *
* RETURN: Status * RETURN: None
* *
* DESCRIPTION: Dump an operand object * DESCRIPTION: Dump an operand object
* *
...@@ -71,12 +71,11 @@ ...@@ -71,12 +71,11 @@
void void
acpi_ex_dump_operand ( acpi_ex_dump_operand (
union acpi_operand_object *obj_desc) union acpi_operand_object *obj_desc,
u32 depth)
{ {
u8 *buf = NULL;
u32 length; u32 length;
union acpi_operand_object **element; u32 index;
u16 element_index;
ACPI_FUNCTION_NAME ("ex_dump_operand") ACPI_FUNCTION_NAME ("ex_dump_operand")
...@@ -88,9 +87,9 @@ acpi_ex_dump_operand ( ...@@ -88,9 +87,9 @@ acpi_ex_dump_operand (
if (!obj_desc) { if (!obj_desc) {
/* /*
* This usually indicates that something serious is wrong * This could be a null element of a package
*/ */
acpi_os_printf ("Null Object Descriptor\n"); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Null Object Descriptor\n"));
return; return;
} }
...@@ -110,7 +109,11 @@ acpi_ex_dump_operand ( ...@@ -110,7 +109,11 @@ acpi_ex_dump_operand (
/* obj_desc is a valid object */ /* obj_desc is a valid object */
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc)); if (depth > 0) {
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "%*s[%u] ", depth, " ", depth));
}
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "%p ", obj_desc));
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case ACPI_TYPE_LOCAL_REFERENCE: case ACPI_TYPE_LOCAL_REFERENCE:
...@@ -193,7 +196,6 @@ acpi_ex_dump_operand ( ...@@ -193,7 +196,6 @@ acpi_ex_dump_operand (
break; break;
} }
break; break;
...@@ -203,7 +205,6 @@ acpi_ex_dump_operand ( ...@@ -203,7 +205,6 @@ acpi_ex_dump_operand (
obj_desc->buffer.length, obj_desc->buffer.pointer); obj_desc->buffer.length, obj_desc->buffer.pointer);
length = obj_desc->buffer.length; length = obj_desc->buffer.length;
if (length > 64) { if (length > 64) {
length = 64; length = 64;
} }
...@@ -213,12 +214,11 @@ acpi_ex_dump_operand ( ...@@ -213,12 +214,11 @@ acpi_ex_dump_operand (
if (obj_desc->buffer.pointer) { if (obj_desc->buffer.pointer) {
acpi_os_printf ("Buffer Contents: "); acpi_os_printf ("Buffer Contents: ");
for (buf = obj_desc->buffer.pointer; length--; ++buf) { for (index = 0; index < length; index++) {
acpi_os_printf (" %02x", *buf); acpi_os_printf (" %02x", obj_desc->buffer.pointer[index]);
} }
acpi_os_printf ("\n"); acpi_os_printf ("\n");
} }
break; break;
...@@ -231,23 +231,20 @@ acpi_ex_dump_operand ( ...@@ -231,23 +231,20 @@ acpi_ex_dump_operand (
case ACPI_TYPE_PACKAGE: case ACPI_TYPE_PACKAGE:
acpi_os_printf ("Package count %X @ %p\n", acpi_os_printf ("Package [Len %X] element_array %p\n",
obj_desc->package.count, obj_desc->package.elements); obj_desc->package.count, obj_desc->package.elements);
/* /*
* If elements exist, package vector pointer is valid, * If elements exist, package element pointer is valid,
* and debug_level exceeds 1, dump package's elements. * and debug_level exceeds 1, dump package's elements.
*/ */
if (obj_desc->package.count && if (obj_desc->package.count &&
obj_desc->package.elements && obj_desc->package.elements &&
acpi_dbg_level > 1) { acpi_dbg_level > 1) {
for (element_index = 0, element = obj_desc->package.elements; for (index = 0; index < obj_desc->package.count; index++) {
element_index < obj_desc->package.count; acpi_ex_dump_operand (obj_desc->package.elements[index], depth+1);
++element_index, ++element) {
acpi_ex_dump_operand (*element);
} }
} }
acpi_os_printf ("\n");
break; break;
...@@ -295,7 +292,7 @@ acpi_ex_dump_operand ( ...@@ -295,7 +292,7 @@ acpi_ex_dump_operand (
obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK, obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK, obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
obj_desc->field.base_byte_offset, obj_desc->field.start_field_bit_offset); obj_desc->field.base_byte_offset, obj_desc->field.start_field_bit_offset);
ACPI_DUMP_STACK_ENTRY (obj_desc->field.region_obj); acpi_ex_dump_operand (obj_desc->field.region_obj, depth+1);
break; break;
...@@ -319,9 +316,8 @@ acpi_ex_dump_operand ( ...@@ -319,9 +316,8 @@ acpi_ex_dump_operand (
acpi_os_printf ("*not a Buffer* \n"); acpi_os_printf ("*not a Buffer* \n");
} }
else { else {
ACPI_DUMP_STACK_ENTRY (obj_desc->buffer_field.buffer_obj); acpi_ex_dump_operand (obj_desc->buffer_field.buffer_obj, depth+1);
} }
break; break;
...@@ -408,7 +404,6 @@ acpi_ex_dump_operands ( ...@@ -408,7 +404,6 @@ acpi_ex_dump_operands (
u32 line_number) u32 line_number)
{ {
acpi_native_uint i; acpi_native_uint i;
union acpi_operand_object **obj_desc;
ACPI_FUNCTION_NAME ("ex_dump_operands"); ACPI_FUNCTION_NAME ("ex_dump_operands");
...@@ -433,8 +428,7 @@ acpi_ex_dump_operands ( ...@@ -433,8 +428,7 @@ acpi_ex_dump_operands (
/* Dump the operand stack starting at the top */ /* Dump the operand stack starting at the top */
for (i = 0; num_levels > 0; i--, num_levels--) { for (i = 0; num_levels > 0; i--, num_levels--) {
obj_desc = &operands[i]; acpi_ex_dump_operand (operands[i], 0);
acpi_ex_dump_operand (*obj_desc);
} }
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
......
...@@ -686,13 +686,19 @@ acpi_ex_opcode_1A_0T_1R ( ...@@ -686,13 +686,19 @@ acpi_ex_opcode_1A_0T_1R (
case AML_TYPE_OP: /* object_type (source_object) */ case AML_TYPE_OP: /* object_type (source_object) */
/*
* Note: The operand is not resolved at this point because we want to
* get the associated object, not its value. For example, we don't want
* to resolve a field_unit to its value, we want the actual field_unit
* object.
*/
/* Get the type of the base object */ /* Get the type of the base object */
status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, NULL); status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, NULL);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
goto cleanup; goto cleanup;
} }
/* Allocate a descriptor to hold the type. */ /* Allocate a descriptor to hold the type. */
return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER); return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
...@@ -707,6 +713,11 @@ acpi_ex_opcode_1A_0T_1R ( ...@@ -707,6 +713,11 @@ acpi_ex_opcode_1A_0T_1R (
case AML_SIZE_OF_OP: /* size_of (source_object) */ case AML_SIZE_OF_OP: /* size_of (source_object) */
/*
* Note: The operand is not resolved at this point because we want to
* get the associated object, not its value.
*/
/* Get the base object */ /* Get the base object */
status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, &temp_desc); status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, &temp_desc);
...@@ -715,11 +726,19 @@ acpi_ex_opcode_1A_0T_1R ( ...@@ -715,11 +726,19 @@ acpi_ex_opcode_1A_0T_1R (
} }
/* /*
* Type is guaranteed to be a buffer, string, or package at this * The type of the base object must be integer, buffer, string, or
* point (even if the original operand was an object reference, it * package. All others are not supported.
* will be resolved and typechecked during operand resolution.) *
* NOTE: Integer is not specifically supported by the ACPI spec,
* but is supported implicitly via implicit operand conversion.
* rather than bother with conversion, we just use the byte width
* global (4 or 8 bytes).
*/ */
switch (type) { switch (type) {
case ACPI_TYPE_INTEGER:
value = acpi_gbl_integer_byte_width;
break;
case ACPI_TYPE_BUFFER: case ACPI_TYPE_BUFFER:
value = temp_desc->buffer.length; value = temp_desc->buffer.length;
break; break;
...@@ -734,7 +753,7 @@ acpi_ex_opcode_1A_0T_1R ( ...@@ -734,7 +753,7 @@ acpi_ex_opcode_1A_0T_1R (
default: default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"size_of, Not Buf/Str/Pkg - found type %s\n", "size_of - Operand is not Buf/Int/Str/Pkg - found type %s\n",
acpi_ut_get_type_name (type))); acpi_ut_get_type_name (type)));
status = AE_AML_OPERAND_TYPE; status = AE_AML_OPERAND_TYPE;
goto cleanup; goto cleanup;
......
...@@ -508,6 +508,7 @@ acpi_ex_prep_field_value ( ...@@ -508,6 +508,7 @@ acpi_ex_prep_field_value (
if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) { if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) {
ACPI_REPORT_ERROR (("Null Index Object during field prep\n")); ACPI_REPORT_ERROR (("Null Index Object during field prep\n"));
acpi_ut_delete_object_desc (obj_desc);
return_ACPI_STATUS (AE_AML_INTERNAL); return_ACPI_STATUS (AE_AML_INTERNAL);
} }
......
...@@ -327,11 +327,44 @@ acpi_ex_resolve_multiple ( ...@@ -327,11 +327,44 @@ acpi_ex_resolve_multiple (
union acpi_operand_object *obj_desc = (void *) operand; union acpi_operand_object *obj_desc = (void *) operand;
struct acpi_namespace_node *node; struct acpi_namespace_node *node;
acpi_object_type type; acpi_object_type type;
acpi_status status;
ACPI_FUNCTION_TRACE ("acpi_ex_resolve_multiple"); ACPI_FUNCTION_TRACE ("acpi_ex_resolve_multiple");
/*
* Operand can be either a namespace node or an operand descriptor
*/
switch (ACPI_GET_DESCRIPTOR_TYPE (obj_desc)) {
case ACPI_DESC_TYPE_OPERAND:
type = obj_desc->common.type;
break;
case ACPI_DESC_TYPE_NAMED:
type = ((struct acpi_namespace_node *) obj_desc)->type;
obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) obj_desc);
/* If we had an Alias node, use the attached object for type info */
if (type == ACPI_TYPE_LOCAL_ALIAS) {
type = ((struct acpi_namespace_node *) obj_desc)->type;
obj_desc = acpi_ns_get_attached_object ((struct acpi_namespace_node *) obj_desc);
}
break;
default:
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
/*
* If type is anything other than a reference, we are done
*/
if (type != ACPI_TYPE_LOCAL_REFERENCE) {
goto exit;
}
/* /*
* For reference objects created via the ref_of or Index operators, * For reference objects created via the ref_of or Index operators,
* we need to get to the base object (as per the ACPI specification * we need to get to the base object (as per the ACPI specification
...@@ -424,6 +457,33 @@ acpi_ex_resolve_multiple ( ...@@ -424,6 +457,33 @@ acpi_ex_resolve_multiple (
break; break;
case AML_LOCAL_OP:
case AML_ARG_OP:
if (return_desc) {
status = acpi_ds_method_data_get_value (obj_desc->reference.opcode,
obj_desc->reference.offset, walk_state, &obj_desc);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
acpi_ut_remove_reference (obj_desc);
}
else {
status = acpi_ds_method_data_get_node (obj_desc->reference.opcode,
obj_desc->reference.offset, walk_state, &node);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
obj_desc = acpi_ns_get_attached_object (node);
if (!obj_desc) {
type = ACPI_TYPE_ANY;
goto exit;
}
}
break;
case AML_DEBUG_OP: case AML_DEBUG_OP:
/* The Debug Object is of type "debug_object" */ /* The Debug Object is of type "debug_object" */
......
...@@ -206,6 +206,7 @@ acpi_ns_root_initialize (void) ...@@ -206,6 +206,7 @@ acpi_ns_root_initialize (void)
status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT, status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT,
1, &obj_desc->mutex.semaphore); 1, &obj_desc->mutex.semaphore);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
acpi_ut_remove_reference (obj_desc);
goto unlock_and_exit; goto unlock_and_exit;
} }
...@@ -221,6 +222,7 @@ acpi_ns_root_initialize (void) ...@@ -221,6 +222,7 @@ acpi_ns_root_initialize (void)
status = acpi_os_create_semaphore (1, 1, status = acpi_os_create_semaphore (1, 1,
&obj_desc->mutex.semaphore); &obj_desc->mutex.semaphore);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
acpi_ut_remove_reference (obj_desc);
goto unlock_and_exit; goto unlock_and_exit;
} }
} }
......
...@@ -318,7 +318,7 @@ ...@@ -318,7 +318,7 @@
#define ARGI_SHIFT_LEFT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) #define ARGI_SHIFT_LEFT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
#define ARGI_SHIFT_RIGHT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) #define ARGI_SHIFT_RIGHT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
#define ARGI_SIGNAL_OP ARGI_LIST1 (ARGI_EVENT) #define ARGI_SIGNAL_OP ARGI_LIST1 (ARGI_EVENT)
#define ARGI_SIZE_OF_OP ARGI_LIST1 (ARGI_DATAOBJECT) #define ARGI_SIZE_OF_OP ARGI_LIST1 (ARGI_REFERENCE) /* Force delay of operand resolution */
#define ARGI_SLEEP_OP ARGI_LIST1 (ARGI_INTEGER) #define ARGI_SLEEP_OP ARGI_LIST1 (ARGI_INTEGER)
#define ARGI_STALL_OP ARGI_LIST1 (ARGI_INTEGER) #define ARGI_STALL_OP ARGI_LIST1 (ARGI_INTEGER)
#define ARGI_STATICSTRING_OP ARGI_INVALID_OPCODE #define ARGI_STATICSTRING_OP ARGI_INVALID_OPCODE
...@@ -333,7 +333,7 @@ ...@@ -333,7 +333,7 @@
#define ARGI_TO_HEX_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET) #define ARGI_TO_HEX_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
#define ARGI_TO_INTEGER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET) #define ARGI_TO_INTEGER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET)
#define ARGI_TO_STRING_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_FIXED_TARGET) #define ARGI_TO_STRING_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_FIXED_TARGET)
#define ARGI_TYPE_OP ARGI_LIST1 (ARGI_ANYTYPE) #define ARGI_TYPE_OP ARGI_LIST1 (ARGI_REFERENCE) /* Force delay of operand resolution */
#define ARGI_UNLOAD_OP ARGI_LIST1 (ARGI_DDBHANDLE) #define ARGI_UNLOAD_OP ARGI_LIST1 (ARGI_DDBHANDLE)
#define ARGI_VAR_PACKAGE_OP ARGI_LIST1 (ARGI_INTEGER) #define ARGI_VAR_PACKAGE_OP ARGI_LIST1 (ARGI_INTEGER)
#define ARGI_WAIT_OP ARGI_LIST2 (ARGI_EVENT, ARGI_INTEGER) #define ARGI_WAIT_OP ARGI_LIST2 (ARGI_EVENT, ARGI_INTEGER)
......
...@@ -164,8 +164,11 @@ acpi_ps_complete_this_op ( ...@@ -164,8 +164,11 @@ acpi_ps_complete_this_op (
/* Delete this op and the subtree below it if asked to */ /* Delete this op and the subtree below it if asked to */
if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) && if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) ||
(walk_state->op_info->class != AML_CLASS_ARGUMENT)) { (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
return_VOID;
}
/* Make sure that we only delete this subtree */ /* Make sure that we only delete this subtree */
if (op->common.parent) { if (op->common.parent) {
...@@ -187,7 +190,7 @@ acpi_ps_complete_this_op ( ...@@ -187,7 +190,7 @@ acpi_ps_complete_this_op (
*/ */
replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
if (!replacement_op) { if (!replacement_op) {
return_VOID; goto cleanup;
} }
break; break;
...@@ -204,7 +207,7 @@ acpi_ps_complete_this_op ( ...@@ -204,7 +207,7 @@ acpi_ps_complete_this_op (
(op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) { (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
if (!replacement_op) { if (!replacement_op) {
return_VOID; goto cleanup;
} }
} }
...@@ -215,7 +218,7 @@ acpi_ps_complete_this_op ( ...@@ -215,7 +218,7 @@ acpi_ps_complete_this_op (
(op->common.aml_opcode == AML_VAR_PACKAGE_OP)) { (op->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
replacement_op = acpi_ps_alloc_op (op->common.aml_opcode); replacement_op = acpi_ps_alloc_op (op->common.aml_opcode);
if (!replacement_op) { if (!replacement_op) {
return_VOID; goto cleanup;
} }
replacement_op->named.data = op->named.data; replacement_op->named.data = op->named.data;
...@@ -227,7 +230,7 @@ acpi_ps_complete_this_op ( ...@@ -227,7 +230,7 @@ acpi_ps_complete_this_op (
default: default:
replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP); replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
if (!replacement_op) { if (!replacement_op) {
return_VOID; goto cleanup;
} }
} }
...@@ -274,13 +277,12 @@ acpi_ps_complete_this_op ( ...@@ -274,13 +277,12 @@ acpi_ps_complete_this_op (
} }
} }
/* Now we can actually delete the subtree rooted at op */
acpi_ps_delete_parse_tree (op); cleanup:
return_VOID; /* Now we can actually delete the subtree rooted at op */
}
acpi_ps_delete_parse_tree (op);
return_VOID; return_VOID;
} }
...@@ -552,7 +554,8 @@ acpi_ps_parse_loop ( ...@@ -552,7 +554,8 @@ acpi_ps_parse_loop (
if (!pre_op) { if (!pre_op) {
pre_op = acpi_ps_alloc_op (walk_state->opcode); pre_op = acpi_ps_alloc_op (walk_state->opcode);
if (!pre_op) { if (!pre_op) {
return_ACPI_STATUS (AE_NO_MEMORY); status = AE_NO_MEMORY;
goto close_this_op;
} }
} }
...@@ -578,7 +581,8 @@ acpi_ps_parse_loop ( ...@@ -578,7 +581,8 @@ acpi_ps_parse_loop (
/* Make sure that we found a NAME and didn't run out of arguments */ /* Make sure that we found a NAME and didn't run out of arguments */
if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) { if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) {
return_ACPI_STATUS (AE_AML_NO_OPERAND); status = AE_AML_NO_OPERAND;
goto close_this_op;
} }
/* We know that this arg is a name, move to next arg */ /* We know that this arg is a name, move to next arg */
...@@ -638,7 +642,8 @@ acpi_ps_parse_loop ( ...@@ -638,7 +642,8 @@ acpi_ps_parse_loop (
walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode); walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
op = acpi_ps_alloc_op (walk_state->opcode); op = acpi_ps_alloc_op (walk_state->opcode);
if (!op) { if (!op) {
return_ACPI_STATUS (AE_NO_MEMORY); status = AE_NO_MEMORY;
goto close_this_op;
} }
if (walk_state->op_info->flags & AML_CREATE) { if (walk_state->op_info->flags & AML_CREATE) {
...@@ -801,7 +806,7 @@ acpi_ps_parse_loop ( ...@@ -801,7 +806,7 @@ acpi_ps_parse_loop (
status = acpi_ps_push_scope (parser_state, op, status = acpi_ps_push_scope (parser_state, op,
walk_state->arg_types, walk_state->arg_count); walk_state->arg_types, walk_state->arg_count);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status); goto close_this_op;
} }
op = NULL; op = NULL;
continue; continue;
...@@ -1128,7 +1133,7 @@ acpi_ps_parse_aml ( ...@@ -1128,7 +1133,7 @@ acpi_ps_parse_aml (
else if (status == AE_CTRL_TERMINATE) { else if (status == AE_CTRL_TERMINATE) {
status = AE_OK; status = AE_OK;
} }
else if (status != AE_OK) { else if ((status != AE_OK) && (walk_state->method_desc)) {
ACPI_REPORT_METHOD_ERROR ("Method execution failed", ACPI_REPORT_METHOD_ERROR ("Method execution failed",
walk_state->method_node, NULL, status); walk_state->method_node, NULL, status);
......
...@@ -251,10 +251,26 @@ acpi_tb_convert_fadt1 ( ...@@ -251,10 +251,26 @@ acpi_tb_convert_fadt1 (
local_fadt->cst_cnt = 0; local_fadt->cst_cnt = 0;
/* /*
* Since there isn't any equivalence in 1.0 and since it highly likely * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0.
* that a 1.0 system has legacy support. * It primarily adds the FADT reset mechanism.
*/
if ((original_fadt->revision == 2) &&
(original_fadt->length == sizeof (struct fadt_descriptor_rev2_minus))) {
/*
* Grab the entire generic address struct, plus the 1-byte reset value
* that immediately follows.
*/
ACPI_MEMCPY (&local_fadt->reset_register,
&((struct fadt_descriptor_rev2_minus *) original_fadt)->reset_register,
sizeof (struct acpi_generic_address) + 1);
}
else {
/*
* Since there isn't any equivalence in 1.0 and since it is highly
* likely that a 1.0 system has legacy support.
*/ */
local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES; local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES;
}
/* /*
* Convert the V1.0 block addresses to V2.0 GAS structures * Convert the V1.0 block addresses to V2.0 GAS structures
...@@ -418,23 +434,21 @@ acpi_tb_convert_table_fadt (void) ...@@ -418,23 +434,21 @@ acpi_tb_convert_table_fadt (void)
/* /*
* acpi_gbl_FADT is valid * acpi_gbl_FADT is valid. Validate the FADT length. The table must be
* Allocate and zero the 2.0 FADT buffer * at least as long as the version 1.0 FADT
*/
local_fadt = ACPI_MEM_CALLOCATE (sizeof (struct fadt_descriptor_rev2));
if (local_fadt == NULL) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/*
* FADT length and version validation. The table must be at least as
* long as the version 1.0 FADT
*/ */
if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) { if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) {
ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", acpi_gbl_FADT->length)); ACPI_REPORT_ERROR (("FADT is invalid, too short: 0x%X\n", acpi_gbl_FADT->length));
return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
} }
/* Allocate buffer for the ACPI 2.0(+) FADT */
local_fadt = ACPI_MEM_CALLOCATE (sizeof (struct fadt_descriptor_rev2));
if (!local_fadt) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) { if (acpi_gbl_FADT->revision >= FADT2_REVISION_ID) {
if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev2)) { if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev2)) {
/* Length is too short to be a V2.0 table */ /* Length is too short to be a V2.0 table */
......
...@@ -269,6 +269,7 @@ acpi_tb_init_table_descriptor ( ...@@ -269,6 +269,7 @@ acpi_tb_init_table_descriptor (
* at this location, so return an error. * at this location, so return an error.
*/ */
if (list_head->next) { if (list_head->next) {
ACPI_MEM_FREE (table_desc);
return_ACPI_STATUS (AE_ALREADY_EXISTS); return_ACPI_STATUS (AE_ALREADY_EXISTS);
} }
......
...@@ -424,23 +424,21 @@ acpi_ut_copy_esimple_to_isimple ( ...@@ -424,23 +424,21 @@ acpi_ut_copy_esimple_to_isimple (
break; break;
default: default:
/* /* All other types are not supported */
* Whatever other type -- it is not supported
*/
return_ACPI_STATUS (AE_SUPPORT); return_ACPI_STATUS (AE_SUPPORT);
} }
switch (external_object->type) {
/* Must COPY string and buffer contents */ /* Must COPY string and buffer contents */
switch (external_object->type) {
case ACPI_TYPE_STRING: case ACPI_TYPE_STRING:
internal_object->string.pointer = internal_object->string.pointer =
ACPI_MEM_CALLOCATE ((acpi_size) external_object->string.length + 1); ACPI_MEM_CALLOCATE ((acpi_size) external_object->string.length + 1);
if (!internal_object->string.pointer) { if (!internal_object->string.pointer) {
return_ACPI_STATUS (AE_NO_MEMORY); goto error_exit;
} }
ACPI_MEMCPY (internal_object->string.pointer, ACPI_MEMCPY (internal_object->string.pointer,
...@@ -456,7 +454,7 @@ acpi_ut_copy_esimple_to_isimple ( ...@@ -456,7 +454,7 @@ acpi_ut_copy_esimple_to_isimple (
internal_object->buffer.pointer = internal_object->buffer.pointer =
ACPI_MEM_CALLOCATE (external_object->buffer.length); ACPI_MEM_CALLOCATE (external_object->buffer.length);
if (!internal_object->buffer.pointer) { if (!internal_object->buffer.pointer) {
return_ACPI_STATUS (AE_NO_MEMORY); goto error_exit;
} }
ACPI_MEMCPY (internal_object->buffer.pointer, ACPI_MEMCPY (internal_object->buffer.pointer,
...@@ -479,6 +477,11 @@ acpi_ut_copy_esimple_to_isimple ( ...@@ -479,6 +477,11 @@ acpi_ut_copy_esimple_to_isimple (
*ret_internal_object = internal_object; *ret_internal_object = internal_object;
return_ACPI_STATUS (AE_OK); return_ACPI_STATUS (AE_OK);
error_exit:
acpi_ut_remove_reference (internal_object);
return_ACPI_STATUS (AE_NO_MEMORY);
} }
...@@ -747,7 +750,7 @@ acpi_ut_copy_ielement_to_ielement ( ...@@ -747,7 +750,7 @@ acpi_ut_copy_ielement_to_ielement (
status = acpi_ut_copy_simple_object (source_object, target_object); status = acpi_ut_copy_simple_object (source_object, target_object);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
return (status); goto error_exit;
} }
*this_target_ptr = target_object; *this_target_ptr = target_object;
...@@ -781,8 +784,8 @@ acpi_ut_copy_ielement_to_ielement ( ...@@ -781,8 +784,8 @@ acpi_ut_copy_ielement_to_ielement (
ACPI_MEM_CALLOCATE (((acpi_size) source_object->package.count + 1) * ACPI_MEM_CALLOCATE (((acpi_size) source_object->package.count + 1) *
sizeof (void *)); sizeof (void *));
if (!target_object->package.elements) { if (!target_object->package.elements) {
ACPI_MEM_FREE (target_object); status = AE_NO_MEMORY;
return (AE_NO_MEMORY); goto error_exit;
} }
/* /*
...@@ -802,6 +805,10 @@ acpi_ut_copy_ielement_to_ielement ( ...@@ -802,6 +805,10 @@ acpi_ut_copy_ielement_to_ielement (
} }
return (status); return (status);
error_exit:
acpi_ut_remove_reference (target_object);
return (status);
} }
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
/* Version string */ /* Version string */
#define ACPI_CA_VERSION 0x20041015 #define ACPI_CA_VERSION 0x20041105
/* /*
* OS name, used for the _OS object. The _OS object is essentially obsolete, * OS name, used for the _OS object. The _OS object is essentially obsolete,
......
...@@ -92,7 +92,10 @@ extern u32 acpi_gbl_nesting_level; ...@@ -92,7 +92,10 @@ extern u32 acpi_gbl_nesting_level;
/* /*
* Enable "slack" in the AML interpreter? Default is FALSE, and the * Enable "slack" in the AML interpreter? Default is FALSE, and the
* interpreter strictly follows the ACPI specification. Setting to TRUE * interpreter strictly follows the ACPI specification. Setting to TRUE
* allows the interpreter to forgive certain bad AML constructs. * allows the interpreter to forgive certain bad AML constructs. Currently:
* 1) Allow "implicit return" of last value in a control method
* 2) Allow access beyond end of operation region
* 3) Allow access to uninitialized locals/args (auto-init to integer 0)
*/ */
ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_enable_interpreter_slack, FALSE); ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_enable_interpreter_slack, FALSE);
......
...@@ -486,12 +486,13 @@ acpi_ex_resolve_object_to_value ( ...@@ -486,12 +486,13 @@ acpi_ex_resolve_object_to_value (
/* /*
* exdump - Scanner debug output routines * exdump - Interpreter debug output routines
*/ */
void void
acpi_ex_dump_operand ( acpi_ex_dump_operand (
union acpi_operand_object *entry_desc); union acpi_operand_object *obj_desc,
u32 depth);
void void
acpi_ex_dump_operands ( acpi_ex_dump_operands (
......
...@@ -533,7 +533,7 @@ ...@@ -533,7 +533,7 @@
/* Stack and buffer dumping */ /* Stack and buffer dumping */
#define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand(a) #define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand((a),0)
#define ACPI_DUMP_OPERANDS(a,b,c,d,e) acpi_ex_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__) #define ACPI_DUMP_OPERANDS(a,b,c,d,e) acpi_ex_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__)
......
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
#define BAF_8042_KEYBOARD_CONTROLLER 0x0002 #define BAF_8042_KEYBOARD_CONTROLLER 0x0002
#define FADT2_REVISION_ID 3 #define FADT2_REVISION_ID 3
#define FADT2_MINUS_REVISION_ID 2
#pragma pack(1) #pragma pack(1)
...@@ -119,48 +120,51 @@ struct acpi_generic_address ...@@ -119,48 +120,51 @@ struct acpi_generic_address
}; };
#define FADT_REV2_COMMON \
u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ \
u32 V1_dsdt; /* 32-bit physical address of DSDT */ \
u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ \
u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */ \
u16 sci_int; /* System vector of SCI interrupt */ \
u32 smi_cmd; /* Port address of SMI command port */ \
u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ \
u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ \
u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */ \
u8 pstate_cnt; /* Processor performance state control*/ \
u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */ \
u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */ \
u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */ \
u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */ \
u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */ \
u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ \
u32 V1_gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */ \
u32 V1_gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */ \
u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */ \
u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */ \
u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */ \
u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */ \
u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */ \
u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */ \
u8 gpe1_base; /* Offset in gpe model where gpe1 events start */ \
u8 cst_cnt; /* Support for the _CST object and C States change notification.*/ \
u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */ \
u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */ \
u16 flush_size; /* Number of flush strides that need to be read */ \
u16 flush_stride; /* Processor's memory cache line width, in bytes */ \
u8 duty_offset; /* Processor's duty cycle index in processor's P_CNT reg*/ \
u8 duty_width; /* Processor's duty cycle value bit width in P_CNT register.*/ \
u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ \
u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ \
u8 century; /* Index to century in RTC CMOS RAM */ \
u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/
/* /*
* ACPI 2.0 Fixed ACPI Description Table (FADT) * ACPI 2.0 Fixed ACPI Description Table (FADT)
*/ */
struct fadt_descriptor_rev2 struct fadt_descriptor_rev2
{ {
ACPI_TABLE_HEADER_DEF /* ACPI common table header */ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
u32 V1_firmware_ctrl; /* 32-bit physical address of FACS */ FADT_REV2_COMMON
u32 V1_dsdt; /* 32-bit physical address of DSDT */
u8 reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/
u8 prefer_PM_profile; /* Conveys preferred power management profile to OSPM. */
u16 sci_int; /* System vector of SCI interrupt */
u32 smi_cmd; /* Port address of SMI command port */
u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */
u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */
u8 S4bios_req; /* Value to write to SMI CMD to enter S4BIOS state */
u8 pstate_cnt; /* Processor performance state control*/
u32 V1_pm1a_evt_blk; /* Port address of Power Mgt 1a acpi_event Reg Blk */
u32 V1_pm1b_evt_blk; /* Port address of Power Mgt 1b acpi_event Reg Blk */
u32 V1_pm1a_cnt_blk; /* Port address of Power Mgt 1a Control Reg Blk */
u32 V1_pm1b_cnt_blk; /* Port address of Power Mgt 1b Control Reg Blk */
u32 V1_pm2_cnt_blk; /* Port address of Power Mgt 2 Control Reg Blk */
u32 V1_pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl Reg Blk */
u32 V1_gpe0_blk; /* Port addr of General Purpose acpi_event 0 Reg Blk */
u32 V1_gpe1_blk; /* Port addr of General Purpose acpi_event 1 Reg Blk */
u8 pm1_evt_len; /* Byte length of ports at pm1_x_evt_blk */
u8 pm1_cnt_len; /* Byte length of ports at pm1_x_cnt_blk */
u8 pm2_cnt_len; /* Byte Length of ports at pm2_cnt_blk */
u8 pm_tm_len; /* Byte Length of ports at pm_tm_blk */
u8 gpe0_blk_len; /* Byte Length of ports at gpe0_blk */
u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
u8 gpe1_base; /* Offset in gpe model where gpe1 events start */
u8 cst_cnt; /* Support for the _CST object and C States change notification.*/
u16 plvl2_lat; /* Worst case HW latency to enter/exit C2 state */
u16 plvl3_lat; /* Worst case HW latency to enter/exit C3 state */
u16 flush_size; /* Number of flush strides that need to be read */
u16 flush_stride; /* Processor's memory cache line width, in bytes */
u8 duty_offset; /* Processor's duty cycle index in processor's P_CNT reg*/
u8 duty_width; /* Processor's duty cycle value bit width in P_CNT register.*/
u8 day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */
u8 mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */
u8 century; /* Index to century in RTC CMOS RAM */
u16 iapc_boot_arch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/
u8 reserved2; /* Reserved */ u8 reserved2; /* Reserved */
u32 wb_invd : 1; /* The wbinvd instruction works properly */ u32 wb_invd : 1; /* The wbinvd instruction works properly */
u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */ u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */
...@@ -195,6 +199,20 @@ struct fadt_descriptor_rev2 ...@@ -195,6 +199,20 @@ struct fadt_descriptor_rev2
}; };
/* "Downrevved" ACPI 2.0 FADT descriptor */
struct fadt_descriptor_rev2_minus
{
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
FADT_REV2_COMMON
u8 reserved2; /* Reserved */
u32 flags;
struct acpi_generic_address reset_register; /* Reset register address in GAS format */
u8 reset_value; /* Value to write to the reset_register port to reset the system. */
u8 reserved7[3]; /* These three bytes must be zero */
};
/* Embedded Controller */ /* Embedded Controller */
struct ec_boot_resources struct ec_boot_resources
......
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