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

tbfadt.c
Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * Module Name: tbfadt   - FADT 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 __TBFADT_C__
00117 
00118 #include "acpi.h"
00119 #include "accommon.h"
00120 #include "actables.h"
00121 
00122 #define _COMPONENT          ACPI_TABLES
00123         ACPI_MODULE_NAME    ("tbfadt")
00124 
00125 /* Local prototypes */
00126 
00127 static ACPI_INLINE void
00128 AcpiTbInitGenericAddress (
00129     ACPI_GENERIC_ADDRESS    *GenericAddress,
00130     UINT8                   SpaceId,
00131     UINT8                   ByteWidth,
00132     UINT64                  Address);
00133 
00134 static void
00135 AcpiTbConvertFadt (
00136     void);
00137 
00138 static void
00139 AcpiTbValidateFadt (
00140     void);
00141 
00142 static void
00143 AcpiTbSetupFadtRegisters (
00144     void);
00145 
00146 
00147 /* Table for conversion of FADT to common internal format and FADT validation */
00148 
00149 typedef struct acpi_fadt_info
00150 {
00151     char                    *Name;
00152     UINT8                   Address64;
00153     UINT8                   Address32;
00154     UINT8                   Length;
00155     UINT8                   DefaultLength;
00156     UINT8                   Type;
00157 
00158 } ACPI_FADT_INFO;
00159 
00160 #define ACPI_FADT_REQUIRED          1
00161 #define ACPI_FADT_SEPARATE_LENGTH   2
00162 
00163 static ACPI_FADT_INFO     FadtInfoTable[] =
00164 {
00165     {"Pm1aEventBlock",
00166         ACPI_FADT_OFFSET (XPm1aEventBlock),
00167         ACPI_FADT_OFFSET (Pm1aEventBlock),
00168         ACPI_FADT_OFFSET (Pm1EventLength),
00169         ACPI_PM1_REGISTER_WIDTH * 2,        /* Enable + Status register */
00170         ACPI_FADT_REQUIRED},
00171 
00172     {"Pm1bEventBlock",
00173         ACPI_FADT_OFFSET (XPm1bEventBlock),
00174         ACPI_FADT_OFFSET (Pm1bEventBlock),
00175         ACPI_FADT_OFFSET (Pm1EventLength),
00176         ACPI_PM1_REGISTER_WIDTH * 2,        /* Enable + Status register */
00177         0},
00178 
00179     {"Pm1aControlBlock",
00180         ACPI_FADT_OFFSET (XPm1aControlBlock),
00181         ACPI_FADT_OFFSET (Pm1aControlBlock),
00182         ACPI_FADT_OFFSET (Pm1ControlLength),
00183         ACPI_PM1_REGISTER_WIDTH,
00184         ACPI_FADT_REQUIRED},
00185 
00186     {"Pm1bControlBlock",
00187         ACPI_FADT_OFFSET (XPm1bControlBlock),
00188         ACPI_FADT_OFFSET (Pm1bControlBlock),
00189         ACPI_FADT_OFFSET (Pm1ControlLength),
00190         ACPI_PM1_REGISTER_WIDTH,
00191         0},
00192 
00193     {"Pm2ControlBlock",
00194         ACPI_FADT_OFFSET (XPm2ControlBlock),
00195         ACPI_FADT_OFFSET (Pm2ControlBlock),
00196         ACPI_FADT_OFFSET (Pm2ControlLength),
00197         ACPI_PM2_REGISTER_WIDTH,
00198         ACPI_FADT_SEPARATE_LENGTH},
00199 
00200     {"PmTimerBlock",
00201         ACPI_FADT_OFFSET (XPmTimerBlock),
00202         ACPI_FADT_OFFSET (PmTimerBlock),
00203         ACPI_FADT_OFFSET (PmTimerLength),
00204         ACPI_PM_TIMER_WIDTH,
00205         ACPI_FADT_REQUIRED},
00206 
00207     {"Gpe0Block",
00208         ACPI_FADT_OFFSET (XGpe0Block),
00209         ACPI_FADT_OFFSET (Gpe0Block),
00210         ACPI_FADT_OFFSET (Gpe0BlockLength),
00211         0,
00212         ACPI_FADT_SEPARATE_LENGTH},
00213 
00214     {"Gpe1Block",
00215         ACPI_FADT_OFFSET (XGpe1Block),
00216         ACPI_FADT_OFFSET (Gpe1Block),
00217         ACPI_FADT_OFFSET (Gpe1BlockLength),
00218         0,
00219         ACPI_FADT_SEPARATE_LENGTH}
00220 };
00221 
00222 #define ACPI_FADT_INFO_ENTRIES \
00223             (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO))
00224 
00225 
00226 /* Table used to split Event Blocks into separate status/enable registers */
00227 
00228 typedef struct acpi_fadt_pm_info
00229 {
00230     ACPI_GENERIC_ADDRESS    *Target;
00231     UINT8                   Source;
00232     UINT8                   RegisterNum;
00233 
00234 } ACPI_FADT_PM_INFO;
00235 
00236 static ACPI_FADT_PM_INFO    FadtPmInfoTable[] =
00237 {
00238     {&AcpiGbl_XPm1aStatus,
00239         ACPI_FADT_OFFSET (XPm1aEventBlock),
00240         0},
00241 
00242     {&AcpiGbl_XPm1aEnable,
00243         ACPI_FADT_OFFSET (XPm1aEventBlock),
00244         1},
00245 
00246     {&AcpiGbl_XPm1bStatus,
00247         ACPI_FADT_OFFSET (XPm1bEventBlock),
00248         0},
00249 
00250     {&AcpiGbl_XPm1bEnable,
00251         ACPI_FADT_OFFSET (XPm1bEventBlock),
00252         1}
00253 };
00254 
00255 #define ACPI_FADT_PM_INFO_ENTRIES \
00256             (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO))
00257 
00258 
00259 /*******************************************************************************
00260  *
00261  * FUNCTION:    AcpiTbInitGenericAddress
00262  *
00263  * PARAMETERS:  GenericAddress      - GAS struct to be initialized
00264  *              SpaceId             - ACPI Space ID for this register
00265  *              ByteWidth           - Width of this register, in bytes
00266  *              Address             - Address of the register
00267  *
00268  * RETURN:      None
00269  *
00270  * DESCRIPTION: Initialize a Generic Address Structure (GAS)
00271  *              See the ACPI specification for a full description and
00272  *              definition of this structure.
00273  *
00274  ******************************************************************************/
00275 
00276 static ACPI_INLINE void
00277 AcpiTbInitGenericAddress (
00278     ACPI_GENERIC_ADDRESS    *GenericAddress,
00279     UINT8                   SpaceId,
00280     UINT8                   ByteWidth,
00281     UINT64                  Address)
00282 {
00283 
00284     /*
00285      * The 64-bit Address field is non-aligned in the byte packed
00286      * GAS struct.
00287      */
00288     ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address);
00289 
00290     /* All other fields are byte-wide */
00291 
00292     GenericAddress->SpaceId = SpaceId;
00293     GenericAddress->BitWidth = (UINT8) ACPI_MUL_8 (ByteWidth);
00294     GenericAddress->BitOffset = 0;
00295     GenericAddress->AccessWidth = 0; /* Access width ANY */
00296 }
00297 
00298 
00299 /*******************************************************************************
00300  *
00301  * FUNCTION:    AcpiTbParseFadt
00302  *
00303  * PARAMETERS:  TableIndex          - Index for the FADT
00304  *
00305  * RETURN:      None
00306  *
00307  * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
00308  *              (FADT contains the addresses of the DSDT and FACS)
00309  *
00310  ******************************************************************************/
00311 
00312 void
00313 AcpiTbParseFadt (
00314     UINT32                  TableIndex)
00315 {
00316     UINT32                  Length;
00317     ACPI_TABLE_HEADER       *Table;
00318 
00319 
00320     /*
00321      * The FADT has multiple versions with different lengths,
00322      * and it contains pointers to both the DSDT and FACS tables.
00323      *
00324      * Get a local copy of the FADT and convert it to a common format
00325      * Map entire FADT, assumed to be smaller than one page.
00326      */
00327     Length = AcpiGbl_RootTableList.Tables[TableIndex].Length;
00328 
00329     Table = AcpiOsMapMemory (
00330                 AcpiGbl_RootTableList.Tables[TableIndex].Address, Length);
00331     if (!Table)
00332     {
00333         return;
00334     }
00335 
00336     /*
00337      * Validate the FADT checksum before we copy the table. Ignore
00338      * checksum error as we want to try to get the DSDT and FACS.
00339      */
00340     (void) AcpiTbVerifyChecksum (Table, Length);
00341 
00342     /* Create a local copy of the FADT in common ACPI 2.0+ format */
00343 
00344     AcpiTbCreateLocalFadt (Table, Length);
00345 
00346     /* All done with the real FADT, unmap it */
00347 
00348     AcpiOsUnmapMemory (Table, Length);
00349 
00350     /* Obtain the DSDT and FACS tables via their addresses within the FADT */
00351 
00352     AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt,
00353         ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
00354 
00355     AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,
00356         ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
00357 }
00358 
00359 
00360 /*******************************************************************************
00361  *
00362  * FUNCTION:    AcpiTbCreateLocalFadt
00363  *
00364  * PARAMETERS:  Table               - Pointer to BIOS FADT
00365  *              Length              - Length of the table
00366  *
00367  * RETURN:      None
00368  *
00369  * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
00370  *              Performs validation on some important FADT fields.
00371  *
00372  * NOTE:        We create a local copy of the FADT regardless of the version.
00373  *
00374  ******************************************************************************/
00375 
00376 void
00377 AcpiTbCreateLocalFadt (
00378     ACPI_TABLE_HEADER       *Table,
00379     UINT32                  Length)
00380 {
00381 
00382     /*
00383      * Check if the FADT is larger than the largest table that we expect
00384      * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue
00385      * a warning.
00386      */
00387     if (Length > sizeof (ACPI_TABLE_FADT))
00388     {
00389         ACPI_WARNING ((AE_INFO,
00390             "FADT (revision %u) is longer than ACPI 2.0 version, "
00391             "truncating length %u to %u",
00392             Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT)));
00393     }
00394 
00395     /* Clear the entire local FADT */
00396 
00397     ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));
00398 
00399     /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */
00400 
00401     ACPI_MEMCPY (&AcpiGbl_FADT, Table,
00402         ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT)));
00403 
00404     /* Convert the local copy of the FADT to the common internal format */
00405 
00406     AcpiTbConvertFadt ();
00407 
00408     /* Validate FADT values now, before we make any changes */
00409 
00410     AcpiTbValidateFadt ();
00411 
00412     /* Initialize the global ACPI register structures */
00413 
00414     AcpiTbSetupFadtRegisters ();
00415 }
00416 
00417 
00418 /*******************************************************************************
00419  *
00420  * FUNCTION:    AcpiTbConvertFadt
00421  *
00422  * PARAMETERS:  None, uses AcpiGbl_FADT
00423  *
00424  * RETURN:      None
00425  *
00426  * DESCRIPTION: Converts all versions of the FADT to a common internal format.
00427  *              Expand 32-bit addresses to 64-bit as necessary.
00428  *
00429  * NOTE:        AcpiGbl_FADT must be of size (ACPI_TABLE_FADT),
00430  *              and must contain a copy of the actual FADT.
00431  *
00432  * Notes on 64-bit register addresses:
00433  *
00434  * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
00435  * fields of the FADT for all ACPI register addresses.
00436  *
00437  * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
00438  * V1.0 fields. Even if they are present in the FADT, they are optional and
00439  * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
00440  * 32-bit V1.0 fields if the corresponding X field is zero.
00441  *
00442  * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
00443  * corresponding "X" fields in the internal FADT.
00444  *
00445  * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
00446  * to the corresponding 64-bit X fields. For compatibility with other ACPI
00447  * implementations, we ignore the 64-bit field if the 32-bit field is valid,
00448  * regardless of whether the host OS is 32-bit or 64-bit.
00449  *
00450  ******************************************************************************/
00451 
00452 static void
00453 AcpiTbConvertFadt (
00454     void)
00455 {
00456     ACPI_GENERIC_ADDRESS    *Address64;
00457     UINT32                  Address32;
00458     UINT32                  i;
00459 
00460 
00461     /* Update the local FADT table header length */
00462 
00463     AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);
00464 
00465     /*
00466      * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
00467      * Later code will always use the X 64-bit field.
00468      */
00469     if (!AcpiGbl_FADT.XFacs)
00470     {
00471         AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
00472     }
00473     if (!AcpiGbl_FADT.XDsdt)
00474     {
00475         AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
00476     }
00477 
00478     /*
00479      * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
00480      * should be zero are indeed zero. This will workaround BIOSs that
00481      * inadvertently place values in these fields.
00482      *
00483      * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
00484      * at offset 45, 55, 95, and the word located at offset 109, 110.
00485      *
00486      * Note: The FADT revision value is unreliable. Only the length can be
00487      * trusted.
00488      */
00489     if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)
00490     {
00491         AcpiGbl_FADT.PreferredProfile = 0;
00492         AcpiGbl_FADT.PstateControl = 0;
00493         AcpiGbl_FADT.CstControl = 0;
00494         AcpiGbl_FADT.BootFlags = 0;
00495     }
00496 
00497     /*
00498      * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
00499      * generic address structures as necessary. Later code will always use
00500      * the 64-bit address structures.
00501      *
00502      * March 2009:
00503      * We now always use the 32-bit address if it is valid (non-null). This
00504      * is not in accordance with the ACPI specification which states that
00505      * the 64-bit address supersedes the 32-bit version, but we do this for
00506      * compatibility with other ACPI implementations. Most notably, in the
00507      * case where both the 32 and 64 versions are non-null, we use the 32-bit
00508      * version. This is the only address that is guaranteed to have been
00509      * tested by the BIOS manufacturer.
00510      */
00511     for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
00512     {
00513         Address32 = *ACPI_ADD_PTR (UINT32,
00514             &AcpiGbl_FADT, FadtInfoTable[i].Address32);
00515 
00516         Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
00517             &AcpiGbl_FADT, FadtInfoTable[i].Address64);
00518 
00519         /*
00520          * If both 32- and 64-bit addresses are valid (non-zero),
00521          * they must match.
00522          */
00523         if (Address64->Address && Address32 &&
00524            (Address64->Address != (UINT64) Address32))
00525         {
00526             ACPI_ERROR ((AE_INFO,
00527                 "32/64X address mismatch in %s: 0x%8.8X/0x%8.8X%8.8X, using 32",
00528                 FadtInfoTable[i].Name, Address32,
00529                 ACPI_FORMAT_UINT64 (Address64->Address)));
00530         }
00531 
00532         /* Always use 32-bit address if it is valid (non-null) */
00533 
00534         if (Address32)
00535         {
00536             /*
00537              * Copy the 32-bit address to the 64-bit GAS structure. The
00538              * Space ID is always I/O for 32-bit legacy address fields
00539              */
00540             AcpiTbInitGenericAddress (Address64, ACPI_ADR_SPACE_SYSTEM_IO,
00541                 *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length),
00542                 (UINT64) Address32);
00543         }
00544     }
00545 }
00546 
00547 
00548 /*******************************************************************************
00549  *
00550  * FUNCTION:    AcpiTbValidateFadt
00551  *
00552  * PARAMETERS:  Table           - Pointer to the FADT to be validated
00553  *
00554  * RETURN:      None
00555  *
00556  * DESCRIPTION: Validate various important fields within the FADT. If a problem
00557  *              is found, issue a message, but no status is returned.
00558  *              Used by both the table manager and the disassembler.
00559  *
00560  * Possible additional checks:
00561  * (AcpiGbl_FADT.Pm1EventLength >= 4)
00562  * (AcpiGbl_FADT.Pm1ControlLength >= 2)
00563  * (AcpiGbl_FADT.PmTimerLength >= 4)
00564  * Gpe block lengths must be multiple of 2
00565  *
00566  ******************************************************************************/
00567 
00568 static void
00569 AcpiTbValidateFadt (
00570     void)
00571 {
00572     char                    *Name;
00573     ACPI_GENERIC_ADDRESS    *Address64;
00574     UINT8                   Length;
00575     UINT32                  i;
00576 
00577 
00578     /*
00579      * Check for FACS and DSDT address mismatches. An address mismatch between
00580      * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
00581      * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables.
00582      */
00583     if (AcpiGbl_FADT.Facs &&
00584         (AcpiGbl_FADT.XFacs != (UINT64) AcpiGbl_FADT.Facs))
00585     {
00586         ACPI_WARNING ((AE_INFO,
00587             "32/64X FACS address mismatch in FADT - "
00588             "0x%8.8X/0x%8.8X%8.8X, using 32",
00589             AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs)));
00590 
00591         AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
00592     }
00593 
00594     if (AcpiGbl_FADT.Dsdt &&
00595         (AcpiGbl_FADT.XDsdt != (UINT64) AcpiGbl_FADT.Dsdt))
00596     {
00597         ACPI_WARNING ((AE_INFO,
00598             "32/64X DSDT address mismatch in FADT - "
00599             "0x%8.8X/0x%8.8X%8.8X, using 32",
00600             AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt)));
00601 
00602         AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
00603     }
00604 
00605     /* Examine all of the 64-bit extended address fields (X fields) */
00606 
00607     for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
00608     {
00609         /*
00610          * Generate pointer to the 64-bit address, get the register
00611          * length (width) and the register name
00612          */
00613         Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
00614                         &AcpiGbl_FADT, FadtInfoTable[i].Address64);
00615         Length = *ACPI_ADD_PTR (UINT8,
00616                         &AcpiGbl_FADT, FadtInfoTable[i].Length);
00617         Name = FadtInfoTable[i].Name;
00618 
00619         /*
00620          * For each extended field, check for length mismatch between the
00621          * legacy length field and the corresponding 64-bit X length field.
00622          */
00623         if (Address64->Address &&
00624            (Address64->BitWidth != ACPI_MUL_8 (Length)))
00625         {
00626             ACPI_WARNING ((AE_INFO,
00627                 "32/64X length mismatch in %s: %u/%u",
00628                 Name, ACPI_MUL_8 (Length), Address64->BitWidth));
00629         }
00630 
00631         if (FadtInfoTable[i].Type & ACPI_FADT_REQUIRED)
00632         {
00633             /*
00634              * Field is required (PM1aEvent, PM1aControl, PmTimer).
00635              * Both the address and length must be non-zero.
00636              */
00637             if (!Address64->Address || !Length)
00638             {
00639                 ACPI_ERROR ((AE_INFO,
00640                     "Required field %s has zero address and/or length:"
00641                     " 0x%8.8X%8.8X/0x%X",
00642                     Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
00643             }
00644         }
00645         else if (FadtInfoTable[i].Type & ACPI_FADT_SEPARATE_LENGTH)
00646         {
00647             /*
00648              * Field is optional (PM2Control, GPE0, GPE1) AND has its own
00649              * length field. If present, both the address and length must
00650              * be valid.
00651              */
00652             if ((Address64->Address && !Length) ||
00653                 (!Address64->Address && Length))
00654             {
00655                 ACPI_WARNING ((AE_INFO,
00656                     "Optional field %s has zero address or length: "
00657                     "0x%8.8X%8.8X/0x%X",
00658                     Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
00659             }
00660         }
00661     }
00662 }
00663 
00664 
00665 /*******************************************************************************
00666  *
00667  * FUNCTION:    AcpiTbSetupFadtRegisters
00668  *
00669  * PARAMETERS:  None, uses AcpiGbl_FADT.
00670  *
00671  * RETURN:      None
00672  *
00673  * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
00674  *              force FADT register definitions to their default lengths.
00675  *
00676  ******************************************************************************/
00677 
00678 static void
00679 AcpiTbSetupFadtRegisters (
00680     void)
00681 {
00682     ACPI_GENERIC_ADDRESS    *Target64;
00683     ACPI_GENERIC_ADDRESS    *Source64;
00684     UINT8                   Pm1RegisterByteWidth;
00685     UINT32                  i;
00686 
00687 
00688     /*
00689      * Optionally check all register lengths against the default values and
00690      * update them if they are incorrect.
00691      */
00692     if (AcpiGbl_UseDefaultRegisterWidths)
00693     {
00694         for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
00695         {
00696             Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
00697                 FadtInfoTable[i].Address64);
00698 
00699             /*
00700              * If a valid register (Address != 0) and the (DefaultLength > 0)
00701              * (Not a GPE register), then check the width against the default.
00702              */
00703             if ((Target64->Address) &&
00704                 (FadtInfoTable[i].DefaultLength > 0) &&
00705                 (FadtInfoTable[i].DefaultLength != Target64->BitWidth))
00706             {
00707                 ACPI_WARNING ((AE_INFO,
00708                     "Invalid length for %s: %u, using default %u",
00709                     FadtInfoTable[i].Name, Target64->BitWidth,
00710                     FadtInfoTable[i].DefaultLength));
00711 
00712                 /* Incorrect size, set width to the default */
00713 
00714                 Target64->BitWidth = FadtInfoTable[i].DefaultLength;
00715             }
00716         }
00717     }
00718 
00719     /*
00720      * Get the length of the individual PM1 registers (enable and status).
00721      * Each register is defined to be (event block length / 2). Extra divide
00722      * by 8 converts bits to bytes.
00723      */
00724     Pm1RegisterByteWidth = (UINT8)
00725         ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth);
00726 
00727     /*
00728      * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
00729      * registers. These addresses do not appear (directly) in the FADT, so it
00730      * is useful to pre-calculate them from the PM1 Event Block definitions.
00731      *
00732      * The PM event blocks are split into two register blocks, first is the
00733      * PM Status Register block, followed immediately by the PM Enable
00734      * Register block. Each is of length (Pm1EventLength/2)
00735      *
00736      * Note: The PM1A event block is required by the ACPI specification.
00737      * However, the PM1B event block is optional and is rarely, if ever,
00738      * used.
00739      */
00740 
00741     for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++)
00742     {
00743         Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
00744             FadtPmInfoTable[i].Source);
00745 
00746         if (Source64->Address)
00747         {
00748             AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target,
00749                 Source64->SpaceId, Pm1RegisterByteWidth,
00750                 Source64->Address +
00751                     (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth));
00752         }
00753     }
00754 }
00755 

Generated on Sat May 26 2012 04:25:56 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.