]> git.proxmox.com Git - mirror_edk2.git/blob - ArmVirtPkg/XenAcpiPlatformDxe/XenAcpiPlatformDxe.c
BaseTools/BinToPcd: Fix Python 2.7.x compatibility issue
[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 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
10
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.
13
14 **/
15
16 #include <Library/BaseLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
19 #include <Library/UefiDriverEntryPoint.h>
20
21 #include <Protocol/AcpiTable.h>
22 #include <Protocol/FdtClient.h>
23
24 #include <IndustryStandard/Acpi.h>
25
26 /**
27 Get the address of Xen ACPI Root System Description Pointer (RSDP)
28 structure.
29
30 @param RsdpStructurePtr Return pointer to RSDP structure
31
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.
35
36 **/
37 STATIC
38 EFI_STATUS
39 EFIAPI
40 GetXenArmAcpiRsdp (
41 OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr
42 )
43 {
44 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;
45 EFI_STATUS Status;
46 FDT_CLIENT_PROTOCOL *FdtClient;
47 CONST UINT64 *Reg;
48 UINT32 RegSize;
49 UINTN AddressCells, SizeCells;
50 UINT64 RegBase;
51 UINT8 Sum;
52
53 RsdpStructurePtr = NULL;
54 FdtClient = NULL;
55 //
56 // Get the RSDP structure address from DeviceTree
57 //
58 Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
59 (VOID **)&FdtClient);
60 ASSERT_EFI_ERROR (Status);
61
62 Status = FdtClient->FindCompatibleNodeReg (FdtClient, "xen,guest-acpi",
63 (CONST VOID **)&Reg, &AddressCells, &SizeCells,
64 &RegSize);
65 if (EFI_ERROR (Status)) {
66 DEBUG ((EFI_D_WARN, "%a: No 'xen,guest-acpi' compatible DT node found\n",
67 __FUNCTION__));
68 return EFI_NOT_FOUND;
69 }
70
71 ASSERT (AddressCells == 2);
72 ASSERT (SizeCells == 2);
73 ASSERT (RegSize == 2 * sizeof (UINT64));
74
75 RegBase = SwapBytes64(Reg[0]);
76 RsdpStructurePtr =
77 (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)RegBase;
78
79 if (RsdpStructurePtr && RsdpStructurePtr->Revision >= 2) {
80 Sum = CalculateSum8 ((CONST UINT8 *)RsdpStructurePtr,
81 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER));
82 if (Sum != 0) {
83 return EFI_ABORTED;
84 }
85 }
86
87 *RsdpPtr = RsdpStructurePtr;
88 return EFI_SUCCESS;
89 }
90
91 /**
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.
95
96 @param AcpiProtocol Protocol instance pointer.
97
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.
104
105 **/
106 STATIC
107 EFI_STATUS
108 EFIAPI
109 InstallXenArmTables (
110 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
111 )
112 {
113 EFI_STATUS Status;
114 UINTN TableHandle;
115 VOID *CurrentTableEntry;
116 UINTN CurrentTablePointer;
117 EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;
118 UINTN Index;
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;
124
125 XenAcpiRsdpStructurePtr = NULL;
126 FadtTable = NULL;
127 DsdtTable = NULL;
128 TableHandle = 0;
129 NumberOfTableEntries = 0;
130
131 //
132 // Try to find Xen ARM ACPI tables
133 //
134 Status = GetXenArmAcpiRsdp (&XenAcpiRsdpStructurePtr);
135 if (EFI_ERROR (Status)) {
136 DEBUG ((EFI_D_INFO, "%a: No RSDP table found\n", __FUNCTION__));
137 return Status;
138 }
139
140 //
141 // If XSDT table is find, just install its tables.
142 //
143 if (XenAcpiRsdpStructurePtr->XsdtAddress) {
144 //
145 // Retrieve the addresses of XSDT and
146 // calculate the number of its table entries.
147 //
148 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN)
149 XenAcpiRsdpStructurePtr->XsdtAddress;
150 NumberOfTableEntries = (Xsdt->Length -
151 sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /
152 sizeof (UINT64);
153 //
154 // Install ACPI tables found in XSDT.
155 //
156 for (Index = 0; Index < NumberOfTableEntries; Index++) {
157 //
158 // Get the table entry from XSDT
159 //
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;
165
166 //
167 // Install the XSDT tables
168 //
169 Status = AcpiProtocol->InstallAcpiTable (
170 AcpiProtocol,
171 CurrentTable,
172 CurrentTable->Length,
173 &TableHandle
174 );
175
176 if (EFI_ERROR (Status)) {
177 return Status;
178 }
179
180 //
181 // Get the FACS and DSDT table address from the table FADT
182 //
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;
187 }
188 }
189 }
190
191 //
192 // Install DSDT table.
193 //
194 Status = AcpiProtocol->InstallAcpiTable (
195 AcpiProtocol,
196 DsdtTable,
197 DsdtTable->Length,
198 &TableHandle
199 );
200 if (EFI_ERROR (Status)) {
201 return Status;
202 }
203
204 return EFI_SUCCESS;
205 }
206
207 STATIC
208 EFI_ACPI_TABLE_PROTOCOL *
209 FindAcpiTableProtocol (
210 VOID
211 )
212 {
213 EFI_STATUS Status;
214 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
215
216 AcpiTable = NULL;
217 Status = gBS->LocateProtocol (
218 &gEfiAcpiTableProtocolGuid,
219 NULL,
220 (VOID**)&AcpiTable
221 );
222 ASSERT_EFI_ERROR (Status);
223 return AcpiTable;
224 }
225
226 /**
227 Entrypoint of Xen ARM Acpi Platform driver.
228
229 @param ImageHandle
230 @param SystemTable
231
232 @return EFI_SUCCESS
233 @return EFI_LOAD_ERROR
234 @return EFI_OUT_OF_RESOURCES
235
236 **/
237
238 EFI_STATUS
239 EFIAPI
240 XenAcpiPlatformEntryPoint (
241 IN EFI_HANDLE ImageHandle,
242 IN EFI_SYSTEM_TABLE *SystemTable
243 )
244 {
245 EFI_STATUS Status;
246
247 Status = InstallXenArmTables (FindAcpiTableProtocol ());
248 return Status;
249 }