aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/resources/rscalc.c
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/rscalc.c
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/rscalc.c')
-rw-r--r--drivers/acpi/resources/rscalc.c100
1 files changed, 45 insertions, 55 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 =