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