Signed-off-by: lzeng14 Reviewed-by: ZhangCaoIntel git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12811 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			261 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			261 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Sample ACPI Platform Driver
 | |
| 
 | |
|   Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
 | |
|   This program and the accompanying materials
 | |
|   are licensed and made available under the terms and conditions of the BSD License
 | |
|   which accompanies this distribution.  The full text of the license may be found at
 | |
|   http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
|   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
|   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/ 
 | |
| 
 | |
| #include <PiDxe.h>
 | |
| 
 | |
| #include <Protocol/AcpiTable.h>
 | |
| #include <Protocol/FirmwareVolume2.h>
 | |
| 
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/UefiBootServicesTableLib.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/PcdLib.h>
 | |
| 
 | |
| #include <IndustryStandard/Acpi.h>
 | |
| 
 | |
| /**
 | |
|   Locate the first instance of a protocol.  If the protocol requested is an
 | |
|   FV protocol, then it will return the first FV that contains the ACPI table
 | |
|   storage file.
 | |
| 
 | |
|   @param  Instance      Return pointer to the first instance of the protocol
 | |
| 
 | |
|   @return EFI_SUCCESS           The function completed successfully.
 | |
|   @return EFI_NOT_FOUND         The protocol could not be located.
 | |
|   @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| LocateFvInstanceWithTables (
 | |
|   OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                    Status;
 | |
|   EFI_HANDLE                    *HandleBuffer;
 | |
|   UINTN                         NumberOfHandles;
 | |
|   EFI_FV_FILETYPE               FileType;
 | |
|   UINT32                        FvStatus;
 | |
|   EFI_FV_FILE_ATTRIBUTES        Attributes;
 | |
|   UINTN                         Size;
 | |
|   UINTN                         Index;
 | |
|   EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
 | |
| 
 | |
|   FvStatus = 0;
 | |
| 
 | |
|   //
 | |
|   // Locate protocol.
 | |
|   //
 | |
|   Status = gBS->LocateHandleBuffer (
 | |
|                    ByProtocol,
 | |
|                    &gEfiFirmwareVolume2ProtocolGuid,
 | |
|                    NULL,
 | |
|                    &NumberOfHandles,
 | |
|                    &HandleBuffer
 | |
|                    );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     //
 | |
|     // Defined errors at this time are not found and out of resources.
 | |
|     //
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
| 
 | |
| 
 | |
|   //
 | |
|   // Looking for FV with ACPI storage file
 | |
|   //
 | |
| 
 | |
|   for (Index = 0; Index < NumberOfHandles; Index++) {
 | |
|     //
 | |
|     // Get the protocol on this handle
 | |
|     // This should not fail because of LocateHandleBuffer
 | |
|     //
 | |
|     Status = gBS->HandleProtocol (
 | |
|                      HandleBuffer[Index],
 | |
|                      &gEfiFirmwareVolume2ProtocolGuid,
 | |
|                      (VOID**) &FvInstance
 | |
|                      );
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|     //
 | |
|     // See if it has the ACPI storage file
 | |
|     //
 | |
|     Status = FvInstance->ReadFile (
 | |
|                            FvInstance,
 | |
|                            (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
 | |
|                            NULL,
 | |
|                            &Size,
 | |
|                            &FileType,
 | |
|                            &Attributes,
 | |
|                            &FvStatus
 | |
|                            );
 | |
| 
 | |
|     //
 | |
|     // If we found it, then we are done
 | |
|     //
 | |
|     if (Status == EFI_SUCCESS) {
 | |
|       *Instance = FvInstance;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Our exit status is determined by the success of the previous operations
 | |
|   // If the protocol was found, Instance already points to it.
 | |
|   //
 | |
| 
 | |
|   //
 | |
|   // Free any allocated buffers
 | |
|   //
 | |
|   gBS->FreePool (HandleBuffer);
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   This function calculates and updates an UINT8 checksum.
 | |
| 
 | |
|   @param  Buffer          Pointer to buffer to checksum
 | |
|   @param  Size            Number of bytes to checksum
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| AcpiPlatformChecksum (
 | |
|   IN UINT8      *Buffer,
 | |
|   IN UINTN      Size
 | |
|   )
 | |
| {
 | |
|   UINTN ChecksumOffset;
 | |
| 
 | |
|   ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);
 | |
| 
 | |
|   //
 | |
|   // Set checksum to 0 first
 | |
|   //
 | |
|   Buffer[ChecksumOffset] = 0;
 | |
| 
 | |
|   //
 | |
|   // Update checksum value
 | |
|   //
 | |
|   Buffer[ChecksumOffset] = CalculateCheckSum8(Buffer, Size);
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Entrypoint of Acpi Platform driver.
 | |
| 
 | |
|   @param  ImageHandle
 | |
|   @param  SystemTable
 | |
| 
 | |
|   @return EFI_SUCCESS
 | |
|   @return EFI_LOAD_ERROR
 | |
|   @return EFI_OUT_OF_RESOURCES
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AcpiPlatformEntryPoint (
 | |
|   IN EFI_HANDLE         ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE   *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                     Status;
 | |
|   EFI_ACPI_TABLE_PROTOCOL        *AcpiTable;
 | |
|   EFI_FIRMWARE_VOLUME2_PROTOCOL  *FwVol;
 | |
|   INTN                           Instance;
 | |
|   EFI_ACPI_COMMON_HEADER         *CurrentTable;
 | |
|   UINTN                          TableHandle;
 | |
|   UINT32                         FvStatus;
 | |
|   UINTN                          TableSize;
 | |
|   UINTN                          Size;
 | |
| 
 | |
|   Instance     = 0;
 | |
|   CurrentTable = NULL;
 | |
|   TableHandle  = 0;
 | |
| 
 | |
|   //
 | |
|   // Find the AcpiTable protocol
 | |
|   //
 | |
|   Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return EFI_ABORTED;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Locate the firmware volume protocol
 | |
|   //
 | |
|   Status = LocateFvInstanceWithTables (&FwVol);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return EFI_ABORTED;
 | |
|   }
 | |
|   //
 | |
|   // Read tables from the storage file.
 | |
|   //
 | |
|   while (Status == EFI_SUCCESS) {
 | |
| 
 | |
|     Status = FwVol->ReadSection (
 | |
|                       FwVol,
 | |
|                       (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),
 | |
|                       EFI_SECTION_RAW,
 | |
|                       Instance,
 | |
|                       (VOID**) &CurrentTable,
 | |
|                       &Size,
 | |
|                       &FvStatus
 | |
|                       );
 | |
|     if (!EFI_ERROR(Status)) {
 | |
|       //
 | |
|       // Add the table
 | |
|       //
 | |
|       TableHandle = 0;
 | |
| 
 | |
|       TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
 | |
|       ASSERT (Size >= TableSize);
 | |
| 
 | |
|       //
 | |
|       // Checksum ACPI table
 | |
|       //
 | |
|       AcpiPlatformChecksum ((UINT8*)CurrentTable, TableSize);
 | |
| 
 | |
|       //
 | |
|       // Install ACPI table
 | |
|       //
 | |
|       Status = AcpiTable->InstallAcpiTable (
 | |
|                             AcpiTable,
 | |
|                             CurrentTable,
 | |
|                             TableSize,
 | |
|                             &TableHandle
 | |
|                             );
 | |
| 
 | |
|       //
 | |
|       // Free memory allocated by ReadSection
 | |
|       //
 | |
|       gBS->FreePool (CurrentTable);
 | |
| 
 | |
|       if (EFI_ERROR(Status)) {
 | |
|         return EFI_ABORTED;
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // Increment the instance
 | |
|       //
 | |
|       Instance++;
 | |
|       CurrentTable = NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 |