AcpiPlatform.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /** @file
  2. Sample ACPI Platform Driver
  3. Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
  4. This program and the accompanying materials
  5. are licensed and made available under the terms and conditions of the BSD License
  6. which accompanies this distribution. The full text of the license may be found at
  7. http://opensource.org/licenses/bsd-license.php
  8. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  10. **/
  11. #include <PiDxe.h>
  12. #include <Protocol/AcpiTable.h>
  13. #include <Protocol/FirmwareVolume2.h>
  14. #include <Library/BaseLib.h>
  15. #include <Library/UefiBootServicesTableLib.h>
  16. #include <Library/DebugLib.h>
  17. #include <Library/PcdLib.h>
  18. #include <IndustryStandard/Acpi.h>
  19. #include "UpdateAcpiTable.h"
  20. /**
  21. Locate the first instance of a protocol. If the protocol requested is an
  22. FV protocol, then it will return the first FV that contains the ACPI table
  23. storage file.
  24. @param Instance Return pointer to the first instance of the protocol
  25. @return EFI_SUCCESS The function completed successfully.
  26. @return EFI_NOT_FOUND The protocol could not be located.
  27. @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
  28. **/
  29. EFI_STATUS
  30. LocateFvInstanceWithTables (
  31. OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance
  32. )
  33. {
  34. EFI_STATUS Status;
  35. EFI_HANDLE *HandleBuffer;
  36. UINTN NumberOfHandles;
  37. EFI_FV_FILETYPE FileType;
  38. UINT32 FvStatus;
  39. EFI_FV_FILE_ATTRIBUTES Attributes;
  40. UINTN Size;
  41. UINTN Index;
  42. EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
  43. FvStatus = 0;
  44. //
  45. // Locate protocol.
  46. //
  47. Status = gBS->LocateHandleBuffer (
  48. ByProtocol,
  49. &gEfiFirmwareVolume2ProtocolGuid,
  50. NULL,
  51. &NumberOfHandles,
  52. &HandleBuffer
  53. );
  54. if (EFI_ERROR (Status)) {
  55. //
  56. // Defined errors at this time are not found and out of resources.
  57. //
  58. return Status;
  59. }
  60. //
  61. // Looking for FV with ACPI storage file
  62. //
  63. for (Index = 0; Index < NumberOfHandles; Index++) {
  64. //
  65. // Get the protocol on this handle
  66. // This should not fail because of LocateHandleBuffer
  67. //
  68. Status = gBS->HandleProtocol (
  69. HandleBuffer[Index],
  70. &gEfiFirmwareVolume2ProtocolGuid,
  71. (VOID**) &FvInstance
  72. );
  73. ASSERT_EFI_ERROR (Status);
  74. //
  75. // See if it has the ACPI storage file
  76. //
  77. Status = FvInstance->ReadFile (
  78. FvInstance,
  79. (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
  80. NULL,
  81. &Size,
  82. &FileType,
  83. &Attributes,
  84. &FvStatus
  85. );
  86. //
  87. // If we found it, then we are done
  88. //
  89. if (Status == EFI_SUCCESS) {
  90. *Instance = FvInstance;
  91. break;
  92. }
  93. }
  94. //
  95. // Our exit status is determined by the success of the previous operations
  96. // If the protocol was found, Instance already points to it.
  97. //
  98. //
  99. // Free any allocated buffers
  100. //
  101. gBS->FreePool (HandleBuffer);
  102. return Status;
  103. }
  104. /**
  105. This function calculates and updates an UINT8 checksum.
  106. @param Buffer Pointer to buffer to checksum
  107. @param Size Number of bytes to checksum
  108. **/
  109. VOID
  110. AcpiPlatformChecksum (
  111. IN UINT8 *Buffer,
  112. IN UINTN Size
  113. )
  114. {
  115. UINTN ChecksumOffset;
  116. ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);
  117. //
  118. // Set checksum to 0 first
  119. //
  120. Buffer[ChecksumOffset] = 0;
  121. //
  122. // Update checksum value
  123. //
  124. Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size);
  125. }
  126. /**
  127. Entrypoint of Acpi Platform driver.
  128. @param ImageHandle
  129. @param SystemTable
  130. @return EFI_SUCCESS
  131. @return EFI_LOAD_ERROR
  132. @return EFI_OUT_OF_RESOURCES
  133. **/
  134. EFI_STATUS
  135. EFIAPI
  136. AcpiPlatformEntryPoint (
  137. IN EFI_HANDLE ImageHandle,
  138. IN EFI_SYSTEM_TABLE *SystemTable
  139. )
  140. {
  141. EFI_STATUS Status;
  142. EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
  143. EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
  144. INTN Instance;
  145. EFI_ACPI_COMMON_HEADER *CurrentTable;
  146. UINTN TableHandle;
  147. UINT32 FvStatus;
  148. UINTN TableSize;
  149. UINTN Size;
  150. EFI_STATUS TableStatus;
  151. EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
  152. Instance = 0;
  153. CurrentTable = NULL;
  154. TableHandle = 0;
  155. //
  156. // Find the AcpiTable protocol
  157. //
  158. Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
  159. if (EFI_ERROR (Status)) {
  160. return EFI_ABORTED;
  161. }
  162. //
  163. // Locate the firmware volume protocol
  164. //
  165. Status = LocateFvInstanceWithTables (&FwVol);
  166. if (EFI_ERROR (Status)) {
  167. return EFI_ABORTED;
  168. }
  169. //
  170. // Read tables from the storage file.
  171. //
  172. while (Status == EFI_SUCCESS) {
  173. Status = FwVol->ReadSection (
  174. FwVol,
  175. (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
  176. EFI_SECTION_RAW,
  177. Instance,
  178. (VOID**) &CurrentTable,
  179. &Size,
  180. &FvStatus
  181. );
  182. if (!EFI_ERROR(Status)) {
  183. //
  184. // Add the table
  185. //
  186. TableHeader = (EFI_ACPI_DESCRIPTION_HEADER*) (CurrentTable);
  187. //Update specfic Acpi Table
  188. //If the Table is updated failed, doesn't install it,
  189. //go to find next section.
  190. TableStatus = UpdateAcpiTable(TableHeader);
  191. if (TableStatus == EFI_SUCCESS) {
  192. TableHandle = 0;
  193. TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
  194. ASSERT (Size >= TableSize);
  195. //
  196. // Checksum ACPI table
  197. //
  198. AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
  199. //
  200. // Install ACPI table
  201. //
  202. Status = AcpiTable->InstallAcpiTable (
  203. AcpiTable,
  204. CurrentTable,
  205. TableSize,
  206. &TableHandle
  207. );
  208. }
  209. //
  210. // Free memory allocated by ReadSection
  211. //
  212. gBS->FreePool (CurrentTable);
  213. if (EFI_ERROR(Status)) {
  214. return EFI_ABORTED;
  215. }
  216. //
  217. // Increment the instance
  218. //
  219. Instance++;
  220. CurrentTable = NULL;
  221. }
  222. }
  223. return EFI_SUCCESS;
  224. }