2 Xen ARM ACPI Platform Driver using Xen ARM multiboot protocol
4 Copyright (C) 2016, Linaro Ltd. All rights reserved.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/BaseLib.h>
11 #include <Library/DebugLib.h>
12 #include <Library/UefiBootServicesTableLib.h>
13 #include <Library/UefiDriverEntryPoint.h>
15 #include <Protocol/AcpiTable.h>
16 #include <Protocol/FdtClient.h>
18 #include <IndustryStandard/Acpi.h>
21 Get the address of Xen ACPI Root System Description Pointer (RSDP)
24 @param RsdpStructurePtr Return pointer to RSDP structure
26 @return EFI_SUCCESS Find Xen RSDP structure successfully.
27 @return EFI_NOT_FOUND Don't find Xen RSDP structure.
28 @return EFI_ABORTED Find Xen RSDP structure, but it's not integrated.
35 OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
**RsdpPtr
38 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*RsdpStructurePtr
;
40 FDT_CLIENT_PROTOCOL
*FdtClient
;
43 UINTN AddressCells
, SizeCells
;
47 RsdpStructurePtr
= NULL
;
50 // Get the RSDP structure address from DeviceTree
52 Status
= gBS
->LocateProtocol (
53 &gFdtClientProtocolGuid
,
57 ASSERT_EFI_ERROR (Status
);
59 Status
= FdtClient
->FindCompatibleNodeReg (
67 if (EFI_ERROR (Status
)) {
70 "%a: No 'xen,guest-acpi' compatible DT node found\n",
76 ASSERT (AddressCells
== 2);
77 ASSERT (SizeCells
== 2);
78 ASSERT (RegSize
== 2 * sizeof (UINT64
));
80 RegBase
= SwapBytes64 (Reg
[0]);
82 (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)(UINTN
)RegBase
;
84 if (RsdpStructurePtr
&& (RsdpStructurePtr
->Revision
>= 2)) {
86 (CONST UINT8
*)RsdpStructurePtr
,
87 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
)
94 *RsdpPtr
= RsdpStructurePtr
;
99 Get Xen Acpi tables from the RSDP structure. And installs Xen ACPI tables
100 into the RSDT/XSDT using InstallAcpiTable. Some signature of the installed
101 ACPI tables are: FACP, APIC, GTDT, DSDT.
103 @param AcpiProtocol Protocol instance pointer.
105 @return EFI_SUCCESS The table was successfully inserted.
106 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableHandle is
107 NULL, or AcpiTableBufferSize and the size
108 field embedded in the ACPI table pointed to
109 by AcpiTableBuffer are not in sync.
110 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
116 InstallXenArmTables (
117 IN EFI_ACPI_TABLE_PROTOCOL
*AcpiProtocol
122 VOID
*CurrentTableEntry
;
123 UINTN CurrentTablePointer
;
124 EFI_ACPI_DESCRIPTION_HEADER
*CurrentTable
;
126 UINTN NumberOfTableEntries
;
127 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*XenAcpiRsdpStructurePtr
;
128 EFI_ACPI_DESCRIPTION_HEADER
*Xsdt
;
129 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*FadtTable
;
130 EFI_ACPI_DESCRIPTION_HEADER
*DsdtTable
;
132 XenAcpiRsdpStructurePtr
= NULL
;
136 NumberOfTableEntries
= 0;
139 // Try to find Xen ARM ACPI tables
141 Status
= GetXenArmAcpiRsdp (&XenAcpiRsdpStructurePtr
);
142 if (EFI_ERROR (Status
)) {
143 DEBUG ((DEBUG_INFO
, "%a: No RSDP table found\n", __FUNCTION__
));
148 // If XSDT table is find, just install its tables.
150 if (XenAcpiRsdpStructurePtr
->XsdtAddress
) {
152 // Retrieve the addresses of XSDT and
153 // calculate the number of its table entries.
155 Xsdt
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)
156 XenAcpiRsdpStructurePtr
->XsdtAddress
;
157 NumberOfTableEntries
= (Xsdt
->Length
-
158 sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) /
161 // Install ACPI tables found in XSDT.
163 for (Index
= 0; Index
< NumberOfTableEntries
; Index
++) {
165 // Get the table entry from XSDT
167 CurrentTableEntry
= (VOID
*)((UINT8
*)Xsdt
+
168 sizeof (EFI_ACPI_DESCRIPTION_HEADER
) +
169 Index
* sizeof (UINT64
));
170 CurrentTablePointer
= (UINTN
)*(UINT64
*)CurrentTableEntry
;
171 CurrentTable
= (EFI_ACPI_DESCRIPTION_HEADER
*)CurrentTablePointer
;
174 // Install the XSDT tables
176 Status
= AcpiProtocol
->InstallAcpiTable (
179 CurrentTable
->Length
,
183 if (EFI_ERROR (Status
)) {
188 // Get the FACS and DSDT table address from the table FADT
190 if (!AsciiStrnCmp ((CHAR8
*)&CurrentTable
->Signature
, "FACP", 4)) {
191 FadtTable
= (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE
*)
192 (UINTN
)CurrentTablePointer
;
193 DsdtTable
= (EFI_ACPI_DESCRIPTION_HEADER
*)(UINTN
)FadtTable
->Dsdt
;
199 // Install DSDT table.
201 Status
= AcpiProtocol
->InstallAcpiTable (
207 if (EFI_ERROR (Status
)) {
215 EFI_ACPI_TABLE_PROTOCOL
*
216 FindAcpiTableProtocol (
221 EFI_ACPI_TABLE_PROTOCOL
*AcpiTable
;
224 Status
= gBS
->LocateProtocol (
225 &gEfiAcpiTableProtocolGuid
,
229 ASSERT_EFI_ERROR (Status
);
234 Entrypoint of Xen ARM Acpi Platform driver.
240 @return EFI_LOAD_ERROR
241 @return EFI_OUT_OF_RESOURCES
246 XenAcpiPlatformEntryPoint (
247 IN EFI_HANDLE ImageHandle
,
248 IN EFI_SYSTEM_TABLE
*SystemTable
253 Status
= InstallXenArmTables (FindAcpiTableProtocol ());