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 (
* was referenced by the method (via the ASL)
* 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:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at node %p\n",
......
......@@ -426,7 +426,9 @@ acpi_ds_exec_end_op (
(walk_state->operands[0]->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[1]->reference.opcode)) {
walk_state->operands[1]->reference.opcode) &&
(walk_state->operands[0]->reference.offset ==
walk_state->operands[1]->reference.offset)) {
status = AE_OK;
}
else {
......
......@@ -182,18 +182,20 @@ acpi_ds_load1_begin_op (
*/
status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
if (ACPI_FAILURE (status)) {
#ifdef _ACPI_ASL_COMPILER
if (status == AE_NOT_FOUND) {
acpi_dm_add_to_external_list (path);
status = AE_OK;
}
else {
ACPI_REPORT_NSERROR (path, status);
}
#else
ACPI_REPORT_NSERROR (path, status);
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);
status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
}
#endif
if (ACPI_FAILURE (status)) {
ACPI_REPORT_NSERROR (path, status);
return (status);
}
......
......@@ -867,6 +867,7 @@ acpi_ds_create_walk_state (
status = acpi_ds_result_stack_push (walk_state);
if (ACPI_FAILURE (status)) {
acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
return_PTR (NULL);
}
......
......@@ -63,7 +63,7 @@
*
* PARAMETERS: *obj_desc - Pointer to entry to be dumped
*
* RETURN: Status
* RETURN: None
*
* DESCRIPTION: Dump an operand object
*
......@@ -71,12 +71,11 @@
void
acpi_ex_dump_operand (
union acpi_operand_object *obj_desc)
union acpi_operand_object *obj_desc,
u32 depth)
{
u8 *buf = NULL;
u32 length;
union acpi_operand_object **element;
u16 element_index;
u32 index;
ACPI_FUNCTION_NAME ("ex_dump_operand")
......@@ -88,9 +87,9 @@ acpi_ex_dump_operand (
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;
}
......@@ -110,7 +109,11 @@ acpi_ex_dump_operand (
/* 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)) {
case ACPI_TYPE_LOCAL_REFERENCE:
......@@ -193,7 +196,6 @@ acpi_ex_dump_operand (
break;
}
break;
......@@ -203,7 +205,6 @@ acpi_ex_dump_operand (
obj_desc->buffer.length, obj_desc->buffer.pointer);
length = obj_desc->buffer.length;
if (length > 64) {
length = 64;
}
......@@ -213,12 +214,11 @@ acpi_ex_dump_operand (
if (obj_desc->buffer.pointer) {
acpi_os_printf ("Buffer Contents: ");
for (buf = obj_desc->buffer.pointer; length--; ++buf) {
acpi_os_printf (" %02x", *buf);
for (index = 0; index < length; index++) {
acpi_os_printf (" %02x", obj_desc->buffer.pointer[index]);
}
acpi_os_printf ("\n");
}
break;
......@@ -231,23 +231,20 @@ acpi_ex_dump_operand (
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);
/*
* 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.
*/
if (obj_desc->package.count &&
obj_desc->package.elements &&
acpi_dbg_level > 1) {
for (element_index = 0, element = obj_desc->package.elements;
element_index < obj_desc->package.count;
++element_index, ++element) {
acpi_ex_dump_operand (*element);
for (index = 0; index < obj_desc->package.count; index++) {
acpi_ex_dump_operand (obj_desc->package.elements[index], depth+1);
}
}
acpi_os_printf ("\n");
break;
......@@ -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_UPDATE_RULE_MASK,
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;
......@@ -319,9 +316,8 @@ acpi_ex_dump_operand (
acpi_os_printf ("*not a Buffer* \n");
}
else {
ACPI_DUMP_STACK_ENTRY (obj_desc->buffer_field.buffer_obj);
acpi_ex_dump_operand (obj_desc->buffer_field.buffer_obj, depth+1);
}
break;
......@@ -408,7 +404,6 @@ acpi_ex_dump_operands (
u32 line_number)
{
acpi_native_uint i;
union acpi_operand_object **obj_desc;
ACPI_FUNCTION_NAME ("ex_dump_operands");
......@@ -433,8 +428,7 @@ acpi_ex_dump_operands (
/* Dump the operand stack starting at the top */
for (i = 0; num_levels > 0; i--, num_levels--) {
obj_desc = &operands[i];
acpi_ex_dump_operand (*obj_desc);
acpi_ex_dump_operand (operands[i], 0);
}
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
......@@ -499,7 +493,7 @@ acpi_ex_out_address (
*
* FUNCTION: acpi_ex_dump_node
*
* PARAMETERS: *Node - Descriptor to dump
* PARAMETERS: *Node - Descriptor to dump
* Flags - Force display
*
* DESCRIPTION: Dumps the members of the given.Node
......
......@@ -686,13 +686,19 @@ acpi_ex_opcode_1A_0T_1R (
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 */
status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, NULL);
if (ACPI_FAILURE (status)) {
goto cleanup;
}
/* Allocate a descriptor to hold the type. */
return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
......@@ -707,6 +713,11 @@ acpi_ex_opcode_1A_0T_1R (
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 */
status = acpi_ex_resolve_multiple (walk_state, operand[0], &type, &temp_desc);
......@@ -715,11 +726,19 @@ acpi_ex_opcode_1A_0T_1R (
}
/*
* Type is guaranteed to be a buffer, string, or package at this
* point (even if the original operand was an object reference, it
* will be resolved and typechecked during operand resolution.)
* The type of the base object must be integer, buffer, string, or
* package. All others are not supported.
*
* 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) {
case ACPI_TYPE_INTEGER:
value = acpi_gbl_integer_byte_width;
break;
case ACPI_TYPE_BUFFER:
value = temp_desc->buffer.length;
break;
......@@ -734,7 +753,7 @@ acpi_ex_opcode_1A_0T_1R (
default:
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)));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
......
......@@ -508,6 +508,7 @@ acpi_ex_prep_field_value (
if (!obj_desc->index_field.data_obj || !obj_desc->index_field.index_obj) {
ACPI_REPORT_ERROR (("Null Index Object during field prep\n"));
acpi_ut_delete_object_desc (obj_desc);
return_ACPI_STATUS (AE_AML_INTERNAL);
}
......
......@@ -327,11 +327,44 @@ acpi_ex_resolve_multiple (
union acpi_operand_object *obj_desc = (void *) operand;
struct acpi_namespace_node *node;
acpi_object_type type;
acpi_status status;
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,
* we need to get to the base object (as per the ACPI specification
......@@ -424,6 +457,33 @@ acpi_ex_resolve_multiple (
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:
/* The Debug Object is of type "debug_object" */
......
......@@ -206,6 +206,7 @@ acpi_ns_root_initialize (void)
status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT,
1, &obj_desc->mutex.semaphore);
if (ACPI_FAILURE (status)) {
acpi_ut_remove_reference (obj_desc);
goto unlock_and_exit;
}
......@@ -221,6 +222,7 @@ acpi_ns_root_initialize (void)
status = acpi_os_create_semaphore (1, 1,
&obj_desc->mutex.semaphore);
if (ACPI_FAILURE (status)) {
acpi_ut_remove_reference (obj_desc);
goto unlock_and_exit;
}
}
......
......@@ -502,8 +502,8 @@ acpi_ns_delete_namespace_subtree (
* visit the node
*/
level++;
parent_node = child_node;
child_node = NULL;
parent_node = child_node;
child_node = NULL;
}
}
else {
......@@ -650,8 +650,8 @@ acpi_ns_delete_namespace_by_owner (
* visit the node
*/
level++;
parent_node = child_node;
child_node = NULL;
parent_node = child_node;
child_node = NULL;
}
else if (child_node->owner_id == owner_id) {
deletion_node = child_node;
......
......@@ -264,8 +264,8 @@ acpi_ns_walk_namespace (
* node, visit the onde
*/
level++;
parent_node = child_node;
child_node = NULL;
parent_node = child_node;
child_node = NULL;
}
}
}
......
......@@ -318,7 +318,7 @@
#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_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_STALL_OP ARGI_LIST1 (ARGI_INTEGER)
#define ARGI_STATICSTRING_OP ARGI_INVALID_OPCODE
......@@ -333,7 +333,7 @@
#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_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_VAR_PACKAGE_OP ARGI_LIST1 (ARGI_INTEGER)
#define ARGI_WAIT_OP ARGI_LIST2 (ARGI_EVENT, ARGI_INTEGER)
......
......@@ -164,123 +164,125 @@ acpi_ps_complete_this_op (
/* Delete this op and the subtree below it if asked to */
if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) &&
(walk_state->op_info->class != AML_CLASS_ARGUMENT)) {
/* Make sure that we only delete this subtree */
if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) ||
(walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
return_VOID;
}
/* Make sure that we only delete this subtree */
if (op->common.parent) {
/*
* Check if we need to replace the operator and its subtree
* with a return value op (placeholder op)
*/
parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
switch (parent_info->class) {
case AML_CLASS_CONTROL:
break;
case AML_CLASS_CREATE:
if (op->common.parent) {
/*
* Check if we need to replace the operator and its subtree
* with a return value op (placeholder op)
* These opcodes contain term_arg operands. The current
* op must be replaced by a placeholder return op
*/
parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
switch (parent_info->class) {
case AML_CLASS_CONTROL:
break;
replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
if (!replacement_op) {
goto cleanup;
}
break;
case AML_CLASS_CREATE:
case AML_CLASS_NAMED_OBJECT:
/*
* These opcodes contain term_arg operands. The current
* op must be replaced by a placeholder return op
*/
/*
* These opcodes contain term_arg operands. The current
* op must be replaced by a placeholder return op
*/
if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
(op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) ||
(op->common.parent->common.aml_opcode == AML_BUFFER_OP) ||
(op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
(op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
if (!replacement_op) {
return_VOID;
goto cleanup;
}
break;
case AML_CLASS_NAMED_OBJECT:
}
/*
* These opcodes contain term_arg operands. The current
* op must be replaced by a placeholder return op
*/
if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
(op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) ||
(op->common.parent->common.aml_opcode == AML_BUFFER_OP) ||
(op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
(op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
if ((op->common.parent->common.aml_opcode == AML_NAME_OP) &&
(walk_state->descending_callback != acpi_ds_exec_begin_op)) {
if ((op->common.aml_opcode == AML_BUFFER_OP) ||
(op->common.aml_opcode == AML_PACKAGE_OP) ||
(op->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
replacement_op = acpi_ps_alloc_op (op->common.aml_opcode);
if (!replacement_op) {
return_VOID;
goto cleanup;
}
replacement_op->named.data = op->named.data;
replacement_op->named.length = op->named.length;
}
}
break;
if ((op->common.parent->common.aml_opcode == AML_NAME_OP) &&
(walk_state->descending_callback != acpi_ds_exec_begin_op)) {
if ((op->common.aml_opcode == AML_BUFFER_OP) ||
(op->common.aml_opcode == AML_PACKAGE_OP) ||
(op->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
replacement_op = acpi_ps_alloc_op (op->common.aml_opcode);
if (!replacement_op) {
return_VOID;
}
default:
replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
if (!replacement_op) {
goto cleanup;
}
}
replacement_op->named.data = op->named.data;
replacement_op->named.length = op->named.length;
}
}
break;
/* We must unlink this op from the parent tree */
default:
replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
if (!replacement_op) {
return_VOID;
}
prev = op->common.parent->common.value.arg;
if (prev == op) {
/* This op is the first in the list */
if (replacement_op) {
replacement_op->common.parent = op->common.parent;
replacement_op->common.value.arg = NULL;
replacement_op->common.node = op->common.node;
op->common.parent->common.value.arg = replacement_op;
replacement_op->common.next = op->common.next;
}
else {
op->common.parent->common.value.arg = op->common.next;
}
}
/* We must unlink this op from the parent tree */
/* Search the parent list */
prev = op->common.parent->common.value.arg;
if (prev == op) {
/* This op is the first in the list */
else while (prev) {
/* Traverse all siblings in the parent's argument list */
next = prev->common.next;
if (next == op) {
if (replacement_op) {
replacement_op->common.parent = op->common.parent;
replacement_op->common.value.arg = NULL;
replacement_op->common.node = op->common.node;
op->common.parent->common.value.arg = replacement_op;
replacement_op->common.next = op->common.next;
replacement_op->common.parent = op->common.parent;
replacement_op->common.value.arg = NULL;
replacement_op->common.node = op->common.node;
prev->common.next = replacement_op;
replacement_op->common.next = op->common.next;
next = NULL;
}
else {
op->common.parent->common.value.arg = op->common.next;
prev->common.next = op->common.next;
next = NULL;
}
}
/* Search the parent list */
else while (prev) {
/* Traverse all siblings in the parent's argument list */
next = prev->common.next;
if (next == op) {
if (replacement_op) {
replacement_op->common.parent = op->common.parent;
replacement_op->common.value.arg = NULL;
replacement_op->common.node = op->common.node;
prev->common.next = replacement_op;
replacement_op->common.next = op->common.next;
next = NULL;
}
else {
prev->common.next = op->common.next;
next = NULL;
}
}
prev = next;
}
prev = next;
}
}
/* 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;
}
......@@ -552,7 +554,8 @@ acpi_ps_parse_loop (
if (!pre_op) {
pre_op = acpi_ps_alloc_op (walk_state->opcode);
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 (
/* Make sure that we found a NAME and didn't run out of arguments */
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 */
......@@ -638,7 +642,8 @@ acpi_ps_parse_loop (
walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
op = acpi_ps_alloc_op (walk_state->opcode);
if (!op) {
return_ACPI_STATUS (AE_NO_MEMORY);
status = AE_NO_MEMORY;
goto close_this_op;
}
if (walk_state->op_info->flags & AML_CREATE) {
......@@ -801,7 +806,7 @@ acpi_ps_parse_loop (
status = acpi_ps_push_scope (parser_state, op,
walk_state->arg_types, walk_state->arg_count);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
goto close_this_op;
}
op = NULL;
continue;
......@@ -1128,7 +1133,7 @@ acpi_ps_parse_aml (
else if (status == AE_CTRL_TERMINATE) {
status = AE_OK;
}
else if (status != AE_OK) {
else if ((status != AE_OK) && (walk_state->method_desc)) {
ACPI_REPORT_METHOD_ERROR ("Method execution failed",
walk_state->method_node, NULL, status);
......
......@@ -251,10 +251,26 @@ acpi_tb_convert_fadt1 (
local_fadt->cst_cnt = 0;
/*
* Since there isn't any equivalence in 1.0 and since it highly likely
* that a 1.0 system has legacy support.
* FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0.
* It primarily adds the FADT reset mechanism.
*/
local_fadt->iapc_boot_arch = BAF_LEGACY_DEVICES;
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;
}
/*
* Convert the V1.0 block addresses to V2.0 GAS structures
......@@ -418,23 +434,21 @@ acpi_tb_convert_table_fadt (void)
/*
* acpi_gbl_FADT is valid
* Allocate and zero the 2.0 FADT buffer
*/
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
* acpi_gbl_FADT is valid. Validate the FADT length. The table must be
* at least as long as the version 1.0 FADT
*/
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);
}
/* 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->length < sizeof (struct fadt_descriptor_rev2)) {
/* Length is too short to be a V2.0 table */
......
......@@ -266,9 +266,10 @@ acpi_tb_init_table_descriptor (
if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) {
/*
* Only one table allowed, and a table has alread been installed
* at this location, so return an error.
* at this location, so return an error.
*/
if (list_head->next) {
ACPI_MEM_FREE (table_desc);
return_ACPI_STATUS (AE_ALREADY_EXISTS);
}
......
......@@ -424,23 +424,21 @@ acpi_ut_copy_esimple_to_isimple (
break;
default:
/*
* Whatever other type -- it is not supported
*/
/* All other types are not supported */
return_ACPI_STATUS (AE_SUPPORT);
}
switch (external_object->type) {
/* Must COPY string and buffer contents */
switch (external_object->type) {
case ACPI_TYPE_STRING:
internal_object->string.pointer =
ACPI_MEM_CALLOCATE ((acpi_size) external_object->string.length + 1);
if (!internal_object->string.pointer) {
return_ACPI_STATUS (AE_NO_MEMORY);
goto error_exit;
}
ACPI_MEMCPY (internal_object->string.pointer,
......@@ -456,7 +454,7 @@ acpi_ut_copy_esimple_to_isimple (
internal_object->buffer.pointer =
ACPI_MEM_CALLOCATE (external_object->buffer.length);
if (!internal_object->buffer.pointer) {
return_ACPI_STATUS (AE_NO_MEMORY);
goto error_exit;
}
ACPI_MEMCPY (internal_object->buffer.pointer,
......@@ -479,6 +477,11 @@ acpi_ut_copy_esimple_to_isimple (
*ret_internal_object = internal_object;
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 (
status = acpi_ut_copy_simple_object (source_object, target_object);
if (ACPI_FAILURE (status)) {
return (status);
goto error_exit;
}
*this_target_ptr = target_object;
......@@ -781,8 +784,8 @@ acpi_ut_copy_ielement_to_ielement (
ACPI_MEM_CALLOCATE (((acpi_size) source_object->package.count + 1) *
sizeof (void *));
if (!target_object->package.elements) {
ACPI_MEM_FREE (target_object);
return (AE_NO_MEMORY);
status = AE_NO_MEMORY;
goto error_exit;
}
/*
......@@ -802,6 +805,10 @@ acpi_ut_copy_ielement_to_ielement (
}
return (status);
error_exit:
acpi_ut_remove_reference (target_object);
return (status);
}
......
......@@ -64,7 +64,7 @@
/* 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,
......
......@@ -92,7 +92,10 @@ extern u32 acpi_gbl_nesting_level;
/*
* Enable "slack" in the AML interpreter? Default is FALSE, and the
* 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);
......
......@@ -486,12 +486,13 @@ acpi_ex_resolve_object_to_value (
/*
* exdump - Scanner debug output routines
* exdump - Interpreter debug output routines
*/
void
acpi_ex_dump_operand (
union acpi_operand_object *entry_desc);
union acpi_operand_object *obj_desc,
u32 depth);
void
acpi_ex_dump_operands (
......
......@@ -533,7 +533,7 @@
/* 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__)
......
......@@ -62,6 +62,7 @@
#define BAF_8042_KEYBOARD_CONTROLLER 0x0002
#define FADT2_REVISION_ID 3
#define FADT2_MINUS_REVISION_ID 2
#pragma pack(1)
......@@ -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)
*/
struct fadt_descriptor_rev2
{
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
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*/
FADT_REV2_COMMON
u8 reserved2; /* Reserved */
u32 wb_invd : 1; /* The wbinvd instruction works properly */
u32 wb_invd_flush : 1; /* The wbinvd flushes but does not invalidate */
......@@ -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 */
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