- inforamtion -> information - tempory -> temporary - boundry -> boundary - immediatly -> immediately - permenent -> permanent Cc: Jiewen Yao <jiewen.yao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Gary Lin <glin@suse.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Giri P Mudusuru <giri.p.mudusuru@intel.com>
		
			
				
	
	
		
			155 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Sample to provide SecTemporaryRamSupport function.
 | 
						|
 | 
						|
  Copyright (c) 2014, 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 <PiPei.h>
 | 
						|
 | 
						|
#include <Ppi/TemporaryRamSupport.h>
 | 
						|
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/PcdLib.h>
 | 
						|
#include <Library/DebugAgentLib.h>
 | 
						|
 | 
						|
/**
 | 
						|
  Switch the stack in the temporary memory to the one in the permanent memory.
 | 
						|
 | 
						|
  This function must be invoked after the memory migration immediately. The relative
 | 
						|
  position of the stack in the temporary and permanent memory is same.
 | 
						|
 | 
						|
  @param[in] TemporaryMemoryBase  Base address of the temporary memory.
 | 
						|
  @param[in] PermenentMemoryBase  Base address of the permanent memory.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SecSwitchStack (
 | 
						|
  IN UINT32   TemporaryMemoryBase,
 | 
						|
  IN UINT32   PermenentMemoryBase
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
 | 
						|
  permanent memory.
 | 
						|
 | 
						|
  @param[in] PeiServices            Pointer to the PEI Services Table.
 | 
						|
  @param[in] TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the
 | 
						|
                                    Temporary RAM contents.
 | 
						|
  @param[in] PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the
 | 
						|
                                    Temporary RAM contents.
 | 
						|
  @param[in] CopySize               Amount of memory to migrate from temporary to permanent memory.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The data was successfully returned.
 | 
						|
  @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
 | 
						|
                                TemporaryMemoryBase > PermanentMemoryBase.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SecTemporaryRamSupport (
 | 
						|
  IN CONST EFI_PEI_SERVICES   **PeiServices,
 | 
						|
  IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
 | 
						|
  IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
 | 
						|
  IN UINTN                    CopySize
 | 
						|
  )
 | 
						|
{
 | 
						|
  IA32_DESCRIPTOR   IdtDescriptor;
 | 
						|
  VOID*             OldHeap;
 | 
						|
  VOID*             NewHeap;
 | 
						|
  VOID*             OldStack;
 | 
						|
  VOID*             NewStack;
 | 
						|
  DEBUG_AGENT_CONTEXT_POSTMEM_SEC  DebugAgentContext;
 | 
						|
  BOOLEAN           OldStatus;
 | 
						|
  UINTN             PeiStackSize;
 | 
						|
 | 
						|
  PeiStackSize = (UINTN)PcdGet32 (PcdPeiTemporaryRamStackSize);
 | 
						|
  if (PeiStackSize == 0) {
 | 
						|
    PeiStackSize = (CopySize >> 1);
 | 
						|
  }
 | 
						|
 | 
						|
  ASSERT (PeiStackSize < CopySize);
 | 
						|
 | 
						|
  //
 | 
						|
  // |-------------------|---->
 | 
						|
  // |      Stack        |    PeiStackSize
 | 
						|
  // |-------------------|---->
 | 
						|
  // |      Heap         |    PeiTemporayRamSize
 | 
						|
  // |-------------------|---->  TempRamBase
 | 
						|
  //
 | 
						|
  // |-------------------|---->
 | 
						|
  // |      Heap         |    PeiTemporayRamSize
 | 
						|
  // |-------------------|---->
 | 
						|
  // |      Stack        |    PeiStackSize
 | 
						|
  // |-------------------|---->  PermanentMemoryBase
 | 
						|
  //
 | 
						|
 | 
						|
  OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
 | 
						|
  NewHeap = (VOID*)((UINTN)PermanentMemoryBase + PeiStackSize);
 | 
						|
 | 
						|
  OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize - PeiStackSize);
 | 
						|
  NewStack = (VOID*)(UINTN)PermanentMemoryBase;
 | 
						|
 | 
						|
  DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
 | 
						|
  DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
 | 
						|
 | 
						|
  OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
 | 
						|
  //
 | 
						|
  // Initialize Debug Agent to support source level debug in PEI phase after memory ready.
 | 
						|
  // It will build HOB and fix up the pointer in IDT table.
 | 
						|
  //
 | 
						|
  InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Migrate Heap
 | 
						|
  //
 | 
						|
  CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize);
 | 
						|
 | 
						|
  //
 | 
						|
  // Migrate Stack
 | 
						|
  //
 | 
						|
  CopyMem (NewStack, OldStack, PeiStackSize);
 | 
						|
 | 
						|
 | 
						|
  //
 | 
						|
  // We need *not* fix the return address because currently,
 | 
						|
  // The PeiCore is executed in flash.
 | 
						|
  //
 | 
						|
 | 
						|
  //
 | 
						|
  // Rebase IDT table in permanent memory
 | 
						|
  //
 | 
						|
  AsmReadIdtr (&IdtDescriptor);
 | 
						|
  IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
 | 
						|
 | 
						|
  AsmWriteIdtr (&IdtDescriptor);
 | 
						|
 | 
						|
 | 
						|
  //
 | 
						|
  // Program MTRR
 | 
						|
  //
 | 
						|
 | 
						|
  //
 | 
						|
  // SecSwitchStack function must be invoked after the memory migration
 | 
						|
  // immediately, also we need fixup the stack change caused by new call into
 | 
						|
  // permanent memory.
 | 
						|
  //
 | 
						|
  SecSwitchStack (
 | 
						|
    (UINT32) (UINTN) OldStack,
 | 
						|
    (UINT32) (UINTN) NewStack
 | 
						|
    );
 | 
						|
 | 
						|
  SaveAndSetDebugTimerInterrupt (OldStatus);
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 |