ReactOS Fundraising Campaign 2012
 
€ 4,060 / € 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

halacpi.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS HAL
00003  * LICENSE:         BSD - See COPYING.ARM in the top level directory
00004  * FILE:            hal/halx86/generic/acpi/halacpi.c
00005  * PURPOSE:         HAL ACPI Code
00006  * PROGRAMMERS:     ReactOS Portable Systems Group
00007  */
00008 
00009 /* INCLUDES *******************************************************************/
00010 
00011 #include <hal.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* GLOBALS ********************************************************************/
00016 
00017 LIST_ENTRY HalpAcpiTableCacheList;
00018 FAST_MUTEX HalpAcpiTableCacheLock;
00019 
00020 BOOLEAN HalpProcessedACPIPhase0;
00021 BOOLEAN HalpPhysicalMemoryMayAppearAbove4GB;
00022 
00023 FADT HalpFixedAcpiDescTable;
00024 PDEBUG_PORT_TABLE HalpDebugPortTable;
00025 PACPI_SRAT HalpAcpiSrat;
00026 PBOOT_TABLE HalpSimpleBootFlagTable;
00027 
00028 PHYSICAL_ADDRESS HalpMaxHotPlugMemoryAddress;
00029 PHYSICAL_ADDRESS HalpLowStubPhysicalAddress;
00030 PHARDWARE_PTE HalpPteForFlush;
00031 PVOID HalpVirtAddrForFlush;
00032 PVOID HalpLowStub;
00033 
00034 PACPI_BIOS_MULTI_NODE HalpAcpiMultiNode;
00035 
00036 LIST_ENTRY HalpAcpiTableMatchList;
00037 
00038 ULONG HalpInvalidAcpiTable;
00039 
00040 ULONG HalpPicVectorRedirect[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15};
00041 
00042 /* This determines the HAL type */
00043 BOOLEAN HalDisableFirmwareMapper = TRUE;
00044 PWCHAR HalHardwareIdString = L"acpipic_up";
00045 PWCHAR HalName = L"ACPI Compatible Eisa/Isa HAL";
00046 
00047 /* PRIVATE FUNCTIONS **********************************************************/
00048 
00049 PDESCRIPTION_HEADER
00050 NTAPI
00051 HalpAcpiGetCachedTable(IN ULONG Signature)
00052 {
00053     PLIST_ENTRY ListHead, NextEntry;
00054     PACPI_CACHED_TABLE CachedTable;
00055 
00056     /* Loop cached tables */
00057     ListHead = &HalpAcpiTableCacheList;
00058     NextEntry = ListHead->Flink;
00059     while (NextEntry != ListHead)
00060     {
00061         /* Get the table */
00062         CachedTable = CONTAINING_RECORD(NextEntry, ACPI_CACHED_TABLE, Links);
00063 
00064         /* Compare signatures */
00065         if (CachedTable->Header.Signature == Signature) return &CachedTable->Header;
00066 
00067         /* Keep going */
00068         NextEntry = NextEntry->Flink;
00069     }
00070 
00071     /* Nothing found */
00072     return NULL;
00073 }
00074 
00075 VOID
00076 NTAPI
00077 HalpAcpiCacheTable(IN PDESCRIPTION_HEADER TableHeader)
00078 {
00079     PACPI_CACHED_TABLE CachedTable;
00080 
00081     /* Get the cached table and link it */
00082     CachedTable = CONTAINING_RECORD(TableHeader, ACPI_CACHED_TABLE, Header);
00083     InsertTailList(&HalpAcpiTableCacheList, &CachedTable->Links);
00084 }
00085 
00086 PVOID
00087 NTAPI
00088 HalpAcpiCopyBiosTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
00089                       IN PDESCRIPTION_HEADER TableHeader)
00090 {
00091     ULONG Size;
00092     PFN_COUNT PageCount;
00093     PHYSICAL_ADDRESS PhysAddress;
00094     PACPI_CACHED_TABLE CachedTable;
00095     PDESCRIPTION_HEADER CopiedTable;
00096 
00097     /* Size we'll need for the cached table */
00098     Size = TableHeader->Length + FIELD_OFFSET(ACPI_CACHED_TABLE, Header);
00099     if (LoaderBlock)
00100     {
00101         /* Phase 0: Convert to pages and use the HAL heap */
00102         PageCount = BYTES_TO_PAGES(Size);
00103         PhysAddress.QuadPart = HalpAllocPhysicalMemory(LoaderBlock,
00104                                                        0x1000000,
00105                                                        PageCount,
00106                                                        FALSE);
00107         if (PhysAddress.QuadPart)
00108         {
00109             /* Map it */
00110             CachedTable = HalpMapPhysicalMemory64(PhysAddress, PageCount);
00111         }
00112         else
00113         {
00114             /* No memory, so nothing to map */
00115             CachedTable = NULL;
00116         }
00117     }
00118     else
00119     {
00120         /* Use Mm pool */
00121         CachedTable = ExAllocatePoolWithTag(NonPagedPool, Size, ' laH');
00122     }
00123 
00124     /* Do we have the cached table? */
00125     if (CachedTable)
00126     {
00127         /* Copy the data */
00128         CopiedTable = &CachedTable->Header;
00129         RtlCopyMemory(CopiedTable, TableHeader, TableHeader->Length);
00130     }
00131     else
00132     {
00133         /* Nothing to return */
00134         CopiedTable = NULL;
00135     }
00136 
00137     /* Return the table */
00138     return CopiedTable;
00139 }
00140 
00141 PVOID
00142 NTAPI
00143 HalpAcpiGetTableFromBios(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
00144                          IN ULONG Signature)
00145 {
00146     PHYSICAL_ADDRESS PhysicalAddress;
00147     PXSDT Xsdt;
00148     PRSDT Rsdt;
00149     PFADT Fadt;
00150     PDESCRIPTION_HEADER Header = NULL;
00151     ULONG TableLength;
00152     CHAR CheckSum = 0;
00153     ULONG Offset;
00154     ULONG EntryCount, CurrentEntry;
00155     PCHAR CurrentByte;
00156     PFN_COUNT PageCount;
00157 
00158     /* Should not query the RSDT/XSDT by itself */
00159     if ((Signature == RSDT_SIGNATURE) || (Signature == XSDT_SIGNATURE)) return NULL;
00160 
00161     /* Special case request for DSDT, because the FADT points to it */
00162     if (Signature == DSDT_SIGNATURE)
00163     {
00164         /* Grab the FADT */
00165         Fadt = HalpAcpiGetTable(LoaderBlock, FADT_SIGNATURE);
00166         if (Fadt)
00167         {
00168             /* Grab the DSDT address and assume 2 pages */
00169             PhysicalAddress.HighPart = 0;
00170             PhysicalAddress.LowPart = Fadt->dsdt;
00171             TableLength = 2 * PAGE_SIZE;
00172 
00173             /* Map it */
00174             if (LoaderBlock)
00175             {
00176                 /* Phase 0, use HAL heap */
00177                 Header = HalpMapPhysicalMemory64(PhysicalAddress, 2u);
00178             }
00179             else
00180             {
00181                 /* Phase 1, use Mm */
00182                 Header = MmMapIoSpace(PhysicalAddress, 2 * PAGE_SIZE, 0);
00183             }
00184 
00185             /* Fail if we couldn't map it */
00186             if (!Header)
00187             {
00188                 DPRINT1("HAL: Failed to map ACPI table.\n");
00189                 return NULL;
00190             }
00191 
00192             /* Validate the signature */
00193             if (Header->Signature != DSDT_SIGNATURE)
00194             {
00195                 /* Fail and unmap */
00196                 if (LoaderBlock)
00197                 {
00198                     /* Using HAL heap */
00199                     HalpUnmapVirtualAddress(Header, 2);
00200                 }
00201                 else
00202                 {
00203                     /* Using Mm */
00204                     MmUnmapIoSpace(Header, 2 * PAGE_SIZE);
00205                 }
00206 
00207                 /* Didn't find anything */
00208                 return NULL;
00209             }
00210         }
00211         else
00212         {
00213             /* Couldn't find it */
00214             return NULL;
00215         }
00216     }
00217     else
00218     {
00219         /* To find tables, we need the RSDT */
00220         Rsdt = HalpAcpiGetTable(LoaderBlock, RSDT_SIGNATURE);
00221         if (Rsdt)
00222         {
00223             /* Won't be using the XSDT */
00224             Xsdt = NULL;
00225         }
00226         else
00227         {
00228             /* Only other choice is to use the XSDT */
00229             Xsdt = HalpAcpiGetTable(LoaderBlock, XSDT_SIGNATURE);
00230             if (!Xsdt) return NULL;
00231 
00232             /* Won't be using the RSDT */
00233             Rsdt = NULL;
00234         }
00235 
00236         /* Smallest RSDT/XSDT is one without table entries */
00237         Offset = FIELD_OFFSET(RSDT, Tables);
00238         if (Xsdt)
00239         {
00240             /* Figure out total size of table and the offset */
00241             TableLength = Xsdt->Header.Length;
00242             if (TableLength < Offset) Offset = Xsdt->Header.Length;
00243 
00244             /* The entries are each 64-bits, so count them */
00245             EntryCount = (TableLength - Offset) / sizeof(PHYSICAL_ADDRESS);
00246         }
00247         else
00248         {
00249             /* Figure out total size of table and the offset */
00250             TableLength = Rsdt->Header.Length;
00251             if (TableLength < Offset) Offset = Rsdt->Header.Length;
00252 
00253             /* The entries are each 32-bits, so count them */
00254             EntryCount = (TableLength - Offset) / sizeof(ULONG);
00255         }
00256 
00257         /* Start at the beginning of the array and loop it */
00258         for (CurrentEntry = 0; CurrentEntry < EntryCount; CurrentEntry++)
00259         {
00260             /* Are we using the XSDT? */
00261             if (!Xsdt)
00262             {
00263                 /* Read the 32-bit physical address */
00264                 PhysicalAddress.LowPart = Rsdt->Tables[CurrentEntry];
00265                 PhysicalAddress.HighPart = 0;
00266             }
00267             else
00268             {
00269                 /* Read the 64-bit physical address */
00270                 PhysicalAddress = Xsdt->Tables[CurrentEntry];
00271             }
00272 
00273             /* Had we already mapped a table? */
00274             if (Header)
00275             {
00276                 /* Yes, unmap it */
00277                 if (LoaderBlock)
00278                 {
00279                     /* Using HAL heap */
00280                     HalpUnmapVirtualAddress(Header, 2);
00281                 }
00282                 else
00283                 {
00284                     /* Using Mm */
00285                     MmUnmapIoSpace(Header, 2 * PAGE_SIZE);
00286                 }
00287             }
00288 
00289             /* Now map this table */
00290             if (!LoaderBlock)
00291             {
00292                 /* Phase 1: Use HAL heap */
00293                 Header = MmMapIoSpace(PhysicalAddress, 2 * PAGE_SIZE, MmNonCached);
00294             }
00295             else
00296             {
00297                 /* Phase 0: Use Mm */
00298                 Header = HalpMapPhysicalMemory64(PhysicalAddress, 2);
00299             }
00300 
00301             /* Check if we mapped it */
00302             if (!Header)
00303             {
00304                 /* Game over */
00305                 DPRINT1("HAL: Failed to map ACPI table.\n");
00306                 return NULL;
00307             }
00308 
00309             /* We found it, break out */
00310             DPRINT("Found ACPI table %c%c%c%c at 0x%p\n",
00311                     Header->Signature & 0xFF,
00312                     (Header->Signature & 0xFF00) >> 8,
00313                     (Header->Signature & 0xFF0000) >> 16,
00314                     (Header->Signature & 0xFF000000) >> 24,
00315                     Header);
00316             if (Header->Signature == Signature) break;
00317         }
00318 
00319         /* Did we end up here back at the last entry? */
00320         if (CurrentEntry == EntryCount)
00321         {
00322             /* Yes, unmap the last table we processed */
00323             if (LoaderBlock)
00324             {
00325                 /* Using HAL heap */
00326                 HalpUnmapVirtualAddress(Header, 2);
00327             }
00328             else
00329             {
00330                 /* Using Mm */
00331                 MmUnmapIoSpace(Header, 2 * PAGE_SIZE);
00332             }
00333 
00334             /* Didn't find anything */
00335             return NULL;
00336         }
00337     }
00338 
00339     /* Past this point, we assume something was found */
00340     ASSERT(Header);
00341 
00342     /* How many pages do we need? */
00343     PageCount = BYTES_TO_PAGES(Header->Length);
00344     if (PageCount != 2)
00345     {
00346         /* We assumed two, but this is not the case, free the current mapping */
00347         if (LoaderBlock)
00348         {
00349             /* Using HAL heap */
00350             HalpUnmapVirtualAddress(Header, 2);
00351         }
00352         else
00353         {
00354             /* Using Mm */
00355             MmUnmapIoSpace(Header, 2 * PAGE_SIZE);
00356         }
00357 
00358         /* Now map this table using its correct size */
00359         if (!LoaderBlock)
00360         {
00361             /* Phase 1: Use HAL heap */
00362             Header = MmMapIoSpace(PhysicalAddress, PageCount << PAGE_SHIFT, MmNonCached);
00363         }
00364         else
00365         {
00366             /* Phase 0: Use Mm */
00367             Header = HalpMapPhysicalMemory64(PhysicalAddress, PageCount);
00368         }
00369     }
00370 
00371     /* Fail if the remapped failed */
00372     if (!Header) return NULL;
00373 
00374     /* All tables in ACPI 3.0 other than the FACP should have correct checksum */
00375     if ((Header->Signature != FADT_SIGNATURE) || (Header->Revision > 2))
00376     {
00377         /* Go to the end of the table */
00378         CheckSum = 0;
00379         CurrentByte = (PCHAR)Header + Header->Length;
00380         while (CurrentByte-- != (PCHAR)Header)
00381         {
00382             /* Add this byte */
00383             CheckSum += *CurrentByte;
00384         }
00385 
00386         /* The correct checksum is always 0, anything else is illegal */
00387         if (CheckSum)
00388         {
00389             HalpInvalidAcpiTable = Header->Signature;
00390             DPRINT1("Checksum failed on ACPI table %c%c%c%c\n",
00391                     (Signature & 0xFF),
00392                     (Signature & 0xFF00) >> 8,
00393                     (Signature & 0xFF0000) >> 16,
00394                     (Signature & 0xFF000000) >> 24);
00395         }
00396     }
00397 
00398     /* Return the table */
00399     return Header;
00400 }
00401 
00402 PVOID
00403 NTAPI
00404 HalpAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
00405                  IN ULONG Signature)
00406 {
00407     PFN_COUNT PageCount;
00408     PDESCRIPTION_HEADER TableAddress, BiosCopy;
00409 
00410     /* See if we have a cached table? */
00411     TableAddress = HalpAcpiGetCachedTable(Signature);
00412     if (!TableAddress)
00413     {
00414         /* No cache, search the BIOS */
00415         TableAddress = HalpAcpiGetTableFromBios(LoaderBlock, Signature);
00416         if (TableAddress)
00417         {
00418             /* Found it, copy it into our own memory */
00419             BiosCopy = HalpAcpiCopyBiosTable(LoaderBlock, TableAddress);
00420 
00421             /* Get the pages, and unmap the BIOS copy */
00422             PageCount = BYTES_TO_PAGES(TableAddress->Length);
00423             if (LoaderBlock)
00424             {
00425                 /* Phase 0, use the HAL heap */
00426                 HalpUnmapVirtualAddress(TableAddress, PageCount);
00427             }
00428             else
00429             {
00430                 /* Phase 1, use Mm */
00431                 MmUnmapIoSpace(TableAddress, PageCount << PAGE_SHIFT);
00432             }
00433 
00434             /* Cache the bios copy */
00435             TableAddress = BiosCopy;
00436             if (BiosCopy) HalpAcpiCacheTable(BiosCopy);
00437         }
00438     }
00439 
00440     /* Return the table */
00441     return TableAddress;
00442 }
00443 
00444 PVOID
00445 NTAPI
00446 HalAcpiGetTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
00447                 IN ULONG Signature)
00448 {
00449     PDESCRIPTION_HEADER TableHeader;
00450 
00451     /* Is this phase0 */
00452     if (LoaderBlock)
00453     {
00454         /* Initialize the cache first */
00455         if (!NT_SUCCESS(HalpAcpiTableCacheInit(LoaderBlock))) return NULL;
00456     }
00457     else
00458     {
00459         /* Lock the cache */
00460         ExAcquireFastMutex(&HalpAcpiTableCacheLock);
00461     }
00462 
00463     /* Get the table */
00464     TableHeader = HalpAcpiGetTable(LoaderBlock, Signature);
00465 
00466     /* Release the lock in phase 1 */
00467     if (!LoaderBlock) ExReleaseFastMutex(&HalpAcpiTableCacheLock);
00468 
00469     /* Return the table */
00470     return TableHeader;
00471 }
00472 
00473 VOID
00474 NTAPI
00475 HalpNumaInitializeStaticConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
00476 {
00477     PACPI_SRAT SratTable;
00478 
00479     /* Get the SRAT, bail out if it doesn't exist */
00480     SratTable = HalAcpiGetTable(LoaderBlock, SRAT_SIGNATURE);
00481     HalpAcpiSrat = SratTable;
00482     if (!SratTable) return;
00483 }
00484 
00485 VOID
00486 NTAPI
00487 HalpGetHotPlugMemoryInfo(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
00488 {
00489     PACPI_SRAT SratTable;
00490 
00491     /* Get the SRAT, bail out if it doesn't exist */
00492     SratTable = HalAcpiGetTable(LoaderBlock, SRAT_SIGNATURE);
00493     HalpAcpiSrat = SratTable;
00494     if (!SratTable) return;
00495 }
00496 
00497 VOID
00498 NTAPI
00499 HalpDynamicSystemResourceConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
00500 {
00501     /* For this HAL, it means to get hot plug memory information */
00502     HalpGetHotPlugMemoryInfo(LoaderBlock);
00503 }
00504 
00505 VOID
00506 NTAPI
00507 HalpAcpiDetectMachineSpecificActions(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
00508                                      IN PFADT DescriptionTable)
00509 {
00510     /* Does this HAL specify something? */
00511     if (HalpAcpiTableMatchList.Flink)
00512     {
00513         /* Great, but we don't support it */
00514         DPRINT1("WARNING: Your HAL has specific ACPI hacks to apply!\n");
00515     }
00516 }
00517 
00518 VOID
00519 NTAPI
00520 HalpInitBootTable(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
00521 {
00522     PBOOT_TABLE BootTable;
00523 
00524     /* Get the boot table */
00525     BootTable = HalAcpiGetTable(LoaderBlock, BOOT_SIGNATURE);
00526     HalpSimpleBootFlagTable = BootTable;
00527 
00528     /* Validate it */
00529     if ((BootTable) &&
00530         (BootTable->Header.Length >= sizeof(BOOT_TABLE)) &&
00531         (BootTable->CMOSIndex >= 9))
00532     {
00533         DPRINT1("ACPI Boot table found, but not supported!\n");
00534     }
00535     else
00536     {
00537         /* Invalid or doesn't exist, ignore it */
00538         HalpSimpleBootFlagTable = 0;
00539     }
00540 
00541     /* Install the end of boot handler */
00542 //    HalEndOfBoot = HalpEndOfBoot;
00543 }
00544 
00545 NTSTATUS
00546 NTAPI
00547 HalpAcpiFindRsdtPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
00548                        OUT PACPI_BIOS_MULTI_NODE* AcpiMultiNode)
00549 {
00550     PCONFIGURATION_COMPONENT_DATA ComponentEntry;
00551     PCONFIGURATION_COMPONENT_DATA Next = NULL;
00552     PCM_PARTIAL_RESOURCE_LIST ResourceList;
00553     PACPI_BIOS_MULTI_NODE NodeData;
00554     SIZE_T NodeLength;
00555     PFN_COUNT PageCount;
00556     PVOID MappedAddress;
00557     PHYSICAL_ADDRESS PhysicalAddress;
00558 
00559     /* Did we already do this once? */
00560     if (HalpAcpiMultiNode)
00561     {
00562         /* Return what we know */
00563         *AcpiMultiNode = HalpAcpiMultiNode;
00564         return STATUS_SUCCESS;
00565     }
00566 
00567     /* Assume failure */
00568     *AcpiMultiNode = NULL;
00569 
00570     /* Find the multi function adapter key */
00571     ComponentEntry = KeFindConfigurationNextEntry(LoaderBlock->ConfigurationRoot,
00572                                                   AdapterClass,
00573                                                   MultiFunctionAdapter,
00574                                                   0,
00575                                                   &Next);
00576     while (ComponentEntry)
00577     {
00578         /* Find the ACPI BIOS key */
00579         if (!_stricmp(ComponentEntry->ComponentEntry.Identifier, "ACPI BIOS"))
00580         {
00581             /* Found it */
00582             break;
00583         }
00584 
00585         /* Keep searching */
00586         Next = ComponentEntry;
00587         ComponentEntry = KeFindConfigurationNextEntry(LoaderBlock->ConfigurationRoot,
00588                                                       AdapterClass,
00589                                                       MultiFunctionAdapter,
00590                                                       NULL,
00591                                                       &Next);
00592     }
00593 
00594     /* Make sure we found it */
00595     if (!ComponentEntry)
00596     {
00597         DPRINT1("**** HalpAcpiFindRsdtPhase0: did NOT find RSDT\n");
00598         return STATUS_NOT_FOUND;
00599     }
00600 
00601     /* The configuration data is a resource list, and the BIOS node follows */
00602     ResourceList = ComponentEntry->ConfigurationData;
00603     NodeData = (PACPI_BIOS_MULTI_NODE)(ResourceList + 1);
00604 
00605     /* How many E820 memory entries are there? */
00606     NodeLength = sizeof(ACPI_BIOS_MULTI_NODE) +
00607                  (NodeData->Count - 1) * sizeof(ACPI_E820_ENTRY);
00608 
00609     /* Convert to pages */
00610     PageCount = (PFN_COUNT)BYTES_TO_PAGES(NodeLength);
00611 
00612     /* Allocate the memory */
00613     PhysicalAddress.QuadPart = HalpAllocPhysicalMemory(LoaderBlock,
00614                                                        0x1000000,
00615                                                        PageCount,
00616                                                        FALSE);
00617     if (PhysicalAddress.QuadPart)
00618     {
00619         /* Map it if the allocation worked */
00620         MappedAddress = HalpMapPhysicalMemory64(PhysicalAddress, PageCount);
00621     }
00622     else
00623     {
00624         /* Otherwise we'll have to fail */
00625         MappedAddress = NULL;
00626     }
00627 
00628     /* Save the multi node, bail out if we didn't find it */
00629     HalpAcpiMultiNode = MappedAddress;
00630     if (!MappedAddress) return STATUS_INSUFFICIENT_RESOURCES;
00631 
00632     /* Copy the multi-node data */
00633     RtlCopyMemory(MappedAddress, NodeData, NodeLength);
00634 
00635     /* Return the data */
00636     *AcpiMultiNode = HalpAcpiMultiNode;
00637     return STATUS_SUCCESS;
00638 }
00639 
00640 NTSTATUS
00641 NTAPI
00642 HalpAcpiTableCacheInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
00643 {
00644     PACPI_BIOS_MULTI_NODE AcpiMultiNode;
00645     NTSTATUS Status = STATUS_SUCCESS;
00646     PHYSICAL_ADDRESS PhysicalAddress;
00647     PVOID MappedAddress;
00648     ULONG TableLength;
00649     PRSDT Rsdt;
00650     PLOADER_PARAMETER_EXTENSION LoaderExtension;
00651 
00652     /* Only initialize once */
00653     if (HalpAcpiTableCacheList.Flink) return Status;
00654 
00655     /* Setup the lock and table */
00656     ExInitializeFastMutex(&HalpAcpiTableCacheLock);
00657     InitializeListHead(&HalpAcpiTableCacheList);
00658 
00659     /* Find the RSDT */
00660     Status = HalpAcpiFindRsdtPhase0(LoaderBlock, &AcpiMultiNode);
00661     if (!NT_SUCCESS(Status)) return Status;
00662 
00663     PhysicalAddress.QuadPart = AcpiMultiNode->RsdtAddress.QuadPart;
00664 
00665     /* Map the RSDT */
00666     if (LoaderBlock)
00667     {
00668         /* Phase0: Use HAL Heap to map the RSDT, we assume it's about 2 pages */
00669         MappedAddress = HalpMapPhysicalMemory64(PhysicalAddress, 2);
00670     }
00671     else
00672     {
00673         /* Use an I/O map */
00674         MappedAddress = MmMapIoSpace(PhysicalAddress, PAGE_SIZE * 2, MmNonCached);
00675     }
00676 
00677     /* Get the RSDT */
00678     Rsdt = MappedAddress;
00679     if (!MappedAddress)
00680     {
00681         /* Fail, no memory */
00682         DPRINT1("HAL: Failed to map RSDT\n");
00683         return STATUS_INSUFFICIENT_RESOURCES;
00684     }
00685 
00686     /* Validate it */
00687     if ((Rsdt->Header.Signature != RSDT_SIGNATURE) &&
00688         (Rsdt->Header.Signature != XSDT_SIGNATURE))
00689     {
00690         /* Very bad: crash */
00691         HalDisplayString("Bad RSDT pointer\n");
00692         KeBugCheckEx(MISMATCHED_HAL, 4, __LINE__, 0, 0);
00693     }
00694 
00695     /* We assumed two pages -- do we need less or more? */
00696     TableLength = ADDRESS_AND_SIZE_TO_SPAN_PAGES(PhysicalAddress.LowPart,
00697                                                  Rsdt->Header.Length);
00698     if (TableLength != 2)
00699     {
00700         /* Are we in phase 0 or 1? */
00701         if (!LoaderBlock)
00702         {
00703             /* Unmap the old table, remap the new one, using Mm I/O space */
00704             MmUnmapIoSpace(MappedAddress, 2 * PAGE_SIZE);
00705             MappedAddress = MmMapIoSpace(PhysicalAddress,
00706                                          TableLength << PAGE_SHIFT,
00707                                          MmNonCached);
00708         }
00709         else
00710         {
00711             /* Unmap the old table, remap the new one, using HAL heap */
00712             HalpUnmapVirtualAddress(MappedAddress, 2);
00713             MappedAddress = HalpMapPhysicalMemory64(PhysicalAddress, TableLength);
00714         }
00715 
00716         /* Get the remapped table */
00717         Rsdt = MappedAddress;
00718         if (!MappedAddress)
00719         {
00720             /* Fail, no memory */
00721             DPRINT1("HAL: Couldn't remap RSDT\n");
00722             return STATUS_INSUFFICIENT_RESOURCES;
00723         }
00724     }
00725 
00726     /* Now take the BIOS copy and make our own local copy */
00727     Rsdt = HalpAcpiCopyBiosTable(LoaderBlock, &Rsdt->Header);
00728     if (!Rsdt)
00729     {
00730         /* Fail, no memory */
00731         DPRINT1("HAL: Couldn't remap RSDT\n");
00732         return STATUS_INSUFFICIENT_RESOURCES;
00733     }
00734 
00735     /* Get rid of the BIOS mapping */
00736     if (LoaderBlock)
00737     {
00738         /* Use HAL heap */
00739         HalpUnmapVirtualAddress(MappedAddress, TableLength);
00740 
00741         LoaderExtension = LoaderBlock->Extension;
00742     }
00743     else
00744     {
00745         /* Use Mm */
00746         MmUnmapIoSpace(MappedAddress, TableLength << PAGE_SHIFT);
00747 
00748         LoaderExtension = NULL;
00749     }
00750 
00751     /* Cache the RSDT */
00752     HalpAcpiCacheTable(&Rsdt->Header);
00753 
00754     /* Check for compatible loader block extension */
00755     if (LoaderExtension && (LoaderExtension->Size >= 0x58))
00756     {
00757         /* Compatible loader: did it provide an ACPI table override? */
00758         if ((LoaderExtension->AcpiTable) && (LoaderExtension->AcpiTableSize))
00759         {
00760             /* Great, because we don't support it! */
00761             DPRINT1("ACPI Table Overrides Not Supported!\n");
00762         }
00763     }
00764 
00765     /* Done */
00766     return Status;
00767 }
00768 
00769 VOID
00770 NTAPI
00771 HaliAcpiTimerInit(IN ULONG TimerPort,
00772                   IN ULONG TimerValExt)
00773 {
00774     PAGED_CODE();
00775 
00776     /* Is this in the init phase? */
00777     if (!TimerPort)
00778     {
00779         /* Get the data from the FADT */
00780         TimerPort = HalpFixedAcpiDescTable.pm_tmr_blk_io_port;
00781         TimerValExt = HalpFixedAcpiDescTable.flags & ACPI_TMR_VAL_EXT;
00782         DPRINT1("ACPI Timer at: %Xh (EXT: %d)\n", TimerPort, TimerValExt);
00783     }
00784 
00785     /* FIXME: Now proceed to the timer initialization */
00786     //HalaAcpiTimerInit(TimerPort, TimerValExt);
00787 }
00788 
00789 NTSTATUS
00790 NTAPI
00791 HalpSetupAcpiPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
00792 {
00793     NTSTATUS Status;
00794     PFADT Fadt;
00795     ULONG TableLength;
00796     PHYSICAL_ADDRESS PhysicalAddress;
00797 
00798     /* Only do this once */
00799     if (HalpProcessedACPIPhase0) return STATUS_SUCCESS;
00800 
00801     /* Setup the ACPI table cache */
00802     Status = HalpAcpiTableCacheInit(LoaderBlock);
00803     if (!NT_SUCCESS(Status)) return Status;
00804 
00805     /* Grab the FADT */
00806     Fadt = HalAcpiGetTable(LoaderBlock, FADT_SIGNATURE);
00807     if (!Fadt)
00808     {
00809         /* Fail */
00810         DPRINT1("HAL: Didn't find the FACP\n");
00811         return STATUS_NOT_FOUND;
00812     }
00813 
00814     /* Assume typical size, otherwise whatever the descriptor table says */
00815     TableLength = sizeof(FADT);
00816     if (Fadt->Header.Length < sizeof(FADT)) TableLength = Fadt->Header.Length;
00817 
00818     /* Copy it in the HAL static buffer */
00819     RtlCopyMemory(&HalpFixedAcpiDescTable, Fadt, TableLength);
00820 
00821     /* Anything special this HAL needs to do? */
00822     HalpAcpiDetectMachineSpecificActions(LoaderBlock, &HalpFixedAcpiDescTable);
00823 
00824     /* Get the debug table for KD */
00825     HalpDebugPortTable = HalAcpiGetTable(LoaderBlock, DBGP_SIGNATURE);
00826 
00827     /* Initialize NUMA through the SRAT */
00828     HalpNumaInitializeStaticConfiguration(LoaderBlock);
00829 
00830     /* Initialize hotplug through the SRAT */
00831     HalpDynamicSystemResourceConfiguration(LoaderBlock);
00832     if (HalpAcpiSrat)
00833     {
00834         DPRINT1("Your machine has a SRAT, but NUMA/HotPlug are not supported!\n");
00835     }
00836 
00837     /* Can there be memory higher than 4GB? */
00838     if (HalpMaxHotPlugMemoryAddress.HighPart >= 1)
00839     {
00840         /* We'll need this for DMA later */
00841         HalpPhysicalMemoryMayAppearAbove4GB = TRUE;
00842     }
00843 
00844     /* Setup the ACPI timer */
00845     HaliAcpiTimerInit(0, 0);
00846 
00847     /* Do we have a low stub address yet? */
00848     if (!HalpLowStubPhysicalAddress.QuadPart)
00849     {
00850         /* Allocate it */
00851         HalpLowStubPhysicalAddress.QuadPart = HalpAllocPhysicalMemory(LoaderBlock,
00852                                                                       0x100000,
00853                                                                       1,
00854                                                                       FALSE);
00855         if (HalpLowStubPhysicalAddress.QuadPart)
00856         {
00857             /* Map it */
00858             HalpLowStub = HalpMapPhysicalMemory64(HalpLowStubPhysicalAddress, 1);
00859         }
00860     }
00861 
00862     /* Grab a page for flushes */
00863     PhysicalAddress.QuadPart = 0x100000;
00864     HalpVirtAddrForFlush = HalpMapPhysicalMemory64(PhysicalAddress, 1);
00865     HalpPteForFlush = HalAddressToPte(HalpVirtAddrForFlush);
00866 
00867     /* Don't do this again */
00868     HalpProcessedACPIPhase0 = TRUE;
00869 
00870     /* Setup the boot table */
00871     HalpInitBootTable(LoaderBlock);
00872 
00873     /* Debugging code */
00874     {
00875         PLIST_ENTRY ListHead, NextEntry;
00876         PACPI_CACHED_TABLE CachedTable;
00877 
00878         /* Loop cached tables */
00879         ListHead = &HalpAcpiTableCacheList;
00880         NextEntry = ListHead->Flink;
00881         while (NextEntry != ListHead)
00882         {
00883             /* Get the table */
00884             CachedTable = CONTAINING_RECORD(NextEntry, ACPI_CACHED_TABLE, Links);
00885 
00886             /* Compare signatures */
00887             if ((CachedTable->Header.Signature == RSDT_SIGNATURE) ||
00888                 (CachedTable->Header.Signature == XSDT_SIGNATURE))
00889             {
00890                 DPRINT1("ACPI %d.0 Detected. Tables: ", (CachedTable->Header.Revision + 1));
00891             }
00892 
00893             DbgPrint("[%c%c%c%c] ",
00894                     (CachedTable->Header.Signature & 0xFF),
00895                     (CachedTable->Header.Signature & 0xFF00) >> 8,
00896                     (CachedTable->Header.Signature & 0xFF0000) >> 16,
00897                     (CachedTable->Header.Signature & 0xFF000000) >> 24);
00898 
00899             /* Keep going */
00900             NextEntry = NextEntry->Flink;
00901         }
00902         DbgPrint("\n");
00903     }
00904 
00905     /* Return success */
00906     return STATUS_SUCCESS;
00907 }
00908 
00909 VOID
00910 NTAPI
00911 HalpInitializePciBus(VOID)
00912 {
00913     /* Setup the PCI stub support */
00914     HalpInitializePciStubs();
00915 
00916     /* Set the NMI crash flag */
00917     HalpGetNMICrashFlag();
00918 }
00919 
00920 VOID
00921 NTAPI
00922 HalpInitNonBusHandler(VOID)
00923 {
00924     /* These should be written by the PCI driver later, but we give defaults */
00925     HalPciTranslateBusAddress = HalpTranslateBusAddress;
00926     HalPciAssignSlotResources = HalpAssignSlotResources;
00927     HalFindBusAddressTranslation = HalpFindBusAddressTranslation;
00928 }
00929 
00930 VOID
00931 NTAPI
00932 HalpInitBusHandlers(VOID)
00933 {
00934     /* On ACPI, we only have a fake PCI bus to worry about */
00935     HalpInitNonBusHandler();
00936 }
00937 
00938 VOID
00939 NTAPI
00940 HalpBuildAddressMap(VOID)
00941 {
00942     /* ACPI is magic baby */
00943 }
00944 
00945 BOOLEAN
00946 NTAPI
00947 HalpGetDebugPortTable(VOID)
00948 {
00949     return ((HalpDebugPortTable) &&
00950             (HalpDebugPortTable->BaseAddress.AddressSpaceID == 1));
00951 }
00952 
00953 ULONG
00954 NTAPI
00955 HalpIs16BitPortDecodeSupported(VOID)
00956 {
00957     /* All ACPI systems are at least "EISA" so they support this */
00958     return CM_RESOURCE_PORT_16_BIT_DECODE;
00959 }
00960 
00961 VOID
00962 NTAPI
00963 HalpAcpiDetectResourceListSize(OUT PULONG ListSize)
00964 {
00965     PAGED_CODE();
00966 
00967     /* One element if there is a SCI */
00968     *ListSize = HalpFixedAcpiDescTable.sci_int_vector ? 1: 0;
00969 }
00970 
00971 NTSTATUS
00972 NTAPI
00973 HalpBuildAcpiResourceList(IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceList)
00974 {
00975     ULONG Interrupt;
00976     PAGED_CODE();
00977     ASSERT(ResourceList != NULL);
00978 
00979     /* Initialize the list */
00980     ResourceList->BusNumber = -1;
00981     ResourceList->AlternativeLists = 1;
00982     ResourceList->InterfaceType = PNPBus;
00983     ResourceList->List[0].Version = 1;
00984     ResourceList->List[0].Revision = 1;
00985     ResourceList->List[0].Count = 0;
00986 
00987     /* Is there a SCI? */
00988     if (HalpFixedAcpiDescTable.sci_int_vector)
00989     {
00990         /* Fill out the entry for it */
00991         ResourceList->List[0].Descriptors[0].Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
00992         ResourceList->List[0].Descriptors[0].Type = CmResourceTypeInterrupt;
00993         ResourceList->List[0].Descriptors[0].ShareDisposition = CmResourceShareShared;
00994 
00995         /* Get the interrupt number */
00996         Interrupt = HalpPicVectorRedirect[HalpFixedAcpiDescTable.sci_int_vector];
00997         ResourceList->List[0].Descriptors[0].u.Interrupt.MinimumVector = Interrupt;
00998         ResourceList->List[0].Descriptors[0].u.Interrupt.MaximumVector = Interrupt;
00999 
01000         /* One more */
01001         ++ResourceList->List[0].Count;
01002     }
01003 
01004     /* All good */
01005     return STATUS_SUCCESS;
01006 }
01007 
01008 NTSTATUS
01009 NTAPI
01010 HalpQueryAcpiResourceRequirements(OUT PIO_RESOURCE_REQUIREMENTS_LIST *Requirements)
01011 {
01012     PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
01013     ULONG Count = 0, ListSize;
01014     NTSTATUS Status;
01015     PAGED_CODE();
01016 
01017     /* Get ACPI resources */
01018     HalpAcpiDetectResourceListSize(&Count);
01019     DPRINT("Resource count: %d\n", Count);
01020 
01021     /* Compute size of the list and allocate it */
01022     ListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List[0].Descriptors) +
01023                (Count * sizeof(IO_RESOURCE_DESCRIPTOR));
01024     DPRINT("Resource list size: %d\n", ListSize);
01025     RequirementsList = ExAllocatePoolWithTag(PagedPool, ListSize, ' laH');
01026     if (RequirementsList)
01027     {
01028         /* Initialize it */
01029         RtlZeroMemory(RequirementsList, ListSize);
01030         RequirementsList->ListSize = ListSize;
01031 
01032         /* Build it */
01033         Status = HalpBuildAcpiResourceList(RequirementsList);
01034         if (NT_SUCCESS(Status))
01035         {
01036             /* It worked, return it */
01037             *Requirements = RequirementsList;
01038 
01039             /* Validate the list */
01040             ASSERT(RequirementsList->List[0].Count == Count);
01041         }
01042         else
01043         {
01044             /* Fail */
01045             ExFreePoolWithTag(RequirementsList, ' laH');
01046             Status = STATUS_NO_SUCH_DEVICE;
01047         }
01048     }
01049     else
01050     {
01051         /* Not enough memory */
01052         Status = STATUS_INSUFFICIENT_RESOURCES;
01053     }
01054 
01055     /* Return the status */
01056     return Status;
01057 }
01058 
01059 /*
01060  * @implemented
01061  */
01062 VOID
01063 NTAPI
01064 HalReportResourceUsage(VOID)
01065 {
01066     INTERFACE_TYPE InterfaceType;
01067     UNICODE_STRING HalString;
01068 
01069     /* FIXME: Initialize DMA 64-bit support */
01070 
01071     /* FIXME: Initialize MCA bus */
01072 
01073     /* Initialize PCI bus. */
01074     HalpInitializePciBus();
01075 
01076     /* What kind of bus is this? */
01077     switch (HalpBusType)
01078     {
01079         /* ISA Machine */
01080         case MACHINE_TYPE_ISA:
01081             InterfaceType = Isa;
01082             break;
01083 
01084         /* EISA Machine */
01085         case MACHINE_TYPE_EISA:
01086             InterfaceType = Eisa;
01087             break;
01088 
01089         /* MCA Machine */
01090         case MACHINE_TYPE_MCA:
01091             InterfaceType = MicroChannel;
01092             break;
01093 
01094         /* Unknown */
01095         default:
01096             InterfaceType = Internal;
01097             break;
01098     }
01099 
01100     /* Build HAL usage */
01101     RtlInitUnicodeString(&HalString, HalName);
01102     HalpReportResourceUsage(&HalString, InterfaceType);
01103 
01104     /* Setup PCI debugging and Hibernation */
01105     HalpRegisterPciDebuggingDeviceInfo();
01106 }
01107 
01108 /* EOF */

Generated on Tue May 22 2012 04:32:42 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.