ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tbutils.c
Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * Module Name: tbutils   - table utilities
00004  *
00005  *****************************************************************************/
00006 
00007 /******************************************************************************
00008  *
00009  * 1. Copyright Notice
00010  *
00011  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00012  * All rights reserved.
00013  *
00014  * 2. License
00015  *
00016  * 2.1. This is your license from Intel Corp. under its intellectual property
00017  * rights.  You may have additional license terms from the party that provided
00018  * you this software, covering your right to use that party's intellectual
00019  * property rights.
00020  *
00021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00022  * copy of the source code appearing in this file ("Covered Code") an
00023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00024  * base code distributed originally by Intel ("Original Intel Code") to copy,
00025  * make derivatives, distribute, use and display any portion of the Covered
00026  * Code in any form, with the right to sublicense such rights; and
00027  *
00028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00029  * license (with the right to sublicense), under only those claims of Intel
00030  * patents that are infringed by the Original Intel Code, to make, use, sell,
00031  * offer to sell, and import the Covered Code and derivative works thereof
00032  * solely to the minimum extent necessary to exercise the above copyright
00033  * license, and in no event shall the patent license extend to any additions
00034  * to or modifications of the Original Intel Code.  No other license or right
00035  * is granted directly or by implication, estoppel or otherwise;
00036  *
00037  * The above copyright and patent license is granted only if the following
00038  * conditions are met:
00039  *
00040  * 3. Conditions
00041  *
00042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00043  * Redistribution of source code of any substantial portion of the Covered
00044  * Code or modification with rights to further distribute source must include
00045  * the above Copyright Notice, the above License, this list of Conditions,
00046  * and the following Disclaimer and Export Compliance provision.  In addition,
00047  * Licensee must cause all Covered Code to which Licensee contributes to
00048  * contain a file documenting the changes Licensee made to create that Covered
00049  * Code and the date of any change.  Licensee must include in that file the
00050  * documentation of any changes made by any predecessor Licensee.  Licensee
00051  * must include a prominent statement that the modification is derived,
00052  * directly or indirectly, from Original Intel Code.
00053  *
00054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00055  * Redistribution of source code of any substantial portion of the Covered
00056  * Code or modification without rights to further distribute source must
00057  * include the following Disclaimer and Export Compliance provision in the
00058  * documentation and/or other materials provided with distribution.  In
00059  * addition, Licensee may not authorize further sublicense of source of any
00060  * portion of the Covered Code, and must include terms to the effect that the
00061  * license from Licensee to its licensee is limited to the intellectual
00062  * property embodied in the software Licensee provides to its licensee, and
00063  * not to intellectual property embodied in modifications its licensee may
00064  * make.
00065  *
00066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00067  * substantial portion of the Covered Code or modification must reproduce the
00068  * above Copyright Notice, and the following Disclaimer and Export Compliance
00069  * provision in the documentation and/or other materials provided with the
00070  * distribution.
00071  *
00072  * 3.4. Intel retains all right, title, and interest in and to the Original
00073  * Intel Code.
00074  *
00075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00076  * Intel shall be used in advertising or otherwise to promote the sale, use or
00077  * other dealings in products derived from or relating to the Covered Code
00078  * without prior written authorization from Intel.
00079  *
00080  * 4. Disclaimer and Export Compliance
00081  *
00082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00083  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00085  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00086  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00088  * PARTICULAR PURPOSE.
00089  *
00090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00097  * LIMITED REMEDY.
00098  *
00099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00100  * software or system incorporating such software without first obtaining any
00101  * required license or other approval from the U. S. Department of Commerce or
00102  * any other agency or department of the United States Government.  In the
00103  * event Licensee exports any such software from the United States or
00104  * re-exports any such software from a foreign destination, Licensee shall
00105  * ensure that the distribution and export/re-export of the software is in
00106  * compliance with all laws, regulations, orders, or other restrictions of the
00107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00108  * any of its subsidiaries will export/re-export any technical data, process,
00109  * software, or service, directly or indirectly, to any country for which the
00110  * United States government or any agency thereof requires an export license,
00111  * other governmental approval, or letter of assurance, without first obtaining
00112  * such license, approval or letter.
00113  *
00114  *****************************************************************************/
00115 
00116 #define __TBUTILS_C__
00117 
00118 #include "acpi.h"
00119 #include "accommon.h"
00120 #include "actables.h"
00121 
00122 #define _COMPONENT          ACPI_TABLES
00123         ACPI_MODULE_NAME    ("tbutils")
00124 
00125 /* Local prototypes */
00126 
00127 static void
00128 AcpiTbFixString (
00129     char                    *String,
00130     ACPI_SIZE               Length);
00131 
00132 static void
00133 AcpiTbCleanupTableHeader (
00134     ACPI_TABLE_HEADER       *OutHeader,
00135     ACPI_TABLE_HEADER       *Header);
00136 
00137 static ACPI_PHYSICAL_ADDRESS
00138 AcpiTbGetRootTableEntry (
00139     UINT8                   *TableEntry,
00140     UINT32                  TableEntrySize);
00141 
00142 
00143 /*******************************************************************************
00144  *
00145  * FUNCTION:    AcpiTbInitializeFacs
00146  *
00147  * PARAMETERS:  None
00148  *
00149  * RETURN:      Status
00150  *
00151  * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global
00152  *              for accessing the Global Lock and Firmware Waking Vector
00153  *
00154  ******************************************************************************/
00155 
00156 ACPI_STATUS
00157 AcpiTbInitializeFacs (
00158     void)
00159 {
00160     ACPI_STATUS             Status;
00161 
00162 
00163     Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS,
00164                 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_FACS));
00165     return (Status);
00166 }
00167 
00168 
00169 /*******************************************************************************
00170  *
00171  * FUNCTION:    AcpiTbTablesLoaded
00172  *
00173  * PARAMETERS:  None
00174  *
00175  * RETURN:      TRUE if required ACPI tables are loaded
00176  *
00177  * DESCRIPTION: Determine if the minimum required ACPI tables are present
00178  *              (FADT, FACS, DSDT)
00179  *
00180  ******************************************************************************/
00181 
00182 BOOLEAN
00183 AcpiTbTablesLoaded (
00184     void)
00185 {
00186 
00187     if (AcpiGbl_RootTableList.CurrentTableCount >= 3)
00188     {
00189         return (TRUE);
00190     }
00191 
00192     return (FALSE);
00193 }
00194 
00195 
00196 /*******************************************************************************
00197  *
00198  * FUNCTION:    AcpiTbFixString
00199  *
00200  * PARAMETERS:  String              - String to be repaired
00201  *              Length              - Maximum length
00202  *
00203  * RETURN:      None
00204  *
00205  * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
00206  *              with a question mark '?'.
00207  *
00208  ******************************************************************************/
00209 
00210 static void
00211 AcpiTbFixString (
00212     char                    *String,
00213     ACPI_SIZE               Length)
00214 {
00215 
00216     while (Length && *String)
00217     {
00218         if (!ACPI_IS_PRINT (*String))
00219         {
00220             *String = '?';
00221         }
00222         String++;
00223         Length--;
00224     }
00225 }
00226 
00227 
00228 /*******************************************************************************
00229  *
00230  * FUNCTION:    AcpiTbCleanupTableHeader
00231  *
00232  * PARAMETERS:  OutHeader           - Where the cleaned header is returned
00233  *              Header              - Input ACPI table header
00234  *
00235  * RETURN:      Returns the cleaned header in OutHeader
00236  *
00237  * DESCRIPTION: Copy the table header and ensure that all "string" fields in
00238  *              the header consist of printable characters.
00239  *
00240  ******************************************************************************/
00241 
00242 static void
00243 AcpiTbCleanupTableHeader (
00244     ACPI_TABLE_HEADER       *OutHeader,
00245     ACPI_TABLE_HEADER       *Header)
00246 {
00247 
00248     ACPI_MEMCPY (OutHeader, Header, sizeof (ACPI_TABLE_HEADER));
00249 
00250     AcpiTbFixString (OutHeader->Signature, ACPI_NAME_SIZE);
00251     AcpiTbFixString (OutHeader->OemId, ACPI_OEM_ID_SIZE);
00252     AcpiTbFixString (OutHeader->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
00253     AcpiTbFixString (OutHeader->AslCompilerId, ACPI_NAME_SIZE);
00254 }
00255 
00256 
00257 /*******************************************************************************
00258  *
00259  * FUNCTION:    AcpiTbPrintTableHeader
00260  *
00261  * PARAMETERS:  Address             - Table physical address
00262  *              Header              - Table header
00263  *
00264  * RETURN:      None
00265  *
00266  * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
00267  *
00268  ******************************************************************************/
00269 
00270 void
00271 AcpiTbPrintTableHeader (
00272     ACPI_PHYSICAL_ADDRESS   Address,
00273     ACPI_TABLE_HEADER       *Header)
00274 {
00275     ACPI_TABLE_HEADER       LocalHeader;
00276 
00277 
00278     /*
00279      * The reason that the Address is cast to a void pointer is so that we
00280      * can use %p which will work properly on both 32-bit and 64-bit hosts.
00281      */
00282     if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_FACS))
00283     {
00284         /* FACS only has signature and length fields */
00285 
00286         ACPI_INFO ((AE_INFO, "%4.4s %p %05X",
00287             Header->Signature, ACPI_CAST_PTR (void, Address),
00288             Header->Length));
00289     }
00290     else if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_RSDP))
00291     {
00292         /* RSDP has no common fields */
00293 
00294         ACPI_MEMCPY (LocalHeader.OemId,
00295             ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId, ACPI_OEM_ID_SIZE);
00296         AcpiTbFixString (LocalHeader.OemId, ACPI_OEM_ID_SIZE);
00297 
00298         ACPI_INFO ((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
00299             ACPI_CAST_PTR (void, Address),
00300             (ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision > 0) ?
00301                 ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Length : 20,
00302             ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision,
00303             LocalHeader.OemId));
00304     }
00305     else
00306     {
00307         /* Standard ACPI table with full common header */
00308 
00309         AcpiTbCleanupTableHeader (&LocalHeader, Header);
00310 
00311         ACPI_INFO ((AE_INFO,
00312             "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
00313             LocalHeader.Signature, ACPI_CAST_PTR (void, Address),
00314             LocalHeader.Length, LocalHeader.Revision, LocalHeader.OemId,
00315             LocalHeader.OemTableId, LocalHeader.OemRevision,
00316             LocalHeader.AslCompilerId, LocalHeader.AslCompilerRevision));
00317     }
00318 }
00319 
00320 
00321 /*******************************************************************************
00322  *
00323  * FUNCTION:    AcpiTbValidateChecksum
00324  *
00325  * PARAMETERS:  Table               - ACPI table to verify
00326  *              Length              - Length of entire table
00327  *
00328  * RETURN:      Status
00329  *
00330  * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
00331  *              exception on bad checksum.
00332  *
00333  ******************************************************************************/
00334 
00335 ACPI_STATUS
00336 AcpiTbVerifyChecksum (
00337     ACPI_TABLE_HEADER       *Table,
00338     UINT32                  Length)
00339 {
00340     UINT8                   Checksum;
00341 
00342 
00343     /* Compute the checksum on the table */
00344 
00345     Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Length);
00346 
00347     /* Checksum ok? (should be zero) */
00348 
00349     if (Checksum)
00350     {
00351         ACPI_WARNING ((AE_INFO,
00352             "Incorrect checksum in table [%4.4s] - 0x%2.2X, should be 0x%2.2X",
00353             Table->Signature, Table->Checksum,
00354             (UINT8) (Table->Checksum - Checksum)));
00355 
00356 #if (ACPI_CHECKSUM_ABORT)
00357         return (AE_BAD_CHECKSUM);
00358 #endif
00359     }
00360 
00361     return (AE_OK);
00362 }
00363 
00364 
00365 /*******************************************************************************
00366  *
00367  * FUNCTION:    AcpiTbChecksum
00368  *
00369  * PARAMETERS:  Buffer          - Pointer to memory region to be checked
00370  *              Length          - Length of this memory region
00371  *
00372  * RETURN:      Checksum (UINT8)
00373  *
00374  * DESCRIPTION: Calculates circular checksum of memory region.
00375  *
00376  ******************************************************************************/
00377 
00378 UINT8
00379 AcpiTbChecksum (
00380     UINT8                   *Buffer,
00381     UINT32                  Length)
00382 {
00383     UINT8                   Sum = 0;
00384     UINT8                   *End = Buffer + Length;
00385 
00386 
00387     while (Buffer < End)
00388     {
00389         Sum = (UINT8) (Sum + *(Buffer++));
00390     }
00391 
00392     return Sum;
00393 }
00394 
00395 
00396 /*******************************************************************************
00397  *
00398  * FUNCTION:    AcpiTbCheckDsdtHeader
00399  *
00400  * PARAMETERS:  None
00401  *
00402  * RETURN:      None
00403  *
00404  * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
00405  *              if the DSDT has been replaced from outside the OS and/or if
00406  *              the DSDT header has been corrupted.
00407  *
00408  ******************************************************************************/
00409 
00410 void
00411 AcpiTbCheckDsdtHeader (
00412     void)
00413 {
00414 
00415     /* Compare original length and checksum to current values */
00416 
00417     if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
00418         AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
00419     {
00420         ACPI_ERROR ((AE_INFO,
00421             "The DSDT has been corrupted or replaced - old, new headers below"));
00422         AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
00423         AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
00424 
00425         /* Disable further error messages */
00426 
00427         AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
00428         AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
00429     }
00430 }
00431 
00432 
00433 /*******************************************************************************
00434  *
00435  * FUNCTION:    AcpiTbCopyDsdt
00436  *
00437  * PARAMETERS:  TableDesc           - Installed table to copy
00438  *
00439  * RETURN:      None
00440  *
00441  * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
00442  *              Some very bad BIOSs are known to either corrupt the DSDT or
00443  *              install a new, bad DSDT. This copy works around the problem.
00444  *
00445  ******************************************************************************/
00446 
00447 ACPI_TABLE_HEADER *
00448 AcpiTbCopyDsdt (
00449     UINT32                  TableIndex)
00450 {
00451     ACPI_TABLE_HEADER       *NewTable;
00452     ACPI_TABLE_DESC         *TableDesc;
00453 
00454 
00455     TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
00456 
00457     NewTable = ACPI_ALLOCATE (TableDesc->Length);
00458     if (!NewTable)
00459     {
00460         ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
00461             TableDesc->Length));
00462         return (NULL);
00463     }
00464 
00465     ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length);
00466     AcpiTbDeleteTable (TableDesc);
00467     TableDesc->Pointer = NewTable;
00468     TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED;
00469 
00470     ACPI_INFO ((AE_INFO,
00471         "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
00472         NewTable->Length));
00473 
00474     return (NewTable);
00475 }
00476 
00477 
00478 /*******************************************************************************
00479  *
00480  * FUNCTION:    AcpiTbInstallTable
00481  *
00482  * PARAMETERS:  Address                 - Physical address of DSDT or FACS
00483  *              Signature               - Table signature, NULL if no need to
00484  *                                        match
00485  *              TableIndex              - Index into root table array
00486  *
00487  * RETURN:      None
00488  *
00489  * DESCRIPTION: Install an ACPI table into the global data structure. The
00490  *              table override mechanism is implemented here to allow the host
00491  *              OS to replace any table before it is installed in the root
00492  *              table array.
00493  *
00494  ******************************************************************************/
00495 
00496 void
00497 AcpiTbInstallTable (
00498     ACPI_PHYSICAL_ADDRESS   Address,
00499     char                    *Signature,
00500     UINT32                  TableIndex)
00501 {
00502     UINT8                   Flags;
00503     ACPI_STATUS             Status;
00504     ACPI_TABLE_HEADER       *TableToInstall;
00505     ACPI_TABLE_HEADER       *MappedTable;
00506     ACPI_TABLE_HEADER       *OverrideTable = NULL;
00507 
00508 
00509     if (!Address)
00510     {
00511         ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]",
00512             Signature));
00513         return;
00514     }
00515 
00516     /* Map just the table header */
00517 
00518     MappedTable = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
00519     if (!MappedTable)
00520     {
00521         return;
00522     }
00523 
00524     /* If a particular signature is expected (DSDT/FACS), it must match */
00525 
00526     if (Signature &&
00527         !ACPI_COMPARE_NAME (MappedTable->Signature, Signature))
00528     {
00529         ACPI_ERROR ((AE_INFO,
00530             "Invalid signature 0x%X for ACPI table, expected [%s]",
00531             *ACPI_CAST_PTR (UINT32, MappedTable->Signature), Signature));
00532         goto UnmapAndExit;
00533     }
00534 
00535     /*
00536      * ACPI Table Override:
00537      *
00538      * Before we install the table, let the host OS override it with a new
00539      * one if desired. Any table within the RSDT/XSDT can be replaced,
00540      * including the DSDT which is pointed to by the FADT.
00541      */
00542     Status = AcpiOsTableOverride (MappedTable, &OverrideTable);
00543     if (ACPI_SUCCESS (Status) && OverrideTable)
00544     {
00545         ACPI_INFO ((AE_INFO,
00546             "%4.4s @ 0x%p Table override, replaced with:",
00547             MappedTable->Signature, ACPI_CAST_PTR (void, Address)));
00548 
00549         AcpiGbl_RootTableList.Tables[TableIndex].Pointer = OverrideTable;
00550         Address = ACPI_PTR_TO_PHYSADDR (OverrideTable);
00551 
00552         TableToInstall = OverrideTable;
00553         Flags = ACPI_TABLE_ORIGIN_OVERRIDE;
00554     }
00555     else
00556     {
00557         TableToInstall = MappedTable;
00558         Flags = ACPI_TABLE_ORIGIN_MAPPED;
00559     }
00560 
00561     /* Initialize the table entry */
00562 
00563     AcpiGbl_RootTableList.Tables[TableIndex].Address = Address;
00564     AcpiGbl_RootTableList.Tables[TableIndex].Length = TableToInstall->Length;
00565     AcpiGbl_RootTableList.Tables[TableIndex].Flags = Flags;
00566 
00567     ACPI_MOVE_32_TO_32 (
00568         &(AcpiGbl_RootTableList.Tables[TableIndex].Signature),
00569         TableToInstall->Signature);
00570 
00571     AcpiTbPrintTableHeader (Address, TableToInstall);
00572 
00573     if (TableIndex == ACPI_TABLE_INDEX_DSDT)
00574     {
00575         /* Global integer width is based upon revision of the DSDT */
00576 
00577         AcpiUtSetIntegerWidth (TableToInstall->Revision);
00578     }
00579 
00580 UnmapAndExit:
00581     AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER));
00582 }
00583 
00584 
00585 /*******************************************************************************
00586  *
00587  * FUNCTION:    AcpiTbGetRootTableEntry
00588  *
00589  * PARAMETERS:  TableEntry          - Pointer to the RSDT/XSDT table entry
00590  *              TableEntrySize      - sizeof 32 or 64 (RSDT or XSDT)
00591  *
00592  * RETURN:      Physical address extracted from the root table
00593  *
00594  * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
00595  *              both 32-bit and 64-bit platforms
00596  *
00597  * NOTE:        ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on
00598  *              64-bit platforms.
00599  *
00600  ******************************************************************************/
00601 
00602 static ACPI_PHYSICAL_ADDRESS
00603 AcpiTbGetRootTableEntry (
00604     UINT8                   *TableEntry,
00605     UINT32                  TableEntrySize)
00606 {
00607     UINT64                  Address64;
00608 
00609 
00610     /*
00611      * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
00612      * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
00613      */
00614     if (TableEntrySize == sizeof (UINT32))
00615     {
00616         /*
00617          * 32-bit platform, RSDT: Return 32-bit table entry
00618          * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
00619          */
00620         return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (UINT32, TableEntry)));
00621     }
00622     else
00623     {
00624         /*
00625          * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
00626          * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
00627          *  return 64-bit
00628          */
00629         ACPI_MOVE_64_TO_64 (&Address64, TableEntry);
00630 
00631 #if ACPI_MACHINE_WIDTH == 32
00632         if (Address64 > ACPI_UINT32_MAX)
00633         {
00634             /* Will truncate 64-bit address to 32 bits, issue warning */
00635 
00636             ACPI_WARNING ((AE_INFO,
00637                 "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
00638                 " truncating",
00639                 ACPI_FORMAT_UINT64 (Address64)));
00640         }
00641 #endif
00642         return ((ACPI_PHYSICAL_ADDRESS) (Address64));
00643     }
00644 }
00645 
00646 
00647 /*******************************************************************************
00648  *
00649  * FUNCTION:    AcpiTbParseRootTable
00650  *
00651  * PARAMETERS:  Rsdp                    - Pointer to the RSDP
00652  *
00653  * RETURN:      Status
00654  *
00655  * DESCRIPTION: This function is called to parse the Root System Description
00656  *              Table (RSDT or XSDT)
00657  *
00658  * NOTE:        Tables are mapped (not copied) for efficiency. The FACS must
00659  *              be mapped and cannot be copied because it contains the actual
00660  *              memory location of the ACPI Global Lock.
00661  *
00662  ******************************************************************************/
00663 
00664 ACPI_STATUS
00665 AcpiTbParseRootTable (
00666     ACPI_PHYSICAL_ADDRESS   RsdpAddress)
00667 {
00668     ACPI_TABLE_RSDP         *Rsdp;
00669     UINT32                  TableEntrySize;
00670     UINT32                  i;
00671     UINT32                  TableCount;
00672     ACPI_TABLE_HEADER       *Table;
00673     ACPI_PHYSICAL_ADDRESS   Address;
00674     UINT32                  Length;
00675     UINT8                   *TableEntry;
00676     ACPI_STATUS             Status;
00677 
00678 
00679     ACPI_FUNCTION_TRACE (TbParseRootTable);
00680 
00681 
00682     /*
00683      * Map the entire RSDP and extract the address of the RSDT or XSDT
00684      */
00685     Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP));
00686     if (!Rsdp)
00687     {
00688         return_ACPI_STATUS (AE_NO_MEMORY);
00689     }
00690 
00691     AcpiTbPrintTableHeader (RsdpAddress,
00692         ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp));
00693 
00694     /* Differentiate between RSDT and XSDT root tables */
00695 
00696     if (Rsdp->Revision > 1 && Rsdp->XsdtPhysicalAddress)
00697     {
00698         /*
00699          * Root table is an XSDT (64-bit physical addresses). We must use the
00700          * XSDT if the revision is > 1 and the XSDT pointer is present, as per
00701          * the ACPI specification.
00702          */
00703         Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress;
00704         TableEntrySize = sizeof (UINT64);
00705     }
00706     else
00707     {
00708         /* Root table is an RSDT (32-bit physical addresses) */
00709 
00710         Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
00711         TableEntrySize = sizeof (UINT32);
00712     }
00713 
00714     /*
00715      * It is not possible to map more than one entry in some environments,
00716      * so unmap the RSDP here before mapping other tables
00717      */
00718     AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP));
00719 
00720 
00721     /* Map the RSDT/XSDT table header to get the full table length */
00722 
00723     Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
00724     if (!Table)
00725     {
00726         return_ACPI_STATUS (AE_NO_MEMORY);
00727     }
00728 
00729     AcpiTbPrintTableHeader (Address, Table);
00730 
00731     /* Get the length of the full table, verify length and map entire table */
00732 
00733     Length = Table->Length;
00734     AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
00735 
00736     if (Length < sizeof (ACPI_TABLE_HEADER))
00737     {
00738         ACPI_ERROR ((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", Length));
00739         return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
00740     }
00741 
00742     Table = AcpiOsMapMemory (Address, Length);
00743     if (!Table)
00744     {
00745         return_ACPI_STATUS (AE_NO_MEMORY);
00746     }
00747 
00748     /* Validate the root table checksum */
00749 
00750     Status = AcpiTbVerifyChecksum (Table, Length);
00751     if (ACPI_FAILURE (Status))
00752     {
00753         AcpiOsUnmapMemory (Table, Length);
00754         return_ACPI_STATUS (Status);
00755     }
00756 
00757     /* Calculate the number of tables described in the root table */
00758 
00759     TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) /
00760         TableEntrySize);
00761 
00762     /*
00763      * First two entries in the table array are reserved for the DSDT
00764      * and FACS, which are not actually present in the RSDT/XSDT - they
00765      * come from the FADT
00766      */
00767     TableEntry = ACPI_CAST_PTR (UINT8, Table) + sizeof (ACPI_TABLE_HEADER);
00768     AcpiGbl_RootTableList.CurrentTableCount = 2;
00769 
00770     /*
00771      * Initialize the root table array from the RSDT/XSDT
00772      */
00773     for (i = 0; i < TableCount; i++)
00774     {
00775         if (AcpiGbl_RootTableList.CurrentTableCount >=
00776             AcpiGbl_RootTableList.MaxTableCount)
00777         {
00778             /* There is no more room in the root table array, attempt resize */
00779 
00780             Status = AcpiTbResizeRootTableList ();
00781             if (ACPI_FAILURE (Status))
00782             {
00783                 ACPI_WARNING ((AE_INFO, "Truncating %u table entries!",
00784                     (unsigned) (TableCount -
00785                     (AcpiGbl_RootTableList.CurrentTableCount - 2))));
00786                 break;
00787             }
00788         }
00789 
00790         /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
00791 
00792         AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount].Address =
00793             AcpiTbGetRootTableEntry (TableEntry, TableEntrySize);
00794 
00795         TableEntry += TableEntrySize;
00796         AcpiGbl_RootTableList.CurrentTableCount++;
00797     }
00798 
00799     /*
00800      * It is not possible to map more than one entry in some environments,
00801      * so unmap the root table here before mapping other tables
00802      */
00803     AcpiOsUnmapMemory (Table, Length);
00804 
00805     /*
00806      * Complete the initialization of the root table array by examining
00807      * the header of each table
00808      */
00809     for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
00810     {
00811         AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address,
00812             NULL, i);
00813 
00814         /* Special case for FADT - get the DSDT and FACS */
00815 
00816         if (ACPI_COMPARE_NAME (
00817                 &AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT))
00818         {
00819             AcpiTbParseFadt (i);
00820         }
00821     }
00822 
00823     return_ACPI_STATUS (AE_OK);
00824 }

Generated on Sun May 27 2012 04:27:23 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.