VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/OvmfPkg/Library/AcpiPlatformLib/DxeAcpiPlatformLib.c

Last change on this file was 101291, checked in by vboxsync, 19 months ago

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

  • Property svn:eol-style set to native
File size: 7.7 KB
Line 
1/** @file
2 OVMF ACPI support
3
4 Copyright (C) 2021, Red Hat, Inc.
5 Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
6 Copyright (c) 2012, Bei Guan <[email protected]>
7
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10**/
11
12#include <Library/AcpiPlatformLib.h>
13#include <Library/BaseLib.h>
14#include <Library/DebugLib.h>
15
16EFI_STATUS
17EFIAPI
18GetAcpiRsdpFromMemory (
19 IN UINTN StartAddress,
20 IN UINTN EndAddress,
21 OUT EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER **RsdpPtr
22 )
23{
24 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdpStructurePtr;
25 UINT8 *AcpiPtr;
26 UINT8 Sum;
27
28 for (AcpiPtr = (UINT8 *)StartAddress;
29 AcpiPtr < (UINT8 *)EndAddress;
30 AcpiPtr += 0x10)
31 {
32 RsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)
33 (UINTN)AcpiPtr;
34
35 if (!AsciiStrnCmp ((CHAR8 *)&RsdpStructurePtr->Signature, "RSD PTR ", 8)) {
36 //
37 // RSDP ACPI 1.0 checksum for 1.0/2.0/3.0 table.
38 // This is only the first 20 bytes of the structure
39 //
40 Sum = CalculateSum8 (
41 (CONST UINT8 *)RsdpStructurePtr,
42 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
43 );
44 if (Sum != 0) {
45 return EFI_ABORTED;
46 }
47
48 if (RsdpStructurePtr->Revision >= 2) {
49 //
50 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
51 //
52 Sum = CalculateSum8 (
53 (CONST UINT8 *)RsdpStructurePtr,
54 sizeof (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
55 );
56 if (Sum != 0) {
57 return EFI_ABORTED;
58 }
59 }
60
61 *RsdpPtr = RsdpStructurePtr;
62 return EFI_SUCCESS;
63 }
64 }
65
66 return EFI_NOT_FOUND;
67}
68
69EFI_STATUS
70EFIAPI
71InstallAcpiTablesFromRsdp (
72 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol,
73 IN EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp
74 )
75{
76 EFI_STATUS Status;
77 UINTN TableHandle;
78
79 EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
80 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
81 VOID *CurrentTableEntry;
82 UINTN CurrentTablePointer;
83 EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;
84 UINTN Index;
85 UINTN NumberOfTableEntries;
86 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table;
87 EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt1Table;
88 EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs2Table;
89 EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs1Table;
90 EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;
91
92 Fadt2Table = NULL;
93 Fadt1Table = NULL;
94 Facs2Table = NULL;
95 Facs1Table = NULL;
96 DsdtTable = NULL;
97 TableHandle = 0;
98 NumberOfTableEntries = 0;
99
100 //
101 // If XSDT table is find, just install its tables.
102 // Otherwise, try to find and install the RSDT tables.
103 //
104 if (Rsdp->XsdtAddress) {
105 //
106 // Retrieve the addresses of XSDT and
107 // calculate the number of its table entries.
108 //
109 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->XsdtAddress;
110 NumberOfTableEntries =
111 (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT64);
112
113 //
114 // Install ACPI tables found in XSDT.
115 //
116 for (Index = 0; Index < NumberOfTableEntries; Index++) {
117 //
118 // Get the table entry from XSDT
119 //
120 CurrentTableEntry =
121 (VOID *)((UINT8 *)Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
122 Index * sizeof (UINT64));
123 CurrentTablePointer = (UINTN)*(UINT64 *)CurrentTableEntry;
124 CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer;
125
126 //
127 // Install the XSDT tables
128 //
129 Status = AcpiProtocol->InstallAcpiTable (
130 AcpiProtocol,
131 CurrentTable,
132 CurrentTable->Length,
133 &TableHandle
134 );
135
136 if (EFI_ERROR (Status)) {
137 return Status;
138 }
139
140 //
141 // Get the FACS and DSDT table address from the table FADT
142 //
143 if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) {
144 Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN)
145 CurrentTablePointer;
146 Facs2Table = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)
147 Fadt2Table->FirmwareCtrl;
148 DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt2Table->Dsdt;
149 }
150 }
151 } else if (Rsdp->RsdtAddress) {
152 //
153 // Retrieve the addresses of RSDT and
154 // calculate the number of its table entries.
155 //
156 Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Rsdp->RsdtAddress;
157 NumberOfTableEntries =
158 (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT32);
159
160 //
161 // Install ACPI tables found in XSDT.
162 //
163 for (Index = 0; Index < NumberOfTableEntries; Index++) {
164 //
165 // Get the table entry from RSDT
166 //
167 CurrentTableEntry =
168 (UINT32 *)((UINT8 *)Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
169 Index * sizeof (UINT32));
170 CurrentTablePointer = *(UINT32 *)CurrentTableEntry;
171 CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer;
172
173 //
174 // Install the RSDT 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 Fadt1Table = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *)(UINTN)
192 CurrentTablePointer;
193 Facs1Table = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)
194 Fadt1Table->FirmwareCtrl;
195 DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt1Table->Dsdt;
196 }
197 }
198 }
199
200 //
201 // Install the FACS table.
202 //
203 if (Fadt2Table) {
204 //
205 // FACS 2.0
206 //
207 Status = AcpiProtocol->InstallAcpiTable (
208 AcpiProtocol,
209 Facs2Table,
210 Facs2Table->Length,
211 &TableHandle
212 );
213 if (EFI_ERROR (Status)) {
214 return Status;
215 }
216 } else if (Fadt1Table) {
217 //
218 // FACS 1.0
219 //
220 Status = AcpiProtocol->InstallAcpiTable (
221 AcpiProtocol,
222 Facs1Table,
223 Facs1Table->Length,
224 &TableHandle
225 );
226 if (EFI_ERROR (Status)) {
227 return Status;
228 }
229 }
230
231 //
232 // Install DSDT table. If we reached this point without finding the DSDT,
233 // then we're out of sync with the hypervisor, and cannot continue.
234 //
235 if (DsdtTable == NULL) {
236 DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __func__));
237 ASSERT (FALSE);
238 CpuDeadLoop ();
239 }
240
241 Status = AcpiProtocol->InstallAcpiTable (
242 AcpiProtocol,
243 DsdtTable,
244 DsdtTable->Length,
245 &TableHandle
246 );
247 if (EFI_ERROR (Status)) {
248 return Status;
249 }
250
251 return EFI_SUCCESS;
252}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette