]> git.proxmox.com Git - mirror_edk2.git/blob - ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ArmVirtPkg / XenAcpiPlatformDxe / XenAcpiPlatformDxe.c
1 /** @file
2 Xen ARM ACPI Platform Driver using Xen ARM multiboot protocol
3
4 Copyright (C) 2016, Linaro Ltd. All rights reserved.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <Library/BaseLib.h>
11 #include <Library/DebugLib.h>
12 #include <Library/UefiBootServicesTableLib.h>
13 #include <Library/UefiDriverEntryPoint.h>
14
15 #include <Protocol/AcpiTable.h>
16 #include <Protocol/FdtClient.h>
17
18 #include <IndustryStandard/Acpi.h>
19
20 /**
21 Get the address of Xen ACPI Root System Description Pointer (RSDP)
22 structure.
23
24 @param RsdpStructurePtr Return pointer to RSDP structure
25
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.
29
30 **/
31 STATIC
32 EFI_STATUS
33 EFIAPI
34 GetXenArmAcpiRsdp (
35 OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr
36 )
37 {
38 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;
39 EFI_STATUS Status;
40 FDT_CLIENT_PROTOCOL *FdtClient;
41 CONST UINT64 *Reg;
42 UINT32 RegSize;
43 UINTN AddressCells, SizeCells;
44 UINT64 RegBase;
45 UINT8 Sum;
46
47 RsdpStructurePtr = NULL;
48 FdtClient = NULL;
49 //
50 // Get the RSDP structure address from DeviceTree
51 //
52 Status = gBS->LocateProtocol (
53 &gFdtClientProtocolGuid,
54 NULL,
55 (VOID **)&FdtClient
56 );
57 ASSERT_EFI_ERROR (Status);
58
59 Status = FdtClient->FindCompatibleNodeReg (
60 FdtClient,
61 "xen,guest-acpi",
62 (CONST VOID **)&Reg,
63 &AddressCells,
64 &SizeCells,
65 &RegSize
66 );
67 if (EFI_ERROR (Status)) {
68 DEBUG ((
69 DEBUG_WARN,
70 "%a: No 'xen,guest-acpi' compatible DT node found\n",
71 __FUNCTION__
72 ));
73 return EFI_NOT_FOUND;
74 }
75
76 ASSERT (AddressCells == 2);
77 ASSERT (SizeCells == 2);
78 ASSERT (RegSize == 2 * sizeof (UINT64));
79
80 RegBase = SwapBytes64 (Reg[0]);
81 RsdpStructurePtr =
82 (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)RegBase;
83
84 if (RsdpStructurePtr && (RsdpStructurePtr->Revision >= 2)) {
85 Sum = CalculateSum8 (
86 (CONST UINT8 *)RsdpStructurePtr,
87 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
88 );
89 if (Sum != 0) {
90 return EFI_ABORTED;
91 }
92 }
93
94 *RsdpPtr = RsdpStructurePtr;
95 return EFI_SUCCESS;
96 }
97
98 /**
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.
102
103 @param AcpiProtocol Protocol instance pointer.
104
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.
111
112 **/
113 STATIC
114 EFI_STATUS
115 EFIAPI
116 InstallXenArmTables (
117 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
118 )
119 {
120 EFI_STATUS Status;
121 UINTN TableHandle;
122 VOID *CurrentTableEntry;
123 UINTN CurrentTablePointer;
124 EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;
125 UINTN Index;
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;
131
132 XenAcpiRsdpStructurePtr = NULL;
133 FadtTable = NULL;
134 DsdtTable = NULL;
135 TableHandle = 0;
136 NumberOfTableEntries = 0;
137
138 //
139 // Try to find Xen ARM ACPI tables
140 //
141 Status = GetXenArmAcpiRsdp (&XenAcpiRsdpStructurePtr);
142 if (EFI_ERROR (Status)) {
143 DEBUG ((DEBUG_INFO, "%a: No RSDP table found\n", __FUNCTION__));
144 return Status;
145 }
146
147 //
148 // If XSDT table is find, just install its tables.
149 //
150 if (XenAcpiRsdpStructurePtr->XsdtAddress) {
151 //
152 // Retrieve the addresses of XSDT and
153 // calculate the number of its table entries.
154 //
155 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)
156 XenAcpiRsdpStructurePtr->XsdtAddress;
157 NumberOfTableEntries = (Xsdt->Length -
158 sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /
159 sizeof (UINT64);
160 //
161 // Install ACPI tables found in XSDT.
162 //
163 for (Index = 0; Index < NumberOfTableEntries; Index++) {
164 //
165 // Get the table entry from XSDT
166 //
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;
172
173 //
174 // Install the XSDT tables
175 //
176 Status = AcpiProtocol->InstallAcpiTable (
177 AcpiProtocol,
178 CurrentTable,
179 CurrentTable->Length,
180 &TableHandle
181 );
182
183 if (EFI_ERROR (Status)) {
184 return Status;
185 }
186
187 //
188 // Get the FACS and DSDT table address from the table FADT
189 //
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;
194 }
195 }
196 }
197
198 //
199 // Install DSDT table.
200 //
201 Status = AcpiProtocol->InstallAcpiTable (
202 AcpiProtocol,
203 DsdtTable,
204 DsdtTable->Length,
205 &TableHandle
206 );
207 if (EFI_ERROR (Status)) {
208 return Status;
209 }
210
211 return EFI_SUCCESS;
212 }
213
214 STATIC
215 EFI_ACPI_TABLE_PROTOCOL *
216 FindAcpiTableProtocol (
217 VOID
218 )
219 {
220 EFI_STATUS Status;
221 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
222
223 AcpiTable = NULL;
224 Status = gBS->LocateProtocol (
225 &gEfiAcpiTableProtocolGuid,
226 NULL,
227 (VOID **)&AcpiTable
228 );
229 ASSERT_EFI_ERROR (Status);
230 return AcpiTable;
231 }
232
233 /**
234 Entrypoint of Xen ARM Acpi Platform driver.
235
236 @param ImageHandle
237 @param SystemTable
238
239 @return EFI_SUCCESS
240 @return EFI_LOAD_ERROR
241 @return EFI_OUT_OF_RESOURCES
242
243 **/
244 EFI_STATUS
245 EFIAPI
246 XenAcpiPlatformEntryPoint (
247 IN EFI_HANDLE ImageHandle,
248 IN EFI_SYSTEM_TABLE *SystemTable
249 )
250 {
251 EFI_STATUS Status;
252
253 Status = InstallXenArmTables (FindAcpiTableProtocol ());
254 return Status;
255 }