Commit dac231e4 authored by Len Brown's avatar Len Brown

[ACPI] Summary of changes for ACPICA version 20031002:

Fixed a problem with Index Fields where the index was not incremented
for fields that require multiple writes to the index/data registers
(Fields that are wider than the data register.)

Fixed a problem with all Field objects where a write could go beyond the
end-of-field if the field was larger than the access granularity and
therefore required multiple writes to complete the request.  An extra
write beyond the end of the field could happen inadvertently.

Fixed a problem with Index Fields where a BUFFER_OVERFLOW error would
incorrectly be returned if the width of the Data Register was larger
than the specified field access width.

Completed fixes for LoadTable() and Unload() and verified their
operation.  Implemented full support for the "DdbHandle" object
throughout the ACPI CA subsystem.

Implemented full support for the MADT and ECDT tables in the ACPI CA
header files.  Even though these tables are not directly consumed by
ACPI CA, the header definitions are useful for ACPI device drivers.

Integrated resource descriptor fixes posted to the Linux ACPI list.
This included checks for minimum descriptor length, and support for
trailing NULL strings within descriptors that have optional string
elements.

Fixed a problem where the SMI_CMD register could be written even if it
was not supported on the platform (when FADT.SMI_CMD is zero)
parent 13ea5e83
......@@ -92,6 +92,9 @@ acpi_ex_add_table (
/* Install the new table into the local data structures */
ACPI_MEMSET (&table_info, 0, sizeof (struct acpi_table_desc));
table_info.type = 5;
table_info.pointer = table;
table_info.length = (acpi_size) table->length;
table_info.allocation = ACPI_MEM_ALLOCATED;
......@@ -178,7 +181,7 @@ acpi_ex_load_table_op (
return_ACPI_STATUS (status);
}
/* Not found, return an Integer=0 and AE_OK */
/* Table not found, return an Integer=0 and AE_OK */
ddb_handle = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
if (!ddb_handle) {
......@@ -248,9 +251,11 @@ acpi_ex_load_table_op (
walk_state);
if (ACPI_FAILURE (status)) {
(void) acpi_ex_unload_table (ddb_handle);
return_ACPI_STATUS (status);
}
}
*return_desc = ddb_handle;
return_ACPI_STATUS (status);
}
......@@ -417,7 +422,7 @@ acpi_status
acpi_ex_unload_table (
union acpi_operand_object *ddb_handle)
{
acpi_status status = AE_NOT_IMPLEMENTED;
acpi_status status = AE_OK;
union acpi_operand_object *table_desc = ddb_handle;
struct acpi_table_desc *table_info;
......
......@@ -160,10 +160,10 @@ acpi_ex_read_data_from_field (
}
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Obj=%p Type=%X Buf=%p Len=%X\n",
"field_read [TO]: Obj %p, Type %X, Buf %p, byte_len %X\n",
obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, (u32) length));
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"field_write: bit_len=%X bit_off=%X byte_off=%X\n",
"field_read [FROM]: bit_len %X, bit_off %X, byte_off %X\n",
obj_desc->common_field.bit_length,
obj_desc->common_field.start_field_bit_offset,
obj_desc->common_field.base_byte_offset));
......@@ -335,10 +335,13 @@ acpi_ex_write_data_to_field (
}
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Obj=%p Type=%X Buf=%p Len=%X\n",
obj_desc, ACPI_GET_OBJECT_TYPE (obj_desc), buffer, length));
"field_write [FROM]: Obj %p (%s:%X), Buf %p, byte_len %X\n",
source_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (source_desc)),
ACPI_GET_OBJECT_TYPE (source_desc), buffer, length));
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"field_read: bit_len=%X bit_off=%X byte_off=%X\n",
"field_write [TO]: Obj %p (%s:%X), bit_len %X, bit_off %X, byte_off %X\n",
obj_desc, acpi_ut_get_type_name (ACPI_GET_OBJECT_TYPE (obj_desc)),
ACPI_GET_OBJECT_TYPE (obj_desc),
obj_desc->common_field.bit_length,
obj_desc->common_field.start_field_bit_offset,
obj_desc->common_field.base_byte_offset));
......
This diff is collapsed.
......@@ -524,7 +524,7 @@ acpi_ex_opcode_1A_0T_1R (
acpi_integer value;
ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_0R", acpi_ps_get_opcode_name (walk_state->opcode));
ACPI_FUNCTION_TRACE_STR ("ex_opcode_1A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode));
/* Examine the AML opcode */
......
......@@ -53,6 +53,133 @@
ACPI_MODULE_NAME ("exprep")
#ifdef ACPI_UNDER_DEVELOPMENT
/*******************************************************************************
*
* FUNCTION: acpi_ex_generate_access
*
* PARAMETERS: field_bit_offset - Start of field within parent region/buffer
* field_bit_length - Length of field in bits
* region_length - Length of parent in bytes
*
* RETURN: Field granularity (8, 16, 32 or 64) and
* byte_alignment (1, 2, 3, or 4)
*
* DESCRIPTION: Generate an optimal access width for fields defined with the
* any_acc keyword.
*
* NOTE: Need to have the region_length in order to check for boundary
* conditions (end-of-region). However, the region_length is a deferred
* operation. Therefore, to complete this implementation, the generation
* of this access width must be deferred until the region length has
* been evaluated.
*
******************************************************************************/
static u32
acpi_ex_generate_access (
u32 field_bit_offset,
u32 field_bit_length,
u32 region_length)
{
u32 field_byte_length;
u32 field_byte_offset;
u32 field_byte_end_offset;
u32 access_byte_width;
u32 field_start_offset;
u32 field_end_offset;
u32 minimum_access_width = 0xFFFFFFFF;
u32 minimum_accesses = 0xFFFFFFFF;
u32 accesses;
ACPI_FUNCTION_TRACE ("ex_generate_access");
/* Round Field start offset and length to "minimal" byte boundaries */
field_byte_offset = ACPI_DIV_8 (ACPI_ROUND_DOWN (field_bit_offset, 8));
field_byte_end_offset = ACPI_DIV_8 (ACPI_ROUND_UP (field_bit_length + field_bit_offset, 8));
field_byte_length = field_byte_end_offset - field_byte_offset;
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Bit length %d, Bit offset %d\n",
field_bit_length, field_bit_offset));
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Byte Length %d, Byte Offset %d, End Offset %d\n",
field_byte_length, field_byte_offset, field_byte_end_offset));
/*
* Iterative search for the maximum access width that is both aligned
* and does not go beyond the end of the region
*
* Start at byte_acc and work upwards to qword_acc max. (1,2,4,8 bytes)
*/
for (access_byte_width = 1; access_byte_width <= 8; access_byte_width <<= 1) {
/*
* 1) Round end offset up to next access boundary and make sure that this
* does not go beyond the end of the parent region.
* 2) When the Access width is greater than the field_byte_length, we are done.
* (This does not optimize for the perfectly aligned case yet).
*/
if (ACPI_ROUND_UP (field_byte_end_offset, access_byte_width) <= region_length) {
field_start_offset = ACPI_ROUND_DOWN (field_byte_offset, access_byte_width) /
access_byte_width;
field_end_offset = ACPI_ROUND_UP ((field_byte_length + field_byte_offset),
access_byte_width) / access_byte_width;
accesses = field_end_offset - field_start_offset;
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"access_width %d end is within region\n", access_byte_width));
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Field Start %d, Field End %d -- requires %d accesses\n",
field_start_offset, field_end_offset, accesses));
/* Single access is optimal */
if (accesses <= 1) {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Entire field can be accessed with one operation of size %d\n",
access_byte_width));
return_VALUE (access_byte_width);
}
/*
* Fits in the region, but requires more than one read/write.
* try the next wider access on next iteration
*/
if (accesses < minimum_accesses) {
minimum_accesses = accesses;
minimum_access_width = access_byte_width;
}
}
else {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"access_width %d end is NOT within region\n", access_byte_width));
if (access_byte_width == 1) {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Field goes beyond end-of-region!\n"));
return_VALUE (0); /* Field does not fit in the region at all */
}
/* This width goes beyond the end-of-region, back off to previous access */
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Backing off to previous optimal access width of %d\n",
minimum_access_width));
return_VALUE (minimum_access_width);
}
}
/* Could not read/write field with one operation, just use max access width */
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Cannot access field in one operation, using width 8\n"));
return_VALUE (8);
}
#endif /* ACPI_UNDER_DEVELOPMENT */
/*******************************************************************************
*
* FUNCTION: acpi_ex_decode_field_access
......@@ -74,12 +201,11 @@ acpi_ex_decode_field_access (
u32 *return_byte_alignment)
{
u32 access;
u8 byte_alignment;
u8 bit_length;
/* u32 Length; */
u32 byte_alignment;
u32 bit_length;
ACPI_FUNCTION_NAME ("ex_decode_field_access");
ACPI_FUNCTION_TRACE ("ex_decode_field_access");
access = (field_flags & AML_FIELD_ACCESS_TYPE_MASK);
......@@ -87,41 +213,15 @@ acpi_ex_decode_field_access (
switch (access) {
case AML_FIELD_ACCESS_ANY:
#ifdef ACPI_UNDER_DEVELOPMENT
byte_alignment = acpi_ex_generate_access (obj_desc->common_field.start_field_bit_offset,
obj_desc->common_field.bit_length,
0xFFFFFFFF /* Temp until we pass region_length as param */);
bit_length = byte_alignment * 8;
#endif
byte_alignment = 1;
bit_length = 8;
#if 0
/*
* TBD: optimize
*
* Any attempt to optimize the access size to the size of the field
* must take into consideration the length of the region and take
* care that an access to the field will not attempt to access
* beyond the end of the region.
*/
/* Use the length to set the access type */
length = obj_desc->common_field.bit_length;
if (length <= 8) {
bit_length = 8;
}
else if (length <= 16) {
bit_length = 16;
}
else if (length <= 32) {
bit_length = 32;
}
else if (length <= 64) {
bit_length = 64;
}
else {
/* Larger than Qword - just use byte-size chunks */
bit_length = 8;
}
#endif
break;
case AML_FIELD_ACCESS_BYTE:
......@@ -151,7 +251,7 @@ acpi_ex_decode_field_access (
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Unknown field access type %X\n",
access));
return (0);
return_VALUE (0);
}
if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
......@@ -164,7 +264,7 @@ acpi_ex_decode_field_access (
}
*return_byte_alignment = byte_alignment;
return (bit_length);
return_VALUE (bit_length);
}
......@@ -336,7 +436,7 @@ acpi_ex_prep_field_value (
type = acpi_ns_get_type (info->region_node);
if (type != ACPI_TYPE_REGION) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Needed Region, found type %X %s\n",
"Needed Region, found type %X (%s)\n",
type, acpi_ut_get_type_name (type)));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
......@@ -372,7 +472,7 @@ acpi_ex_prep_field_value (
acpi_ut_add_reference (obj_desc->field.region_obj);
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"region_field: Bitoff=%X Off=%X Gran=%X Region %p\n",
"region_field: bit_off %X, Off %X, Gran %X, Region %p\n",
obj_desc->field.start_field_bit_offset, obj_desc->field.base_byte_offset,
obj_desc->field.access_byte_width, obj_desc->field.region_obj));
break;
......@@ -390,7 +490,7 @@ acpi_ex_prep_field_value (
acpi_ut_add_reference (obj_desc->bank_field.bank_obj);
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Bank Field: bit_off=%X Off=%X Gran=%X Region %p bank_reg %p\n",
"Bank Field: bit_off %X, Off %X, Gran %X, Region %p, bank_reg %p\n",
obj_desc->bank_field.start_field_bit_offset,
obj_desc->bank_field.base_byte_offset,
obj_desc->field.access_byte_width,
......@@ -417,9 +517,10 @@ acpi_ex_prep_field_value (
acpi_ut_add_reference (obj_desc->index_field.index_obj);
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"index_field: bitoff=%X off=%X gran=%X Index %p Data %p\n",
"index_field: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
obj_desc->index_field.start_field_bit_offset,
obj_desc->index_field.base_byte_offset,
obj_desc->index_field.value,
obj_desc->field.access_byte_width,
obj_desc->index_field.index_obj,
obj_desc->index_field.data_obj));
......@@ -437,7 +538,7 @@ acpi_ex_prep_field_value (
status = acpi_ns_attach_object (info->field_node, obj_desc,
acpi_ns_get_type (info->field_node));
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "set named_obj %p (%4.4s) val = %p\n",
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set named_obj %p [%4.4s], obj_desc %p\n",
info->field_node, info->field_node->name.ascii, obj_desc));
/* Remove local reference to the object */
......
......@@ -47,6 +47,8 @@
#include <acpi/acdispat.h>
#include <acpi/acinterp.h>
#include <acpi/acnamesp.h>
#include <acpi/acparser.h>
#include <acpi/amlcode.h>
#define _COMPONENT ACPI_EXECUTER
......@@ -243,12 +245,26 @@ acpi_ex_resolve_node_to_value (
case ACPI_TYPE_LOCAL_REFERENCE:
/* No named references are allowed here */
switch (source_desc->reference.opcode) {
case AML_LOAD_OP:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X\n",
source_desc->reference.opcode));
/* This is a ddb_handle */
/* Return an additional reference to the object */
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
obj_desc = source_desc;
acpi_ut_add_reference (obj_desc);
break;
default:
/* No named references are allowed here */
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported Reference opcode %X (%s)\n",
source_desc->reference.opcode,
acpi_ps_get_opcode_name (source_desc->reference.opcode)));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
break;
/* Default case is for unknown types */
......
......@@ -48,6 +48,7 @@
#include <acpi/acdispat.h>
#include <acpi/acinterp.h>
#include <acpi/acnamesp.h>
#include <acpi/acparser.h>
#define _COMPONENT ACPI_EXECUTER
......@@ -248,6 +249,7 @@ acpi_ex_resolve_object_to_value (
case AML_REF_OF_OP:
case AML_DEBUG_OP:
case AML_LOAD_OP:
/* Just leave the object as-is */
......@@ -256,8 +258,8 @@ acpi_ex_resolve_object_to_value (
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference opcode %X in %p\n",
opcode, stack_desc));
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Reference opcode %X (%s) in %p\n",
opcode, acpi_ps_get_opcode_name (opcode), stack_desc));
status = AE_AML_INTERNAL;
break;
}
......
......@@ -224,6 +224,7 @@ acpi_ex_resolve_operands (
case AML_REF_OF_OP:
case AML_ARG_OP:
case AML_LOCAL_OP:
case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
ACPI_DEBUG_ONLY_MEMBERS (ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
"Reference Opcode: %s\n", op_info->name)));
......@@ -231,8 +232,9 @@ acpi_ex_resolve_operands (
default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Unknown Reference Opcode %X\n",
obj_desc->reference.opcode));
"Unknown Reference Opcode %X [%s]\n",
obj_desc->reference.opcode,
(acpi_ps_get_opcode_info (obj_desc->reference.opcode))->name));
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
......@@ -378,6 +380,13 @@ acpi_ex_resolve_operands (
type_needed = ACPI_TYPE_ANY;
break;
case ARGI_DDBHANDLE:
/* Need an operand of type ACPI_TYPE_DDB_HANDLE */
type_needed = ACPI_TYPE_LOCAL_REFERENCE;
break;
/*
* The more complex cases allow multiple resolved object types
......
......@@ -46,6 +46,7 @@
#include <acpi/acpi.h>
#include <acpi/acinterp.h>
#include <acpi/amlcode.h>
#define _COMPONENT ACPI_EXECUTER
......@@ -114,9 +115,10 @@ acpi_ex_resolve_object (
/*
* Must have a Integer, Buffer, or String
*/
if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) &&
(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) &&
(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING)) {
if ((ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_INTEGER) &&
(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_BUFFER) &&
(ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_TYPE_STRING) &&
!((ACPI_GET_OBJECT_TYPE (source_desc) == ACPI_TYPE_LOCAL_REFERENCE) && (source_desc->reference.opcode == AML_LOAD_OP))) {
/*
* Conversion successful but still not a valid type
*/
......
......@@ -129,18 +129,13 @@ acpi_ex_system_do_stall (
ACPI_FUNCTION_ENTRY ();
if (how_long > 1000) /* 1 millisecond */ {
/* Since this thread will sleep, we must release the interpreter */
acpi_ex_exit_interpreter ();
acpi_os_sleep (0, (how_long / 1000) + 1);
/* And now we must get the interpreter again */
status = acpi_ex_enter_interpreter ();
if (how_long > 100) /* 100 microseconds */ {
/*
* Longer than 100 usec, use sleep instead
* (according to ACPI specification)
*/
status = acpi_ex_system_do_suspend ((how_long / 1000) + 1);
}
else {
acpi_os_stall (how_long);
}
......
......@@ -208,6 +208,15 @@ acpi_hw_get_mode (void)
ACPI_FUNCTION_TRACE ("hw_get_mode");
/*
* ACPI 2.0 clarified that if SMI_CMD in FADT is zero,
* system does not support mode transition.
*/
if (!acpi_gbl_FADT->smi_cmd) {
return_VALUE (ACPI_SYS_MODE_ACPI);
}
status = acpi_get_register (ACPI_BITREG_SCI_ENABLE, &value, ACPI_MTX_LOCK);
if (ACPI_FAILURE (status)) {
return_VALUE (ACPI_SYS_MODE_LEGACY);
......
......@@ -94,6 +94,12 @@ acpi_rs_address16_resource (
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
/* Validate minimum descriptor length */
if (temp16 < 13) {
return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
}
*bytes_consumed = temp16 + 3;
output_struct->id = ACPI_RSTYPE_ADDRESS16;
......@@ -199,8 +205,11 @@ acpi_rs_address16_resource (
* pointer to where the null terminated string goes:
* Each Interrupt takes 32-bits + the 5 bytes of the
* stream that are default.
*
* Note: Some resource descriptors will have an additional null, so
* we add 1 to the length.
*/
if (*bytes_consumed > 16) {
if (*bytes_consumed > (16 + 1)) {
/* Dereference the Index */
temp8 = *buffer;
......@@ -401,7 +410,7 @@ acpi_rs_address16_stream (
/*
* Buffer needs to be set to the length of the sting + one for the
* terminating null
* terminating null
*/
buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address16.resource_source.string_ptr) + 1);
}
......@@ -470,8 +479,14 @@ acpi_rs_address32_resource (
*/
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
*bytes_consumed = temp16 + 3;
/* Validate minimum descriptor length */
if (temp16 < 23) {
return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
}
*bytes_consumed = temp16 + 3;
output_struct->id = ACPI_RSTYPE_ADDRESS32;
/*
......@@ -578,8 +593,11 @@ acpi_rs_address32_resource (
* This will leave us pointing to the Resource Source Index
* If it is present, then save it off and calculate the
* pointer to where the null terminated string goes:
*
* Note: Some resource descriptors will have an additional null, so
* we add 1 to the length.
*/
if (*bytes_consumed > 26) {
if (*bytes_consumed > (26 + 1)) {
/* Dereference the Index */
temp8 = *buffer;
......@@ -616,8 +634,8 @@ acpi_rs_address32_resource (
/*
* In order for the struct_size to fall on a 32-bit boundary,
* calculate the length of the string and expand the
* struct_size to the next 32-bit boundary.
* calculate the length of the string and expand the
* struct_size to the next 32-bit boundary.
*/
temp8 = (u8) (index + 1);
struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
......@@ -848,6 +866,12 @@ acpi_rs_address64_resource (
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
/* Validate minimum descriptor length */
if (temp16 < 43) {
return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
}
*bytes_consumed = temp16 + 3;
output_struct->id = ACPI_RSTYPE_ADDRESS64;
......@@ -958,8 +982,11 @@ acpi_rs_address64_resource (
* pointer to where the null terminated string goes:
* Each Interrupt takes 32-bits + the 5 bytes of the
* stream that are default.
*
* Note: Some resource descriptors will have an additional null, so
* we add 1 to the length.
*/
if (*bytes_consumed > 46) {
if (*bytes_consumed > (46 + 1)) {
/* Dereference the Index */
temp8 = *buffer;
......@@ -992,7 +1019,6 @@ acpi_rs_address64_resource (
* Add the terminating null
*/
*temp_ptr = 0x00;
output_struct->data.address64.resource_source.string_length = index + 1;
/*
......@@ -1064,7 +1090,6 @@ acpi_rs_address64_stream (
/*
* Set a pointer to the Length field - to be filled in later
*/
length_field = ACPI_CAST_PTR (u16, buffer);
buffer += 2;
......@@ -1161,7 +1186,7 @@ acpi_rs_address64_stream (
/*
* Buffer needs to be set to the length of the sting + one for the
* terminating null
* terminating null
*/
buffer += (acpi_size)(ACPI_STRLEN (linked_list->data.address64.resource_source.string_ptr) + 1);
}
......
......@@ -319,6 +319,12 @@ acpi_rs_extended_irq_resource (
buffer += 1;
ACPI_MOVE_16_TO_16 (&temp16, buffer);
/* Validate minimum descriptor length */
if (temp16 < 6) {
return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
}
*bytes_consumed = temp16 + 3;
output_struct->id = ACPI_RSTYPE_EXT_IRQ;
......@@ -357,6 +363,12 @@ acpi_rs_extended_irq_resource (
buffer += 1;
temp8 = *buffer;
/* Must have at least one IRQ */
if (temp8 < 1) {
return_ACPI_STATUS (AE_AML_BAD_RESOURCE_LENGTH);
}
output_struct->data.extended_irq.number_of_interrupts = temp8;
/*
......@@ -388,9 +400,12 @@ acpi_rs_extended_irq_resource (
* pointer to where the null terminated string goes:
* Each Interrupt takes 32-bits + the 5 bytes of the
* stream that are default.
*
* Note: Some resource descriptors will have an additional null, so
* we add 1 to the length.
*/
if (*bytes_consumed >
((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) + 5) {
((acpi_size) output_struct->data.extended_irq.number_of_interrupts * 4) + (5 + 1)) {
/* Dereference the Index */
temp8 = *buffer;
......
......@@ -131,7 +131,7 @@ acpi_tb_convert_to_xsdt (
/* Copy the header and set the length */
ACPI_MEMCPY (new_table, table_info->pointer, sizeof (struct acpi_table_header));
new_table->header.length = (u32) table_size;
new_table->length = (u32) table_size;
/* Copy the table pointers */
......@@ -430,17 +430,17 @@ acpi_tb_convert_table_fadt (void)
* FADT length and version validation. The table must be at least as
* long as the version 1.0 FADT
*/
if (acpi_gbl_FADT->header.length < sizeof (struct fadt_descriptor_rev1)) {
ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", acpi_gbl_FADT->header.length));
if (acpi_gbl_FADT->length < sizeof (struct fadt_descriptor_rev1)) {
ACPI_REPORT_ERROR (("Invalid FADT table length: 0x%X\n", acpi_gbl_FADT->length));
return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
}
if (acpi_gbl_FADT->header.revision >= FADT2_REVISION_ID) {
if (acpi_gbl_FADT->header.length < sizeof (struct fadt_descriptor_rev2)) {
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 */
ACPI_REPORT_WARNING (("Inconsistent FADT length (0x%X) and revision (0x%X), using FADT V1.0 portion of table\n",
acpi_gbl_FADT->header.length, acpi_gbl_FADT->header.revision));
acpi_gbl_FADT->length, acpi_gbl_FADT->revision));
acpi_tb_convert_fadt1 (local_fadt, (void *) acpi_gbl_FADT);
}
......@@ -460,7 +460,7 @@ acpi_tb_convert_table_fadt (void)
* Global FADT pointer will point to the new common V2.0 FADT
*/
acpi_gbl_FADT = local_fadt;
acpi_gbl_FADT->header.length = sizeof (FADT_DESCRIPTOR);
acpi_gbl_FADT->length = sizeof (FADT_DESCRIPTOR);
/* Free the original table */
......@@ -477,8 +477,8 @@ acpi_tb_convert_table_fadt (void)
ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
"Hex dump of common internal FADT, size %d (%X)\n",
acpi_gbl_FADT->header.length, acpi_gbl_FADT->header.length));
ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->header.length);
acpi_gbl_FADT->length, acpi_gbl_FADT->length));
ACPI_DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->length);
return_ACPI_STATUS (AE_OK);
}
......
......@@ -350,7 +350,7 @@ acpi_tb_init_table_descriptor (
void
acpi_tb_delete_all_tables (void)
{
acpi_table_type type;
acpi_table_type type;
/*
......@@ -378,7 +378,7 @@ acpi_tb_delete_all_tables (void)
void
acpi_tb_delete_tables_by_type (
acpi_table_type type)
acpi_table_type type)
{
struct acpi_table_desc *table_desc;
u32 count;
......@@ -425,15 +425,16 @@ acpi_tb_delete_tables_by_type (
break;
}
/* Free the table */
/* Get the head of the list */
/*
* Free the table
* 1) Get the head of the list
*/
table_desc = acpi_gbl_table_lists[type].next;
count = acpi_gbl_table_lists[type].count;
/*
* Walk the entire list, deleting both the allocated tables
* and the table descriptors
* 2) Walk the entire list, deleting both the allocated tables
* and the table descriptors
*/
for (i = 0; i < count; i++) {
table_desc = acpi_tb_uninstall_table (table_desc);
......
......@@ -795,7 +795,7 @@ acpi_ut_remove_allocation (
ACPI_MEMSET (&allocation->user_space, 0xEA, allocation->size);
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size %X\n", allocation->size));
ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", allocation->size));
status = acpi_ut_release_mutex (ACPI_MTX_MEMORY);
return_ACPI_STATUS (status);
......
......@@ -307,8 +307,8 @@ struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] =
/*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */
/* RSDP 0 */ {RSDP_NAME, RSDP_SIG, NULL, sizeof (RSDP_SIG)-1, ACPI_TABLE_ROOT | ACPI_TABLE_SINGLE},
/* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE},
/* FADT 2 */ {FADT_SIG, FADT_SIG, (void *) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE},
/* DSDT 1 */ {DSDT_SIG, DSDT_SIG, (void *) &acpi_gbl_DSDT, sizeof (DSDT_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE | ACPI_TABLE_EXECUTABLE},
/* FADT 2 */ {FADT_SIG, FADT_SIG, (void *) &acpi_gbl_FADT, sizeof (FADT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_SINGLE},
/* FACS 3 */ {FACS_SIG, FACS_SIG, (void *) &acpi_gbl_FACS, sizeof (FACS_SIG)-1, ACPI_TABLE_SECONDARY| ACPI_TABLE_SINGLE},
/* PSDT 4 */ {PSDT_SIG, PSDT_SIG, NULL, sizeof (PSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
/* SSDT 5 */ {SSDT_SIG, SSDT_SIG, NULL, sizeof (SSDT_SIG)-1, ACPI_TABLE_PRIMARY | ACPI_TABLE_MULTIPLE | ACPI_TABLE_EXECUTABLE},
......
......@@ -64,7 +64,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20030918
#define ACPI_CA_VERSION 0x20031002
/* Maximum objects in the various object caches */
......
......@@ -163,6 +163,7 @@
#define AE_AML_NO_RESOURCE_END_TAG (acpi_status) (0x001E | AE_CODE_AML)
#define AE_AML_BAD_RESOURCE_VALUE (acpi_status) (0x001F | AE_CODE_AML)
#define AE_AML_CIRCULAR_REFERENCE (acpi_status) (0x0020 | AE_CODE_AML)
#define AE_AML_BAD_RESOURCE_LENGTH (acpi_status) (0x0021 | AE_CODE_AML)
#define AE_CODE_AML_MAX 0x0020
......@@ -280,7 +281,8 @@ char const *acpi_gbl_exception_names_aml[] =
"AE_AML_ALIGNMENT",
"AE_AML_NO_RESOURCE_END_TAG",
"AE_AML_BAD_RESOURCE_VALUE",
"AE_AML_CIRCULAR_REFERENCE"
"AE_AML_CIRCULAR_REFERENCE",
"AE_AML_BAD_RESOURCE_LENGTH"
};
char const *acpi_gbl_exception_names_ctrl[] =
......
This diff is collapsed.
......@@ -51,7 +51,7 @@
*/
struct rsdt_descriptor_rev1
{
struct acpi_table_header header; /* ACPI Table header */
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
u32 table_offset_entry [1]; /* Array of pointers to other */
/* ACPI tables */
};
......@@ -78,7 +78,7 @@ struct facs_descriptor_rev1
*/
struct fadt_descriptor_rev1
{
struct acpi_table_header header; /* ACPI Table header */
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
u32 firmware_ctrl; /* Physical address of FACS */
u32 dsdt; /* Physical address of DSDT */
u8 model; /* System Interrupt Model */
......
......@@ -71,7 +71,7 @@
*/
struct rsdt_descriptor_rev2
{
struct acpi_table_header header; /* ACPI table header */
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
u32 table_offset_entry [1]; /* Array of pointers to */
/* ACPI table headers */
};
......@@ -82,7 +82,7 @@ struct rsdt_descriptor_rev2
*/
struct xsdt_descriptor_rev2
{
struct acpi_table_header header; /* ACPI table header */
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
u64 table_offset_entry [1]; /* Array of pointers to */
/* ACPI table headers */
};
......@@ -124,7 +124,7 @@ struct acpi_generic_address
*/
struct fadt_descriptor_rev2
{
struct acpi_table_header header; /* ACPI table header */
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*/
......@@ -195,6 +195,19 @@ struct fadt_descriptor_rev2
};
/* Embedded Controller */
struct ec_boot_resources
{
ACPI_TABLE_HEADER_DEF
struct acpi_generic_address ec_control; /* Address of EC command/status register */
struct acpi_generic_address ec_data; /* Address of EC data register */
u32 uid; /* Unique ID - must be same as the EC _UID method */
u8 gpe_bit; /* The GPE for the EC */
u8 ec_id[1]; /* Full namepath of the EC in the ACPI namespace */
};
#pragma pack()
#endif /* __ACTBL2_H__ */
......
......@@ -207,6 +207,7 @@ typedef u32 acpi_size;
/*
* Miscellaneous common types
*/
typedef u16 UINT16_BIT;
typedef u32 UINT32_BIT;
typedef acpi_native_uint ACPI_PTRDIFF;
......
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