Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: tbutils   - table utilities
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2011, 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 __TBUTILS_C__
  117.  
  118. #include "acpi.h"
  119. #include "accommon.h"
  120. #include "actables.h"
  121.  
  122. #define _COMPONENT          ACPI_TABLES
  123.         ACPI_MODULE_NAME    ("tbutils")
  124.  
  125. /* Local prototypes */
  126.  
  127. static void
  128. AcpiTbFixString (
  129.     char                    *String,
  130.     ACPI_SIZE               Length);
  131.  
  132. static void
  133. AcpiTbCleanupTableHeader (
  134.     ACPI_TABLE_HEADER       *OutHeader,
  135.     ACPI_TABLE_HEADER       *Header);
  136.  
  137. static ACPI_PHYSICAL_ADDRESS
  138. AcpiTbGetRootTableEntry (
  139.     UINT8                   *TableEntry,
  140.     UINT32                  TableEntrySize);
  141.  
  142.  
  143. /*******************************************************************************
  144.  *
  145.  * FUNCTION:    AcpiTbInitializeFacs
  146.  *
  147.  * PARAMETERS:  None
  148.  *
  149.  * RETURN:      Status
  150.  *
  151.  * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global
  152.  *              for accessing the Global Lock and Firmware Waking Vector
  153.  *
  154.  ******************************************************************************/
  155.  
  156. ACPI_STATUS
  157. AcpiTbInitializeFacs (
  158.     void)
  159. {
  160.     ACPI_STATUS             Status;
  161.  
  162.  
  163.     Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS,
  164.                 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_FACS));
  165.     return (Status);
  166. }
  167.  
  168.  
  169. /*******************************************************************************
  170.  *
  171.  * FUNCTION:    AcpiTbTablesLoaded
  172.  *
  173.  * PARAMETERS:  None
  174.  *
  175.  * RETURN:      TRUE if required ACPI tables are loaded
  176.  *
  177.  * DESCRIPTION: Determine if the minimum required ACPI tables are present
  178.  *              (FADT, FACS, DSDT)
  179.  *
  180.  ******************************************************************************/
  181.  
  182. BOOLEAN
  183. AcpiTbTablesLoaded (
  184.     void)
  185. {
  186.  
  187.     if (AcpiGbl_RootTableList.CurrentTableCount >= 3)
  188.     {
  189.         return (TRUE);
  190.     }
  191.  
  192.     return (FALSE);
  193. }
  194.  
  195.  
  196. /*******************************************************************************
  197.  *
  198.  * FUNCTION:    AcpiTbFixString
  199.  *
  200.  * PARAMETERS:  String              - String to be repaired
  201.  *              Length              - Maximum length
  202.  *
  203.  * RETURN:      None
  204.  *
  205.  * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
  206.  *              with a question mark '?'.
  207.  *
  208.  ******************************************************************************/
  209.  
  210. static void
  211. AcpiTbFixString (
  212.     char                    *String,
  213.     ACPI_SIZE               Length)
  214. {
  215.  
  216.     while (Length && *String)
  217.     {
  218.         if (!ACPI_IS_PRINT (*String))
  219.         {
  220.             *String = '?';
  221.         }
  222.         String++;
  223.         Length--;
  224.     }
  225. }
  226.  
  227.  
  228. /*******************************************************************************
  229.  *
  230.  * FUNCTION:    AcpiTbCleanupTableHeader
  231.  *
  232.  * PARAMETERS:  OutHeader           - Where the cleaned header is returned
  233.  *              Header              - Input ACPI table header
  234.  *
  235.  * RETURN:      Returns the cleaned header in OutHeader
  236.  *
  237.  * DESCRIPTION: Copy the table header and ensure that all "string" fields in
  238.  *              the header consist of printable characters.
  239.  *
  240.  ******************************************************************************/
  241.  
  242. static void
  243. AcpiTbCleanupTableHeader (
  244.     ACPI_TABLE_HEADER       *OutHeader,
  245.     ACPI_TABLE_HEADER       *Header)
  246. {
  247.  
  248.     ACPI_MEMCPY (OutHeader, Header, sizeof (ACPI_TABLE_HEADER));
  249.  
  250.     AcpiTbFixString (OutHeader->Signature, ACPI_NAME_SIZE);
  251.     AcpiTbFixString (OutHeader->OemId, ACPI_OEM_ID_SIZE);
  252.     AcpiTbFixString (OutHeader->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
  253.     AcpiTbFixString (OutHeader->AslCompilerId, ACPI_NAME_SIZE);
  254. }
  255.  
  256.  
  257. /*******************************************************************************
  258.  *
  259.  * FUNCTION:    AcpiTbPrintTableHeader
  260.  *
  261.  * PARAMETERS:  Address             - Table physical address
  262.  *              Header              - Table header
  263.  *
  264.  * RETURN:      None
  265.  *
  266.  * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
  267.  *
  268.  ******************************************************************************/
  269.  
  270. void
  271. AcpiTbPrintTableHeader (
  272.     ACPI_PHYSICAL_ADDRESS   Address,
  273.     ACPI_TABLE_HEADER       *Header)
  274. {
  275.     ACPI_TABLE_HEADER       LocalHeader;
  276.  
  277.  
  278.     /*
  279.      * The reason that the Address is cast to a void pointer is so that we
  280.      * can use %p which will work properly on both 32-bit and 64-bit hosts.
  281.      */
  282.     if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_FACS))
  283.     {
  284.         /* FACS only has signature and length fields */
  285.  
  286.         ACPI_INFO ((AE_INFO, "%4.4s %p %05X",
  287.             Header->Signature, ACPI_CAST_PTR (void, Address),
  288.             Header->Length));
  289.     }
  290.     else if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_RSDP))
  291.     {
  292.         /* RSDP has no common fields */
  293.  
  294.         ACPI_MEMCPY (LocalHeader.OemId,
  295.             ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId, ACPI_OEM_ID_SIZE);
  296.         AcpiTbFixString (LocalHeader.OemId, ACPI_OEM_ID_SIZE);
  297.  
  298.         ACPI_INFO ((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
  299.             ACPI_CAST_PTR (void, Address),
  300.             (ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision > 0) ?
  301.                 ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Length : 20,
  302.             ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision,
  303.             LocalHeader.OemId));
  304.     }
  305.     else
  306.     {
  307.         /* Standard ACPI table with full common header */
  308.  
  309.         AcpiTbCleanupTableHeader (&LocalHeader, Header);
  310.  
  311.         ACPI_INFO ((AE_INFO,
  312.             "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
  313.             LocalHeader.Signature, ACPI_CAST_PTR (void, Address),
  314.             LocalHeader.Length, LocalHeader.Revision, LocalHeader.OemId,
  315.             LocalHeader.OemTableId, LocalHeader.OemRevision,
  316.             LocalHeader.AslCompilerId, LocalHeader.AslCompilerRevision));
  317.     }
  318. }
  319.  
  320.  
  321. /*******************************************************************************
  322.  *
  323.  * FUNCTION:    AcpiTbValidateChecksum
  324.  *
  325.  * PARAMETERS:  Table               - ACPI table to verify
  326.  *              Length              - Length of entire table
  327.  *
  328.  * RETURN:      Status
  329.  *
  330.  * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
  331.  *              exception on bad checksum.
  332.  *
  333.  ******************************************************************************/
  334.  
  335. ACPI_STATUS
  336. AcpiTbVerifyChecksum (
  337.     ACPI_TABLE_HEADER       *Table,
  338.     UINT32                  Length)
  339. {
  340.     UINT8                   Checksum;
  341.  
  342.  
  343.     /* Compute the checksum on the table */
  344.  
  345.     Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Length);
  346.  
  347.     /* Checksum ok? (should be zero) */
  348.  
  349.     if (Checksum)
  350.     {
  351.         ACPI_WARNING ((AE_INFO,
  352.             "Incorrect checksum in table [%4.4s] - 0x%2.2X, should be 0x%2.2X",
  353.             Table->Signature, Table->Checksum,
  354.             (UINT8) (Table->Checksum - Checksum)));
  355.  
  356. #if (ACPI_CHECKSUM_ABORT)
  357.         return (AE_BAD_CHECKSUM);
  358. #endif
  359.     }
  360.  
  361.     return (AE_OK);
  362. }
  363.  
  364.  
  365. /*******************************************************************************
  366.  *
  367.  * FUNCTION:    AcpiTbChecksum
  368.  *
  369.  * PARAMETERS:  Buffer          - Pointer to memory region to be checked
  370.  *              Length          - Length of this memory region
  371.  *
  372.  * RETURN:      Checksum (UINT8)
  373.  *
  374.  * DESCRIPTION: Calculates circular checksum of memory region.
  375.  *
  376.  ******************************************************************************/
  377.  
  378. UINT8
  379. AcpiTbChecksum (
  380.     UINT8                   *Buffer,
  381.     UINT32                  Length)
  382. {
  383.     UINT8                   Sum = 0;
  384.     UINT8                   *End = Buffer + Length;
  385.  
  386.  
  387.     while (Buffer < End)
  388.     {
  389.         Sum = (UINT8) (Sum + *(Buffer++));
  390.     }
  391.  
  392.     return Sum;
  393. }
  394.  
  395.  
  396. /*******************************************************************************
  397.  *
  398.  * FUNCTION:    AcpiTbCheckDsdtHeader
  399.  *
  400.  * PARAMETERS:  None
  401.  *
  402.  * RETURN:      None
  403.  *
  404.  * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
  405.  *              if the DSDT has been replaced from outside the OS and/or if
  406.  *              the DSDT header has been corrupted.
  407.  *
  408.  ******************************************************************************/
  409.  
  410. void
  411. AcpiTbCheckDsdtHeader (
  412.     void)
  413. {
  414.  
  415.     /* Compare original length and checksum to current values */
  416.  
  417.     if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
  418.         AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
  419.     {
  420.         ACPI_ERROR ((AE_INFO,
  421.             "The DSDT has been corrupted or replaced - old, new headers below"));
  422.         AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
  423.         AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
  424.  
  425.         /* Disable further error messages */
  426.  
  427.         AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
  428.         AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
  429.     }
  430. }
  431.  
  432.  
  433. /*******************************************************************************
  434.  *
  435.  * FUNCTION:    AcpiTbCopyDsdt
  436.  *
  437.  * PARAMETERS:  TableDesc           - Installed table to copy
  438.  *
  439.  * RETURN:      None
  440.  *
  441.  * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
  442.  *              Some very bad BIOSs are known to either corrupt the DSDT or
  443.  *              install a new, bad DSDT. This copy works around the problem.
  444.  *
  445.  ******************************************************************************/
  446.  
  447. ACPI_TABLE_HEADER *
  448. AcpiTbCopyDsdt (
  449.     UINT32                  TableIndex)
  450. {
  451.     ACPI_TABLE_HEADER       *NewTable;
  452.     ACPI_TABLE_DESC         *TableDesc;
  453.  
  454.  
  455.     TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
  456.  
  457.     NewTable = ACPI_ALLOCATE (TableDesc->Length);
  458.     if (!NewTable)
  459.     {
  460.         ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
  461.             TableDesc->Length));
  462.         return (NULL);
  463.     }
  464.  
  465.     ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length);
  466.     AcpiTbDeleteTable (TableDesc);
  467.     TableDesc->Pointer = NewTable;
  468.     TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED;
  469.  
  470.     ACPI_INFO ((AE_INFO,
  471.         "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
  472.         NewTable->Length));
  473.  
  474.     return (NewTable);
  475. }
  476.  
  477.  
  478. /*******************************************************************************
  479.  *
  480.  * FUNCTION:    AcpiTbInstallTable
  481.  *
  482.  * PARAMETERS:  Address                 - Physical address of DSDT or FACS
  483.  *              Signature               - Table signature, NULL if no need to
  484.  *                                        match
  485.  *              TableIndex              - Index into root table array
  486.  *
  487.  * RETURN:      None
  488.  *
  489.  * DESCRIPTION: Install an ACPI table into the global data structure. The
  490.  *              table override mechanism is implemented here to allow the host
  491.  *              OS to replace any table before it is installed in the root
  492.  *              table array.
  493.  *
  494.  ******************************************************************************/
  495.  
  496. void
  497. AcpiTbInstallTable (
  498.     ACPI_PHYSICAL_ADDRESS   Address,
  499.     char                    *Signature,
  500.     UINT32                  TableIndex)
  501. {
  502.     UINT8                   Flags;
  503.     ACPI_STATUS             Status;
  504.     ACPI_TABLE_HEADER       *TableToInstall;
  505.     ACPI_TABLE_HEADER       *MappedTable;
  506.     ACPI_TABLE_HEADER       *OverrideTable = NULL;
  507.  
  508.  
  509.     if (!Address)
  510.     {
  511.         ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]",
  512.             Signature));
  513.         return;
  514.     }
  515.  
  516.     /* Map just the table header */
  517.  
  518.     MappedTable = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
  519.     if (!MappedTable)
  520.     {
  521.         return;
  522.     }
  523.  
  524.     /* If a particular signature is expected (DSDT/FACS), it must match */
  525.  
  526.     if (Signature &&
  527.         !ACPI_COMPARE_NAME (MappedTable->Signature, Signature))
  528.     {
  529.         ACPI_ERROR ((AE_INFO,
  530.             "Invalid signature 0x%X for ACPI table, expected [%s]",
  531.             *ACPI_CAST_PTR (UINT32, MappedTable->Signature), Signature));
  532.         goto UnmapAndExit;
  533.     }
  534.  
  535.     /*
  536.      * ACPI Table Override:
  537.      *
  538.      * Before we install the table, let the host OS override it with a new
  539.      * one if desired. Any table within the RSDT/XSDT can be replaced,
  540.      * including the DSDT which is pointed to by the FADT.
  541.      */
  542.     Status = AcpiOsTableOverride (MappedTable, &OverrideTable);
  543.     if (ACPI_SUCCESS (Status) && OverrideTable)
  544.     {
  545.         ACPI_INFO ((AE_INFO,
  546.             "%4.4s @ 0x%p Table override, replaced with:",
  547.             MappedTable->Signature, ACPI_CAST_PTR (void, Address)));
  548.  
  549.         AcpiGbl_RootTableList.Tables[TableIndex].Pointer = OverrideTable;
  550.         Address = ACPI_PTR_TO_PHYSADDR (OverrideTable);
  551.  
  552.         TableToInstall = OverrideTable;
  553.         Flags = ACPI_TABLE_ORIGIN_OVERRIDE;
  554.     }
  555.     else
  556.     {
  557.         TableToInstall = MappedTable;
  558.         Flags = ACPI_TABLE_ORIGIN_MAPPED;
  559.     }
  560.  
  561.     /* Initialize the table entry */
  562.  
  563.     AcpiGbl_RootTableList.Tables[TableIndex].Address = Address;
  564.     AcpiGbl_RootTableList.Tables[TableIndex].Length = TableToInstall->Length;
  565.     AcpiGbl_RootTableList.Tables[TableIndex].Flags = Flags;
  566.  
  567.     ACPI_MOVE_32_TO_32 (
  568.         &(AcpiGbl_RootTableList.Tables[TableIndex].Signature),
  569.         TableToInstall->Signature);
  570.  
  571.     AcpiTbPrintTableHeader (Address, TableToInstall);
  572.  
  573.     if (TableIndex == ACPI_TABLE_INDEX_DSDT)
  574.     {
  575.         /* Global integer width is based upon revision of the DSDT */
  576.  
  577.         AcpiUtSetIntegerWidth (TableToInstall->Revision);
  578.     }
  579.  
  580. UnmapAndExit:
  581.     AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER));
  582. }
  583.  
  584.  
  585. /*******************************************************************************
  586.  *
  587.  * FUNCTION:    AcpiTbGetRootTableEntry
  588.  *
  589.  * PARAMETERS:  TableEntry          - Pointer to the RSDT/XSDT table entry
  590.  *              TableEntrySize      - sizeof 32 or 64 (RSDT or XSDT)
  591.  *
  592.  * RETURN:      Physical address extracted from the root table
  593.  *
  594.  * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
  595.  *              both 32-bit and 64-bit platforms
  596.  *
  597.  * NOTE:        ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on
  598.  *              64-bit platforms.
  599.  *
  600.  ******************************************************************************/
  601.  
  602. static ACPI_PHYSICAL_ADDRESS
  603. AcpiTbGetRootTableEntry (
  604.     UINT8                   *TableEntry,
  605.     UINT32                  TableEntrySize)
  606. {
  607.     UINT64                  Address64;
  608.  
  609.  
  610.     /*
  611.      * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
  612.      * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
  613.      */
  614.     if (TableEntrySize == sizeof (UINT32))
  615.     {
  616.         /*
  617.          * 32-bit platform, RSDT: Return 32-bit table entry
  618.          * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
  619.          */
  620.         return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (UINT32, TableEntry)));
  621.     }
  622.     else
  623.     {
  624.         /*
  625.          * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
  626.          * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
  627.          *  return 64-bit
  628.          */
  629.         ACPI_MOVE_64_TO_64 (&Address64, TableEntry);
  630.  
  631. #if ACPI_MACHINE_WIDTH == 32
  632.         if (Address64 > ACPI_UINT32_MAX)
  633.         {
  634.             /* Will truncate 64-bit address to 32 bits, issue warning */
  635.  
  636.             ACPI_WARNING ((AE_INFO,
  637.                 "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
  638.                 " truncating",
  639.                 ACPI_FORMAT_UINT64 (Address64)));
  640.         }
  641. #endif
  642.         return ((ACPI_PHYSICAL_ADDRESS) (Address64));
  643.     }
  644. }
  645.  
  646.  
  647. /*******************************************************************************
  648.  *
  649.  * FUNCTION:    AcpiTbParseRootTable
  650.  *
  651.  * PARAMETERS:  Rsdp                    - Pointer to the RSDP
  652.  *
  653.  * RETURN:      Status
  654.  *
  655.  * DESCRIPTION: This function is called to parse the Root System Description
  656.  *              Table (RSDT or XSDT)
  657.  *
  658.  * NOTE:        Tables are mapped (not copied) for efficiency. The FACS must
  659.  *              be mapped and cannot be copied because it contains the actual
  660.  *              memory location of the ACPI Global Lock.
  661.  *
  662.  ******************************************************************************/
  663.  
  664. ACPI_STATUS
  665. AcpiTbParseRootTable (
  666.     ACPI_PHYSICAL_ADDRESS   RsdpAddress)
  667. {
  668.     ACPI_TABLE_RSDP         *Rsdp;
  669.     UINT32                  TableEntrySize;
  670.     UINT32                  i;
  671.     UINT32                  TableCount;
  672.     ACPI_TABLE_HEADER       *Table;
  673.     ACPI_PHYSICAL_ADDRESS   Address;
  674.     UINT32                  Length;
  675.     UINT8                   *TableEntry;
  676.     ACPI_STATUS             Status;
  677.  
  678.  
  679.     ACPI_FUNCTION_TRACE (TbParseRootTable);
  680.  
  681.  
  682.     /*
  683.      * Map the entire RSDP and extract the address of the RSDT or XSDT
  684.      */
  685.     Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP));
  686.     if (!Rsdp)
  687.     {
  688.         return_ACPI_STATUS (AE_NO_MEMORY);
  689.     }
  690.  
  691.     AcpiTbPrintTableHeader (RsdpAddress,
  692.         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp));
  693.  
  694.     /* Differentiate between RSDT and XSDT root tables */
  695.  
  696.     if (Rsdp->Revision > 1 && Rsdp->XsdtPhysicalAddress)
  697.     {
  698.         /*
  699.          * Root table is an XSDT (64-bit physical addresses). We must use the
  700.          * XSDT if the revision is > 1 and the XSDT pointer is present, as per
  701.          * the ACPI specification.
  702.          */
  703.         Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress;
  704.         TableEntrySize = sizeof (UINT64);
  705.     }
  706.     else
  707.     {
  708.         /* Root table is an RSDT (32-bit physical addresses) */
  709.  
  710.         Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
  711.         TableEntrySize = sizeof (UINT32);
  712.     }
  713.  
  714.     /*
  715.      * It is not possible to map more than one entry in some environments,
  716.      * so unmap the RSDP here before mapping other tables
  717.      */
  718.     AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP));
  719.  
  720.  
  721.     /* Map the RSDT/XSDT table header to get the full table length */
  722.  
  723.     Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
  724.     if (!Table)
  725.     {
  726.         return_ACPI_STATUS (AE_NO_MEMORY);
  727.     }
  728.  
  729.     AcpiTbPrintTableHeader (Address, Table);
  730.  
  731.     /* Get the length of the full table, verify length and map entire table */
  732.  
  733.     Length = Table->Length;
  734.     AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
  735.  
  736.     if (Length < sizeof (ACPI_TABLE_HEADER))
  737.     {
  738.         ACPI_ERROR ((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", Length));
  739.         return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
  740.     }
  741.  
  742.     Table = AcpiOsMapMemory (Address, Length);
  743.     if (!Table)
  744.     {
  745.         return_ACPI_STATUS (AE_NO_MEMORY);
  746.     }
  747.  
  748.     /* Validate the root table checksum */
  749.  
  750.     Status = AcpiTbVerifyChecksum (Table, Length);
  751.     if (ACPI_FAILURE (Status))
  752.     {
  753.         AcpiOsUnmapMemory (Table, Length);
  754.         return_ACPI_STATUS (Status);
  755.     }
  756.  
  757.     /* Calculate the number of tables described in the root table */
  758.  
  759.     TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) /
  760.         TableEntrySize);
  761.  
  762.     /*
  763.      * First two entries in the table array are reserved for the DSDT
  764.      * and FACS, which are not actually present in the RSDT/XSDT - they
  765.      * come from the FADT
  766.      */
  767.     TableEntry = ACPI_CAST_PTR (UINT8, Table) + sizeof (ACPI_TABLE_HEADER);
  768.     AcpiGbl_RootTableList.CurrentTableCount = 2;
  769.  
  770.     /*
  771.      * Initialize the root table array from the RSDT/XSDT
  772.      */
  773.     for (i = 0; i < TableCount; i++)
  774.     {
  775.         if (AcpiGbl_RootTableList.CurrentTableCount >=
  776.             AcpiGbl_RootTableList.MaxTableCount)
  777.         {
  778.             /* There is no more room in the root table array, attempt resize */
  779.  
  780.             Status = AcpiTbResizeRootTableList ();
  781.             if (ACPI_FAILURE (Status))
  782.             {
  783.                 ACPI_WARNING ((AE_INFO, "Truncating %u table entries!",
  784.                     (unsigned) (TableCount -
  785.                     (AcpiGbl_RootTableList.CurrentTableCount - 2))));
  786.                 break;
  787.             }
  788.         }
  789.  
  790.         /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
  791.  
  792.         AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount].Address =
  793.             AcpiTbGetRootTableEntry (TableEntry, TableEntrySize);
  794.  
  795.         TableEntry += TableEntrySize;
  796.         AcpiGbl_RootTableList.CurrentTableCount++;
  797.     }
  798.  
  799.     /*
  800.      * It is not possible to map more than one entry in some environments,
  801.      * so unmap the root table here before mapping other tables
  802.      */
  803.     AcpiOsUnmapMemory (Table, Length);
  804.  
  805.     /*
  806.      * Complete the initialization of the root table array by examining
  807.      * the header of each table
  808.      */
  809.     for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
  810.     {
  811.         AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address,
  812.             NULL, i);
  813.  
  814.         /* Special case for FADT - get the DSDT and FACS */
  815.  
  816.         if (ACPI_COMPARE_NAME (
  817.                 &AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT))
  818.         {
  819.             AcpiTbParseFadt (i);
  820.         }
  821.     }
  822.  
  823.     return_ACPI_STATUS (AE_OK);
  824. }
  825.