aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/resources
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2006-02-17 00:00:00 -0500
committerLen Brown <len.brown@intel.com>2006-04-01 01:23:23 -0500
commitea936b78f46cbe089a4ac363e1682dee7d427096 (patch)
treec444b65c3d02b05934497caefcdcbbe675a00bdf /drivers/acpi/resources
parent52fc0b026e99b5d5d585095148d997d5634bbc25 (diff)
ACPI: ACPICA 20060217
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>
Diffstat (limited to 'drivers/acpi/resources')
-rw-r--r--drivers/acpi/resources/rscalc.c100
-rw-r--r--drivers/acpi/resources/rscreate.c2
-rw-r--r--drivers/acpi/resources/rslist.c15
-rw-r--r--drivers/acpi/resources/rsmisc.c6
-rw-r--r--drivers/acpi/resources/rsutils.c17
5 files changed, 72 insertions, 68 deletions
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index 223bdc493269..8e406d992f3b 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -162,9 +162,11 @@ acpi_rs_stream_option_length(u32 resource_length,
162 resource_length - minimum_aml_resource_length - 1; 162 resource_length - minimum_aml_resource_length - 1;
163 } 163 }
164 164
165 /* Round up length to 32 bits for internal structure alignment */ 165 /*
166 166 * Round the length up to a multiple of the native word in order to
167 return ((u32) ACPI_ROUND_UP_to_32_bITS(string_length)); 167 * guarantee that the entire resource descriptor is native word aligned
168 */
169 return ((u32) ACPI_ROUND_UP_TO_NATIVE_WORD(string_length));
168} 170}
169 171
170/******************************************************************************* 172/*******************************************************************************
@@ -336,7 +338,7 @@ acpi_rs_get_list_length(u8 * aml_buffer,
336 acpi_status status; 338 acpi_status status;
337 u8 *end_aml; 339 u8 *end_aml;
338 u8 *buffer; 340 u8 *buffer;
339 u32 buffer_size = 0; 341 u32 buffer_size;
340 u16 temp16; 342 u16 temp16;
341 u16 resource_length; 343 u16 resource_length;
342 u32 extra_struct_bytes; 344 u32 extra_struct_bytes;
@@ -345,6 +347,7 @@ acpi_rs_get_list_length(u8 * aml_buffer,
345 347
346 ACPI_FUNCTION_TRACE("rs_get_list_length"); 348 ACPI_FUNCTION_TRACE("rs_get_list_length");
347 349
350 *size_needed = 0;
348 end_aml = aml_buffer + aml_buffer_length; 351 end_aml = aml_buffer + aml_buffer_length;
349 352
350 /* Walk the list of AML resource descriptors */ 353 /* Walk the list of AML resource descriptors */
@@ -391,37 +394,28 @@ acpi_rs_get_list_length(u8 * aml_buffer,
391 break; 394 break;
392 395
393 case ACPI_RESOURCE_NAME_VENDOR_SMALL: 396 case ACPI_RESOURCE_NAME_VENDOR_SMALL:
397 case ACPI_RESOURCE_NAME_VENDOR_LARGE:
394 /* 398 /*
395 * Vendor Resource: 399 * Vendor Resource:
396 * Ensure a 32-bit boundary for the structure 400 * Get the number of vendor data bytes
397 */ 401 */
398 extra_struct_bytes = (u32) 402 extra_struct_bytes = resource_length;
399 ACPI_ROUND_UP_to_32_bITS(resource_length) -
400 resource_length;
401 break; 403 break;
402 404
403 case ACPI_RESOURCE_NAME_END_TAG: 405 case ACPI_RESOURCE_NAME_END_TAG:
404 /* 406 /*
405 * End Tag: This is the normal exit, add size of end_tag 407 * End Tag:
408 * This is the normal exit, add size of end_tag
406 */ 409 */
407 *size_needed = buffer_size + ACPI_RS_SIZE_MIN; 410 *size_needed += ACPI_RS_SIZE_MIN;
408 return_ACPI_STATUS(AE_OK); 411 return_ACPI_STATUS(AE_OK);
409 412
410 case ACPI_RESOURCE_NAME_VENDOR_LARGE:
411 /*
412 * Vendor Resource:
413 * Add vendor data and ensure a 32-bit boundary for the structure
414 */
415 extra_struct_bytes = (u32)
416 ACPI_ROUND_UP_to_32_bITS(resource_length) -
417 resource_length;
418 break;
419
420 case ACPI_RESOURCE_NAME_ADDRESS32: 413 case ACPI_RESOURCE_NAME_ADDRESS32:
421 case ACPI_RESOURCE_NAME_ADDRESS16: 414 case ACPI_RESOURCE_NAME_ADDRESS16:
415 case ACPI_RESOURCE_NAME_ADDRESS64:
422 /* 416 /*
423 * 32-Bit or 16-bit Address Resource: 417 * Address Resource:
424 * Add the size of any optional data (resource_source) 418 * Add the size of the optional resource_source
425 */ 419 */
426 extra_struct_bytes = 420 extra_struct_bytes =
427 acpi_rs_stream_option_length(resource_length, 421 acpi_rs_stream_option_length(resource_length,
@@ -430,50 +424,46 @@ acpi_rs_get_list_length(u8 * aml_buffer,
430 424
431 case ACPI_RESOURCE_NAME_EXTENDED_IRQ: 425 case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
432 /* 426 /*
433 * Extended IRQ: 427 * Extended IRQ Resource:
434 * Point past the interrupt_vector_flags to get the 428 * Using the interrupt_table_length, add 4 bytes for each additional
435 * interrupt_table_length. 429 * interrupt. Note: at least one interrupt is required and is
430 * included in the minimum descriptor size (reason for the -1)
436 */ 431 */
437 buffer++; 432 extra_struct_bytes = (buffer[1] - 1) * sizeof(u32);
438 433
439 extra_struct_bytes = (u32) 434 /* Add the size of the optional resource_source */
440 /* 435
441 * Add 4 bytes for each additional interrupt. Note: at 436 extra_struct_bytes +=
442 * least one interrupt is required and is included in
443 * the minimum descriptor size
444 */
445 ((*buffer - 1) * sizeof(u32)) +
446 /* Add the size of any optional data (resource_source) */
447 acpi_rs_stream_option_length(resource_length - 437 acpi_rs_stream_option_length(resource_length -
448 extra_struct_bytes, 438 extra_struct_bytes,
449 minimum_aml_resource_length); 439 minimum_aml_resource_length);
450 break; 440 break;
451 441
452 case ACPI_RESOURCE_NAME_ADDRESS64:
453 /*
454 * 64-Bit Address Resource:
455 * Add the size of any optional data (resource_source)
456 * Ensure a 64-bit boundary for the structure
457 */
458 extra_struct_bytes = (u32)
459 ACPI_ROUND_UP_to_64_bITS
460 (acpi_rs_stream_option_length
461 (resource_length, minimum_aml_resource_length));
462 break;
463
464 default: 442 default:
465 break; 443 break;
466 } 444 }
467 445
468 /* Update the required buffer size for the internal descriptor structs */ 446 /*
447 * Update the required buffer size for the internal descriptor structs
448 *
449 * Important: Round the size up for the appropriate alignment. This
450 * is a requirement on IA64.
451 */
452 buffer_size = acpi_gbl_resource_struct_sizes[resource_index] +
453 extra_struct_bytes;
454 buffer_size = ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size);
455
456 *size_needed += buffer_size;
469 457
470 temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] + 458 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
471 extra_struct_bytes); 459 "Type %.2X, Aml %.2X internal %.2X\n",
472 buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16); 460 acpi_ut_get_resource_type(aml_buffer),
461 acpi_ut_get_descriptor_length(aml_buffer),
462 buffer_size));
473 463
474 /* 464 /*
475 * Point to the next resource within the stream 465 * Point to the next resource within the AML stream using the length
476 * using the size of the header plus the length contained in the header 466 * contained in the resource descriptor header
477 */ 467 */
478 aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); 468 aml_buffer += acpi_ut_get_descriptor_length(aml_buffer);
479 } 469 }
@@ -589,7 +579,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
589 579
590 /* Round up the size since each element must be aligned */ 580 /* Round up the size since each element must be aligned */
591 581
592 temp_size_needed = ACPI_ROUND_UP_to_64_bITS(temp_size_needed); 582 temp_size_needed = ACPI_ROUND_UP_to_64_bIT(temp_size_needed);
593 583
594 /* Point to the next union acpi_operand_object */ 584 /* Point to the next union acpi_operand_object */
595 585
@@ -597,7 +587,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
597 } 587 }
598 588
599 /* 589 /*
600 * Adding an extra element to the end of the list, essentially a 590 * Add an extra element to the end of the list, essentially a
601 * NULL terminator 591 * NULL terminator
602 */ 592 */
603 *buffer_size_needed = 593 *buffer_size_needed =
diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c
index 8c128dea3252..67c052af7bbe 100644
--- a/drivers/acpi/resources/rscreate.c
+++ b/drivers/acpi/resources/rscreate.c
@@ -332,7 +332,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
332 /* Now align the current length */ 332 /* Now align the current length */
333 333
334 user_prt->length = 334 user_prt->length =
335 (u32) ACPI_ROUND_UP_to_64_bITS(user_prt->length); 335 (u32) ACPI_ROUND_UP_to_64_bIT(user_prt->length);
336 336
337 /* 4) Fourth subobject: Dereference the PRT.source_index */ 337 /* 4) Fourth subobject: Dereference the PRT.source_index */
338 338
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
index c27dca64d5d0..6f2d8de39523 100644
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -77,6 +77,15 @@ acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer)
77 /* Loop until end-of-buffer or an end_tag is found */ 77 /* Loop until end-of-buffer or an end_tag is found */
78 78
79 while (aml < end_aml) { 79 while (aml < end_aml) {
80 /*
81 * Check that the input buffer and all subsequent pointers into it
82 * are aligned on a native word boundary. Most important on IA64
83 */
84 if (ACPI_IS_MISALIGNED(resource)) {
85 ACPI_WARNING((AE_INFO,
86 "Misaligned resource pointer %p",
87 resource));
88 }
80 89
81 /* Validate the Resource Type and Resource Length */ 90 /* Validate the Resource Type and Resource Length */
82 91
@@ -101,6 +110,12 @@ acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer)
101 return_ACPI_STATUS(status); 110 return_ACPI_STATUS(status);
102 } 111 }
103 112
113 ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES,
114 "Type %.2X, Aml %.2X internal %.2X\n",
115 acpi_ut_get_resource_type(aml),
116 acpi_ut_get_descriptor_length(aml),
117 resource->length));
118
104 /* Normal exit on completion of an end_tag resource descriptor */ 119 /* Normal exit on completion of an end_tag resource descriptor */
105 120
106 if (acpi_ut_get_resource_type(aml) == 121 if (acpi_ut_get_resource_type(aml) ==
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
index 095730196a8a..6a731f4028d4 100644
--- a/drivers/acpi/resources/rsmisc.c
+++ b/drivers/acpi/resources/rsmisc.c
@@ -81,7 +81,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
81 u16 item_count = 0; 81 u16 item_count = 0;
82 u16 temp16 = 0; 82 u16 temp16 = 0;
83 83
84 ACPI_FUNCTION_TRACE("rs_get_resource"); 84 ACPI_FUNCTION_TRACE("rs_convert_aml_to_resource");
85 85
86 if (((acpi_native_uint) resource) & 0x3) { 86 if (((acpi_native_uint) resource) & 0x3) {
87 87
@@ -297,10 +297,10 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
297 exit: 297 exit:
298 if (!flags_mode) { 298 if (!flags_mode) {
299 299
300 /* Round the resource struct length up to the next 32-bit boundary */ 300 /* Round the resource struct length up to the next boundary (32 or 64) */
301 301
302 resource->length = 302 resource->length =
303 (u32) ACPI_ROUND_UP_to_32_bITS(resource->length); 303 (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(resource->length);
304 } 304 }
305 return_ACPI_STATUS(AE_OK); 305 return_ACPI_STATUS(AE_OK);
306} 306}
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index c5f7014929b4..9bcf0b637d22 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -299,7 +299,8 @@ static u16 acpi_rs_strcpy(char *destination, char *source)
299 * string_ptr - (optional) where to store the actual 299 * string_ptr - (optional) where to store the actual
300 * resource_source string 300 * resource_source string
301 * 301 *
302 * RETURN: Length of the string plus NULL terminator, rounded up to 32 bit 302 * RETURN: Length of the string plus NULL terminator, rounded up to native
303 * word boundary
303 * 304 *
304 * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor 305 * DESCRIPTION: Copy the optional resource_source data from a raw AML descriptor
305 * to an internal resource descriptor 306 * to an internal resource descriptor
@@ -346,18 +347,16 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length,
346 } 347 }
347 348
348 /* 349 /*
349 * In order for the struct_size to fall on a 32-bit boundary, calculate 350 * In order for the Resource length to be a multiple of the native
350 * the length of the string (+1 for the NULL terminator) and expand the 351 * word, calculate the length of the string (+1 for NULL terminator)
351 * struct_size to the next 32-bit boundary. 352 * and expand to the next word multiple.
352 * 353 *
353 * Zero the entire area of the buffer. 354 * Zero the entire area of the buffer.
354 */ 355 */
355 total_length = 356 total_length =
356 (u32) 357 ACPI_STRLEN(ACPI_CAST_PTR(char, &aml_resource_source[1])) +
357 ACPI_ROUND_UP_to_32_bITS(ACPI_STRLEN 358 1;
358 (ACPI_CAST_PTR 359 total_length = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(total_length);
359 (char,
360 &aml_resource_source[1])) + 1);
361 360
362 ACPI_MEMSET(resource_source->string_ptr, 0, total_length); 361 ACPI_MEMSET(resource_source->string_ptr, 0, total_length);
363 362