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