1. Do not use tab characters 2. No trailing white space in one line 3. All files must end with CRLF Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Liming Gao <liming.gao@intel.com>
		
			
				
	
	
		
			205 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  This is an implementation of the ACPI S3 Save protocol.  This is defined in
 | 
						|
  S3 boot path specification 0.9.
 | 
						|
 | 
						|
Copyright (c) 2006 - 2018, 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 <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/UefiBootServicesTableLib.h>
 | 
						|
#include <Library/PcdLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Protocol/AcpiS3Save.h>
 | 
						|
 | 
						|
#include "AcpiS3Save.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Hook point for AcpiVariableThunkPlatform for InstallAcpiS3Save.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
InstallAcpiS3SaveThunk (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Hook point for AcpiVariableThunkPlatform for S3Ready.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
S3ReadyThunkPlatform (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
UINTN     mLegacyRegionSize;
 | 
						|
 | 
						|
EFI_ACPI_S3_SAVE_PROTOCOL mS3Save = {
 | 
						|
  LegacyGetS3MemorySize,
 | 
						|
  S3Ready,
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Allocate memory below 4G memory address.
 | 
						|
 | 
						|
  This function allocates memory below 4G memory address.
 | 
						|
 | 
						|
  @param  MemoryType   Memory type of memory to allocate.
 | 
						|
  @param  Size         Size of memory to allocate.
 | 
						|
 | 
						|
  @return Allocated address for output.
 | 
						|
 | 
						|
**/
 | 
						|
VOID*
 | 
						|
AllocateMemoryBelow4G (
 | 
						|
  IN EFI_MEMORY_TYPE    MemoryType,
 | 
						|
  IN UINTN              Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                 Pages;
 | 
						|
  EFI_PHYSICAL_ADDRESS  Address;
 | 
						|
  EFI_STATUS            Status;
 | 
						|
  VOID*                 Buffer;
 | 
						|
 | 
						|
  Pages = EFI_SIZE_TO_PAGES (Size);
 | 
						|
  Address = 0xffffffff;
 | 
						|
 | 
						|
  Status  = gBS->AllocatePages (
 | 
						|
                   AllocateMaxAddress,
 | 
						|
                   MemoryType,
 | 
						|
                   Pages,
 | 
						|
                   &Address
 | 
						|
                   );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  Buffer = (VOID *) (UINTN) Address;
 | 
						|
  ZeroMem (Buffer, Size);
 | 
						|
 | 
						|
  return Buffer;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Gets the buffer of legacy memory below 1 MB
 | 
						|
  This function is to get the buffer in legacy memory below 1MB that is required during S3 resume.
 | 
						|
 | 
						|
  @param This           A pointer to the EFI_ACPI_S3_SAVE_PROTOCOL instance.
 | 
						|
  @param Size           The returned size of legacy memory below 1 MB.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           Size is successfully returned.
 | 
						|
  @retval EFI_INVALID_PARAMETER The pointer Size is NULL.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
LegacyGetS3MemorySize (
 | 
						|
  IN  EFI_ACPI_S3_SAVE_PROTOCOL   *This,
 | 
						|
  OUT UINTN                       *Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Size == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *Size = mLegacyRegionSize;
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Prepares all information that is needed in the S3 resume boot path.
 | 
						|
 | 
						|
  Allocate the resources or prepare informations and save in ACPI variable set for S3 resume boot path
 | 
						|
 | 
						|
  @param This                 A pointer to the EFI_ACPI_S3_SAVE_PROTOCOL instance.
 | 
						|
  @param LegacyMemoryAddress  The base address of legacy memory.
 | 
						|
 | 
						|
  @retval EFI_NOT_FOUND         Some necessary information cannot be found.
 | 
						|
  @retval EFI_SUCCESS           All information was saved successfully.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  Resources were insufficient to save all the information.
 | 
						|
  @retval EFI_INVALID_PARAMETER The memory range is not located below 1 MB.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
S3Ready (
 | 
						|
  IN EFI_ACPI_S3_SAVE_PROTOCOL    *This,
 | 
						|
  IN VOID                         *LegacyMemoryAddress
 | 
						|
  )
 | 
						|
{
 | 
						|
  STATIC BOOLEAN                  AlreadyEntered;
 | 
						|
 | 
						|
  DEBUG ((EFI_D_INFO, "S3Ready!\n"));
 | 
						|
 | 
						|
  //
 | 
						|
  // Platform may invoke AcpiS3Save->S3Save() before ExitPmAuth, because we need save S3 information there, while BDS ReadyToBoot may invoke it again.
 | 
						|
  // So if 2nd S3Save() is triggered later, we need ignore it.
 | 
						|
  //
 | 
						|
  if (AlreadyEntered) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
  AlreadyEntered = TRUE;
 | 
						|
 | 
						|
  if (FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {
 | 
						|
    S3ReadyThunkPlatform ();
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  The Driver Entry Point.
 | 
						|
 | 
						|
  The function is the driver Entry point which will produce AcpiS3SaveProtocol.
 | 
						|
 | 
						|
  @param ImageHandle   A handle for the image that is initializing this driver
 | 
						|
  @param SystemTable   A pointer to the EFI system table
 | 
						|
 | 
						|
  @retval EFI_SUCCESS               Driver initialized successfully
 | 
						|
  @retval EFI_UNSUPPORTED           Do not support ACPI S3
 | 
						|
  @retval EFI_OUT_OF_RESOURCES      Could not allocate needed resources
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
InstallAcpiS3Save (
 | 
						|
  IN EFI_HANDLE           ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE     *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS        Status;
 | 
						|
 | 
						|
  if (!PcdGetBool (PcdAcpiS3Enable)) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!FeaturePcdGet(PcdPlatformCsmSupport)) {
 | 
						|
    //
 | 
						|
    // More memory for no CSM tip, because GDT need relocation
 | 
						|
    //
 | 
						|
    mLegacyRegionSize = 0x250;
 | 
						|
  } else {
 | 
						|
    mLegacyRegionSize = 0x100;
 | 
						|
  }
 | 
						|
 | 
						|
  if (FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {
 | 
						|
    InstallAcpiS3SaveThunk ();
 | 
						|
  }
 | 
						|
 | 
						|
  Status = gBS->InstallProtocolInterface (
 | 
						|
                  &ImageHandle,
 | 
						|
                  &gEfiAcpiS3SaveProtocolGuid,
 | 
						|
                  EFI_NATIVE_INTERFACE,
 | 
						|
                  &mS3Save
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
  return Status;
 | 
						|
}
 |