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 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 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 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