Skip to content

Commit

Permalink
ACPI: ACPICA 20060217
Browse files Browse the repository at this point in the history
Implemented a change to the IndexField support to match
the behavior of the Microsoft AML interpreter. The value
written to the Index register is now a byte offset,
no longer an index based upon the width of the Data
register. This should fix IndexField problems seen on
some machines where the Data register is not exactly one
byte wide. The ACPI specification will be clarified on
this point.

Fixed a problem where several resource descriptor
types could overrun the internal descriptor buffer due
to size miscalculation: VendorShort, VendorLong, and
Interrupt. This was noticed on IA64 machines, but could
affect all platforms.

Fixed a problem where individual resource descriptors were
misaligned within the internal buffer, causing alignment
faults on IA64 platforms.

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Bob Moore authored and Len Brown committed Apr 1, 2006
1 parent 52fc0b0 commit ea936b7
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 101 deletions.
17 changes: 12 additions & 5 deletions drivers/acpi/executer/exprep.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,13 +519,20 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
acpi_ut_add_reference(obj_desc->index_field.index_obj);

/*
* February 2006: Changed to match MS behavior
*
* The value written to the Index register is the byte offset of the
* target field
* Note: may change code to: ACPI_DIV_8 (Info->field_bit_position)
* target field.
*
* Previously, the value was calculated as an index in terms of the
* width of the Data register, as below:
*
* obj_desc->index_field.Value = (u32)
* (Info->field_bit_position / ACPI_MUL_8 (
* obj_desc->Field.access_byte_width));
*/
obj_desc->index_field.value = (u32)
(info->field_bit_position /
ACPI_MUL_8(obj_desc->field.access_byte_width));
obj_desc->index_field.value =
(u32) ACPI_DIV_8(info->field_bit_position);

ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"index_field: bit_off %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n",
Expand Down
5 changes: 3 additions & 2 deletions drivers/acpi/namespace/nsutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ acpi_ns_report_error(char *module_name,
char *internal_name, acpi_status lookup_status)
{
acpi_status status;
u32 bad_name;
char *name = NULL;

acpi_ut_report_error(module_name, line_number);
Expand All @@ -86,8 +87,8 @@ acpi_ns_report_error(char *module_name,

/* There is a non-ascii character in the name */

acpi_os_printf("[0x%4.4X] (NON-ASCII)",
*(ACPI_CAST_PTR(u32, internal_name)));
ACPI_MOVE_32_TO_32(&bad_name, internal_name);
acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name);
} else {
/* Convert path to external format */

Expand Down
1 change: 1 addition & 0 deletions drivers/acpi/parser/psloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
return_ACPI_STATUS(status2);
}
}

acpi_ps_pop_scope(parser_state, &op,
&walk_state->arg_types,
&walk_state->arg_count);
Expand Down
100 changes: 45 additions & 55 deletions drivers/acpi/resources/rscalc.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,11 @@ acpi_rs_stream_option_length(u32 resource_length,
resource_length - minimum_aml_resource_length - 1;
}

/* Round up length to 32 bits for internal structure alignment */

return ((u32) ACPI_ROUND_UP_to_32_bITS(string_length));
/*
* Round the length up to a multiple of the native word in order to
* guarantee that the entire resource descriptor is native word aligned
*/
return ((u32) ACPI_ROUND_UP_TO_NATIVE_WORD(string_length));
}

