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