123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- /** @file
- Xen ARM ACPI Platform Driver using Xen ARM multiboot protocol
- Copyright (C) 2016, Linaro Ltd. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Library/BaseLib.h>
- #include <Library/DebugLib.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include <Library/UefiDriverEntryPoint.h>
- #include <Protocol/AcpiTable.h>
- #include <Protocol/FdtClient.h>
- #include <IndustryStandard/Acpi.h>
- /**
- Get the address of Xen ACPI Root System Description Pointer (RSDP)
- structure.
- @param RsdpStructurePtr Return pointer to RSDP structure
- @return EFI_SUCCESS Find Xen RSDP structure successfully.
- @return EFI_NOT_FOUND Don't find Xen RSDP structure.
- @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.
- **/
- STATIC
- EFI_STATUS
- EFIAPI
- GetXenArmAcpiRsdp (
- OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr
- )
- {
- EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;
- EFI_STATUS Status;
- FDT_CLIENT_PROTOCOL *FdtClient;
- CONST UINT64 *Reg;
- UINT32 RegSize;
- UINTN AddressCells, SizeCells;
- UINT64 RegBase;
- UINT8 Sum;
- RsdpStructurePtr = NULL;
- FdtClient = NULL;
- //
- // Get the RSDP structure address from DeviceTree
- //
- Status = gBS->LocateProtocol (
- &gFdtClientProtocolGuid,
- NULL,
- (VOID **)&FdtClient
- );
- ASSERT_EFI_ERROR (Status);
- Status = FdtClient->FindCompatibleNodeReg (
- FdtClient,
- "xen,guest-acpi",
- (CONST VOID **)&Reg,
- &AddressCells,
- &SizeCells,
- &RegSize
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_WARN,
- "%a: No 'xen,guest-acpi' compatible DT node found\n",
- __FUNCTION__
- ));
- return EFI_NOT_FOUND;
- }
- ASSERT (AddressCells == 2);
- ASSERT (SizeCells == 2);
- ASSERT (RegSize == 2 * sizeof (UINT64));
- RegBase = SwapBytes64 (Reg[0]);
- RsdpStructurePtr =
- (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)RegBase;
- if (RsdpStructurePtr && (RsdpStructurePtr->Revision >= 2)) {
- Sum = CalculateSum8 (
- (CONST UINT8 *)RsdpStructurePtr,
- sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
- );
- if (Sum != 0) {
- return EFI_ABORTED;
- }
- }
- *RsdpPtr = RsdpStructurePtr;
- return EFI_SUCCESS;
- }
- /**
- Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables
- into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed
- ACPI tables are: FACP, APIC, GTDT, DSDT.
- @param AcpiProtocol Protocol instance pointer.
- @return EFI_SUCCESS The table was successfully inserted.
- @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is
- NULL, or AcpiTableBufferSize and the size
- field embedded in the ACPI table pointed to
- by AcpiTableBuffer are not in sync.
- @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
- **/
- STATIC
- EFI_STATUS
- EFIAPI
- InstallXenArmTables (
- IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
- )
- {
- EFI_STATUS Status;
- UINTN TableHandle;
- VOID *CurrentTableEntry;
- UINTN CurrentTablePointer;
- EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;
- UINTN Index;
- UINTN NumberOfTableEntries;
- EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *XenAcpiRsdpStructurePtr;
- EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtTable;
- EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;
- XenAcpiRsdpStructurePtr = NULL;
- FadtTable = NULL;
- DsdtTable = NULL;
- TableHandle = 0;
- NumberOfTableEntries = 0;
- //
- // Try to find Xen ARM ACPI tables
- //
- Status = GetXenArmAcpiRsdp (&XenAcpiRsdpStructurePtr);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, "%a: No RSDP table found\n", __FUNCTION__));
- return Status;
- }
- //
- // If XSDT table is find, just install its tables.
- //
- if (XenAcpiRsdpStructurePtr->XsdtAddress) {
- //
- // Retrieve the addresses of XSDT and
- // calculate the number of its table entries.
- //
- Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)
- XenAcpiRsdpStructurePtr->XsdtAddress;
- NumberOfTableEntries = (Xsdt->Length -
- sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /
- sizeof (UINT64);
- //
- // Install ACPI tables found in XSDT.
- //
- for (Index = 0; Index < NumberOfTableEntries; Index++) {
- //
- // Get the table entry from XSDT
- //
- CurrentTableEntry = (VOID *)((UINT8 *)Xsdt +
- sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
- Index * sizeof (UINT64));
- CurrentTablePointer = (UINTN)*(UINT64 *)CurrentTableEntry;
- CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer;
- //
- // Install the XSDT tables
- //
- Status = AcpiProtocol->InstallAcpiTable (
- AcpiProtocol,
- CurrentTable,
- CurrentTable->Length,
- &TableHandle
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Get the FACS and DSDT table address from the table FADT
- //
- if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) {
- FadtTable = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)
- (UINTN)CurrentTablePointer;
- DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)FadtTable->Dsdt;
- }
- }
- }
- //
- // Install DSDT table.
- //
- Status = AcpiProtocol->InstallAcpiTable (
- AcpiProtocol,
- DsdtTable,
- DsdtTable->Length,
- &TableHandle
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- return EFI_SUCCESS;
- }
- STATIC
- EFI_ACPI_TABLE_PROTOCOL *
- FindAcpiTableProtocol (
- VOID
- )
- {
- EFI_STATUS Status;
- EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
- AcpiTable = NULL;
- Status = gBS->LocateProtocol (
- &gEfiAcpiTableProtocolGuid,
- NULL,
- (VOID **)&AcpiTable
- );
- ASSERT_EFI_ERROR (Status);
- return AcpiTable;
- }
- /**
- Entrypoint of Xen ARM Acpi Platform driver.
- @param ImageHandle
- @param SystemTable
- @return EFI_SUCCESS
- @return EFI_LOAD_ERROR
- @return EFI_OUT_OF_RESOURCES
- **/
- EFI_STATUS
- EFIAPI
- XenAcpiPlatformEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- Status = InstallXenArmTables (FindAcpiTableProtocol ());
- return Status;
- }
|