]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Library/AcpiLib/AcpiLib.c
EmbeddedPkg: Introduced AcpiLib
[mirror_edk2.git] / EmbeddedPkg / Library / AcpiLib / AcpiLib.c
CommitLineData
3356211b
OM
1/** @file\r
2*\r
3* Copyright (c) 2014, ARM Limited. All rights reserved.\r
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
27 Locate and Install the ACPI tables from the Firmware Volume\r
28\r
29 @param AcpiFile Guid of the ACPI file into the Firmware Volume\r
30\r
31 @return EFI_SUCCESS The function completed successfully.\r
32 @return EFI_NOT_FOUND The protocol could not be located.\r
33 @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.\r
34\r
35**/\r
36EFI_STATUS\r
37LocateAndInstallAcpiFromFv (\r
38 IN CONST EFI_GUID* AcpiFile\r
39 )\r
40{\r
41 EFI_STATUS Status;\r
42 EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol;\r
43 EFI_HANDLE *HandleBuffer;\r
44 UINTN NumberOfHandles;\r
45 UINT32 FvStatus;\r
46 UINTN Index;\r
47 EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
48 INTN SectionInstance;\r
49 UINTN SectionSize;\r
50 EFI_ACPI_COMMON_HEADER *AcpiTable;\r
51 UINTN AcpiTableSize;\r
52 UINTN AcpiTableKey;\r
53\r
54 // Ensure the ACPI Table is present\r
55 Status = gBS->LocateProtocol (\r
56 &gEfiAcpiTableProtocolGuid,\r
57 NULL,\r
58 (VOID**)&AcpiProtocol\r
59 );\r
60 if (EFI_ERROR (Status)) {\r
61 return Status;\r
62 }\r
63\r
64 FvStatus = 0;\r
65 SectionInstance = 0;\r
66\r
67 // Locate all the Firmware Volume protocols.\r
68 Status = gBS->LocateHandleBuffer (\r
69 ByProtocol,\r
70 &gEfiFirmwareVolume2ProtocolGuid,\r
71 NULL,\r
72 &NumberOfHandles,\r
73 &HandleBuffer\r
74 );\r
75 if (EFI_ERROR (Status)) {\r
76 return Status;\r
77 }\r
78\r
79 // Looking for FV with ACPI storage file\r
80 for (Index = 0; Index < NumberOfHandles; Index++) {\r
81 //\r
82 // Get the protocol on this handle\r
83 // This should not fail because of LocateHandleBuffer\r
84 //\r
85 Status = gBS->HandleProtocol (\r
86 HandleBuffer[Index],\r
87 &gEfiFirmwareVolume2ProtocolGuid,\r
88 (VOID**) &FvInstance\r
89 );\r
90 if (EFI_ERROR (Status)) {\r
91 goto FREE_HANDLE_BUFFER;\r
92 }\r
93\r
94 while (Status == EFI_SUCCESS) {\r
95 // AcpiTable must be allocated by ReadSection (ie: AcpiTable == NULL)\r
96 AcpiTable = NULL;\r
97\r
98 // See if it has the ACPI storage file\r
99 Status = FvInstance->ReadSection (\r
100 FvInstance,\r
101 AcpiFile,\r
102 EFI_SECTION_RAW,\r
103 SectionInstance,\r
104 (VOID**) &AcpiTable,\r
105 &SectionSize,\r
106 &FvStatus\r
107 );\r
108 if (!EFI_ERROR (Status)) {\r
109 AcpiTableKey = 0;\r
110 AcpiTableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Length;\r
111 ASSERT (SectionSize >= AcpiTableSize);\r
112\r
113 DEBUG ((EFI_D_ERROR, "- Found '%c%c%c%c' ACPI Table\n",\r
114 (((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature & 0xFF),\r
115 ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 8) & 0xFF),\r
116 ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 16) & 0xFF),\r
117 ((((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTable)->Signature >> 24) & 0xFF)));\r
118\r
119 // Install the ACPI Table\r
120 Status = AcpiProtocol->InstallAcpiTable (\r
121 AcpiProtocol,\r
122 AcpiTable,\r
123 AcpiTableSize,\r
124 &AcpiTableKey\r
125 );\r
126 // Free memory allocated by ReadSection\r
127 gBS->FreePool (AcpiTable);\r
128\r
129 if (EFI_ERROR (Status)) {\r
130 break;\r
131 }\r
132\r
133 // Increment the section instance\r
134 SectionInstance++;\r
135 }\r
136 }\r
137 }\r
138\r
139FREE_HANDLE_BUFFER:\r
140 //\r
141 // Free any allocated buffers\r
142 //\r
143 gBS->FreePool (HandleBuffer);\r
144\r
145 return EFI_SUCCESS;\r
146}\r