/*******************************************************************************
Expand Down Expand Up @@ -336,7 +338,7 @@ acpi_rs_get_list_length(u8 * aml_buffer,
acpi_status status;
u8 *end_aml;
u8 *buffer;
u32 buffer_size = 0;
u32 buffer_size;
u16 temp16;
u16 resource_length;
u32 extra_struct_bytes;
Expand All @@ -345,6 +347,7 @@ acpi_rs_get_list_length(u8 * aml_buffer,

ACPI_FUNCTION_TRACE("rs_get_list_length");

*size_needed = 0;
end_aml = aml_buffer + aml_buffer_length;

/* Walk the list of AML resource descriptors */
Expand Down Expand Up @@ -391,37 +394,28 @@ acpi_rs_get_list_length(u8 * aml_buffer,
break;

case ACPI_RESOURCE_NAME_VENDOR_SMALL:
case ACPI_RESOURCE_NAME_VENDOR_LARGE:
/*
* Vendor Resource:
* Ensure a 32-bit boundary for the structure
* Get the number of vendor data bytes
*/
extra_struct_bytes = (u32)
ACPI_ROUND_UP_to_32_bITS(resource_length) -
resource_length;
extra_struct_bytes = resource_length;
break;

case ACPI_RESOURCE_NAME_END_TAG:
/*
* End Tag: This is the normal exit, add size of end_tag
* End Tag:
* This is the normal exit, add size of end_tag
*/
*size_needed = buffer_size + ACPI_RS_SIZE_MIN;
*size_needed += ACPI_RS_SIZE_MIN;
return_ACPI_STATUS(AE_OK);

case ACPI_RESOURCE_NAME_VENDOR_LARGE:
/*
* Vendor Resource:
* Add vendor data and ensure a 32-bit boundary for the structure
*/
extra_struct_bytes = (u32)
ACPI_ROUND_UP_to_32_bITS(resource_length) -
resource_length;
break;

case ACPI_RESOURCE_NAME_ADDRESS32:
case ACPI_RESOURCE_NAME_ADDRESS16:
case ACPI_RESOURCE_NAME_ADDRESS64:
/*
* 32-Bit or 16-bit Address Resource:
* Add the size of any optional data (resource_source)
* Address Resource:
* Add the size of the optional resource_source
*/
extra_struct_bytes =
acpi_rs_stream_option_length(resource_length,
Expand All @@ -430,50 +424,46 @@ acpi_rs_get_list_length(u8 * aml_buffer,

case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
/*
* Extended IRQ:
* Point past the interrupt_vector_flags to get the
* interrupt_table_length.
* Extended IRQ Resource:
* Using the interrupt_table_length, add 4 bytes for each additional
* interrupt. Note: at least one interrupt is required and is
* included in the minimum descriptor size (reason for the -1)
*/
buffer++;

extra_struct_bytes = (u32)
/*
* Add 4 bytes for each additional interrupt. Note: at
* least one interrupt is required and is included in
* the minimum descriptor size
*/
((*buffer - 1) * sizeof(u32)) +
/* Add the size of any optional data (resource_source) */
extra_struct_bytes = (buffer[1] - 1) * sizeof(u32);

/* Add the size of the optional resource_source */

extra_struct_bytes +=
acpi_rs_stream_option_length(resource_length -
extra_struct_bytes,
minimum_aml_resource_length);
break;

case ACPI_RESOURCE_NAME_ADDRESS64:
/*
* 64-Bit Address Resource:
* Add the size of any optional data (resource_source)
* Ensure a 64-bit boundary for the structure
*/
extra_struct_bytes = (u32)
ACPI_ROUND_UP_to_64_bITS
(acpi_rs_stream_option_length
(resource_length, minimum_aml_resource_length));
break;

default:
break;
}

/* Update the required buffer size for the internal descriptor structs */
/*
* Update the required buffer size for the internal descriptor structs
*
* Important: Round the size up for the appropriate alignment. This
* is a requirement on IA64.
*/
buffer_size = acpi_gbl_resource_struct_sizes[resource_index] +
extra_struct_bytes;
buffer_size = ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size);

*size_needed += buffer_size;

temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] +
extra_struct_bytes);
buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16);
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
"Type %.2X, Aml %.2X internal %.2X\n",
acpi_ut_get_resource_type(aml_buffer),
acpi_ut_get_descriptor_length(aml_buffer),
buffer_size));

/*
* Point to the next resource within the stream
* using the size of the header plus the length contained in the header
* Point to the next resource within the AML stream using the length
* contained in the resource descriptor header
*/
aml_buffer += acpi_ut_get_descriptor_length(aml_buffer);
}
Expand Down Expand Up @@ -589,15 +579,15 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,

/* Round up the size since each element must be aligned */

