# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1120 -> 1.1121 # drivers/acpi/resources/rsaddr.c 1.12 -> 1.13 # drivers/acpi/hardware/hwacpi.c 1.16 -> 1.17 # drivers/acpi/executer/exfield.c 1.15 -> 1.16 # include/acpi/acexcep.h 1.13 -> 1.14 # drivers/acpi/utilities/utglobal.c 1.21 -> 1.22 # drivers/acpi/executer/exstoren.c 1.14 -> 1.15 # drivers/acpi/utilities/utalloc.c 1.14 -> 1.15 # include/acpi/actbl1.h 1.11 -> 1.12 # drivers/acpi/executer/exprep.c 1.14 -> 1.15 # include/acpi/acconfig.h 1.38 -> 1.39 # drivers/acpi/tables/tbinstal.c 1.17 -> 1.18 # drivers/acpi/executer/exresnte.c 1.16 -> 1.17 # drivers/acpi/executer/exfldio.c 1.20 -> 1.21 # drivers/acpi/executer/exresolv.c 1.15 -> 1.16 # drivers/acpi/tables/tbconvrt.c 1.22 -> 1.23 # drivers/acpi/resources/rsirq.c 1.12 -> 1.13 # include/acpi/actbl.h 1.13 -> 1.14 # include/acpi/actypes.h 1.27 -> 1.28 # drivers/acpi/executer/exconfig.c 1.13 -> 1.14 # include/acpi/actbl2.h 1.14 -> 1.15 # drivers/acpi/executer/exsystem.c 1.12 -> 1.13 # drivers/acpi/executer/exresop.c 1.16 -> 1.17 # drivers/acpi/executer/exoparg1.c 1.17 -> 1.18 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/10/06 len.brown@intel.com 1.1121 # [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) # -------------------------------------------- # diff -Nru a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c --- a/drivers/acpi/executer/exconfig.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/executer/exconfig.c Mon Oct 6 16:45:01 2003 @@ -92,6 +92,9 @@ /* 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 @@ 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 @@ 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_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; diff -Nru a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c --- a/drivers/acpi/executer/exfield.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/executer/exfield.c Mon Oct 6 16:45:01 2003 @@ -160,10 +160,10 @@ } 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_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)); diff -Nru a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c --- a/drivers/acpi/executer/exfldio.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/executer/exfldio.c Mon Oct 6 16:45:01 2003 @@ -64,7 +64,8 @@ * RETURN: Status * * DESCRIPTION: Common processing for acpi_ex_extract_from_field and - * acpi_ex_insert_into_field. Initialize the + * acpi_ex_insert_into_field. Initialize the Region if necessary and + * validate the request. * ******************************************************************************/ @@ -96,7 +97,7 @@ * If the Region Address and Length have not been previously evaluated, * evaluate them now and save the results. */ - if (!(rgn_desc->region.flags & AOPOBJ_DATA_VALID)) { + if (!(rgn_desc->common.flags & AOPOBJ_DATA_VALID)) { status = acpi_ds_get_region_arguments (rgn_desc); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); @@ -109,6 +110,18 @@ return_ACPI_STATUS (AE_OK); } +#ifdef ACPI_UNDER_DEVELOPMENT + /* + * If the Field access is any_acc, we can now compute the optimal + * access (because we know know the length of the parent region) + */ + if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) { + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } +#endif + /* * Validate the request. The entire request from the byte offset for a * length of one field datum (access width) must fit within the region. @@ -242,7 +255,7 @@ } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_BFIELD, - " Region[%s-%X] Access %X Base:Off %X:%X at %8.8X%8.8X\n", + " Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n", acpi_ut_get_region_name (rgn_desc->region.space_id), rgn_desc->region.space_id, obj_desc->common_field.access_byte_width, @@ -365,10 +378,10 @@ /* * The four types of fields are: * - * buffer_fields - Read/write from/to a Buffer - * region_fields - Read/write from/to a Operation Region. - * bank_fields - Write to a Bank Register, then read/write from/to an op_region - * index_fields - Write to an Index Register, then read/write from/to a Data Register + * buffer_field - Read/write from/to a Buffer + * region_field - Read/write from/to a Operation Region. + * bank_field - Write to a Bank Register, then read/write from/to an op_region + * index_field - Write to an Index Register, then read/write from/to a Data Register */ switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { case ACPI_TYPE_BUFFER_FIELD: @@ -458,24 +471,34 @@ /* Write the index value to the index_register (itself a region_field) */ + field_datum_byte_offset += obj_desc->index_field.value; + + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Write to Index Register: Value %8.8X\n", + field_datum_byte_offset)); + status = acpi_ex_insert_into_field (obj_desc->index_field.index_obj, - &obj_desc->index_field.value, - sizeof (obj_desc->index_field.value)); + &field_datum_byte_offset, + sizeof (field_datum_byte_offset)); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "I/O to Data Register: value_ptr %p\n", + value)); + if (read_write == ACPI_READ) { /* Read the datum from the data_register */ status = acpi_ex_extract_from_field (obj_desc->index_field.data_obj, - value, obj_desc->common_field.access_byte_width); + value, sizeof (acpi_integer)); } else { - /* Write the datum to the Data register */ + /* Write the datum to the data_register */ status = acpi_ex_insert_into_field (obj_desc->index_field.data_obj, - value, obj_desc->common_field.access_byte_width); + value, sizeof (acpi_integer)); } break; @@ -490,12 +513,14 @@ if (ACPI_SUCCESS (status)) { if (read_write == ACPI_READ) { - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read=%8.8X%8.8X\n", - ACPI_HIDWORD (*value), ACPI_LODWORD (*value))); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n", + ACPI_HIDWORD (*value), ACPI_LODWORD (*value), + obj_desc->common_field.access_byte_width)); } else { - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written=%8.8X%8.8X\n", - ACPI_HIDWORD (*value), ACPI_LODWORD (*value))); + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n", + ACPI_HIDWORD (*value), ACPI_LODWORD (*value), + obj_desc->common_field.access_byte_width)); } } @@ -554,6 +579,10 @@ */ status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, ¤t_value, ACPI_READ); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + merged_value |= (current_value & ~mask); } break; @@ -573,6 +602,7 @@ break; default: + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "write_with_update_rule: Unknown update_rule setting: %X\n", (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK))); @@ -580,18 +610,19 @@ } } - /* Write the merged value */ - - status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, - &merged_value, ACPI_WRITE); - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "Mask %8.8X%8.8X datum_offset %X Value %8.8X%8.8X, merged_value %8.8X%8.8X\n", + "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n", ACPI_HIDWORD (mask), ACPI_LODWORD (mask), field_datum_byte_offset, + obj_desc->common_field.access_byte_width, ACPI_HIDWORD (field_value), ACPI_LODWORD (field_value), ACPI_HIDWORD (merged_value),ACPI_LODWORD (merged_value))); + /* Write the merged value */ + + status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, + &merged_value, ACPI_WRITE); + return_ACPI_STATUS (status); } @@ -625,7 +656,7 @@ u32 index; - ACPI_FUNCTION_ENTRY (); + ACPI_FUNCTION_TRACE_U32 ("ex_get_buffer_datum", byte_granularity); /* Get proper index into buffer (handles big/little endian) */ @@ -659,6 +690,8 @@ /* Should not get here */ break; } + + return_VOID; } @@ -690,7 +723,8 @@ { u32 index; - ACPI_FUNCTION_ENTRY (); + + ACPI_FUNCTION_TRACE_U32 ("ex_set_buffer_datum", byte_granularity); /* Get proper index into buffer (handles big/little endian) */ @@ -724,6 +758,8 @@ /* Should not get here */ break; } + + return_VOID; } @@ -777,7 +813,7 @@ obj_desc->common_field.access_byte_width); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "byte_len=%X, datum_len=%X, byte_gran=%X\n", + "byte_len %X, datum_len %X, byte_gran %X\n", byte_field_length, datum_count,obj_desc->common_field.access_byte_width)); /* @@ -942,20 +978,27 @@ * larger than the field, this typically happens when an integer is * written to a field that is actually smaller than an integer. */ - byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length); + byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES ( + obj_desc->common_field.bit_length); if (buffer_length < byte_field_length) { - ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Buffer length %X too small for field %X\n", + ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, + "Buffer length %X too small for field %X\n", buffer_length, byte_field_length)); return_ACPI_STATUS (AE_BUFFER_OVERFLOW); } + byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES ( + obj_desc->common_field.start_field_bit_offset + + obj_desc->common_field.bit_length); + /* Convert byte count to datum count, round up if necessary */ - datum_count = ACPI_ROUND_UP_TO (byte_field_length, obj_desc->common_field.access_byte_width); + datum_count = ACPI_ROUND_UP_TO (byte_field_length, + obj_desc->common_field.access_byte_width); ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, - "byte_len=%X, datum_len=%X, byte_gran=%X\n", + "Bytes %X, Datums %X, byte_gran %X\n", byte_field_length, datum_count, obj_desc->common_field.access_byte_width)); /* @@ -1006,6 +1049,10 @@ return_ACPI_STATUS (status); } + /* We just wrote the first datum */ + + datum_offset++; + /* If the entire field fits within one datum, we are done. */ if ((datum_count == 1) && @@ -1025,7 +1072,6 @@ * applied in Part3 below. */ while (datum_offset < datum_count) { - datum_offset++; field_datum_byte_offset += obj_desc->common_field.access_byte_width; /* @@ -1057,33 +1103,34 @@ * a datum boundary. Update Rule must be applied to the bits outside * the field. */ - if (datum_offset == datum_count) { + datum_offset++; + if ((datum_offset == datum_count) && + (obj_desc->common_field.end_field_valid_bits)) { /* * If there are dangling non-aligned bits, perform one more merged write * Else - field is aligned at the end, no need for any more writes */ - if (obj_desc->common_field.end_field_valid_bits) { - /* - * Part3: - * This is the last datum and the field does not end on a datum boundary. - * Build the partial datum and write with the update rule. - * - * Mask off the unused bits above (after) the end-of-field - */ - mask = ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); - merged_datum &= mask; - /* Write the last datum with the update rule */ + /* + * Part3: + * This is the last datum and the field does not end on a datum boundary. + * Build the partial datum and write with the update rule. + * + * Mask off the unused bits above (after) the end-of-field + */ + mask = ACPI_MASK_BITS_ABOVE (obj_desc->common_field.end_field_valid_bits); + merged_datum &= mask; + + /* Write the last datum with the update rule */ - status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, - field_datum_byte_offset); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + status = acpi_ex_write_with_update_rule (obj_desc, mask, merged_datum, + field_datum_byte_offset); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } } else { - /* Normal case -- write the completed datum */ + /* Normal (aligned) case -- write the completed datum */ status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, &merged_datum, ACPI_WRITE); diff -Nru a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c --- a/drivers/acpi/executer/exoparg1.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/executer/exoparg1.c Mon Oct 6 16:45:01 2003 @@ -524,7 +524,7 @@ 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 */ diff -Nru a/drivers/acpi/executer/exprep.c b/drivers/acpi/executer/exprep.c --- a/drivers/acpi/executer/exprep.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/executer/exprep.c Mon Oct 6 16:45:01 2003 @@ -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 @@ 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 @@ 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_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 @@ } *return_byte_alignment = byte_alignment; - return (bit_length); + return_VALUE (bit_length); } @@ -336,7 +436,7 @@ 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_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_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_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 @@ 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 */ diff -Nru a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c --- a/drivers/acpi/executer/exresnte.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/executer/exresnte.c Mon Oct 6 16:45:01 2003 @@ -47,6 +47,8 @@ #include #include #include +#include +#include #define _COMPONENT ACPI_EXECUTER @@ -243,12 +245,26 @@ 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 */ + + obj_desc = source_desc; + acpi_ut_add_reference (obj_desc); + break; + + default: + /* No named references are allowed here */ - return_ACPI_STATUS (AE_AML_OPERAND_TYPE); + 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 */ diff -Nru a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c --- a/drivers/acpi/executer/exresolv.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/executer/exresolv.c Mon Oct 6 16:45:01 2003 @@ -48,6 +48,7 @@ #include #include #include +#include #define _COMPONENT ACPI_EXECUTER @@ -248,6 +249,7 @@ case AML_REF_OF_OP: case AML_DEBUG_OP: + case AML_LOAD_OP: /* Just leave the object as-is */ @@ -256,8 +258,8 @@ 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; } diff -Nru a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c --- a/drivers/acpi/executer/exresop.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/executer/exresop.c Mon Oct 6 16:45:01 2003 @@ -224,6 +224,7 @@ 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 @@ 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); } @@ -376,6 +378,13 @@ /* Any operand type will do */ 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; diff -Nru a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c --- a/drivers/acpi/executer/exstoren.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/executer/exstoren.c Mon Oct 6 16:45:01 2003 @@ -46,6 +46,7 @@ #include #include +#include #define _COMPONENT ACPI_EXECUTER @@ -114,9 +115,10 @@ /* * 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 */ diff -Nru a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c --- a/drivers/acpi/executer/exsystem.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/executer/exsystem.c Mon Oct 6 16:45:01 2003 @@ -129,18 +129,13 @@ 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); } diff -Nru a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c --- a/drivers/acpi/hardware/hwacpi.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/hardware/hwacpi.c Mon Oct 6 16:45:01 2003 @@ -212,6 +212,15 @@ if (!acpi_gbl_FADT->smi_cmd) return_VALUE (ACPI_SYS_MODE_ACPI); + + /* + * 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); diff -Nru a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c --- a/drivers/acpi/resources/rsaddr.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/resources/rsaddr.c Mon Oct 6 16:45:01 2003 @@ -94,6 +94,12 @@ 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 @@ * 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 @@ /* * 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 @@ */ 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 @@ * 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 @@ /* * 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 @@ 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 @@ * 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 @@ * Add the terminating null */ *temp_ptr = 0x00; - output_struct->data.address64.resource_source.string_length = index + 1; /* @@ -1064,7 +1090,6 @@ /* * 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 @@ /* * 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); } diff -Nru a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c --- a/drivers/acpi/resources/rsirq.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/resources/rsirq.c Mon Oct 6 16:45:01 2003 @@ -319,6 +319,12 @@ 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 @@ 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 @@ * 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; diff -Nru a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c --- a/drivers/acpi/tables/tbconvrt.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/tables/tbconvrt.c Mon Oct 6 16:45:01 2003 @@ -131,7 +131,7 @@ /* 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 @@ * 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 @@ * 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_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); } diff -Nru a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c --- a/drivers/acpi/tables/tbinstal.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/tables/tbinstal.c Mon Oct 6 16:45:01 2003 @@ -350,7 +350,7 @@ void acpi_tb_delete_all_tables (void) { - acpi_table_type type; + acpi_table_type type; /* @@ -378,7 +378,7 @@ 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 @@ 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); diff -Nru a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c --- a/drivers/acpi/utilities/utalloc.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/utilities/utalloc.c Mon Oct 6 16:45:01 2003 @@ -795,7 +795,7 @@ 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); diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c --- a/drivers/acpi/utilities/utglobal.c Mon Oct 6 16:45:01 2003 +++ b/drivers/acpi/utilities/utglobal.c Mon Oct 6 16:45:01 2003 @@ -307,8 +307,8 @@ /*********** 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}, diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h --- a/include/acpi/acconfig.h Mon Oct 6 16:45:01 2003 +++ b/include/acpi/acconfig.h Mon Oct 6 16:45:01 2003 @@ -64,7 +64,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20030918 +#define ACPI_CA_VERSION 0x20031002 /* Maximum objects in the various object caches */ diff -Nru a/include/acpi/acexcep.h b/include/acpi/acexcep.h --- a/include/acpi/acexcep.h Mon Oct 6 16:45:01 2003 +++ b/include/acpi/acexcep.h Mon Oct 6 16:45:01 2003 @@ -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 @@ "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[] = diff -Nru a/include/acpi/actbl.h b/include/acpi/actbl.h --- a/include/acpi/actbl.h Mon Oct 6 16:45:01 2003 +++ b/include/acpi/actbl.h Mon Oct 6 16:45:01 2003 @@ -65,16 +65,6 @@ #define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */ -/* values of Mapic.Model */ - -#define DUAL_PIC 0 -#define MULTIPLE_APIC 1 - -/* values of Type in struct apic_header */ - -#define APIC_PROC 0 -#define APIC_IO 1 - /* * Common table types. The base code can remain @@ -89,8 +79,10 @@ #pragma pack(1) /* - * Architecture-independent tables - * The architecture dependent tables are in separate files + * ACPI Version-independent tables + * + * NOTE: The tables that are specific to ACPI versions (1.0, 2.0, etc.) + * are in separate files. */ struct rsdp_descriptor /* Root System Descriptor Pointer */ { @@ -106,20 +98,6 @@ }; -struct acpi_table_header /* ACPI common table header */ -{ - char signature [4]; /* ACPI signature (4 ASCII characters) */ - u32 length; /* Length of table, in bytes, including header */ - u8 revision; /* ACPI Specification minor version # */ - u8 checksum; /* To make sum of entire table == 0 */ - char oem_id [6]; /* OEM identification */ - char oem_table_id [8]; /* OEM table identification */ - u32 oem_revision; /* OEM revision number */ - char asl_compiler_id [4]; /* ASL compiler vendor ID */ - u32 asl_compiler_revision; /* ASL compiler revision number */ -}; - - struct acpi_common_facs /* Common FACS for internal use */ { u32 *global_lock; @@ -128,68 +106,196 @@ }; -struct apic_table +#define ACPI_TABLE_HEADER_DEF /* ACPI common table header */ \ + char signature [4]; /* ACPI signature (4 ASCII characters) */\ + u32 length; /* Length of table, in bytes, including header */\ + u8 revision; /* ACPI Specification minor version # */\ + u8 checksum; /* To make sum of entire table == 0 */\ + char oem_id [6]; /* OEM identification */\ + char oem_table_id [8]; /* OEM table identification */\ + u32 oem_revision; /* OEM revision number */\ + char asl_compiler_id [4]; /* ASL compiler vendor ID */\ + u32 asl_compiler_revision; /* ASL compiler revision number */ + + +struct acpi_table_header /* ACPI common table header */ { - struct acpi_table_header header; /* ACPI table header */ - u32 local_apic_address; /* Physical address for accessing local APICs */ - u32 PCATcompat : 1; /* a one indicates system also has dual 8259s */ - u32 reserved1 : 31; + ACPI_TABLE_HEADER_DEF }; -struct apic_header +/* + * MADT values and structures + */ + +/* Values for MADT PCATCompat */ + +#define DUAL_PIC 0 +#define MULTIPLE_APIC 1 + + +/* Master MADT */ + +struct multiple_apic_table { - u8 type; /* APIC type. Either APIC_PROC or APIC_IO */ - u8 length; /* Length of APIC structure */ + ACPI_TABLE_HEADER_DEF /* ACPI common table header */ + u32 local_apic_address; /* Physical address of local APIC */ + u32 PCATcompat : 1; /* A one indicates system also has dual 8259s */ + u32 reserved1 : 31; }; -struct processor_apic +/* Values for Type in APIC_HEADER_DEF */ + +#define APIC_PROCESSOR 0 +#define APIC_IO 1 +#define APIC_XRUPT_OVERRIDE 2 +#define APIC_NMI 3 +#define APIC_LOCAL_NMI 4 +#define APIC_ADDRESS_OVERRIDE 5 +#define APIC_IO_SAPIC 6 +#define APIC_LOCAL_SAPIC 7 +#define APIC_XRUPT_SOURCE 8 +#define APIC_RESERVED 9 /* 9 and greater are reserved */ + +/* + * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE) + */ +#define APIC_HEADER_DEF /* Common APIC sub-structure header */\ + u8 type; \ + u8 length; + +/* Values for MPS INTI flags */ + +#define POLARITY_CONFORMS 0 +#define POLARITY_ACTIVE_HIGH 1 +#define POLARITY_RESERVED 2 +#define POLARITY_ACTIVE_LOW 3 + +#define TRIGGER_CONFORMS 0 +#define TRIGGER_EDGE 1 +#define TRIGGER_RESERVED 2 +#define TRIGGER_LEVEL 3 + +/* Common flag definitions */ + +#define MPS_INTI_FLAGS \ + u16 polarity : 2; /* Polarity of APIC I/O input signals */\ + u16 trigger_mode : 2; /* Trigger mode of APIC input signals */\ + u16 reserved1 : 12; /* Reserved, must be zero */ + +#define LOCAL_APIC_FLAGS \ + u32 processor_enabled: 1; /* Processor is usable if set */\ + u32 reserved2 : 31; /* Reserved, must be zero */ + +/* Sub-structures for MADT */ + +struct madt_processor_apic { - struct apic_header header; - u8 processor_apic_id; /* ACPI processor id */ + APIC_HEADER_DEF + u8 processor_id; /* ACPI processor id */ u8 local_apic_id; /* Processor's local APIC id */ - u32 processor_enabled: 1; /* Processor is usable if set */ - u32 reserved1 : 31; + LOCAL_APIC_FLAGS }; - -struct io_apic +struct madt_io_apic { - struct apic_header header; + APIC_HEADER_DEF u8 io_apic_id; /* I/O APIC ID */ u8 reserved; /* Reserved - must be zero */ - u32 io_apic_address; /* APIC's physical address */ - u32 vector; /* Interrupt vector index where INTI + u32 address; /* APIC physical address */ + u32 interrupt; /* Global system interrupt where INTI * lines start */ }; +struct madt_interrupt_override +{ + APIC_HEADER_DEF + u8 bus; /* 0 - ISA */ + u8 source; /* Interrupt source (IRQ) */ + u32 interrupt; /* Global system interrupt */ + MPS_INTI_FLAGS +}; + +struct madt_nmi_source +{ + APIC_HEADER_DEF + MPS_INTI_FLAGS + u32 interrupt; /* Global system interrupt */ +}; + +struct madt_local_apic_nmi +{ + APIC_HEADER_DEF + u8 processor_id; /* ACPI processor id */ + MPS_INTI_FLAGS + u8 lint; /* LINTn to which NMI is connected */ +}; + +struct madt_address_override +{ + APIC_HEADER_DEF + u16 reserved; /* Reserved - must be zero */ + u32 address; /* APIC physical address */ +}; + +struct madt_io_sapic +{ + APIC_HEADER_DEF + u8 io_sapic_id; /* I/O SAPIC ID */ + u8 reserved; /* Reserved - must be zero */ + u32 interrupt_base; /* Glocal interrupt for SAPIC start */ + u64 address; /* SAPIC physical address */ +}; + +struct madt_local_sapic +{ + APIC_HEADER_DEF + u8 processor_id; /* ACPI processor id */ + u8 local_sapic_id; /* SAPIC ID */ + u8 local_sapic_eid; /* SAPIC EID */ + u8 reserved [3]; /* Reserved - must be zero */ + LOCAL_APIC_FLAGS +}; + +struct madt_interrupt_source +{ + APIC_HEADER_DEF + MPS_INTI_FLAGS + u8 interrupt_type; /* 1=PMI, 2=INIT, 3=corrected */ + u8 processor_id; /* Processor ID */ + u8 processor_eid; /* Processor EID */ + u8 io_sapic_vector; /* Vector value for PMI interrupts */ + u32 interrupt; /* Global system interrupt */ + u32 reserved; /* Reserved - must be zero */ +}; -/* - * IA64 TBD: Add SAPIC Tables - */ /* - * IA64 TBD: Modify Smart Battery Description to comply with ACPI IA64 - * extensions. + * Smart Battery */ -struct smart_battery_description_table +struct smart_battery_table { - struct acpi_table_header header; + ACPI_TABLE_HEADER_DEF u32 warning_level; u32 low_level; u32 critical_level; }; -struct hpet_description_table + +/* + * High performance timer + */ +struct hpet_table { - struct acpi_table_header header; + ACPI_TABLE_HEADER_DEF u32 hardware_id; - u32 base_address[3]; + u32 base_address [3]; u8 hpet_number; u16 clock_tick; u8 attributes; }; + #pragma pack() @@ -227,9 +333,10 @@ /* - * Get the architecture-specific tables + * Get the ACPI version-specific tables */ #include "actbl1.h" /* Acpi 1.0 table definitions */ #include "actbl2.h" /* Acpi 2.0 table definitions */ + #endif /* __ACTBL_H__ */ diff -Nru a/include/acpi/actbl1.h b/include/acpi/actbl1.h --- a/include/acpi/actbl1.h Mon Oct 6 16:45:01 2003 +++ b/include/acpi/actbl1.h Mon Oct 6 16:45:01 2003 @@ -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 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 */ diff -Nru a/include/acpi/actbl2.h b/include/acpi/actbl2.h --- a/include/acpi/actbl2.h Mon Oct 6 16:45:01 2003 +++ b/include/acpi/actbl2.h Mon Oct 6 16:45:01 2003 @@ -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 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 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*/ @@ -192,6 +192,19 @@ struct acpi_generic_address xpm_tmr_blk; /* Extended Power Mgt Timer Ctrl Reg Blk address */ struct acpi_generic_address xgpe0_blk; /* Extended General Purpose acpi_event 0 Reg Blk address */ struct acpi_generic_address xgpe1_blk; /* Extended General Purpose acpi_event 1 Reg Blk address */ +}; + + +/* 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 */ }; diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h --- a/include/acpi/actypes.h Mon Oct 6 16:45:01 2003 +++ b/include/acpi/actypes.h Mon Oct 6 16:45:01 2003 @@ -207,6 +207,7 @@ /* * Miscellaneous common types */ +typedef u16 UINT16_BIT; typedef u32 UINT32_BIT; typedef acpi_native_uint ACPI_PTRDIFF;