Commit 8c15f7c9 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] ACPICA 20041119 from Bob Moore

Fixed a problem in acpi_ex_convert_to_integer
where new integers were not truncated to 32 bits for
32-bit ACPI tables. This routine converts buffers and
strings to integers.

Implemented support to store a value to an Index() on a
String object.  This is an ACPI 2.0 feature that had not
yet been implemented.

Implemented new behavior for storing objects to individual
package elements (via the Index() operator). The
previous behavior was to invoke the implicit conversion
rules if an object was already present at the index.
The new behavior is to simply delete any existing object
and directly store the new object. Although the ACPI
specification seems unclear on this subject, other ACPI
implementations behave in this manner.  (This is the root
of the AE_BAD_HEX_CONSTANT issue.)

Modified the RSDP memory scan mechanism to support the
extended checksum for ACPI 2.0 (and above) RSDPs. Note
that the search continues until a valid RSDP signature is
found with a valid checksum.
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 1c9af6dd
...@@ -95,7 +95,7 @@ acpi_ex_add_table ( ...@@ -95,7 +95,7 @@ acpi_ex_add_table (
ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc)); ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc));
table_info.type = 5; table_info.type = ACPI_TABLE_SSDT;
table_info.pointer = table; table_info.pointer = table;
table_info.length = (acpi_size) table->length; table_info.length = (acpi_size) table->length;
table_info.allocation = ACPI_MEM_ALLOCATED; table_info.allocation = ACPI_MEM_ALLOCATED;
......
...@@ -115,12 +115,6 @@ acpi_ex_convert_to_integer ( ...@@ -115,12 +115,6 @@ acpi_ex_convert_to_integer (
*/ */
result = 0; result = 0;
/* Transfer no more than an integer's worth of data */
if (count > acpi_gbl_integer_byte_width) {
count = acpi_gbl_integer_byte_width;
}
/* /*
* String conversion is different than Buffer conversion * String conversion is different than Buffer conversion
*/ */
...@@ -142,6 +136,12 @@ acpi_ex_convert_to_integer ( ...@@ -142,6 +136,12 @@ acpi_ex_convert_to_integer (
case ACPI_TYPE_BUFFER: case ACPI_TYPE_BUFFER:
/* Transfer no more than an integer's worth of data */
if (count > acpi_gbl_integer_byte_width) {
count = acpi_gbl_integer_byte_width;
}
/* /*
* Convert buffer to an integer - we simply grab enough raw data * Convert buffer to an integer - we simply grab enough raw data
* from the buffer to fill an integer * from the buffer to fill an integer
...@@ -173,6 +173,7 @@ acpi_ex_convert_to_integer ( ...@@ -173,6 +173,7 @@ acpi_ex_convert_to_integer (
/* Save the Result */ /* Save the Result */
return_desc->integer.value = result; return_desc->integer.value = result;
acpi_ex_truncate_for32bit_table (return_desc);
*result_desc = return_desc; *result_desc = return_desc;
return_ACPI_STATUS (AE_OK); return_ACPI_STATUS (AE_OK);
} }
...@@ -520,7 +521,8 @@ acpi_ex_convert_to_string ( ...@@ -520,7 +521,8 @@ acpi_ex_convert_to_string (
/* Recalculate length */ /* Recalculate length */
return_desc->string.length = ACPI_STRLEN (return_desc->string.pointer); return_desc->string.length = (u32)
ACPI_STRLEN (return_desc->string.pointer);
break; break;
default: default:
......
...@@ -110,10 +110,12 @@ acpi_ex_dump_operand ( ...@@ -110,10 +110,12 @@ acpi_ex_dump_operand (
/* obj_desc is a valid object */ /* obj_desc is a valid object */
if (depth > 0) { if (depth > 0) {
ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "%*s[%u] ", depth, " ", depth)); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%*s[%u] %p ",
depth, " ", depth, obj_desc));
}
else {
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%p ", obj_desc));
} }
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:
......
...@@ -410,7 +410,7 @@ acpi_ex_opcode_2A_1T_1R ( ...@@ -410,7 +410,7 @@ acpi_ex_opcode_2A_1T_1R (
index = (u32) operand[1]->integer.value; index = (u32) operand[1]->integer.value;
/* /*
* At this point, the Source operand is either a Package or a Buffer * At this point, the Source operand is a Package, Buffer, or String
*/ */
if (ACPI_GET_OBJECT_TYPE (operand[0]) == ACPI_TYPE_PACKAGE) { if (ACPI_GET_OBJECT_TYPE (operand[0]) == ACPI_TYPE_PACKAGE) {
/* Object to be indexed is a Package */ /* Object to be indexed is a Package */
...@@ -428,7 +428,7 @@ acpi_ex_opcode_2A_1T_1R ( ...@@ -428,7 +428,7 @@ acpi_ex_opcode_2A_1T_1R (
return_desc->reference.where = &operand[0]->package.elements [index]; return_desc->reference.where = &operand[0]->package.elements [index];
} }
else { else {
/* Object to be indexed is a Buffer */ /* Object to be indexed is a Buffer/String */
if (index >= operand[0]->buffer.length) { if (index >= operand[0]->buffer.length) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
......
...@@ -295,56 +295,45 @@ acpi_ex_store_object_to_index ( ...@@ -295,56 +295,45 @@ acpi_ex_store_object_to_index (
switch (index_desc->reference.target_type) { switch (index_desc->reference.target_type) {
case ACPI_TYPE_PACKAGE: case ACPI_TYPE_PACKAGE:
/* /*
* Storing to a package element is not simple. The source must be * Storing to a package element. Copy the object and replace
* evaluated and converted to the type of the destination and then the * any existing object with the new object. No implicit
* source is copied into the destination - we can't just point to the * conversion is performed.
* source object. *
*/
/*
* The object at *(index_desc->Reference.Where) is the * The object at *(index_desc->Reference.Where) is the
* element within the package that is to be modified. * element within the package that is to be modified.
* The parent package object is at index_desc->Reference.Object * The parent package object is at index_desc->Reference.Object
*/ */
obj_desc = *(index_desc->reference.where); obj_desc = *(index_desc->reference.where);
/* Do the conversion/store */ status = acpi_ut_copy_iobject_to_iobject (source_desc, &new_desc, walk_state);
status = acpi_ex_store_object_to_object (source_desc, obj_desc, &new_desc,
walk_state);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not store object to indexed package element\n"));
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
/* if (obj_desc) {
* If a new object was created, we must install it as the new /* Decrement reference count by the ref count of the parent package */
* package element
*/
if (new_desc != obj_desc) {
acpi_ut_remove_reference (obj_desc);
*(index_desc->reference.where) = new_desc;
/* If same as the original source, add a reference */ for (i = 0; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
acpi_ut_remove_reference (obj_desc);
if (new_desc == source_desc) {
acpi_ut_add_reference (new_desc);
} }
}
/* Increment reference count by the ref count of the parent package -1 */ *(index_desc->reference.where) = new_desc;
for (i = 1; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) { /* Increment reference count by the ref count of the parent package -1 */
acpi_ut_add_reference (new_desc);
} for (i = 1; i < ((union acpi_operand_object *) index_desc->reference.object)->common.reference_count; i++) {
acpi_ut_add_reference (new_desc);
} }
break; break;
case ACPI_TYPE_BUFFER_FIELD: case ACPI_TYPE_BUFFER_FIELD:
/* /*
* Store into a Buffer (not actually a real buffer_field) at a * Store into a Buffer or String (not actually a real buffer_field)
* location defined by an Index. * at a location defined by an Index.
* *
* The first 8-bit element of the source object is written to the * The first 8-bit element of the source object is written to the
* 8-bit Buffer location defined by the Index destination object, * 8-bit Buffer location defined by the Index destination object,
...@@ -352,10 +341,13 @@ acpi_ex_store_object_to_index ( ...@@ -352,10 +341,13 @@ acpi_ex_store_object_to_index (
*/ */
/* /*
* Make sure the target is a Buffer * Make sure the target is a Buffer or String. An error should
* not happen here, since the reference_object was constructed
* by the INDEX_OP code.
*/ */
obj_desc = index_desc->reference.object; obj_desc = index_desc->reference.object;
if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) { if ((ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_BUFFER) &&
(ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_STRING)) {
return_ACPI_STATUS (AE_AML_OPERAND_TYPE); return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
} }
...@@ -372,13 +364,11 @@ acpi_ex_store_object_to_index ( ...@@ -372,13 +364,11 @@ acpi_ex_store_object_to_index (
break; break;
case ACPI_TYPE_BUFFER: case ACPI_TYPE_BUFFER:
value = source_desc->buffer.pointer[0];
break;
case ACPI_TYPE_STRING: case ACPI_TYPE_STRING:
value = (u8) source_desc->string.pointer[0]; /* Note: Takes advantage of common string/buffer fields */
value = source_desc->buffer.pointer[0];
break; break;
default: default:
......
...@@ -277,6 +277,7 @@ acpi_tb_get_table_rsdt ( ...@@ -277,6 +277,7 @@ acpi_tb_get_table_rsdt (
acpi_tb_get_rsdt_address (&address); acpi_tb_get_rsdt_address (&address);
table_info.type = ACPI_TABLE_XSDT;
status = acpi_tb_get_table (&address, &table_info); status = acpi_tb_get_table (&address, &table_info);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n", ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the RSDT/XSDT, %s\n",
......
...@@ -387,35 +387,58 @@ acpi_tb_scan_memory_for_rsdp ( ...@@ -387,35 +387,58 @@ acpi_tb_scan_memory_for_rsdp (
u8 *start_address, u8 *start_address,
u32 length) u32 length)
{ {
u32 offset;
u8 *mem_rover; u8 *mem_rover;
u8 *end_address;
u8 checksum;
ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp"); ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp");
/* Search from given start addr for the requested length */ end_address = start_address + length;
for (offset = 0, mem_rover = start_address; /* Search from given start address for the requested length */
offset < length;
offset += ACPI_RSDP_SCAN_STEP, mem_rover += ACPI_RSDP_SCAN_STEP) {
for (mem_rover = start_address; mem_rover < end_address;
mem_rover += ACPI_RSDP_SCAN_STEP) {
/* The signature and checksum must both be correct */ /* The signature and checksum must both be correct */
if (ACPI_STRNCMP ((char *) mem_rover, if (ACPI_STRNCMP ((char *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 && /* No signature match, keep looking */
acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH) == 0) {
/* If so, we have found the RSDP */ continue;
}
/* Signature matches, check the appropriate checksum */
if (((struct rsdp_descriptor *) mem_rover)->revision < 2) {
/* ACPI version 1.0 */
checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH);
}
else {
/* Post ACPI 1.0, use extended_checksum */
checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH);
}
if (checksum == 0) {
/* Checksum valid, we have found a valid RSDP */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"RSDP located at physical address %p\n",mem_rover)); "RSDP located at physical address %p\n", mem_rover));
return_PTR (mem_rover); return_PTR (mem_rover);
} }
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Found an RSDP at physical address %p, but it has a bad checksum\n",
mem_rover));
} }
/* Searched entire block, no RSDP was found */ /* Searched entire block, no RSDP was found */
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,"Searched entire block, no RSDP was found.\n")); ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"Searched entire block, no valid RSDP was found.\n"));
return_PTR (NULL); return_PTR (NULL);
} }
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
/* Version string */ /* Version string */
#define ACPI_CA_VERSION 0x20041105 #define ACPI_CA_VERSION 0x20041119
/* /*
* 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,
......
...@@ -487,19 +487,19 @@ ...@@ -487,19 +487,19 @@
* The first parameter should be the procedure name as a quoted string. This is declared * The first parameter should be the procedure name as a quoted string. This is declared
* as a local string ("_proc_name) so that it can be also used by the function exit macros below. * as a local string ("_proc_name) so that it can be also used by the function exit macros below.
*/ */
#define ACPI_FUNCTION_NAME(a) struct acpi_debug_print_info _dbg; \ #define ACPI_FUNCTION_NAME(a) struct acpi_debug_print_info _debug_info; \
_dbg.component_id = _COMPONENT; \ _debug_info.component_id = _COMPONENT; \
_dbg.proc_name = a; \ _debug_info.proc_name = a; \
_dbg.module_name = _THIS_MODULE; _debug_info.module_name = _THIS_MODULE;
#define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \ #define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \
acpi_ut_trace(__LINE__,&_dbg) acpi_ut_trace(__LINE__,&_debug_info)
#define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \ #define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \
acpi_ut_trace_ptr(__LINE__,&_dbg,(void *)b) acpi_ut_trace_ptr(__LINE__,&_debug_info,(void *)b)
#define ACPI_FUNCTION_TRACE_U32(a,b) ACPI_FUNCTION_NAME(a) \ #define ACPI_FUNCTION_TRACE_U32(a,b) ACPI_FUNCTION_NAME(a) \
acpi_ut_trace_u32(__LINE__,&_dbg,(u32)b) acpi_ut_trace_u32(__LINE__,&_debug_info,(u32)b)
#define ACPI_FUNCTION_TRACE_STR(a,b) ACPI_FUNCTION_NAME(a) \ #define ACPI_FUNCTION_TRACE_STR(a,b) ACPI_FUNCTION_NAME(a) \
acpi_ut_trace_str(__LINE__,&_dbg,(char *)b) acpi_ut_trace_str(__LINE__,&_debug_info,(char *)b)
#define ACPI_FUNCTION_ENTRY() acpi_ut_track_stack_ptr() #define ACPI_FUNCTION_ENTRY() acpi_ut_track_stack_ptr()
...@@ -516,10 +516,10 @@ ...@@ -516,10 +516,10 @@
#define ACPI_DO_WHILE0(a) a #define ACPI_DO_WHILE0(a) a
#endif #endif
#define return_VOID ACPI_DO_WHILE0 ({acpi_ut_exit(__LINE__,&_dbg);return;}) #define return_VOID ACPI_DO_WHILE0 ({acpi_ut_exit(__LINE__,&_debug_info);return;})
#define return_ACPI_STATUS(s) ACPI_DO_WHILE0 ({acpi_ut_status_exit(__LINE__,&_dbg,(s));return((s));}) #define return_ACPI_STATUS(s) ACPI_DO_WHILE0 ({acpi_ut_status_exit(__LINE__,&_debug_info,(s));return((s));})
#define return_VALUE(s) ACPI_DO_WHILE0 ({acpi_ut_value_exit(__LINE__,&_dbg,(acpi_integer)(s));return((s));}) #define return_VALUE(s) ACPI_DO_WHILE0 ({acpi_ut_value_exit(__LINE__,&_debug_info,(acpi_integer)(s));return((s));})
#define return_PTR(s) ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(__LINE__,&_dbg,(u8 *)(s));return((s));}) #define return_PTR(s) ACPI_DO_WHILE0 ({acpi_ut_ptr_exit(__LINE__,&_debug_info,(u8 *)(s));return((s));})
/* Conditional execution */ /* Conditional execution */
......
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
/* /*
* Debug level macros that are used in the DEBUG_PRINT macros * Debug level macros that are used in the DEBUG_PRINT macros
*/ */
#define ACPI_DEBUG_LEVEL(dl) (u32) dl,__LINE__,&_dbg #define ACPI_DEBUG_LEVEL(dl) (u32) dl,__LINE__,&_debug_info
/* Exception level -- used in the global "debug_level" */ /* Exception level -- used in the global "debug_level" */
......
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