2 Xen ARM ACPI Platform Driver using Xen ARM multiboot protocol
4 Copyright (C) 2016, Linaro Ltd. All rights reserved.
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/BaseLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
19 #include <Library/UefiDriverEntryPoint.h>
21 #include <Protocol/AcpiTable.h>
22 #include <Protocol/FdtClient.h>
24 #include <IndustryStandard/Acpi.h>
27 Get the address of Xen ACPI Root System Description Pointer (RSDP)
30 @param RsdpStructurePtr Return pointer to RSDP structure
32 @return EFI_SUCCESS Find Xen RSDP structure successfully.
33 @return EFI_NOT_FOUND Don't find Xen RSDP structure.
34 @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.
41 OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
**RsdpPtr
44 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*RsdpStructurePtr
;
46 FDT_CLIENT_PROTOCOL
*FdtClient
;
49 UINTN AddressCells
, SizeCells
;
53 RsdpStructurePtr
= NULL
;
56 // Get the RSDP structure address from DeviceTree
58 Status
= gBS
->LocateProtocol (&gFdtClientProtocolGuid
, NULL
,
60 ASSERT_EFI_ERROR (Status
);
62 Status
= FdtClient
->FindCompatibleNodeReg (FdtClient
, "xen,guest-acpi",
63 (CONST VOID
**)&Reg
, &AddressCells
, &SizeCells
,
65 if (EFI_ERROR (Status
)) {
66 DEBUG ((EFI_D_WARN
, "%a: No 'xen,guest-acpi' compatible DT node found\n",
71 ASSERT (AddressCells
== 2);
72 ASSERT (SizeCells
== 2);
73 ASSERT (RegSize
== 2 * sizeof (UINT64
));
75 RegBase
= SwapBytes64(Reg
[0]);
77 (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)(UINTN
)RegBase
;
79 if (RsdpStructurePtr
&& RsdpStructurePtr
->Revision
>= 2) {
80 Sum
= CalculateSum8 ((CONST UINT8
*)RsdpStructurePtr
,
81 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
));
87 *RsdpPtr
= RsdpStructurePtr
;
92 Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables
93 into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed
94 ACPI tables are: FACP, APIC, GTDT, DSDT.
96 @param AcpiProtocol Protocol instance pointer.
98 @return EFI_SUCCESS The table was successfully inserted.
99 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is
100 NULL, or AcpiTableBufferSize and the size
101 field embedded in the ACPI table pointed to
102 by AcpiTableBuffer are not in sync.
103 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
109 InstallXenArmTables (
110 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
115 VOID
*CurrentTableEntry
;
116 UINTN CurrentTablePointer
;
117 EFI_ACPI_DESCRIPTION_HEADER
*CurrentTable
;
119 UINTN NumberOfTableEntries
;
120 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*XenAcpiRsdpStructurePtr
;
121 EFI_ACPI_DESCRIPTION_HEADER
*Xsdt
;
122 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*FadtTable
;
123 EFI_ACPI_DESCRIPTION_HEADER
*DsdtTable
;
125 XenAcpiRsdpStructurePtr
= NULL
;
129 NumberOfTableEntries
= 0;
132 // Try to find Xen ARM ACPI tables
134 Status
= GetXenArmAcpiRsdp (&XenAcpiRsdpStructurePtr
);
135 if (EFI_ERROR (Status
)) {
136 DEBUG ((EFI_D_INFO
, "%a: No RSDP table found\n", __FUNCTION__
));
141 // If XSDT table is find, just install its tables.
143 if (XenAcpiRsdpStructurePtr
->XsdtAddress
) {
145 // Retrieve the addresses of XSDT and
146 // calculate the number of its table entries.
148 Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
)
149 XenAcpiRsdpStructurePtr
->XsdtAddress
;
150 NumberOfTableEntries
= (Xsdt
->Length
-
151 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
154 // Install ACPI tables found in XSDT.
156 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
158 // Get the table entry from XSDT
160 CurrentTableEntry
= (VOID
*) ((UINT8
*) Xsdt
+
161 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
162 Index
* sizeof (UINT64
));
163 CurrentTablePointer
= (UINTN
) *(UINT64
*)CurrentTableEntry
;
164 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) CurrentTablePointer
;
167 // Install the XSDT tables
169 Status
= AcpiProtocol
->InstallAcpiTable (
172 CurrentTable
->Length
,
176 if (EFI_ERROR (Status
)) {
181 // Get the FACS and DSDT table address from the table FADT
183 if (!AsciiStrnCmp ((CHAR8
*) &CurrentTable
->Signature
, "FACP", 4)) {
184 FadtTable
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
185 (UINTN
) CurrentTablePointer
;
186 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*) (UINTN
) FadtTable
->Dsdt
;
192 // Install DSDT table.
194 Status
= AcpiProtocol
->InstallAcpiTable (
200 if (EFI_ERROR (Status
)) {
208 EFI_ACPI_TABLE_PROTOCOL
*
209 FindAcpiTableProtocol (
214 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
217 Status
= gBS
->LocateProtocol (
218 &gEfiAcpiTableProtocolGuid
,
222 ASSERT_EFI_ERROR (Status
);
227 Entrypoint of Xen ARM Acpi Platform driver.
233 @return EFI_LOAD_ERROR
234 @return EFI_OUT_OF_RESOURCES
240 XenAcpiPlatformEntryPoint (
241 IN EFI_HANDLE ImageHandle
,
242 IN EFI_SYSTEM_TABLE
*SystemTable
247 Status
= InstallXenArmTables (FindAcpiTableProtocol ());