aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2014-01-08 00:43:46 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-08 09:31:36 -0500
commit0249ed2444d65d65fc3f3f64f398f1ad0b7e54cd (patch)
tree98217f25d2eda9cdd96d4f386021e7228d04f30a /drivers/acpi
parentfab4610583855d544394320d47fccb43305a6398 (diff)
ACPICA: Add option to favor 32-bit FADT addresses.
This change adds an option to favor 32-bit FADT addresses when there is a conflict between the 32-bit and 64-bit versions of the same address. The default behavior is to use the 64-bit version in accordance with the ACPI specification. This can now be overridden via the AcpiGbl_Use32BitFadtAddresses flag. Lv Zheng. Also, the "Convert FADT" and "Verify FADT" functions have been merged to simplify the code, make it easier to understand, and make it easier to maintain. Bob Moore. References: https://bugs.acpica.org/show_bug.cgi?id=885 References: https://bugs.acpica.org/show_bug.cgi?id=993 Original-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/acpica/acglobal.h10
-rw-r--r--drivers/acpi/acpica/tbfadt.c335
2 files changed, 193 insertions, 152 deletions
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index cffb45742aa5..268699879904 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -127,6 +127,16 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE);
127u8 ACPI_INIT_GLOBAL(acpi_gbl_do_not_use_xsdt, FALSE); 127u8 ACPI_INIT_GLOBAL(acpi_gbl_do_not_use_xsdt, FALSE);
128 128
129/* 129/*
130 * Optionally use 32-bit FADT addresses if and when there is a conflict
131 * (address mismatch) between the 32-bit and 64-bit versions of the
132 * address. Although ACPICA adheres to the ACPI specification which
133 * requires the use of the corresponding 64-bit address if it is non-zero,
134 * some machines have been found to have a corrupted non-zero 64-bit
135 * address. Default is FALSE, do not favor the 32-bit addresses.
136 */
137u8 ACPI_INIT_GLOBAL(acpi_gbl_use32_bit_fadt_addresses, FALSE);
138
139/*
130 * Optionally truncate I/O addresses to 16 bits. Provides compatibility 140 * Optionally truncate I/O addresses to 16 bits. Provides compatibility
131 * with other ACPI implementations. NOTE: During ACPICA initialization, 141 * with other ACPI implementations. NOTE: During ACPICA initialization,
132 * this value is set to TRUE if any Windows OSI strings have been 142 * this value is set to TRUE if any Windows OSI strings have been
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 9d99f2189693..8f89263ac47e 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -56,10 +56,11 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
56 56
57static void acpi_tb_convert_fadt(void); 57static void acpi_tb_convert_fadt(void);
58 58
59static void acpi_tb_validate_fadt(void);
60
61static void acpi_tb_setup_fadt_registers(void); 59static void acpi_tb_setup_fadt_registers(void);
62 60
61static u64
62acpi_tb_select_address(char *register_name, u32 address32, u64 address64);
63
63/* Table for conversion of FADT to common internal format and FADT validation */ 64/* Table for conversion of FADT to common internal format and FADT validation */
64 65
65typedef struct acpi_fadt_info { 66typedef struct acpi_fadt_info {
@@ -175,6 +176,7 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
175 * space_id - ACPI Space ID for this register 176 * space_id - ACPI Space ID for this register
176 * byte_width - Width of this register 177 * byte_width - Width of this register
177 * address - Address of the register 178 * address - Address of the register
179 * register_name - ASCII name of the ACPI register
178 * 180 *
179 * RETURN: None 181 * RETURN: None
180 * 182 *
@@ -220,6 +222,68 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
220 222
221/******************************************************************************* 223/*******************************************************************************
222 * 224 *
225 * FUNCTION: acpi_tb_select_address
226 *
227 * PARAMETERS: register_name - ASCII name of the ACPI register
228 * address32 - 32-bit address of the register
229 * address64 - 64-bit address of the register
230 *
231 * RETURN: The resolved 64-bit address
232 *
233 * DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within
234 * the FADT. Used for the FACS and DSDT addresses.
235 *
236 * NOTES:
237 *
238 * Check for FACS and DSDT address mismatches. An address mismatch between
239 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
240 * DSDT/X_DSDT) could be a corrupted address field or it might indicate
241 * the presence of two FACS or two DSDT tables.
242 *
243 * November 2013:
244 * By default, as per the ACPICA specification, a valid 64-bit address is
245 * used regardless of the value of the 32-bit address. However, this
246 * behavior can be overridden via the acpi_gbl_use32_bit_fadt_addresses flag.
247 *
248 ******************************************************************************/
249
250static u64
251acpi_tb_select_address(char *register_name, u32 address32, u64 address64)
252{
253
254 if (!address64) {
255
256 /* 64-bit address is zero, use 32-bit address */
257
258 return ((u64)address32);
259 }
260
261 if (address32 && (address64 != (u64)address32)) {
262
263 /* Address mismatch between 32-bit and 64-bit versions */
264
265 ACPI_BIOS_WARNING((AE_INFO,
266 "32/64X %s address mismatch in FADT: "
267 "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
268 register_name, address32,
269 ACPI_FORMAT_UINT64(address64),
270 acpi_gbl_use32_bit_fadt_addresses ? 32 :
271 64));
272
273 /* 32-bit address override */
274
275 if (acpi_gbl_use32_bit_fadt_addresses) {
276 return ((u64)address32);
277 }
278 }
279
280 /* Default is to use the 64-bit address */
281
282 return (address64);
283}
284
285/*******************************************************************************
286 *
223 * FUNCTION: acpi_tb_parse_fadt 287 * FUNCTION: acpi_tb_parse_fadt
224 * 288 *
225 * PARAMETERS: table_index - Index for the FADT 289 * PARAMETERS: table_index - Index for the FADT
@@ -331,10 +395,6 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
331 395
332 acpi_tb_convert_fadt(); 396 acpi_tb_convert_fadt();
333 397
334 /* Validate FADT values now, before we make any changes */
335
336 acpi_tb_validate_fadt();
337
338 /* Initialize the global ACPI register structures */ 398 /* Initialize the global ACPI register structures */
339 399
340 acpi_tb_setup_fadt_registers(); 400 acpi_tb_setup_fadt_registers();
@@ -344,66 +404,55 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
344 * 404 *
345 * FUNCTION: acpi_tb_convert_fadt 405 * FUNCTION: acpi_tb_convert_fadt
346 * 406 *
347 * PARAMETERS: None, uses acpi_gbl_FADT 407 * PARAMETERS: none - acpi_gbl_FADT is used.
348 * 408 *
349 * RETURN: None 409 * RETURN: None
350 * 410 *
351 * DESCRIPTION: Converts all versions of the FADT to a common internal format. 411 * DESCRIPTION: Converts all versions of the FADT to a common internal format.
352 * Expand 32-bit addresses to 64-bit as necessary. 412 * Expand 32-bit addresses to 64-bit as necessary. Also validate
413 * important fields within the FADT.
353 * 414 *
354 * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), 415 * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), and must
355 * and must contain a copy of the actual FADT. 416 * contain a copy of the actual BIOS-provided FADT.
356 * 417 *
357 * Notes on 64-bit register addresses: 418 * Notes on 64-bit register addresses:
358 * 419 *
359 * After this FADT conversion, later ACPICA code will only use the 64-bit "X" 420 * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
360 * fields of the FADT for all ACPI register addresses. 421 * fields of the FADT for all ACPI register addresses.
361 * 422 *
362 * The 64-bit "X" fields are optional extensions to the original 32-bit FADT 423 * The 64-bit X fields are optional extensions to the original 32-bit FADT
363 * V1.0 fields. Even if they are present in the FADT, they are optional and 424 * V1.0 fields. Even if they are present in the FADT, they are optional and
364 * are unused if the BIOS sets them to zero. Therefore, we must copy/expand 425 * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
365 * 32-bit V1.0 fields if the corresponding X field is zero. 426 * 32-bit V1.0 fields to the 64-bit X fields if the the 64-bit X field is
427 * originally zero.
366 * 428 *
367 * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the 429 * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address
368 * corresponding "X" fields in the internal FADT. 430 * fields are expanded to the corresponding 64-bit X fields in the internal
431 * common FADT.
369 * 432 *
370 * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded 433 * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
371 * to the corresponding 64-bit X fields. For compatibility with other ACPI 434 * to the corresponding 64-bit X fields, if the 64-bit field is originally
372 * implementations, we ignore the 64-bit field if the 32-bit field is valid, 435 * zero. Adhering to the ACPI specification, we completely ignore the 32-bit
373 * regardless of whether the host OS is 32-bit or 64-bit. 436 * field if the 64-bit field is valid, regardless of whether the host OS is
437 * 32-bit or 64-bit.
438 *
439 * Possible additional checks:
440 * (acpi_gbl_FADT.pm1_event_length >= 4)
441 * (acpi_gbl_FADT.pm1_control_length >= 2)
442 * (acpi_gbl_FADT.pm_timer_length >= 4)
443 * Gpe block lengths must be multiple of 2
374 * 444 *
375 ******************************************************************************/ 445 ******************************************************************************/
376 446
377static void acpi_tb_convert_fadt(void) 447static void acpi_tb_convert_fadt(void)
378{ 448{
449 char *name;
379 struct acpi_generic_address *address64; 450 struct acpi_generic_address *address64;
380 u32 address32; 451 u32 address32;
452 u8 length;
381 u32 i; 453 u32 i;
382 454
383 /* 455 /*
384 * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
385 * Later code will always use the X 64-bit field. Also, check for an
386 * address mismatch between the 32-bit and 64-bit address fields
387 * (FIRMWARE_CTRL/X_FIRMWARE_CTRL, DSDT/X_DSDT) which would indicate
388 * the presence of two FACS or two DSDT tables.
389 */
390 if (!acpi_gbl_FADT.Xfacs) {
391 acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
392 } else if (acpi_gbl_FADT.facs &&
393 (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
394 ACPI_WARNING((AE_INFO,
395 "32/64 FACS address mismatch in FADT - two FACS tables!"));
396 }
397
398 if (!acpi_gbl_FADT.Xdsdt) {
399 acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
400 } else if (acpi_gbl_FADT.dsdt &&
401 (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
402 ACPI_WARNING((AE_INFO,
403 "32/64 DSDT address mismatch in FADT - two DSDT tables!"));
404 }
405
406 /*
407 * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which 456 * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
408 * should be zero are indeed zero. This will workaround BIOSs that 457 * should be zero are indeed zero. This will workaround BIOSs that
409 * inadvertently place values in these fields. 458 * inadvertently place values in these fields.
@@ -421,119 +470,24 @@ static void acpi_tb_convert_fadt(void)
421 acpi_gbl_FADT.boot_flags = 0; 470 acpi_gbl_FADT.boot_flags = 0;
422 } 471 }
423 472
424 /* Update the local FADT table header length */
425
426 acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
427
428 /* 473 /*
429 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" 474 * Now we can update the local FADT length to the length of the
430 * generic address structures as necessary. Later code will always use 475 * current FADT version as defined by the ACPI specification.
431 * the 64-bit address structures. 476 * Thus, we will have a common FADT internally.
432 *
433 * March 2009:
434 * We now always use the 32-bit address if it is valid (non-null). This
435 * is not in accordance with the ACPI specification which states that
436 * the 64-bit address supersedes the 32-bit version, but we do this for
437 * compatibility with other ACPI implementations. Most notably, in the
438 * case where both the 32 and 64 versions are non-null, we use the 32-bit
439 * version. This is the only address that is guaranteed to have been
440 * tested by the BIOS manufacturer.
441 */ 477 */
442 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { 478 acpi_gbl_FADT.header.length = sizeof(struct acpi_table_fadt);
443 address32 = *ACPI_ADD_PTR(u32,
444 &acpi_gbl_FADT,
445 fadt_info_table[i].address32);
446
447 address64 = ACPI_ADD_PTR(struct acpi_generic_address,
448 &acpi_gbl_FADT,
449 fadt_info_table[i].address64);
450
451 /*
452 * If both 32- and 64-bit addresses are valid (non-zero),
453 * they must match.
454 */
455 if (address64->address && address32 &&
456 (address64->address != (u64)address32)) {
457 ACPI_BIOS_ERROR((AE_INFO,
458 "32/64X address mismatch in FADT/%s: "
459 "0x%8.8X/0x%8.8X%8.8X, using 32",
460 fadt_info_table[i].name, address32,
461 ACPI_FORMAT_UINT64(address64->
462 address)));
463 }
464
465 /* Always use 32-bit address if it is valid (non-null) */
466
467 if (address32) {
468 /*
469 * Copy the 32-bit address to the 64-bit GAS structure. The
470 * Space ID is always I/O for 32-bit legacy address fields
471 */
472 acpi_tb_init_generic_address(address64,
473 ACPI_ADR_SPACE_SYSTEM_IO,
474 *ACPI_ADD_PTR(u8,
475 &acpi_gbl_FADT,
476 fadt_info_table
477 [i].length),
478 (u64) address32,
479 fadt_info_table[i].name);
480 }
481 }
482}
483
484/*******************************************************************************
485 *
486 * FUNCTION: acpi_tb_validate_fadt
487 *
488 * PARAMETERS: table - Pointer to the FADT to be validated
489 *
490 * RETURN: None
491 *
492 * DESCRIPTION: Validate various important fields within the FADT. If a problem
493 * is found, issue a message, but no status is returned.
494 * Used by both the table manager and the disassembler.
495 *
496 * Possible additional checks:
497 * (acpi_gbl_FADT.pm1_event_length >= 4)
498 * (acpi_gbl_FADT.pm1_control_length >= 2)
499 * (acpi_gbl_FADT.pm_timer_length >= 4)
500 * Gpe block lengths must be multiple of 2
501 *
502 ******************************************************************************/
503
504static void acpi_tb_validate_fadt(void)
505{
506 char *name;
507 struct acpi_generic_address *address64;
508 u8 length;
509 u32 i;
510 479
511 /* 480 /*
512 * Check for FACS and DSDT address mismatches. An address mismatch between 481 * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
513 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and 482 * Later ACPICA code will always use the X 64-bit field.
514 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables.
515 */ 483 */
516 if (acpi_gbl_FADT.facs && 484 acpi_gbl_FADT.Xfacs = acpi_tb_select_address("FACS",
517 (acpi_gbl_FADT.Xfacs != (u64)acpi_gbl_FADT.facs)) { 485 acpi_gbl_FADT.facs,
518 ACPI_BIOS_WARNING((AE_INFO, 486 acpi_gbl_FADT.Xfacs);
519 "32/64X FACS address mismatch in FADT - "
520 "0x%8.8X/0x%8.8X%8.8X, using 32",
521 acpi_gbl_FADT.facs,
522 ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
523
524 acpi_gbl_FADT.Xfacs = (u64)acpi_gbl_FADT.facs;
525 }
526
527 if (acpi_gbl_FADT.dsdt &&
528 (acpi_gbl_FADT.Xdsdt != (u64)acpi_gbl_FADT.dsdt)) {
529 ACPI_BIOS_WARNING((AE_INFO,
530 "32/64X DSDT address mismatch in FADT - "
531 "0x%8.8X/0x%8.8X%8.8X, using 32",
532 acpi_gbl_FADT.dsdt,
533 ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
534 487
535 acpi_gbl_FADT.Xdsdt = (u64)acpi_gbl_FADT.dsdt; 488 acpi_gbl_FADT.Xdsdt = acpi_tb_select_address("DSDT",
536 } 489 acpi_gbl_FADT.dsdt,
490 acpi_gbl_FADT.Xdsdt);
537 491
538 /* If Hardware Reduced flag is set, we are all done */ 492 /* If Hardware Reduced flag is set, we are all done */
539 493
@@ -545,18 +499,95 @@ static void acpi_tb_validate_fadt(void)
545 499
546 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { 500 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
547 /* 501 /*
548 * Generate pointer to the 64-bit address, get the register 502 * Get the 32-bit and 64-bit addresses, as well as the register
549 * length (width) and the register name 503 * length and register name.
550 */ 504 */
505 address32 = *ACPI_ADD_PTR(u32,
506 &acpi_gbl_FADT,
507 fadt_info_table[i].address32);
508
551 address64 = ACPI_ADD_PTR(struct acpi_generic_address, 509 address64 = ACPI_ADD_PTR(struct acpi_generic_address,
552 &acpi_gbl_FADT, 510 &acpi_gbl_FADT,
553 fadt_info_table[i].address64); 511 fadt_info_table[i].address64);
554 length = 512
555 *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, 513 length = *ACPI_ADD_PTR(u8,
556 fadt_info_table[i].length); 514 &acpi_gbl_FADT,
515 fadt_info_table[i].length);
516
557 name = fadt_info_table[i].name; 517 name = fadt_info_table[i].name;
558 518
559 /* 519 /*
520 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
521 * generic address structures as necessary. Later code will always use
522 * the 64-bit address structures.
523 *
524 * November 2013:
525 * Now always use the 64-bit address if it is valid (non-zero), in
526 * accordance with the ACPI specification which states that a 64-bit
527 * address supersedes the 32-bit version. This behavior can be
528 * overridden by the acpi_gbl_use32_bit_fadt_addresses flag.
529 *
530 * During 64-bit address construction and verification,
531 * these cases are handled:
532 *
533 * Address32 zero, Address64 [don't care] - Use Address64
534 *
535 * Address32 non-zero, Address64 zero - Copy/use Address32
536 * Address32 non-zero == Address64 non-zero - Use Address64
537 * Address32 non-zero != Address64 non-zero - Warning, use Address64
538 *
539 * Override: if acpi_gbl_use32_bit_fadt_addresses is TRUE, and:
540 * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32
541 *
542 * Note: space_id is always I/O for 32-bit legacy address fields
543 */
544 if (address32) {
545 if (!address64->address) {
546
547 /* 64-bit address is zero, use 32-bit address */
548
549 acpi_tb_init_generic_address(address64,
550 ACPI_ADR_SPACE_SYSTEM_IO,
551 *ACPI_ADD_PTR(u8,
552 &acpi_gbl_FADT,
553 fadt_info_table
554 [i].
555 length),
556 (u64)address32,
557 name);
558 } else if (address64->address != (u64)address32) {
559
560 /* Address mismatch */
561
562 ACPI_BIOS_WARNING((AE_INFO,
563 "32/64X address mismatch in FADT/%s: "
564 "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
565 name, address32,
566 ACPI_FORMAT_UINT64
567 (address64->address),
568 acpi_gbl_use32_bit_fadt_addresses
569 ? 32 : 64));
570
571 if (acpi_gbl_use32_bit_fadt_addresses) {
572
573 /* 32-bit address override */
574
575 acpi_tb_init_generic_address(address64,
576 ACPI_ADR_SPACE_SYSTEM_IO,
577 *ACPI_ADD_PTR
578 (u8,
579 &acpi_gbl_FADT,
580 fadt_info_table
581 [i].
582 length),
583 (u64)
584 address32,
585 name);
586 }
587 }
588 }
589
590 /*
560 * For each extended field, check for length mismatch between the 591 * For each extended field, check for length mismatch between the
561 * legacy length field and the corresponding 64-bit X length field. 592 * legacy length field and the corresponding 64-bit X length field.
562 * Note: If the legacy length field is > 0xFF bits, ignore this 593 * Note: If the legacy length field is > 0xFF bits, ignore this