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