temp_size_needed = ACPI_ROUND_UP_to_64_bITS(temp_size_needed);
temp_size_needed = ACPI_ROUND_UP_to_64_bIT(temp_size_needed);

/* Point to the next union acpi_operand_object */

top_object_list++;
}

/*
* Adding an extra element to the end of the list, essentially a
* Add an extra element to the end of the list, essentially a
* NULL terminator
*/
*buffer_size_needed =
Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/resources/rscreate.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* Now align the current length */

user_prt->length =
(u32) ACPI_ROUND_UP_to_64_bITS(user_prt->length);
(u32) ACPI_ROUND_UP_to_64_bIT(user_prt->length);

/* 4) Fourth subobject: Dereference the PRT.source_index */

Expand Down
15 changes: 15 additions & 0 deletions drivers/acpi/resources/rslist.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer)
/* Loop until end-of-buffer or an end_tag is found */

while (aml < end_aml) {
/*
* Check that the input buffer and all subsequent pointers into it
* are aligned on a native word boundary. Most important on IA64
*/
if (ACPI_IS_MISALIGNED(resource)) {
ACPI_WARNING((AE_INFO,
"Misaligned resource pointer %p",
resource));
}

/* Validate the Resource Type and Resource Length */

Expand All @@ -101,6 +110,12 @@ acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer)
return_ACPI_STATUS(status);
}

ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
"Type %.2X, Aml %.2X internal %.2X\n",
acpi_ut_get_resource_type(aml),
acpi_ut_get_descriptor_length(aml),
resource->length));

/* Normal exit on completion of an end_tag resource descriptor */

if (acpi_ut_get_resource_type(aml) ==
Expand Down
6 changes: 3 additions & 3 deletions drivers/acpi/resources/rsmisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
u16 item_count = 0;
u16 temp16 = 0;

ACPI_FUNCTION_TRACE("rs_get_resource");
ACPI_FUNCTION_TRACE("rs_convert_aml_to_resource");

if (((acpi_native_uint) resource) & 0x3) {

Expand Down Expand Up @@ -297,10 +297,10 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
exit:
if (!flags_mode) {

/* Round the resource struct length up to the next 32-bit boundary */
/* Round the resource struct length up to the next boundary (32 or 64) */

resource->length =
(u32) ACPI_ROUND_UP_to_32_bITS(resource->length);
(u32) ACPI_ROUND_UP_TO_NATIVE_WORD(resource->length);
}
return_ACPI_STATUS(AE_OK);
}
Expand Down
17 changes: 8 additions & 9 deletions drivers/acpi/resources/rsutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ static u16 acpi_rs_strcpy(char *destination, char *source)
* string_ptr - (optional) where to store the actual
* resource_source string
*
* RETURN: Length of the string plus NULL terminator, rounded up to 32 bit
* RETURN: Length of the string plus NULL terminator, rounded up to native
* word boundary
*
* DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor
* to an internal resource descriptor
Expand Down Expand Up @@ -346,18 +347,16 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length,
}

/*
* In order for the struct_size to fall on a 32-bit boundary, calculate
* the length of the string (+1 for the NULL terminator) and expand the
* struct_size to the next 32-bit boundary.
* In order for the Resource length to be a multiple of the native
* word, calculate the length of the string (+1 for NULL terminator)
* and expand to the next word multiple.
*
* Zero the entire area of the buffer.
*/
total_length =
(u32)
ACPI_ROUND_UP_to_32_bITS(ACPI_STRLEN
(ACPI_CAST_PTR
(char,
&aml_resource_source[1])) + 1);
ACPI_STRLEN(ACPI_CAST_PTR(char, &aml_resource_source[1])) +
1;
total_length = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(total_length);

ACPI_MEMSET(resource_source->string_ptr, 0, total_length);

Expand Down
2 changes: 1 addition & 1 deletion include/acpi/acconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@

/* Current ACPICA subsystem version in YYYYMMDD format */

#define ACPI_CA_VERSION 0x20060210
#define ACPI_CA_VERSION 0x20060217

