Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentbfadt.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
1.7.6.1
|