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