/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
Expand Down
34 changes: 19 additions & 15 deletions include/acpi/acmacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,40 +341,44 @@
/*
* Rounding macros (Power of two boundaries only)
*/
#define ACPI_ROUND_DOWN(value,boundary) (((acpi_native_uint)(value)) & \
#define ACPI_ROUND_DOWN(value,boundary) (((acpi_native_uint)(value)) & \
(~(((acpi_native_uint) boundary)-1)))

#define ACPI_ROUND_UP(value,boundary) ((((acpi_native_uint)(value)) + \
#define ACPI_ROUND_UP(value,boundary) ((((acpi_native_uint)(value)) + \
(((acpi_native_uint) boundary)-1)) & \
(~(((acpi_native_uint) boundary)-1)))

#define ACPI_ROUND_DOWN_TO_32_BITS(a) ACPI_ROUND_DOWN(a,4)
#define ACPI_ROUND_DOWN_TO_64_BITS(a) ACPI_ROUND_DOWN(a,8)
#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY)
/* Note: sizeof(acpi_native_uint) evaluates to either 2, 4, or 8 */

#define ACPI_ROUND_UP_to_32_bITS(a) ACPI_ROUND_UP(a,4)
#define ACPI_ROUND_UP_to_64_bITS(a) ACPI_ROUND_UP(a,8)
#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY)
#define ACPI_ROUND_DOWN_to_32_bIT(a) ACPI_ROUND_DOWN(a,4)
#define ACPI_ROUND_DOWN_to_64_bIT(a) ACPI_ROUND_DOWN(a,8)
#define ACPI_ROUND_DOWN_TO_NATIVE_WORD(a) ACPI_ROUND_DOWN(a,sizeof(acpi_native_uint))

#define ACPI_ROUND_BITS_UP_TO_BYTES(a) ACPI_DIV_8((a) + 7)
#define ACPI_ROUND_BITS_DOWN_TO_BYTES(a) ACPI_DIV_8((a))
#define ACPI_ROUND_UP_to_32_bIT(a) ACPI_ROUND_UP(a,4)
#define ACPI_ROUND_UP_to_64_bIT(a) ACPI_ROUND_UP(a,8)
#define ACPI_ROUND_UP_TO_NATIVE_WORD(a) ACPI_ROUND_UP(a,sizeof(acpi_native_uint))

#define ACPI_ROUND_UP_TO_1K(a) (((a) + 1023) >> 10)
#define ACPI_ROUND_BITS_UP_TO_BYTES(a) ACPI_DIV_8((a) + 7)
#define ACPI_ROUND_BITS_DOWN_TO_BYTES(a) ACPI_DIV_8((a))

#define ACPI_ROUND_UP_TO_1K(a) (((a) + 1023) >> 10)

/* Generic (non-power-of-two) rounding */

#define ACPI_ROUND_UP_TO(value,boundary) (((value) + ((boundary)-1)) / (boundary))
#define ACPI_ROUND_UP_TO(value,boundary) (((value) + ((boundary)-1)) / (boundary))

#define ACPI_IS_MISALIGNED(value) (((acpi_native_uint)value) & (sizeof(acpi_native_uint)-1))

/*
* Bitmask creation
* Bit positions start at zero.
* MASK_BITS_ABOVE creates a mask starting AT the position and above
* MASK_BITS_BELOW creates a mask starting one bit BELOW the position
*/
#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_INTEGER_MAX) << ((u32) (position))))
#define ACPI_MASK_BITS_BELOW(position) ((ACPI_INTEGER_MAX) << ((u32) (position)))
#define ACPI_MASK_BITS_ABOVE(position) (~((ACPI_INTEGER_MAX) << ((u32) (position))))
#define ACPI_MASK_BITS_BELOW(position) ((ACPI_INTEGER_MAX) << ((u32) (position)))

#define ACPI_IS_OCTAL_DIGIT(d) (((char)(d) >= '0') && ((char)(d) <= '7'))
#define ACPI_IS_OCTAL_DIGIT(d) (((char)(d) >= '0') && ((char)(d) <= '7'))

/* Bitfields within ACPI registers */

Expand Down
Loading

0 comments on commit ea936b7

Please sign in to comment.