• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Sample ACPI Platform Driver
3 
4   Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
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 <PiDxe.h>
16 
17 #include <Protocol/AcpiTable.h>
18 #include <Protocol/FirmwareVolume2.h>
19 
20 #include <Library/BaseLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/DebugLib.h>
23 #include <Library/PcdLib.h>
24 
25 #include <IndustryStandard/Acpi.h>
26 
27 /**
28   Locate the first instance of a protocol.  If the protocol requested is an
29   FV protocol, then it will return the first FV that contains the ACPI table
30   storage file.
31 
32   @param  Instance      Return pointer to the first instance of the protocol
33 
34   @return EFI_SUCCESS           The function completed successfully.
35   @return EFI_NOT_FOUND         The protocol could not be located.
36   @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
37 
38 **/
39 EFI_STATUS
LocateFvInstanceWithTables(OUT EFI_FIRMWARE_VOLUME2_PROTOCOL ** Instance)40 LocateFvInstanceWithTables (
41   OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance
42   )
43 {
44   EFI_STATUS                    Status;
45   EFI_HANDLE                    *HandleBuffer;
46   UINTN                         NumberOfHandles;
47   EFI_FV_FILETYPE               FileType;
48   UINT32                        FvStatus;
49   EFI_FV_FILE_ATTRIBUTES        Attributes;
50   UINTN                         Size;
51   UINTN                         Index;
52   EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
53 
54   FvStatus = 0;
55 
56   //
57   // Locate protocol.
58   //
59   Status = gBS->LocateHandleBuffer (
60                    ByProtocol,
61                    &gEfiFirmwareVolume2ProtocolGuid,
62                    NULL,
63                    &NumberOfHandles,
64                    &HandleBuffer
65                    );
66   if (EFI_ERROR (Status)) {
67     //
68     // Defined errors at this time are not found and out of resources.
69     //
70     return Status;
71   }
72 
73 
74 
75   //
76   // Looking for FV with ACPI storage file
77   //
78 
79   for (Index = 0; Index < NumberOfHandles; Index++) {
80     //
81     // Get the protocol on this handle
82     // This should not fail because of LocateHandleBuffer
83     //
84     Status = gBS->HandleProtocol (
85                      HandleBuffer[Index],
86                      &gEfiFirmwareVolume2ProtocolGuid,
87                      (VOID**) &FvInstance
88                      );
89     ASSERT_EFI_ERROR (Status);
90 
91     //
92     // See if it has the ACPI storage file
93     //
94     Status = FvInstance->ReadFile (
95                            FvInstance,
96                            (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
97                            NULL,
98                            &Size,
99                            &FileType,
100                            &Attributes,
101                            &FvStatus
102                            );
103 
104     //
105     // If we found it, then we are done
106     //
107     if (Status == EFI_SUCCESS) {
108       *Instance = FvInstance;
109       break;
110     }
111   }
112 
113   //
114   // Our exit status is determined by the success of the previous operations
115   // If the protocol was found, Instance already points to it.
116   //
117 
118   //
119   // Free any allocated buffers
120   //
121   gBS->FreePool (HandleBuffer);
122 
123   return Status;
124 }
125 
126 
127 /**
128   This function calculates and updates an UINT8 checksum.
129 
130   @param  Buffer          Pointer to buffer to checksum
131   @param  Size            Number of bytes to checksum
132 
133 **/
134 VOID
AcpiPlatformChecksum(IN UINT8 * Buffer,IN UINTN Size)135 AcpiPlatformChecksum (
136   IN UINT8      *Buffer,
137   IN UINTN      Size
138   )
139 {
140   UINTN ChecksumOffset;
141 
142   ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);
143 
144   //
145   // Set checksum to 0 first
146   //
147   Buffer[ChecksumOffset] = 0;
148 
149   //
150   // Update checksum value
151   //
152   Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size);
153 }
154 
155 
156 /**
157   Entrypoint of Acpi Platform driver.
158 
159   @param  ImageHandle
160   @param  SystemTable
161 
162   @return EFI_SUCCESS
163   @return EFI_LOAD_ERROR
164   @return EFI_OUT_OF_RESOURCES
165 
166 **/
167 EFI_STATUS
168 EFIAPI
AcpiPlatformEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)169 AcpiPlatformEntryPoint (
170   IN EFI_HANDLE         ImageHandle,
171   IN EFI_SYSTEM_TABLE   *SystemTable
172   )
173 {
174   EFI_STATUS                     Status;
175   EFI_ACPI_TABLE_PROTOCOL        *AcpiTable;
176   EFI_FIRMWARE_VOLUME2_PROTOCOL  *FwVol;
177   INTN                           Instance;
178   EFI_ACPI_COMMON_HEADER         *CurrentTable;
179   UINTN                          TableHandle;
180   UINT32                         FvStatus;
181   UINTN                          TableSize;
182   UINTN                          Size;
183 
184   Instance     = 0;
185   CurrentTable = NULL;
186   TableHandle  = 0;
187 
188   //
189   // Find the AcpiTable protocol
190   //
191   Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
192   if (EFI_ERROR (Status)) {
193     return EFI_ABORTED;
194   }
195 
196   //
197   // Locate the firmware volume protocol
198   //
199   Status = LocateFvInstanceWithTables (&FwVol);
200   if (EFI_ERROR (Status)) {
201     return EFI_ABORTED;
202   }
203   //
204   // Read tables from the storage file.
205   //
206   while (Status == EFI_SUCCESS) {
207 
208     Status = FwVol->ReadSection (
209                       FwVol,
210                       (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
211                       EFI_SECTION_RAW,
212                       Instance,
213                       (VOID**) &CurrentTable,
214                       &Size,
215                       &FvStatus
216                       );
217     if (!EFI_ERROR(Status)) {
218       //
219       // Add the table
220       //
221       TableHandle = 0;
222 
223       TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
224       ASSERT (Size >= TableSize);
225 
226       //
227       // Checksum ACPI table
228       //
229       AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
230 
231       //
232       // Install ACPI table
233       //
234       Status = AcpiTable->InstallAcpiTable (
235                             AcpiTable,
236                             CurrentTable,
237                             TableSize,
238                             &TableHandle
239                             );
240 
241       //
242       // Free memory allocated by ReadSection
243       //
244       gBS->FreePool (CurrentTable);
245 
246       if (EFI_ERROR(Status)) {
247         return EFI_ABORTED;
248       }
249 
250       //
251       // Increment the instance
252       //
253       Instance++;
254       CurrentTable = NULL;
255     }
256   }
257 
258   return EFI_SUCCESS;
259 }
260 
261