]> git.proxmox.com Git - mirror_edk2.git/blob - EmbeddedPkg/Library/AcpiLib/AcpiLib.c
EmbeddedPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / EmbeddedPkg / Library / AcpiLib / AcpiLib.c
1 /** @file
2 *
3 * Copyright (c) 2014-2015, ARM Limited. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause-Patent
6 *
7 **/
8
9 #include <Uefi.h>
10
11 #include <Library/AcpiLib.h>
12 #include <Library/DebugLib.h>
13 #include <Library/UefiBootServicesTableLib.h>
14
15 #include <Protocol/AcpiTable.h>
16 #include <Protocol/FirmwareVolume2.h>
17
18 #include <IndustryStandard/Acpi.h>
19
20 /**
21 Locate and Install the ACPI tables from the Firmware Volume if it verifies
22 the function condition.
23
24 @param AcpiFile Guid of the ACPI file into the Firmware Volume
25 @param CheckAcpiTableFunction Function that checks if the ACPI table should be installed
26
27 @return EFI_SUCCESS The function completed successfully.
28 @return EFI_NOT_FOUND The protocol could not be located.
29 @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
30
31 **/
32 EFI_STATUS
33 LocateAndInstallAcpiFromFvConditional (
34 IN CONST EFI_GUID* AcpiFile,
35 IN EFI_LOCATE_ACPI_CHECK CheckAcpiTableFunction
36 )
37 {
38 EFI_STATUS Status;
39 EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol;
40 EFI_HANDLE *HandleBuffer;
41 UINTN NumberOfHandles;
42 UINT32 FvStatus;
43 UINTN Index;
44 EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
45 INTN SectionInstance;
46 UINTN SectionSize;
47 EFI_ACPI_COMMON_HEADER *AcpiTable;
48 UINTN AcpiTableSize;
49 UINTN AcpiTableKey;
50 BOOLEAN Valid;
51
52 // Ensure the ACPI Table is present
53 Status = gBS->LocateProtocol (
54 &gEfiAcpiTableProtocolGuid,
55 NULL,
56 (VOID**)&AcpiProtocol
57 );
58 if (EFI_ERROR (Status)) {
59 return Status;
60 }
61
62 FvStatus = 0;
63 SectionInstance = 0;
64
65 // Locate all the Firmware Volume protocols.
66 Status = gBS->LocateHandleBuffer (
67 ByProtocol,
68 &gEfiFirmwareVolume2ProtocolGuid,
69 NULL,
70 &NumberOfHandles,
71 &HandleBuffer
72 );
73 if (EFI_ERROR (Status)) {
74 return Status;
75 }
76
77 // Looking for FV with ACPI storage file
78 for (Index = 0; Index < NumberOfHandles; Index++) {
79 //
80 // Get the protocol on this handle
81 // This should not fail because of LocateHandleBuffer
82 //
83 Status = gBS->HandleProtocol (
84 HandleBuffer[Index],
85 &gEfiFirmwareVolume2ProtocolGuid,
86 (VOID**) &FvInstance
87 );
88 if (EFI_ERROR (Status)) {
89 goto FREE_HANDLE_BUFFER;
90 }
91
92 while (Status == EFI_SUCCESS) {
93 // AcpiTable must be allocated by ReadSection (ie: AcpiTable == NULL)
94 AcpiTable = NULL;
95
96 // See if it has the ACPI storage file
97 Status = FvInstance->ReadSection (
98 FvInstance,
99 AcpiFile,
100 EFI_SECTION_RAW,
101 SectionInstance,
102 (VOID**) &AcpiTable,
103 &SectionSize,
104 &FvStatus
105 );
106 if (!EFI_ERROR (Status)) {
107 AcpiTableKey = 0;
108 AcpiTableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Length;
109 ASSERT (SectionSize >= AcpiTableSize);
110
111 DEBUG ((EFI_D_ERROR, "- Found '%c%c%c%c' ACPI Table\n",
112 (((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature & 0xFF),
113 ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 8) & 0xFF),
114 ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 16) & 0xFF),
115 ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 24) & 0xFF)));
116
117 // Is the ACPI table valid?
118 if (CheckAcpiTableFunction) {
119 Valid = CheckAcpiTableFunction ((EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable);
120 } else {
121 Valid = TRUE;
122 }
123
124 // Install the ACPI Table
125 if (Valid) {
126 Status = AcpiProtocol->InstallAcpiTable (
127 AcpiProtocol,
128 AcpiTable,
129 AcpiTableSize,
130 &AcpiTableKey
131 );
132 }
133
134 // Free memory allocated by ReadSection
135 gBS->FreePool (AcpiTable);
136
137 if (EFI_ERROR (Status)) {
138 break;
139 }
140
141 // Increment the section instance
142 SectionInstance++;
143 }
144 }
145 }
146
147 FREE_HANDLE_BUFFER:
148 //
149 // Free any allocated buffers
150 //
151 gBS->FreePool (HandleBuffer);
152
153 return EFI_SUCCESS;
154 }
155
156 /**
157 Locate and Install the ACPI tables from the Firmware Volume
158
159 @param AcpiFile Guid of the ACPI file into the Firmware Volume
160
161 @return EFI_SUCCESS The function completed successfully.
162 @return EFI_NOT_FOUND The protocol could not be located.
163 @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
164
165 **/
166 EFI_STATUS
167 LocateAndInstallAcpiFromFv (
168 IN CONST EFI_GUID* AcpiFile
169 )
170 {
171 return LocateAndInstallAcpiFromFvConditional (AcpiFile, NULL);
172 }