1 /******************************************************************************
   2  *
   3  * Module Name: tbutils - ACPI Table utilities
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, 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 }