git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10087 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			255 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			255 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Sample ACPI Platform Driver
 | 
						|
 | 
						|
  Copyright (c) 2008 - 2010, Intel Corporation<BR>
 | 
						|
  All rights reserved. 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
 | 
						|
                            );
 | 
						|
      if (EFI_ERROR(Status)) {
 | 
						|
        return EFI_ABORTED;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Increment the instance
 | 
						|
      //
 | 
						|
      Instance++;
 | 
						|
      CurrentTable = NULL;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 |