1 /****************************************************************************** 2 * 3 * Module Name: tbutils - ACPI Table utilities 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 __TBUTILS_C__ 45 46 #include "acpi.h" 47 #include "accommon.h" 48 #include "actables.h" 49 50 #define _COMPONENT ACPI_TABLES 51 ACPI_MODULE_NAME ("tbutils") 52 53 54 /* Local prototypes */ 55 56 static ACPI_STATUS 57 AcpiTbValidateXsdt ( 58 ACPI_PHYSICAL_ADDRESS Address); 59 60 static ACPI_PHYSICAL_ADDRESS 61 AcpiTbGetRootTableEntry ( 62 UINT8 *TableEntry, 63 UINT32 TableEntrySize); 64 65 66 #if (!ACPI_REDUCED_HARDWARE) 67 /******************************************************************************* 68 * 69 * FUNCTION: AcpiTbInitializeFacs 70 * 71 * PARAMETERS: None 72 * 73 * RETURN: Status 74 * 75 * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global 76 * for accessing the Global Lock and Firmware Waking Vector 77 * 78 ******************************************************************************/ 79 80 ACPI_STATUS 81 AcpiTbInitializeFacs ( 82 void) 83 { 84 ACPI_STATUS Status; 85 86 87 /* If Hardware Reduced flag is set, there is no FACS */ 88 89 if (AcpiGbl_ReducedHardware) 90 { 91 AcpiGbl_FACS = NULL; 92 return (AE_OK); 93 } 94 95 Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, 96 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_FACS)); 97 return (Status); 98 } 99 #endif /* !ACPI_REDUCED_HARDWARE */ 100 101 102 /******************************************************************************* 103 * 104 * FUNCTION: AcpiTbTablesLoaded 105 * 106 * PARAMETERS: None 107 * 108 * RETURN: TRUE if required ACPI tables are loaded 109 * 110 * DESCRIPTION: Determine if the minimum required ACPI tables are present 111 * (FADT, FACS, DSDT) 112 * 113 ******************************************************************************/ 114 115 BOOLEAN 116 AcpiTbTablesLoaded ( 117 void) 118 { 119 120 if (AcpiGbl_RootTableList.CurrentTableCount >= 3) 121 { 122 return (TRUE); 123 } 124 125 return (FALSE); 126 } 127 128 129 /******************************************************************************* 130 * 131 * FUNCTION: AcpiTbCheckDsdtHeader 132 * 133 * PARAMETERS: None 134 * 135 * RETURN: None 136 * 137 * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect 138 * if the DSDT has been replaced from outside the OS and/or if 139 * the DSDT header has been corrupted. 140 * 141 ******************************************************************************/ 142 143 void 144 AcpiTbCheckDsdtHeader ( 145 void) 146 { 147 148 /* Compare original length and checksum to current values */ 149 150 if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length || 151 AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum) 152 { 153 ACPI_BIOS_ERROR ((AE_INFO, 154 "The DSDT has been corrupted or replaced - " 155 "old, new headers below")); 156 AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader); 157 AcpiTbPrintTableHeader (0, AcpiGbl_DSDT); 158 159 /* Disable further error messages */ 160 161 AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length; 162 AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum; 163 } 164 } 165 166 167 /******************************************************************************* 168 * 169 * FUNCTION: AcpiTbCopyDsdt 170 * 171 * PARAMETERS: TableDesc - Installed table to copy 172 * 173 * RETURN: None 174 * 175 * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory. 176 * Some very bad BIOSs are known to either corrupt the DSDT or 177 * install a new, bad DSDT. This copy works around the problem. 178 * 179 ******************************************************************************/ 180 181 ACPI_TABLE_HEADER * 182 AcpiTbCopyDsdt ( 183 UINT32 TableIndex) 184 { 185 ACPI_TABLE_HEADER *NewTable; 186 ACPI_TABLE_DESC *TableDesc; 187 188 189 TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex]; 190 191 NewTable = ACPI_ALLOCATE (TableDesc->Length); 192 if (!NewTable) 193 { 194 ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X", 195 TableDesc->Length)); 196 return (NULL); 197 } 198 199 ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length); 200 AcpiTbDeleteTable (TableDesc); 201 TableDesc->Pointer = NewTable; 202 TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED; 203 204 ACPI_INFO ((AE_INFO, 205 "Forced DSDT copy: length 0x%05X copied locally, original unmapped", 206 NewTable->Length)); 207 208 return (NewTable); 209 } 210 211 212 /******************************************************************************* 213 * 214 * FUNCTION: AcpiTbInstallTable 215 * 216 * PARAMETERS: Address - Physical address of DSDT or FACS 217 * Signature - Table signature, NULL if no need to 218 * match 219 * TableIndex - Index into root table array 220 * 221 * RETURN: None 222 * 223 * DESCRIPTION: Install an ACPI table into the global data structure. The 224 * table override mechanism is called to allow the host 225 * OS to replace any table before it is installed in the root 226 * table array. 227 * 228 ******************************************************************************/ 229 230 void 231 AcpiTbInstallTable ( 232 ACPI_PHYSICAL_ADDRESS Address, 233 char *Signature, 234 UINT32 TableIndex) 235 { 236 ACPI_TABLE_HEADER *Table; 237 ACPI_TABLE_HEADER *FinalTable; 238 ACPI_TABLE_DESC *TableDesc; 239 240 241 if (!Address) 242 { 243 ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]", 244 Signature)); 245 return; 246 } 247 248 /* Map just the table header */ 249 250 Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 251 if (!Table) 252 { 253 ACPI_ERROR ((AE_INFO, "Could not map memory for table [%s] at %p", 254 Signature, ACPI_CAST_PTR (void, Address))); 255 return; 256 } 257 258 /* If a particular signature is expected (DSDT/FACS), it must match */ 259 260 if (Signature && 261 !ACPI_COMPARE_NAME (Table->Signature, Signature)) 262 { 263 ACPI_BIOS_ERROR ((AE_INFO, 264 "Invalid signature 0x%X for ACPI table, expected [%s]", 265 *ACPI_CAST_PTR (UINT32, Table->Signature), Signature)); 266 goto UnmapAndExit; 267 } 268 269 /* 270 * Initialize the table entry. Set the pointer to NULL, since the 271 * table is not fully mapped at this time. 272 */ 273 TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex]; 274 275 TableDesc->Address = Address; 276 TableDesc->Pointer = NULL; 277 TableDesc->Length = Table->Length; 278 TableDesc->Flags = ACPI_TABLE_ORIGIN_MAPPED; 279 ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature); 280 281 /* 282 * ACPI Table Override: 283 * 284 * Before we install the table, let the host OS override it with a new 285 * one if desired. Any table within the RSDT/XSDT can be replaced, 286 * including the DSDT which is pointed to by the FADT. 287 * 288 * NOTE: If the table is overridden, then FinalTable will contain a 289 * mapped pointer to the full new table. If the table is not overridden, 290 * or if there has been a physical override, then the table will be 291 * fully mapped later (in verify table). In any case, we must 292 * unmap the header that was mapped above. 293 */ 294 FinalTable = AcpiTbTableOverride (Table, TableDesc); 295 if (!FinalTable) 296 { 297 FinalTable = Table; /* There was no override */ 298 } 299 300 AcpiTbPrintTableHeader (TableDesc->Address, FinalTable); 301 302 /* Set the global integer width (based upon revision of the DSDT) */ 303 304 if (TableIndex == ACPI_TABLE_INDEX_DSDT) 305 { 306 AcpiUtSetIntegerWidth (FinalTable->Revision); 307 } 308 309 /* 310 * If we have a physical override during this early loading of the ACPI 311 * tables, unmap the table for now. It will be mapped again later when 312 * it is actually used. This supports very early loading of ACPI tables, 313 * before virtual memory is fully initialized and running within the 314 * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE 315 * flag set and will not be deleted below. 316 */ 317 if (FinalTable != Table) 318 { 319 AcpiTbDeleteTable (TableDesc); 320 } 321 322 323 UnmapAndExit: 324 325 /* Always unmap the table header that we mapped above */ 326 327 AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 328 } 329 330 331 /******************************************************************************* 332 * 333 * FUNCTION: AcpiTbGetRootTableEntry 334 * 335 * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry 336 * TableEntrySize - sizeof 32 or 64 (RSDT or XSDT) 337 * 338 * RETURN: Physical address extracted from the root table 339 * 340 * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on 341 * both 32-bit and 64-bit platforms 342 * 343 * NOTE: ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on 344 * 64-bit platforms. 345 * 346 ******************************************************************************/ 347 348 static ACPI_PHYSICAL_ADDRESS 349 AcpiTbGetRootTableEntry ( 350 UINT8 *TableEntry, 351 UINT32 TableEntrySize) 352 { 353 UINT64 Address64; 354 355 356 /* 357 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): 358 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT 359 */ 360 if (TableEntrySize == ACPI_RSDT_ENTRY_SIZE) 361 { 362 /* 363 * 32-bit platform, RSDT: Return 32-bit table entry 364 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return 365 */ 366 return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (UINT32, TableEntry))); 367 } 368 else 369 { 370 /* 371 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return 372 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, 373 * return 64-bit 374 */ 375 ACPI_MOVE_64_TO_64 (&Address64, TableEntry); 376 377 #if ACPI_MACHINE_WIDTH == 32 378 if (Address64 > ACPI_UINT32_MAX) 379 { 380 /* Will truncate 64-bit address to 32 bits, issue warning */ 381 382 ACPI_BIOS_WARNING ((AE_INFO, 383 "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X)," 384 " truncating", 385 ACPI_FORMAT_UINT64 (Address64))); 386 } 387 #endif 388 return ((ACPI_PHYSICAL_ADDRESS) (Address64)); 389 } 390 } 391 392 393 /******************************************************************************* 394 * 395 * FUNCTION: AcpiTbValidateXsdt 396 * 397 * PARAMETERS: Address - Physical address of the XSDT (from RSDP) 398 * 399 * RETURN: Status. AE_OK if the table appears to be valid. 400 * 401 * DESCRIPTION: Validate an XSDT to ensure that it is of minimum size and does 402 * not contain any NULL entries. A problem that is seen in the 403 * field is that the XSDT exists, but is actually useless because 404 * of one or more (or all) NULL entries. 405 * 406 ******************************************************************************/ 407 408 static ACPI_STATUS 409 AcpiTbValidateXsdt ( 410 ACPI_PHYSICAL_ADDRESS XsdtAddress) 411 { 412 ACPI_TABLE_HEADER *Table; 413 UINT8 *NextEntry; 414 ACPI_PHYSICAL_ADDRESS Address; 415 UINT32 Length; 416 UINT32 EntryCount; 417 ACPI_STATUS Status; 418 UINT32 i; 419 420 421 /* Get the XSDT length */ 422 423 Table = AcpiOsMapMemory (XsdtAddress, sizeof (ACPI_TABLE_HEADER)); 424 if (!Table) 425 { 426 return (AE_NO_MEMORY); 427 } 428 429 Length = Table->Length; 430 AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 431 432 /* 433 * Minimum XSDT length is the size of the standard ACPI header 434 * plus one physical address entry 435 */ 436 if (Length < (sizeof (ACPI_TABLE_HEADER) + ACPI_XSDT_ENTRY_SIZE)) 437 { 438 return (AE_INVALID_TABLE_LENGTH); 439 } 440 441 /* Map the entire XSDT */ 442 443 Table = AcpiOsMapMemory (XsdtAddress, Length); 444 if (!Table) 445 { 446 return (AE_NO_MEMORY); 447 } 448 449 /* Get the number of entries and pointer to first entry */ 450 451 Status = AE_OK; 452 NextEntry = ACPI_ADD_PTR (UINT8, Table, sizeof (ACPI_TABLE_HEADER)); 453 EntryCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) / 454 ACPI_XSDT_ENTRY_SIZE); 455 456 /* Validate each entry (physical address) within the XSDT */ 457 458 for (i = 0; i < EntryCount; i++) 459 { 460 Address = AcpiTbGetRootTableEntry (NextEntry, ACPI_XSDT_ENTRY_SIZE); 461 if (!Address) 462 { 463 /* Detected a NULL entry, XSDT is invalid */ 464 465 Status = AE_NULL_ENTRY; 466 break; 467 } 468 469 NextEntry += ACPI_XSDT_ENTRY_SIZE; 470 } 471 472 /* Unmap table */ 473 474 AcpiOsUnmapMemory (Table, Length); 475 return (Status); 476 } 477 478 479 /******************************************************************************* 480 * 481 * FUNCTION: AcpiTbParseRootTable 482 * 483 * PARAMETERS: Rsdp - Pointer to the RSDP 484 * 485 * RETURN: Status 486 * 487 * DESCRIPTION: This function is called to parse the Root System Description 488 * Table (RSDT or XSDT) 489 * 490 * NOTE: Tables are mapped (not copied) for efficiency. The FACS must 491 * be mapped and cannot be copied because it contains the actual 492 * memory location of the ACPI Global Lock. 493 * 494 ******************************************************************************/ 495 496 ACPI_STATUS 497 AcpiTbParseRootTable ( 498 ACPI_PHYSICAL_ADDRESS RsdpAddress) 499 { 500 ACPI_TABLE_RSDP *Rsdp; 501 UINT32 TableEntrySize; 502 UINT32 i; 503 UINT32 TableCount; 504 ACPI_TABLE_HEADER *Table; 505 ACPI_PHYSICAL_ADDRESS Address; 506 UINT32 Length; 507 UINT8 *TableEntry; 508 ACPI_STATUS Status; 509 510 511 ACPI_FUNCTION_TRACE (TbParseRootTable); 512 513 514 /* Map the entire RSDP and extract the address of the RSDT or XSDT */ 515 516 Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP)); 517 if (!Rsdp) 518 { 519 return_ACPI_STATUS (AE_NO_MEMORY); 520 } 521 522 AcpiTbPrintTableHeader (RsdpAddress, 523 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp)); 524 525 /* Use XSDT if present and not overridden. Otherwise, use RSDT */ 526 527 if ((Rsdp->Revision > 1) && 528 Rsdp->XsdtPhysicalAddress && 529 !AcpiGbl_DoNotUseXsdt) 530 { 531 /* 532 * RSDP contains an XSDT (64-bit physical addresses). We must use 533 * the XSDT if the revision is > 1 and the XSDT pointer is present, 534 * as per the ACPI specification. 535 */ 536 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress; 537 TableEntrySize = ACPI_XSDT_ENTRY_SIZE; 538 } 539 else 540 { 541 /* Root table is an RSDT (32-bit physical addresses) */ 542 543 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress; 544 TableEntrySize = ACPI_RSDT_ENTRY_SIZE; 545 } 546 547 /* 548 * It is not possible to map more than one entry in some environments, 549 * so unmap the RSDP here before mapping other tables 550 */ 551 AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP)); 552 553 /* 554 * If it is present and used, validate the XSDT for access/size 555 * and ensure that all table entries are at least non-NULL 556 */ 557 if (TableEntrySize == ACPI_XSDT_ENTRY_SIZE) 558 { 559 Status = AcpiTbValidateXsdt (Address); 560 if (ACPI_FAILURE (Status)) 561 { 562 ACPI_BIOS_WARNING ((AE_INFO, "XSDT is invalid (%s), using RSDT", 563 AcpiFormatException (Status))); 564 565 /* Fall back to the RSDT */ 566 567 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress; 568 TableEntrySize = ACPI_RSDT_ENTRY_SIZE; 569 } 570 } 571 572 /* Map the RSDT/XSDT table header to get the full table length */ 573 574 Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 575 if (!Table) 576 { 577 return_ACPI_STATUS (AE_NO_MEMORY); 578 } 579 580 AcpiTbPrintTableHeader (Address, Table); 581 582 /* 583 * Validate length of the table, and map entire table. 584 * Minimum length table must contain at least one entry. 585 */ 586 Length = Table->Length; 587 AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 588 589 if (Length < (sizeof (ACPI_TABLE_HEADER) + TableEntrySize)) 590 { 591 ACPI_BIOS_ERROR ((AE_INFO, 592 "Invalid table length 0x%X in RSDT/XSDT", Length)); 593 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); 594 } 595 596 Table = AcpiOsMapMemory (Address, Length); 597 if (!Table) 598 { 599 return_ACPI_STATUS (AE_NO_MEMORY); 600 } 601 602 /* Validate the root table checksum */ 603 604 Status = AcpiTbVerifyChecksum (Table, Length); 605 if (ACPI_FAILURE (Status)) 606 { 607 AcpiOsUnmapMemory (Table, Length); 608 return_ACPI_STATUS (Status); 609 } 610 611 /* Get the number of entries and pointer to first entry */ 612 613 TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) / 614 TableEntrySize); 615 TableEntry = ACPI_ADD_PTR (UINT8, Table, sizeof (ACPI_TABLE_HEADER)); 616 617 /* 618 * First two entries in the table array are reserved for the DSDT 619 * and FACS, which are not actually present in the RSDT/XSDT - they 620 * come from the FADT 621 */ 622 AcpiGbl_RootTableList.CurrentTableCount = 2; 623 624 /* Initialize the root table array from the RSDT/XSDT */ 625 626 for (i = 0; i < TableCount; i++) 627 { 628 if (AcpiGbl_RootTableList.CurrentTableCount >= 629 AcpiGbl_RootTableList.MaxTableCount) 630 { 631 /* There is no more room in the root table array, attempt resize */ 632 633 Status = AcpiTbResizeRootTableList (); 634 if (ACPI_FAILURE (Status)) 635 { 636 ACPI_WARNING ((AE_INFO, "Truncating %u table entries!", 637 (unsigned) (TableCount - 638 (AcpiGbl_RootTableList.CurrentTableCount - 2)))); 639 break; 640 } 641 } 642 643 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ 644 645 AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount].Address = 646 AcpiTbGetRootTableEntry (TableEntry, TableEntrySize); 647 648 TableEntry += TableEntrySize; 649 AcpiGbl_RootTableList.CurrentTableCount++; 650 } 651 652 /* 653 * It is not possible to map more than one entry in some environments, 654 * so unmap the root table here before mapping other tables 655 */ 656 AcpiOsUnmapMemory (Table, Length); 657 658 /* 659 * Complete the initialization of the root table array by examining 660 * the header of each table 661 */ 662 for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 663 { 664 AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address, 665 NULL, i); 666 667 /* Special case for FADT - validate it then get the DSDT and FACS */ 668 669 if (ACPI_COMPARE_NAME ( 670 &AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT)) 671 { 672 AcpiTbParseFadt (i); 673 } 674 } 675 676 return_ACPI_STATUS (AE_OK); 677 }