• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
4   This program and the accompanying materials
5   are licensed and made available under the terms and conditions of the BSD License
6   which accompanies this distribution.  The full text of the license may be found at
7   http://opensource.org/licenses/bsd-license.php.
8 
9   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 
12 **/
13 
14 #include "SecMain.h"
15 #include "SecFsp.h"
16 
17 EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = {
18   SecTemporaryRamSupport
19 };
20 
21 EFI_PEI_PPI_DESCRIPTOR            mPeiSecPlatformInformationPpi[] = {
22   {
23     (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
24     &gEfiTemporaryRamSupportPpiGuid,
25     &gSecTemporaryRamSupportPpi
26   }
27 };
28 
29 //
30 // These are IDT entries pointing to 08:FFFFFFE4h.
31 //
32 UINT64  mIdtEntryTemplate = 0xffff8e000008ffe4ULL;
33 
34 /**
35 
36   Entry point to the C language phase of SEC. After the SEC assembly
37   code has initialized some temporary memory and set up the stack,
38   the control is transferred to this function.
39 
40 
41   @param[in] SizeOfRam          Size of the temporary memory available for use.
42   @param[in] TempRamBase        Base address of temporary ram
43   @param[in] BootFirmwareVolume Base address of the Boot Firmware Volume.
44   @param[in] PeiCore            PeiCore entry point.
45   @param[in] BootLoaderStack    BootLoader stack.
46   @param[in] ApiIdx             the index of API.
47 
48   @return This function never returns.
49 
50 **/
51 VOID
52 EFIAPI
SecStartup(IN UINT32 SizeOfRam,IN UINT32 TempRamBase,IN VOID * BootFirmwareVolume,IN PEI_CORE_ENTRY PeiCore,IN UINT32 BootLoaderStack,IN UINT32 ApiIdx)53 SecStartup (
54   IN UINT32                   SizeOfRam,
55   IN UINT32                   TempRamBase,
56   IN VOID                    *BootFirmwareVolume,
57   IN PEI_CORE_ENTRY           PeiCore,
58   IN UINT32                   BootLoaderStack,
59   IN UINT32                   ApiIdx
60   )
61 {
62   EFI_SEC_PEI_HAND_OFF        SecCoreData;
63   IA32_DESCRIPTOR             IdtDescriptor;
64   SEC_IDT_TABLE               IdtTableInStack;
65   UINT32                      Index;
66   FSP_GLOBAL_DATA             PeiFspData;
67   UINT64                      ExceptionHandler;
68 
69   //
70   // Process all libraries constructor function linked to SecCore.
71   //
72   ProcessLibraryConstructorList ();
73 
74   //
75   // Initialize floating point operating environment
76   // to be compliant with UEFI spec.
77   //
78   InitializeFloatingPointUnits ();
79 
80 
81   // |-------------------|---->
82   // |Idt Table          |
83   // |-------------------|
84   // |PeiService Pointer |    PeiStackSize
85   // |-------------------|
86   // |                   |
87   // |      Stack        |
88   // |-------------------|---->
89   // |                   |
90   // |                   |
91   // |      Heap         |    PeiTemporayRamSize
92   // |                   |
93   // |                   |
94   // |-------------------|---->  TempRamBase
95   IdtTableInStack.PeiService  = NULL;
96   ExceptionHandler = FspGetExceptionHandler(mIdtEntryTemplate);
97   for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
98     CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&ExceptionHandler, sizeof (UINT64));
99   }
100 
101   IdtDescriptor.Base  = (UINTN) &IdtTableInStack.IdtTable;
102   IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
103 
104   AsmWriteIdtr (&IdtDescriptor);
105 
106   //
107   // Initialize the global FSP data region
108   //
109   FspGlobalDataInit (&PeiFspData, BootLoaderStack, (UINT8)ApiIdx);
110 
111   //
112   // Update the base address and length of Pei temporary memory
113   //
114   SecCoreData.DataSize               = sizeof (EFI_SEC_PEI_HAND_OFF);
115   SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;
116   SecCoreData.BootFirmwareVolumeSize = (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *)BootFirmwareVolume)->FvLength;
117 
118   SecCoreData.TemporaryRamBase       = (VOID*)(UINTN) TempRamBase;
119   SecCoreData.TemporaryRamSize       = SizeOfRam;
120   SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
121   SecCoreData.PeiTemporaryRamSize    = SecCoreData.TemporaryRamSize * PcdGet8 (PcdFspHeapSizePercentage) / 100;
122   SecCoreData.StackBase              = (VOID*)(UINTN)((UINTN)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize);
123   SecCoreData.StackSize              = SecCoreData.TemporaryRamSize - SecCoreData.PeiTemporaryRamSize;
124 
125   DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));
126   DEBUG ((DEBUG_INFO, "Fsp BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));
127   DEBUG ((DEBUG_INFO, "Fsp TemporaryRamBase       - 0x%x\n", SecCoreData.TemporaryRamBase));
128   DEBUG ((DEBUG_INFO, "Fsp TemporaryRamSize       - 0x%x\n", SecCoreData.TemporaryRamSize));
129   DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamBase    - 0x%x\n", SecCoreData.PeiTemporaryRamBase));
130   DEBUG ((DEBUG_INFO, "Fsp PeiTemporaryRamSize    - 0x%x\n", SecCoreData.PeiTemporaryRamSize));
131   DEBUG ((DEBUG_INFO, "Fsp StackBase              - 0x%x\n", SecCoreData.StackBase));
132   DEBUG ((DEBUG_INFO, "Fsp StackSize              - 0x%x\n", SecCoreData.StackSize));
133 
134   //
135   // Call PeiCore Entry
136   //
137   PeiCore (&SecCoreData, mPeiSecPlatformInformationPpi);
138 
139   //
140   // Should never be here
141   //
142   CpuDeadLoop ();
143 }
144 
145 /**
146   This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into
147   permanent memory.
148 
149   @param[in] PeiServices            Pointer to the PEI Services Table.
150   @param[in] TemporaryMemoryBase    Source Address in temporary memory from which the SEC or PEIM will copy the
151                                 Temporary RAM contents.
152   @param[in] PermanentMemoryBase    Destination Address in permanent memory into which the SEC or PEIM will copy the
153                                 Temporary RAM contents.
154   @param[in] CopySize               Amount of memory to migrate from temporary to permanent memory.
155 
156   @retval EFI_SUCCESS           The data was successfully returned.
157   @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when
158                                 TemporaryMemoryBase > PermanentMemoryBase.
159 
160 **/
161 EFI_STATUS
162 EFIAPI
SecTemporaryRamSupport(IN CONST EFI_PEI_SERVICES ** PeiServices,IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,IN UINTN CopySize)163 SecTemporaryRamSupport (
164   IN CONST EFI_PEI_SERVICES   **PeiServices,
165   IN EFI_PHYSICAL_ADDRESS     TemporaryMemoryBase,
166   IN EFI_PHYSICAL_ADDRESS     PermanentMemoryBase,
167   IN UINTN                    CopySize
168   )
169 {
170   IA32_DESCRIPTOR   IdtDescriptor;
171   VOID*             OldHeap;
172   VOID*             NewHeap;
173   VOID*             OldStack;
174   VOID*             NewStack;
175   UINTN             HeapSize;
176   UINTN             StackSize;
177 
178   HeapSize   = CopySize * PcdGet8 (PcdFspHeapSizePercentage) / 100 ;
179   StackSize  = CopySize - HeapSize;
180 
181   OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
182   NewHeap = (VOID*)((UINTN)PermanentMemoryBase + StackSize);
183 
184   OldStack = (VOID*)((UINTN)TemporaryMemoryBase + HeapSize);
185   NewStack = (VOID*)(UINTN)PermanentMemoryBase;
186 
187   //
188   // Migrate Heap
189   //
190   CopyMem (NewHeap, OldHeap, HeapSize);
191 
192   //
193   // Migrate Stack
194   //
195   CopyMem (NewStack, OldStack, StackSize);
196 
197 
198   //
199   // We need *not* fix the return address because currently,
200   // The PeiCore is executed in flash.
201   //
202 
203   //
204   // Rebase IDT table in permanent memory
205   //
206   AsmReadIdtr (&IdtDescriptor);
207   IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
208 
209   AsmWriteIdtr (&IdtDescriptor);
210 
211   //
212   // Fixed the FSP data pointer
213   //
214   FspDataPointerFixUp ((UINTN)NewStack - (UINTN)OldStack);
215 
216   //
217   // SecSwitchStack function must be invoked after the memory migration
218   // immediately, also we need fixup the stack change caused by new call into
219   // permanent memory.
220   //
221   SecSwitchStack (
222     (UINT32) (UINTN) OldStack,
223     (UINT32) (UINTN) NewStack
224     );
225 
226   return EFI_SUCCESS;
227 }
228