mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-30 18:53:45 +01:00 
			
		
		
		
	Contributed-under: TianoCore Contribution Agreement 1.0 Signed off by: Jiewen Yao <jiewen.yao@intel.com> Reviewed by: Ravi Rangarajan <ravi.p.rangarajan@intel.com> Reviewed by: Maurice Ma <maurice.ma@intel.com> Reviewed by: Giri Mudusuru <giri.p.mudusuru@intel.com> Reviewed by: Liming Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15676 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			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
 | |
|   // immediatly, also we need fixup the stack change caused by new call into
 | |
|   // permenent memory.
 | |
|   //
 | |
|   SecSwitchStack (
 | |
|     (UINT32) (UINTN) OldStack,
 | |
|     (UINT32) (UINTN) NewStack
 | |
|     );
 | |
| 
 | |
|   SaveAndSetDebugTimerInterrupt (OldStatus);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 |