1 /** @file
2   C functions in SEC
3 
4   Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
5   This program and the accompanying materials
6   are licensed and made available under the terms and conditions of the BSD License
7   which accompanies this distribution.  The full text of the license may be found at
8   http://opensource.org/licenses/bsd-license.php.
9 
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 
16 #include "SecMain.h"
17 
18 EFI_PEI_PPI_DESCRIPTOR            mPeiSecMainPpi[] = {
19   {
20     EFI_PEI_PPI_DESCRIPTOR_PPI,
21     &gTopOfTemporaryRamPpiGuid,
22     NULL // To be patched later.
23   },
24   {
25     EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
26     &gFspInitDonePpiGuid,
27     &gFspInitDonePpi
28   },
29 };
30 
31 FSP_INIT_DONE_PPI gFspInitDonePpi = {
32   FspInitDoneGetFspHobList
33 };
34 
35 //
36 // These are IDT entries pointing to 10:FFFFFFE4h.
37 //
38 UINT64  mIdtEntryTemplate = 0xffff8e000010ffe4ULL;
39 
40 /**
41   Caller provided function to be invoked at the end of InitializeDebugAgent().
42 
43   Entry point to the C language phase of SEC. After the SEC assembly
44   code has initialized some temporary memory and set up the stack,
45   the control is transferred to this function.
46 
47   @param[in] Context    The first input parameter of InitializeDebugAgent().
48 
49 **/
50 VOID
51 EFIAPI
52 SecStartupPhase2(
53   IN VOID                     *Context
54   );
55 
56 
57 /**
58 
59   Entry point to the C language phase of SEC. After the SEC assembly
60   code has initialized some temporary memory and set up the stack,
61   the control is transferred to this function.
62 
63   @param[in] SizeOfRam           Size of the temporary memory available for use.
64   @param[in] TempRamBase         Base address of tempory ram
65   @param[in] BootFirmwareVolume  Base address of the Boot Firmware Volume.
66 **/
67 VOID
68 EFIAPI
SecStartup(IN UINT32 SizeOfRam,IN UINT32 TempRamBase,IN VOID * BootFirmwareVolume)69 SecStartup (
70   IN UINT32                   SizeOfRam,
71   IN UINT32                   TempRamBase,
72   IN VOID                     *BootFirmwareVolume
73   )
74 {
75   EFI_SEC_PEI_HAND_OFF        SecCoreData;
76   IA32_DESCRIPTOR             IdtDescriptor;
77   SEC_IDT_TABLE               IdtTableInStack;
78   UINT32                      Index;
79   UINT32                      PeiStackSize;
80 
81   PeiStackSize = PcdGet32 (PcdPeiTemporaryRamStackSize);
82   if (PeiStackSize == 0) {
83     PeiStackSize = (SizeOfRam >> 1);
84   }
85 
86   ASSERT (PeiStackSize < SizeOfRam);
87 
88   //
89   // Process all libraries constructor function linked to SecCore.
90   //
91   ProcessLibraryConstructorList ();
92 
93   DEBUG ((DEBUG_INFO, "FspPei - SecStartup\n"));
94 
95   //
96   // Initialize floating point operating environment
97   // to be compliant with UEFI spec.
98   //
99   InitializeFloatingPointUnits ();
100 
101 
102   // |-------------------|---->
103   // |Idt Table          |
104   // |-------------------|
105   // |PeiService Pointer |    PeiStackSize
106   // |-------------------|
107   // |                   |
108   // |      Stack        |
109   // |-------------------|---->
110   // |                   |
111   // |                   |
112   // |      Heap         |    PeiTemporayRamSize
113   // |                   |
114   // |                   |
115   // |-------------------|---->  TempRamBase
116 
117   IdtTableInStack.PeiService = 0;
118   for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
119     CopyMem ((VOID*)&IdtTableInStack.IdtTable[Index], (VOID*)&mIdtEntryTemplate, sizeof (UINT64));
120   }
121 
122   IdtDescriptor.Base  = (UINTN) &IdtTableInStack.IdtTable;
123   IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
124 
125   AsmWriteIdtr (&IdtDescriptor);
126 
127   //
128   // Update the base address and length of Pei temporary memory
129   //
130   SecCoreData.DataSize               = (UINT16) sizeof (EFI_SEC_PEI_HAND_OFF);
131   SecCoreData.BootFirmwareVolumeBase = BootFirmwareVolume;
132   SecCoreData.BootFirmwareVolumeSize = (UINTN)(SIZE_4GB - (UINTN) BootFirmwareVolume);
133   SecCoreData.TemporaryRamBase       = (VOID*)(UINTN) TempRamBase;
134   SecCoreData.TemporaryRamSize       = SizeOfRam;
135   SecCoreData.PeiTemporaryRamBase    = SecCoreData.TemporaryRamBase;
136   SecCoreData.PeiTemporaryRamSize    = SizeOfRam - PeiStackSize;
137   SecCoreData.StackBase              = (VOID*)(UINTN)(TempRamBase + SecCoreData.PeiTemporaryRamSize);
138   SecCoreData.StackSize              = PeiStackSize;
139 
140   DEBUG ((DEBUG_INFO, "BootFirmwareVolumeBase - 0x%x\n", SecCoreData.BootFirmwareVolumeBase));
141   DEBUG ((DEBUG_INFO, "BootFirmwareVolumeSize - 0x%x\n", SecCoreData.BootFirmwareVolumeSize));
142   DEBUG ((DEBUG_INFO, "TemporaryRamBase       - 0x%x\n", SecCoreData.TemporaryRamBase));
143   DEBUG ((DEBUG_INFO, "TemporaryRamSize       - 0x%x\n", SecCoreData.TemporaryRamSize));
144   DEBUG ((DEBUG_INFO, "PeiTemporaryRamBase    - 0x%x\n", SecCoreData.PeiTemporaryRamBase));
145   DEBUG ((DEBUG_INFO, "PeiTemporaryRamSize    - 0x%x\n", SecCoreData.PeiTemporaryRamSize));
146   DEBUG ((DEBUG_INFO, "StackBase              - 0x%x\n", SecCoreData.StackBase));
147   DEBUG ((DEBUG_INFO, "StackSize              - 0x%x\n", SecCoreData.StackSize));
148 
149   //
150   // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
151   //
152   InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);
153 
154 }
155 
156 /**
157   This API patch the TopOfTemporaryRam value in SecPpiList.
158 
159   @param[in,out] SecPpiList           PPI list to be patched.
160   @param[in]     TopOfTemporaryRam    The top of Temporary Ram.
161 
162 **/
163 VOID
PatchTopOfTemporaryRamPpi(IN OUT EFI_PEI_PPI_DESCRIPTOR * SecPpiList,IN VOID * TopOfTemporaryRam)164 PatchTopOfTemporaryRamPpi (
165   IN OUT EFI_PEI_PPI_DESCRIPTOR *SecPpiList,
166   IN VOID                       *TopOfTemporaryRam
167   )
168 {
169   SecPpiList[0].Ppi = TopOfTemporaryRam;
170 }
171 
172 /**
173   Caller provided function to be invoked at the end of InitializeDebugAgent().
174 
175   Entry point to the C language phase of SEC. After the SEC assembly
176   code has initialized some temporary memory and set up the stack,
177   the control is transferred to this function.
178 
179   @param[in] Context    The first input parameter of InitializeDebugAgent().
180 
181 **/
182 VOID
183 EFIAPI
SecStartupPhase2(IN VOID * Context)184 SecStartupPhase2(
185   IN VOID                     *Context
186   )
187 {
188   EFI_SEC_PEI_HAND_OFF        *SecCoreData;
189   EFI_PEI_PPI_DESCRIPTOR      *PpiList;
190   UINT32                      Index;
191   EFI_PEI_PPI_DESCRIPTOR      LocalSecPpiList[sizeof(mPeiSecMainPpi)/sizeof(mPeiSecMainPpi[0])];
192   EFI_PEI_PPI_DESCRIPTOR      AllSecPpiList[FixedPcdGet32(PcdSecCoreMaxPpiSupported)];
193   EFI_PEI_CORE_ENTRY_POINT    PeiCoreEntryPoint;
194 
195   SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
196   //
197   // Find Pei Core entry point. It will report SEC and Pei Core debug information if remote debug
198   // is enabled.
199   //
200   FindAndReportEntryPoints ((EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase, &PeiCoreEntryPoint);
201   if (PeiCoreEntryPoint == NULL)
202   {
203     CpuDeadLoop ();
204   }
205 
206   CopyMem (LocalSecPpiList, mPeiSecMainPpi, sizeof(mPeiSecMainPpi));
207   PatchTopOfTemporaryRamPpi (LocalSecPpiList, (VOID *)((UINTN)SecCoreData->TemporaryRamBase + SecCoreData->TemporaryRamSize));
208 
209   //
210   // Perform platform specific initialization before entering PeiCore.
211   //
212   PpiList = SecPlatformMain (SecCoreData);
213   if (PpiList != NULL) {
214     //
215     // Remove the terminal flag from the terminal Ppi
216     //
217     CopyMem (AllSecPpiList, LocalSecPpiList, sizeof (LocalSecPpiList));
218     for (Index = 0; Index < PcdGet32 (PcdSecCoreMaxPpiSupported); Index ++) {
219       if ((AllSecPpiList[Index].Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
220         break;
221       }
222     }
223     AllSecPpiList[Index].Flags = AllSecPpiList[Index].Flags & (~EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
224 
225     //
226     // Append the platform additional Ppi list
227     //
228     Index += 1;
229     while (Index < PcdGet32 (PcdSecCoreMaxPpiSupported) &&
230            ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) != EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)) {
231       CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR));
232       Index++;
233       PpiList++;
234     }
235 
236     //
237     // Check whether the total Ppis exceeds the max supported Ppi.
238     //
239     if (Index >= PcdGet32 (PcdSecCoreMaxPpiSupported)) {
240       //
241       // the total Ppi is larger than the supported Max
242       // PcdSecCoreMaxPpiSupported can be enlarged to solve it.
243       //
244       CpuDeadLoop ();
245     } else {
246       //
247       // Add the terminal Ppi
248       //
249       CopyMem (&AllSecPpiList[Index], PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR));
250     }
251 
252     //
253     // Set PpiList to the total Ppi
254     //
255     PpiList = &AllSecPpiList[0];
256   } else {
257     //
258     // No addition Ppi, PpiList directly point to the common Ppi list.
259     //
260     PpiList = &LocalSecPpiList[0];
261   }
262 
263   //
264   // Transfer the control to the PEI core
265   //
266   ASSERT (PeiCoreEntryPoint != NULL);
267   (*PeiCoreEntryPoint) (SecCoreData, PpiList);
268 
269   //
270   // Should not come here.
271   //
272   return ;
273 }
274 
275 /**
276   Return Hob list produced by FSP.
277 
278   @param[in]  PeiServices  The pointer to the PEI Services Table.
279   @param[in]  This         The pointer to this instance of this PPI.
280   @param[out] FspHobList   The pointer to Hob list produced by FSP.
281 
282   @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.
283 **/
284 EFI_STATUS
285 EFIAPI
FspInitDoneGetFspHobList(IN CONST EFI_PEI_SERVICES ** PeiServices,IN FSP_INIT_DONE_PPI * This,OUT VOID ** FspHobList)286 FspInitDoneGetFspHobList (
287   IN  CONST EFI_PEI_SERVICES         **PeiServices,
288   IN  FSP_INIT_DONE_PPI              *This,
289   OUT VOID                           **FspHobList
290   )
291 {
292   VOID        *TopOfTemporaryRamPpi;
293   EFI_STATUS  Status;
294 
295   Status = (*PeiServices)->LocatePpi (
296                              PeiServices,
297                              &gTopOfTemporaryRamPpiGuid,
298                              0,
299                              NULL,
300                              (VOID **) &TopOfTemporaryRamPpi
301                              );
302   if (EFI_ERROR (Status)) {
303     return EFI_NOT_FOUND;
304   }
305 
306   *FspHobList = (VOID *)(UINTN)(*(UINT32 *)((UINTN)TopOfTemporaryRamPpi - sizeof(UINT32)));
307 
308   return EFI_SUCCESS;
309 }
310 
311