1 /****************************************************************************** 2 * 3 * Module Name: tbfadt - FADT table utilities 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 #define __TBFADT_C__ 117 118 #include "acpi.h" 119 #include "accommon.h" 120 #include "actables.h" 121 122 #define _COMPONENT ACPI_TABLES 123 ACPI_MODULE_NAME ("tbfadt") 124 125 /* Local prototypes */ 126 127 static void 128 AcpiTbInitGenericAddress ( 129 ACPI_GENERIC_ADDRESS *GenericAddress, 130 UINT8 SpaceId, 131 UINT8 ByteWidth, 132 UINT64 Address, 133 char *RegisterName); 134 135 static void 136 AcpiTbConvertFadt ( 137 void); 138 139 static void 140 AcpiTbValidateFadt ( 141 void); 142 143 static void 144 AcpiTbSetupFadtRegisters ( 145 void); 146 147 148 /* Table for conversion of FADT to common internal format and FADT validation */ 149 150 typedef struct acpi_fadt_info 151 { 152 char *Name; 153 UINT16 Address64; 154 UINT16 Address32; 155 UINT16 Length; 156 UINT8 DefaultLength; 157 UINT8 Type; 158 159 } ACPI_FADT_INFO; 160 161 #define ACPI_FADT_OPTIONAL 0 162 #define ACPI_FADT_REQUIRED 1 163 #define ACPI_FADT_SEPARATE_LENGTH 2 164 165 static ACPI_FADT_INFO FadtInfoTable[] = 166 { 167 {"Pm1aEventBlock", 168 ACPI_FADT_OFFSET (XPm1aEventBlock), 169 ACPI_FADT_OFFSET (Pm1aEventBlock), 170 ACPI_FADT_OFFSET (Pm1EventLength), 171 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 172 ACPI_FADT_REQUIRED}, 173 174 {"Pm1bEventBlock", 175 ACPI_FADT_OFFSET (XPm1bEventBlock), 176 ACPI_FADT_OFFSET (Pm1bEventBlock), 177 ACPI_FADT_OFFSET (Pm1EventLength), 178 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 179 ACPI_FADT_OPTIONAL}, 180 181 {"Pm1aControlBlock", 182 ACPI_FADT_OFFSET (XPm1aControlBlock), 183 ACPI_FADT_OFFSET (Pm1aControlBlock), 184 ACPI_FADT_OFFSET (Pm1ControlLength), 185 ACPI_PM1_REGISTER_WIDTH, 186 ACPI_FADT_REQUIRED}, 187 188 {"Pm1bControlBlock", 189 ACPI_FADT_OFFSET (XPm1bControlBlock), 190 ACPI_FADT_OFFSET (Pm1bControlBlock), 191 ACPI_FADT_OFFSET (Pm1ControlLength), 192 ACPI_PM1_REGISTER_WIDTH, 193 ACPI_FADT_OPTIONAL}, 194 195 {"Pm2ControlBlock", 196 ACPI_FADT_OFFSET (XPm2ControlBlock), 197 ACPI_FADT_OFFSET (Pm2ControlBlock), 198 ACPI_FADT_OFFSET (Pm2ControlLength), 199 ACPI_PM2_REGISTER_WIDTH, 200 ACPI_FADT_SEPARATE_LENGTH}, 201 202 {"PmTimerBlock", 203 ACPI_FADT_OFFSET (XPmTimerBlock), 204 ACPI_FADT_OFFSET (PmTimerBlock), 205 ACPI_FADT_OFFSET (PmTimerLength), 206 ACPI_PM_TIMER_WIDTH, 207 ACPI_FADT_REQUIRED}, 208 209 {"Gpe0Block", 210 ACPI_FADT_OFFSET (XGpe0Block), 211 ACPI_FADT_OFFSET (Gpe0Block), 212 ACPI_FADT_OFFSET (Gpe0BlockLength), 213 0, 214 ACPI_FADT_SEPARATE_LENGTH}, 215 216 {"Gpe1Block", 217 ACPI_FADT_OFFSET (XGpe1Block), 218 ACPI_FADT_OFFSET (Gpe1Block), 219 ACPI_FADT_OFFSET (Gpe1BlockLength), 220 0, 221 ACPI_FADT_SEPARATE_LENGTH} 222 }; 223 224 #define ACPI_FADT_INFO_ENTRIES \ 225 (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO)) 226 227 228 /* Table used to split Event Blocks into separate status/enable registers */ 229 230 typedef struct acpi_fadt_pm_info 231 { 232 ACPI_GENERIC_ADDRESS *Target; 233 UINT16 Source; 234 UINT8 RegisterNum; 235 236 } ACPI_FADT_PM_INFO; 237 238 static ACPI_FADT_PM_INFO FadtPmInfoTable[] = 239 { 240 {&AcpiGbl_XPm1aStatus, 241 ACPI_FADT_OFFSET (XPm1aEventBlock), 242 0}, 243 244 {&AcpiGbl_XPm1aEnable, 245 ACPI_FADT_OFFSET (XPm1aEventBlock), 246 1}, 247 248 {&AcpiGbl_XPm1bStatus, 249 ACPI_FADT_OFFSET (XPm1bEventBlock), 250 0}, 251 252 {&AcpiGbl_XPm1bEnable, 253 ACPI_FADT_OFFSET (XPm1bEventBlock), 254 1} 255 }; 256 257 #define ACPI_FADT_PM_INFO_ENTRIES \ 258 (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO)) 259 260 261 /******************************************************************************* 262 * 263 * FUNCTION: AcpiTbInitGenericAddress 264 * 265 * PARAMETERS: GenericAddress - GAS struct to be initialized 266 * SpaceId - ACPI Space ID for this register 267 * ByteWidth - Width of this register 268 * Address - Address of the register 269 * 270 * RETURN: None 271 * 272 * DESCRIPTION: Initialize a Generic Address Structure (GAS) 273 * See the ACPI specification for a full description and 274 * definition of this structure. 275 * 276 ******************************************************************************/ 277 278 static void 279 AcpiTbInitGenericAddress ( 280 ACPI_GENERIC_ADDRESS *GenericAddress, 281 UINT8 SpaceId, 282 UINT8 ByteWidth, 283 UINT64 Address, 284 char *RegisterName) 285 { 286 UINT8 BitWidth; 287 288 289 /* Bit width field in the GAS is only one byte long, 255 max */ 290 291 BitWidth = (UINT8) (ByteWidth * 8); 292 293 if (ByteWidth > 31) /* (31*8)=248 */ 294 { 295 ACPI_ERROR ((AE_INFO, 296 "%s - 32-bit FADT register is too long (%u bytes, %u bits) " 297 "to convert to GAS struct - 255 bits max, truncating", 298 RegisterName, ByteWidth, (ByteWidth * 8))); 299 300 BitWidth = 255; 301 } 302 303 /* 304 * The 64-bit Address field is non-aligned in the byte packed 305 * GAS struct. 306 */ 307 ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address); 308 309 /* All other fields are byte-wide */ 310 311 GenericAddress->SpaceId = SpaceId; 312 GenericAddress->BitWidth = BitWidth; 313 GenericAddress->BitOffset = 0; 314 GenericAddress->AccessWidth = 0; /* Access width ANY */ 315 } 316 317 318 /******************************************************************************* 319 * 320 * FUNCTION: AcpiTbParseFadt 321 * 322 * PARAMETERS: TableIndex - Index for the FADT 323 * 324 * RETURN: None 325 * 326 * DESCRIPTION: Initialize the FADT, DSDT and FACS tables 327 * (FADT contains the addresses of the DSDT and FACS) 328 * 329 ******************************************************************************/ 330 331 void 332 AcpiTbParseFadt ( 333 UINT32 TableIndex) 334 { 335 UINT32 Length; 336 ACPI_TABLE_HEADER *Table; 337 338 339 /* 340 * The FADT has multiple versions with different lengths, 341 * and it contains pointers to both the DSDT and FACS tables. 342 * 343 * Get a local copy of the FADT and convert it to a common format 344 * Map entire FADT, assumed to be smaller than one page. 345 */ 346 Length = AcpiGbl_RootTableList.Tables[TableIndex].Length; 347 348 Table = AcpiOsMapMemory ( 349 AcpiGbl_RootTableList.Tables[TableIndex].Address, Length); 350 if (!Table) 351 { 352 return; 353 } 354 355 /* 356 * Validate the FADT checksum before we copy the table. Ignore 357 * checksum error as we want to try to get the DSDT and FACS. 358 */ 359 (void) AcpiTbVerifyChecksum (Table, Length); 360 361 /* Create a local copy of the FADT in common ACPI 2.0+ format */ 362 363 AcpiTbCreateLocalFadt (Table, Length); 364 365 /* All done with the real FADT, unmap it */ 366 367 AcpiOsUnmapMemory (Table, Length); 368 369 /* Obtain the DSDT and FACS tables via their addresses within the FADT */ 370 371 AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt, 372 ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); 373 374 /* If Hardware Reduced flag is set, there is no FACS */ 375 376 if (!AcpiGbl_ReducedHardware) 377 { 378 AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs, 379 ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); 380 } 381 } 382 383 384 /******************************************************************************* 385 * 386 * FUNCTION: AcpiTbCreateLocalFadt 387 * 388 * PARAMETERS: Table - Pointer to BIOS FADT 389 * Length - Length of the table 390 * 391 * RETURN: None 392 * 393 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. 394 * Performs validation on some important FADT fields. 395 * 396 * NOTE: We create a local copy of the FADT regardless of the version. 397 * 398 ******************************************************************************/ 399 400 void 401 AcpiTbCreateLocalFadt ( 402 ACPI_TABLE_HEADER *Table, 403 UINT32 Length) 404 { 405 406 /* 407 * Check if the FADT is larger than the largest table that we expect 408 * (the ACPI 5.0 version). If so, truncate the table, and issue 409 * a warning. 410 */ 411 if (Length > sizeof (ACPI_TABLE_FADT)) 412 { 413 ACPI_BIOS_WARNING ((AE_INFO, 414 "FADT (revision %u) is longer than ACPI 5.0 version, " 415 "truncating length %u to %u", 416 Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT))); 417 } 418 419 /* Clear the entire local FADT */ 420 421 ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT)); 422 423 /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */ 424 425 ACPI_MEMCPY (&AcpiGbl_FADT, Table, 426 ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT))); 427 428 /* Take a copy of the Hardware Reduced flag */ 429 430 AcpiGbl_ReducedHardware = FALSE; 431 if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED) 432 { 433 AcpiGbl_ReducedHardware = TRUE; 434 } 435 436 /* Convert the local copy of the FADT to the common internal format */ 437 438 AcpiTbConvertFadt (); 439 440 /* Validate FADT values now, before we make any changes */ 441 442 AcpiTbValidateFadt (); 443 444 /* Initialize the global ACPI register structures */ 445 446 AcpiTbSetupFadtRegisters (); 447 } 448 449 450 /******************************************************************************* 451 * 452 * FUNCTION: AcpiTbConvertFadt 453 * 454 * PARAMETERS: None, uses AcpiGbl_FADT 455 * 456 * RETURN: None 457 * 458 * DESCRIPTION: Converts all versions of the FADT to a common internal format. 459 * Expand 32-bit addresses to 64-bit as necessary. 460 * 461 * NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), 462 * and must contain a copy of the actual FADT. 463 * 464 * Notes on 64-bit register addresses: 465 * 466 * After this FADT conversion, later ACPICA code will only use the 64-bit "X" 467 * fields of the FADT for all ACPI register addresses. 468 * 469 * The 64-bit "X" fields are optional extensions to the original 32-bit FADT 470 * V1.0 fields. Even if they are present in the FADT, they are optional and 471 * are unused if the BIOS sets them to zero. Therefore, we must copy/expand 472 * 32-bit V1.0 fields if the corresponding X field is zero. 473 * 474 * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the 475 * corresponding "X" fields in the internal FADT. 476 * 477 * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded 478 * to the corresponding 64-bit X fields. For compatibility with other ACPI 479 * implementations, we ignore the 64-bit field if the 32-bit field is valid, 480 * regardless of whether the host OS is 32-bit or 64-bit. 481 * 482 ******************************************************************************/ 483 484 static void 485 AcpiTbConvertFadt ( 486 void) 487 { 488 ACPI_GENERIC_ADDRESS *Address64; 489 UINT32 Address32; 490 UINT32 i; 491 492 493 /* 494 * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. 495 * Later code will always use the X 64-bit field. 496 */ 497 if (!AcpiGbl_FADT.XFacs) 498 { 499 AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs; 500 } 501 if (!AcpiGbl_FADT.XDsdt) 502 { 503 AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt; 504 } 505 506 /* 507 * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which 508 * should be zero are indeed zero. This will workaround BIOSs that 509 * inadvertently place values in these fields. 510 * 511 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located 512 * at offset 45, 55, 95, and the word located at offset 109, 110. 513 * 514 * Note: The FADT revision value is unreliable. Only the length can be 515 * trusted. 516 */ 517 if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE) 518 { 519 AcpiGbl_FADT.PreferredProfile = 0; 520 AcpiGbl_FADT.PstateControl = 0; 521 AcpiGbl_FADT.CstControl = 0; 522 AcpiGbl_FADT.BootFlags = 0; 523 } 524 525 /* 526 * Now we can update the local FADT length to the length of the 527 * current FADT version as defined by the ACPI specification. 528 * Thus, we will have a common FADT internally. 529 */ 530 AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT); 531 532 /* 533 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" 534 * generic address structures as necessary. Later code will always use 535 * the 64-bit address structures. 536 * 537 * March 2009: 538 * We now always use the 32-bit address if it is valid (non-null). This 539 * is not in accordance with the ACPI specification which states that 540 * the 64-bit address supersedes the 32-bit version, but we do this for 541 * compatibility with other ACPI implementations. Most notably, in the 542 * case where both the 32 and 64 versions are non-null, we use the 32-bit 543 * version. This is the only address that is guaranteed to have been 544 * tested by the BIOS manufacturer. 545 */ 546 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 547 { 548 Address32 = *ACPI_ADD_PTR (UINT32, 549 &AcpiGbl_FADT, FadtInfoTable[i].Address32); 550 551 Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, 552 &AcpiGbl_FADT, FadtInfoTable[i].Address64); 553 554 /* 555 * If both 32- and 64-bit addresses are valid (non-zero), 556 * they must match. 557 */ 558 if (Address64->Address && Address32 && 559 (Address64->Address != (UINT64) Address32)) 560 { 561 ACPI_BIOS_ERROR ((AE_INFO, 562 "32/64X address mismatch in FADT/%s: " 563 "0x%8.8X/0x%8.8X%8.8X, using 32", 564 FadtInfoTable[i].Name, Address32, 565 ACPI_FORMAT_UINT64 (Address64->Address))); 566 } 567 568 /* Always use 32-bit address if it is valid (non-null) */ 569 570 if (Address32) 571 { 572 /* 573 * Copy the 32-bit address to the 64-bit GAS structure. The 574 * Space ID is always I/O for 32-bit legacy address fields 575 */ 576 AcpiTbInitGenericAddress (Address64, ACPI_ADR_SPACE_SYSTEM_IO, 577 *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length), 578 (UINT64) Address32, FadtInfoTable[i].Name); 579 } 580 } 581 } 582 583 584 /******************************************************************************* 585 * 586 * FUNCTION: AcpiTbValidateFadt 587 * 588 * PARAMETERS: Table - Pointer to the FADT to be validated 589 * 590 * RETURN: None 591 * 592 * DESCRIPTION: Validate various important fields within the FADT. If a problem 593 * is found, issue a message, but no status is returned. 594 * Used by both the table manager and the disassembler. 595 * 596 * Possible additional checks: 597 * (AcpiGbl_FADT.Pm1EventLength >= 4) 598 * (AcpiGbl_FADT.Pm1ControlLength >= 2) 599 * (AcpiGbl_FADT.PmTimerLength >= 4) 600 * Gpe block lengths must be multiple of 2 601 * 602 ******************************************************************************/ 603 604 static void 605 AcpiTbValidateFadt ( 606 void) 607 { 608 char *Name; 609 ACPI_GENERIC_ADDRESS *Address64; 610 UINT8 Length; 611 UINT32 i; 612 613 614 /* 615 * Check for FACS and DSDT address mismatches. An address mismatch between 616 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and 617 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables. 618 */ 619 if (AcpiGbl_FADT.Facs && 620 (AcpiGbl_FADT.XFacs != (UINT64) AcpiGbl_FADT.Facs)) 621 { 622 ACPI_BIOS_WARNING ((AE_INFO, 623 "32/64X FACS address mismatch in FADT - " 624 "0x%8.8X/0x%8.8X%8.8X, using 32", 625 AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs))); 626 627 AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs; 628 } 629 630 if (AcpiGbl_FADT.Dsdt && 631 (AcpiGbl_FADT.XDsdt != (UINT64) AcpiGbl_FADT.Dsdt)) 632 { 633 ACPI_BIOS_WARNING ((AE_INFO, 634 "32/64X DSDT address mismatch in FADT - " 635 "0x%8.8X/0x%8.8X%8.8X, using 32", 636 AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt))); 637 638 AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt; 639 } 640 641 /* If Hardware Reduced flag is set, we are all done */ 642 643 if (AcpiGbl_ReducedHardware) 644 { 645 return; 646 } 647 648 /* Examine all of the 64-bit extended address fields (X fields) */ 649 650 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 651 { 652 /* 653 * Generate pointer to the 64-bit address, get the register 654 * length (width) and the register name 655 */ 656 Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, 657 &AcpiGbl_FADT, FadtInfoTable[i].Address64); 658 Length = *ACPI_ADD_PTR (UINT8, 659 &AcpiGbl_FADT, FadtInfoTable[i].Length); 660 Name = FadtInfoTable[i].Name; 661 662 /* 663 * For each extended field, check for length mismatch between the 664 * legacy length field and the corresponding 64-bit X length field. 665 */ 666 if (Address64->Address && 667 (Address64->BitWidth != ACPI_MUL_8 (Length))) 668 { 669 ACPI_BIOS_WARNING ((AE_INFO, 670 "32/64X length mismatch in FADT/%s: %u/%u", 671 Name, ACPI_MUL_8 (Length), Address64->BitWidth)); 672 } 673 674 if (FadtInfoTable[i].Type & ACPI_FADT_REQUIRED) 675 { 676 /* 677 * Field is required (PM1aEvent, PM1aControl, PmTimer). 678 * Both the address and length must be non-zero. 679 */ 680 if (!Address64->Address || !Length) 681 { 682 ACPI_BIOS_ERROR ((AE_INFO, 683 "Required FADT field %s has zero address and/or length: " 684 "0x%8.8X%8.8X/0x%X", 685 Name, ACPI_FORMAT_UINT64 (Address64->Address), Length)); 686 } 687 } 688 else if (FadtInfoTable[i].Type & ACPI_FADT_SEPARATE_LENGTH) 689 { 690 /* 691 * Field is optional (PM2Control, GPE0, GPE1) AND has its own 692 * length field. If present, both the address and length must 693 * be valid. 694 */ 695 if ((Address64->Address && !Length) || 696 (!Address64->Address && Length)) 697 { 698 ACPI_BIOS_WARNING ((AE_INFO, 699 "Optional FADT field %s has zero address or length: " 700 "0x%8.8X%8.8X/0x%X", 701 Name, ACPI_FORMAT_UINT64 (Address64->Address), Length)); 702 } 703 } 704 } 705 } 706 707 708 /******************************************************************************* 709 * 710 * FUNCTION: AcpiTbSetupFadtRegisters 711 * 712 * PARAMETERS: None, uses AcpiGbl_FADT. 713 * 714 * RETURN: None 715 * 716 * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally, 717 * force FADT register definitions to their default lengths. 718 * 719 ******************************************************************************/ 720 721 static void 722 AcpiTbSetupFadtRegisters ( 723 void) 724 { 725 ACPI_GENERIC_ADDRESS *Target64; 726 ACPI_GENERIC_ADDRESS *Source64; 727 UINT8 Pm1RegisterByteWidth; 728 UINT32 i; 729 730 731 /* 732 * Optionally check all register lengths against the default values and 733 * update them if they are incorrect. 734 */ 735 if (AcpiGbl_UseDefaultRegisterWidths) 736 { 737 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 738 { 739 Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, 740 FadtInfoTable[i].Address64); 741 742 /* 743 * If a valid register (Address != 0) and the (DefaultLength > 0) 744 * (Not a GPE register), then check the width against the default. 745 */ 746 if ((Target64->Address) && 747 (FadtInfoTable[i].DefaultLength > 0) && 748 (FadtInfoTable[i].DefaultLength != Target64->BitWidth)) 749 { 750 ACPI_BIOS_WARNING ((AE_INFO, 751 "Invalid length for FADT/%s: %u, using default %u", 752 FadtInfoTable[i].Name, Target64->BitWidth, 753 FadtInfoTable[i].DefaultLength)); 754 755 /* Incorrect size, set width to the default */ 756 757 Target64->BitWidth = FadtInfoTable[i].DefaultLength; 758 } 759 } 760 } 761 762 /* 763 * Get the length of the individual PM1 registers (enable and status). 764 * Each register is defined to be (event block length / 2). Extra divide 765 * by 8 converts bits to bytes. 766 */ 767 Pm1RegisterByteWidth = (UINT8) 768 ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth); 769 770 /* 771 * Calculate separate GAS structs for the PM1x (A/B) Status and Enable 772 * registers. These addresses do not appear (directly) in the FADT, so it 773 * is useful to pre-calculate them from the PM1 Event Block definitions. 774 * 775 * The PM event blocks are split into two register blocks, first is the 776 * PM Status Register block, followed immediately by the PM Enable 777 * Register block. Each is of length (Pm1EventLength/2) 778 * 779 * Note: The PM1A event block is required by the ACPI specification. 780 * However, the PM1B event block is optional and is rarely, if ever, 781 * used. 782 */ 783 784 for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) 785 { 786 Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, 787 FadtPmInfoTable[i].Source); 788 789 if (Source64->Address) 790 { 791 AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target, 792 Source64->SpaceId, Pm1RegisterByteWidth, 793 Source64->Address + 794 (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth), 795 "PmRegisters"); 796 } 797 } 798 } 799 800