1 /****************************************************************************** 2 * 3 * Module Name: tbfadt - FADT table utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2012, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #define __TBFADT_C__ 45 46 #include <contrib/dev/acpica/include/acpi.h> 47 #include <contrib/dev/acpica/include/accommon.h> 48 #include <contrib/dev/acpica/include/actables.h> 49 50 #define _COMPONENT ACPI_TABLES 51 ACPI_MODULE_NAME ("tbfadt") 52 53 /* Local prototypes */ 54 55 static ACPI_INLINE void 56 AcpiTbInitGenericAddress ( 57 ACPI_GENERIC_ADDRESS *GenericAddress, 58 UINT8 SpaceId, 59 UINT8 ByteWidth, 60 UINT64 Address); 61 62 static void 63 AcpiTbConvertFadt ( 64 void); 65 66 static void 67 AcpiTbValidateFadt ( 68 void); 69 70 static void 71 AcpiTbSetupFadtRegisters ( 72 void); 73 74 75 /* Table for conversion of FADT to common internal format and FADT validation */ 76 77 typedef struct acpi_fadt_info 78 { 79 char *Name; 80 UINT16 Address64; 81 UINT16 Address32; 82 UINT16 Length; 83 UINT8 DefaultLength; 84 UINT8 Type; 85 86 } ACPI_FADT_INFO; 87 88 #define ACPI_FADT_OPTIONAL 0 89 #define ACPI_FADT_REQUIRED 1 90 #define ACPI_FADT_SEPARATE_LENGTH 2 91 92 static ACPI_FADT_INFO FadtInfoTable[] = 93 { 94 {"Pm1aEventBlock", 95 ACPI_FADT_OFFSET (XPm1aEventBlock), 96 ACPI_FADT_OFFSET (Pm1aEventBlock), 97 ACPI_FADT_OFFSET (Pm1EventLength), 98 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 99 ACPI_FADT_REQUIRED}, 100 101 {"Pm1bEventBlock", 102 ACPI_FADT_OFFSET (XPm1bEventBlock), 103 ACPI_FADT_OFFSET (Pm1bEventBlock), 104 ACPI_FADT_OFFSET (Pm1EventLength), 105 ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */ 106 ACPI_FADT_OPTIONAL}, 107 108 {"Pm1aControlBlock", 109 ACPI_FADT_OFFSET (XPm1aControlBlock), 110 ACPI_FADT_OFFSET (Pm1aControlBlock), 111 ACPI_FADT_OFFSET (Pm1ControlLength), 112 ACPI_PM1_REGISTER_WIDTH, 113 ACPI_FADT_REQUIRED}, 114 115 {"Pm1bControlBlock", 116 ACPI_FADT_OFFSET (XPm1bControlBlock), 117 ACPI_FADT_OFFSET (Pm1bControlBlock), 118 ACPI_FADT_OFFSET (Pm1ControlLength), 119 ACPI_PM1_REGISTER_WIDTH, 120 ACPI_FADT_OPTIONAL}, 121 122 {"Pm2ControlBlock", 123 ACPI_FADT_OFFSET (XPm2ControlBlock), 124 ACPI_FADT_OFFSET (Pm2ControlBlock), 125 ACPI_FADT_OFFSET (Pm2ControlLength), 126 ACPI_PM2_REGISTER_WIDTH, 127 ACPI_FADT_SEPARATE_LENGTH}, 128 129 {"PmTimerBlock", 130 ACPI_FADT_OFFSET (XPmTimerBlock), 131 ACPI_FADT_OFFSET (PmTimerBlock), 132 ACPI_FADT_OFFSET (PmTimerLength), 133 ACPI_PM_TIMER_WIDTH, 134 ACPI_FADT_REQUIRED}, 135 136 {"Gpe0Block", 137 ACPI_FADT_OFFSET (XGpe0Block), 138 ACPI_FADT_OFFSET (Gpe0Block), 139 ACPI_FADT_OFFSET (Gpe0BlockLength), 140 0, 141 ACPI_FADT_SEPARATE_LENGTH}, 142 143 {"Gpe1Block", 144 ACPI_FADT_OFFSET (XGpe1Block), 145 ACPI_FADT_OFFSET (Gpe1Block), 146 ACPI_FADT_OFFSET (Gpe1BlockLength), 147 0, 148 ACPI_FADT_SEPARATE_LENGTH} 149 }; 150 151 #define ACPI_FADT_INFO_ENTRIES \ 152 (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO)) 153 154 155 /* Table used to split Event Blocks into separate status/enable registers */ 156 157 typedef struct acpi_fadt_pm_info 158 { 159 ACPI_GENERIC_ADDRESS *Target; 160 UINT16 Source; 161 UINT8 RegisterNum; 162 163 } ACPI_FADT_PM_INFO; 164 165 static ACPI_FADT_PM_INFO FadtPmInfoTable[] = 166 { 167 {&AcpiGbl_XPm1aStatus, 168 ACPI_FADT_OFFSET (XPm1aEventBlock), 169 0}, 170 171 {&AcpiGbl_XPm1aEnable, 172 ACPI_FADT_OFFSET (XPm1aEventBlock), 173 1}, 174 175 {&AcpiGbl_XPm1bStatus, 176 ACPI_FADT_OFFSET (XPm1bEventBlock), 177 0}, 178 179 {&AcpiGbl_XPm1bEnable, 180 ACPI_FADT_OFFSET (XPm1bEventBlock), 181 1} 182 }; 183 184 #define ACPI_FADT_PM_INFO_ENTRIES \ 185 (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO)) 186 187 188 /******************************************************************************* 189 * 190 * FUNCTION: AcpiTbInitGenericAddress 191 * 192 * PARAMETERS: GenericAddress - GAS struct to be initialized 193 * SpaceId - ACPI Space ID for this register 194 * ByteWidth - Width of this register, in bytes 195 * Address - Address of the register 196 * 197 * RETURN: None 198 * 199 * DESCRIPTION: Initialize a Generic Address Structure (GAS) 200 * See the ACPI specification for a full description and 201 * definition of this structure. 202 * 203 ******************************************************************************/ 204 205 static ACPI_INLINE void 206 AcpiTbInitGenericAddress ( 207 ACPI_GENERIC_ADDRESS *GenericAddress, 208 UINT8 SpaceId, 209 UINT8 ByteWidth, 210 UINT64 Address) 211 { 212 213 /* 214 * The 64-bit Address field is non-aligned in the byte packed 215 * GAS struct. 216 */ 217 ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address); 218 219 /* All other fields are byte-wide */ 220 221 GenericAddress->SpaceId = SpaceId; 222 GenericAddress->BitWidth = (UINT8) ACPI_MUL_8 (ByteWidth); 223 GenericAddress->BitOffset = 0; 224 GenericAddress->AccessWidth = 0; /* Access width ANY */ 225 } 226 227 228 /******************************************************************************* 229 * 230 * FUNCTION: AcpiTbParseFadt 231 * 232 * PARAMETERS: TableIndex - Index for the FADT 233 * 234 * RETURN: None 235 * 236 * DESCRIPTION: Initialize the FADT, DSDT and FACS tables 237 * (FADT contains the addresses of the DSDT and FACS) 238 * 239 ******************************************************************************/ 240 241 void 242 AcpiTbParseFadt ( 243 UINT32 TableIndex) 244 { 245 UINT32 Length; 246 ACPI_TABLE_HEADER *Table; 247 248 249 /* 250 * The FADT has multiple versions with different lengths, 251 * and it contains pointers to both the DSDT and FACS tables. 252 * 253 * Get a local copy of the FADT and convert it to a common format 254 * Map entire FADT, assumed to be smaller than one page. 255 */ 256 Length = AcpiGbl_RootTableList.Tables[TableIndex].Length; 257 258 Table = AcpiOsMapMemory ( 259 AcpiGbl_RootTableList.Tables[TableIndex].Address, Length); 260 if (!Table) 261 { 262 return; 263 } 264 265 /* 266 * Validate the FADT checksum before we copy the table. Ignore 267 * checksum error as we want to try to get the DSDT and FACS. 268 */ 269 (void) AcpiTbVerifyChecksum (Table, Length); 270 271 /* Create a local copy of the FADT in common ACPI 2.0+ format */ 272 273 AcpiTbCreateLocalFadt (Table, Length); 274 275 /* All done with the real FADT, unmap it */ 276 277 AcpiOsUnmapMemory (Table, Length); 278 279 /* Obtain the DSDT and FACS tables via their addresses within the FADT */ 280 281 AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt, 282 ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); 283 284 /* If Hardware Reduced flag is set, there is no FACS */ 285 286 if (!AcpiGbl_ReducedHardware) 287 { 288 AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs, 289 ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); 290 } 291 } 292 293 294 /******************************************************************************* 295 * 296 * FUNCTION: AcpiTbCreateLocalFadt 297 * 298 * PARAMETERS: Table - Pointer to BIOS FADT 299 * Length - Length of the table 300 * 301 * RETURN: None 302 * 303 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. 304 * Performs validation on some important FADT fields. 305 * 306 * NOTE: We create a local copy of the FADT regardless of the version. 307 * 308 ******************************************************************************/ 309 310 void 311 AcpiTbCreateLocalFadt ( 312 ACPI_TABLE_HEADER *Table, 313 UINT32 Length) 314 { 315 316 /* 317 * Check if the FADT is larger than the largest table that we expect 318 * (the ACPI 5.0 version). If so, truncate the table, and issue 319 * a warning. 320 */ 321 if (Length > sizeof (ACPI_TABLE_FADT)) 322 { 323 ACPI_WARNING ((AE_INFO, 324 "FADT (revision %u) is longer than ACPI 5.0 version, " 325 "truncating length %u to %u", 326 Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT))); 327 } 328 329 /* Clear the entire local FADT */ 330 331 ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT)); 332 333 /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */ 334 335 ACPI_MEMCPY (&AcpiGbl_FADT, Table, 336 ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT))); 337 338 /* Take a copy of the Hardware Reduced flag */ 339 340 AcpiGbl_ReducedHardware = FALSE; 341 if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED) 342 { 343 AcpiGbl_ReducedHardware = TRUE; 344 } 345 346 /* Convert the local copy of the FADT to the common internal format */ 347 348 AcpiTbConvertFadt (); 349 350 /* Validate FADT values now, before we make any changes */ 351 352 AcpiTbValidateFadt (); 353 354 /* Initialize the global ACPI register structures */ 355 356 AcpiTbSetupFadtRegisters (); 357 } 358 359 360 /******************************************************************************* 361 * 362 * FUNCTION: AcpiTbConvertFadt 363 * 364 * PARAMETERS: None, uses AcpiGbl_FADT 365 * 366 * RETURN: None 367 * 368 * DESCRIPTION: Converts all versions of the FADT to a common internal format. 369 * Expand 32-bit addresses to 64-bit as necessary. 370 * 371 * NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), 372 * and must contain a copy of the actual FADT. 373 * 374 * Notes on 64-bit register addresses: 375 * 376 * After this FADT conversion, later ACPICA code will only use the 64-bit "X" 377 * fields of the FADT for all ACPI register addresses. 378 * 379 * The 64-bit "X" fields are optional extensions to the original 32-bit FADT 380 * V1.0 fields. Even if they are present in the FADT, they are optional and 381 * are unused if the BIOS sets them to zero. Therefore, we must copy/expand 382 * 32-bit V1.0 fields if the corresponding X field is zero. 383 * 384 * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the 385 * corresponding "X" fields in the internal FADT. 386 * 387 * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded 388 * to the corresponding 64-bit X fields. For compatibility with other ACPI 389 * implementations, we ignore the 64-bit field if the 32-bit field is valid, 390 * regardless of whether the host OS is 32-bit or 64-bit. 391 * 392 ******************************************************************************/ 393 394 static void 395 AcpiTbConvertFadt ( 396 void) 397 { 398 ACPI_GENERIC_ADDRESS *Address64; 399 UINT32 Address32; 400 UINT32 i; 401 402 403 /* Update the local FADT table header length */ 404 405 AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT); 406 407 /* 408 * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary. 409 * Later code will always use the X 64-bit field. 410 */ 411 if (!AcpiGbl_FADT.XFacs) 412 { 413 AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs; 414 } 415 if (!AcpiGbl_FADT.XDsdt) 416 { 417 AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt; 418 } 419 420 /* 421 * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which 422 * should be zero are indeed zero. This will workaround BIOSs that 423 * inadvertently place values in these fields. 424 * 425 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located 426 * at offset 45, 55, 95, and the word located at offset 109, 110. 427 * 428 * Note: The FADT revision value is unreliable. Only the length can be 429 * trusted. 430 */ 431 if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE) 432 { 433 AcpiGbl_FADT.PreferredProfile = 0; 434 AcpiGbl_FADT.PstateControl = 0; 435 AcpiGbl_FADT.CstControl = 0; 436 AcpiGbl_FADT.BootFlags = 0; 437 } 438 439 /* 440 * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" 441 * generic address structures as necessary. Later code will always use 442 * the 64-bit address structures. 443 * 444 * March 2009: 445 * We now always use the 32-bit address if it is valid (non-null). This 446 * is not in accordance with the ACPI specification which states that 447 * the 64-bit address supersedes the 32-bit version, but we do this for 448 * compatibility with other ACPI implementations. Most notably, in the 449 * case where both the 32 and 64 versions are non-null, we use the 32-bit 450 * version. This is the only address that is guaranteed to have been 451 * tested by the BIOS manufacturer. 452 */ 453 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 454 { 455 Address32 = *ACPI_ADD_PTR (UINT32, 456 &AcpiGbl_FADT, FadtInfoTable[i].Address32); 457 458 Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, 459 &AcpiGbl_FADT, FadtInfoTable[i].Address64); 460 461 /* 462 * If both 32- and 64-bit addresses are valid (non-zero), 463 * they must match. 464 */ 465 if (Address64->Address && Address32 && 466 (Address64->Address != (UINT64) Address32)) 467 { 468 ACPI_ERROR ((AE_INFO, 469 "32/64X address mismatch in %s: 0x%8.8X/0x%8.8X%8.8X, using 32", 470 FadtInfoTable[i].Name, Address32, 471 ACPI_FORMAT_UINT64 (Address64->Address))); 472 } 473 474 /* Always use 32-bit address if it is valid (non-null) */ 475 476 if (Address32) 477 { 478 /* 479 * Copy the 32-bit address to the 64-bit GAS structure. The 480 * Space ID is always I/O for 32-bit legacy address fields 481 */ 482 AcpiTbInitGenericAddress (Address64, ACPI_ADR_SPACE_SYSTEM_IO, 483 *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length), 484 (UINT64) Address32); 485 } 486 } 487 } 488 489 490 /******************************************************************************* 491 * 492 * FUNCTION: AcpiTbValidateFadt 493 * 494 * PARAMETERS: Table - Pointer to the FADT to be validated 495 * 496 * RETURN: None 497 * 498 * DESCRIPTION: Validate various important fields within the FADT. If a problem 499 * is found, issue a message, but no status is returned. 500 * Used by both the table manager and the disassembler. 501 * 502 * Possible additional checks: 503 * (AcpiGbl_FADT.Pm1EventLength >= 4) 504 * (AcpiGbl_FADT.Pm1ControlLength >= 2) 505 * (AcpiGbl_FADT.PmTimerLength >= 4) 506 * Gpe block lengths must be multiple of 2 507 * 508 ******************************************************************************/ 509 510 static void 511 AcpiTbValidateFadt ( 512 void) 513 { 514 char *Name; 515 ACPI_GENERIC_ADDRESS *Address64; 516 UINT8 Length; 517 UINT32 i; 518 519 520 /* 521 * Check for FACS and DSDT address mismatches. An address mismatch between 522 * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and 523 * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables. 524 */ 525 if (AcpiGbl_FADT.Facs && 526 (AcpiGbl_FADT.XFacs != (UINT64) AcpiGbl_FADT.Facs)) 527 { 528 ACPI_WARNING ((AE_INFO, 529 "32/64X FACS address mismatch in FADT - " 530 "0x%8.8X/0x%8.8X%8.8X, using 32", 531 AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs))); 532 533 AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs; 534 } 535 536 if (AcpiGbl_FADT.Dsdt && 537 (AcpiGbl_FADT.XDsdt != (UINT64) AcpiGbl_FADT.Dsdt)) 538 { 539 ACPI_WARNING ((AE_INFO, 540 "32/64X DSDT address mismatch in FADT - " 541 "0x%8.8X/0x%8.8X%8.8X, using 32", 542 AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt))); 543 544 AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt; 545 } 546 547 /* If Hardware Reduced flag is set, we are all done */ 548 549 if (AcpiGbl_ReducedHardware) 550 { 551 return; 552 } 553 554 /* Examine all of the 64-bit extended address fields (X fields) */ 555 556 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 557 { 558 /* 559 * Generate pointer to the 64-bit address, get the register 560 * length (width) and the register name 561 */ 562 Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, 563 &AcpiGbl_FADT, FadtInfoTable[i].Address64); 564 Length = *ACPI_ADD_PTR (UINT8, 565 &AcpiGbl_FADT, FadtInfoTable[i].Length); 566 Name = FadtInfoTable[i].Name; 567 568 /* 569 * For each extended field, check for length mismatch between the 570 * legacy length field and the corresponding 64-bit X length field. 571 */ 572 if (Address64->Address && 573 (Address64->BitWidth != ACPI_MUL_8 (Length))) 574 { 575 ACPI_WARNING ((AE_INFO, 576 "32/64X length mismatch in %s: %u/%u", 577 Name, ACPI_MUL_8 (Length), Address64->BitWidth)); 578 } 579 580 if (FadtInfoTable[i].Type & ACPI_FADT_REQUIRED) 581 { 582 /* 583 * Field is required (PM1aEvent, PM1aControl, PmTimer). 584 * Both the address and length must be non-zero. 585 */ 586 if (!Address64->Address || !Length) 587 { 588 ACPI_ERROR ((AE_INFO, 589 "Required field %s has zero address and/or length:" 590 " 0x%8.8X%8.8X/0x%X", 591 Name, ACPI_FORMAT_UINT64 (Address64->Address), Length)); 592 } 593 } 594 else if (FadtInfoTable[i].Type & ACPI_FADT_SEPARATE_LENGTH) 595 { 596 /* 597 * Field is optional (PM2Control, GPE0, GPE1) AND has its own 598 * length field. If present, both the address and length must 599 * be valid. 600 */ 601 if ((Address64->Address && !Length) || 602 (!Address64->Address && Length)) 603 { 604 ACPI_WARNING ((AE_INFO, 605 "Optional field %s has zero address or length: " 606 "0x%8.8X%8.8X/0x%X", 607 Name, ACPI_FORMAT_UINT64 (Address64->Address), Length)); 608 } 609 } 610 } 611 } 612 613 614 /******************************************************************************* 615 * 616 * FUNCTION: AcpiTbSetupFadtRegisters 617 * 618 * PARAMETERS: None, uses AcpiGbl_FADT. 619 * 620 * RETURN: None 621 * 622 * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally, 623 * force FADT register definitions to their default lengths. 624 * 625 ******************************************************************************/ 626 627 static void 628 AcpiTbSetupFadtRegisters ( 629 void) 630 { 631 ACPI_GENERIC_ADDRESS *Target64; 632 ACPI_GENERIC_ADDRESS *Source64; 633 UINT8 Pm1RegisterByteWidth; 634 UINT32 i; 635 636 637 /* 638 * Optionally check all register lengths against the default values and 639 * update them if they are incorrect. 640 */ 641 if (AcpiGbl_UseDefaultRegisterWidths) 642 { 643 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) 644 { 645 Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, 646 FadtInfoTable[i].Address64); 647 648 /* 649 * If a valid register (Address != 0) and the (DefaultLength > 0) 650 * (Not a GPE register), then check the width against the default. 651 */ 652 if ((Target64->Address) && 653 (FadtInfoTable[i].DefaultLength > 0) && 654 (FadtInfoTable[i].DefaultLength != Target64->BitWidth)) 655 { 656 ACPI_WARNING ((AE_INFO, 657 "Invalid length for %s: %u, using default %u", 658 FadtInfoTable[i].Name, Target64->BitWidth, 659 FadtInfoTable[i].DefaultLength)); 660 661 /* Incorrect size, set width to the default */ 662 663 Target64->BitWidth = FadtInfoTable[i].DefaultLength; 664 } 665 } 666 } 667 668 /* 669 * Get the length of the individual PM1 registers (enable and status). 670 * Each register is defined to be (event block length / 2). Extra divide 671 * by 8 converts bits to bytes. 672 */ 673 Pm1RegisterByteWidth = (UINT8) 674 ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth); 675 676 /* 677 * Calculate separate GAS structs for the PM1x (A/B) Status and Enable 678 * registers. These addresses do not appear (directly) in the FADT, so it 679 * is useful to pre-calculate them from the PM1 Event Block definitions. 680 * 681 * The PM event blocks are split into two register blocks, first is the 682 * PM Status Register block, followed immediately by the PM Enable 683 * Register block. Each is of length (Pm1EventLength/2) 684 * 685 * Note: The PM1A event block is required by the ACPI specification. 686 * However, the PM1B event block is optional and is rarely, if ever, 687 * used. 688 */ 689 690 for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) 691 { 692 Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, 693 FadtPmInfoTable[i].Source); 694 695 if (Source64->Address) 696 { 697 AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target, 698 Source64->SpaceId, Pm1RegisterByteWidth, 699 Source64->Address + 700 (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth)); 701 } 702 } 703 } 704 705