Commit 51b3e81b authored by Len Brown's avatar Len Brown

Merge intel.com:/home/lenb/src/26-stable-acpica

into intel.com:/home/lenb/src/26-stable-dev
parents a3e945a6 adbd7582
......@@ -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