]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Library/PrePiLib/PrePiLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmbeddedPkg / Library / PrePiLib / PrePiLib.c
CommitLineData
1e57a462 1/** @file\r
2\r
3 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
3402aac7 4\r
878b807a 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
1e57a462 6\r
7**/\r
8\r
9#include <PrePi.h>\r
10\r
11//\r
12// Hack to work in NT32\r
13//\r
14EFI_STATUS\r
15\r
16EFIAPI\r
17\r
18SecWinNtPeiLoadFile (\r
e7108d0e
MK
19 IN VOID *Pe32Data,\r
20 IN EFI_PHYSICAL_ADDRESS *ImageAddress,\r
21 IN UINT64 *ImageSize,\r
22 IN EFI_PHYSICAL_ADDRESS *EntryPoint\r
1e57a462 23 );\r
24\r
6ac97ad3 25STATIC\r
e7108d0e 26VOID *\r
6ac97ad3
AB
27EFIAPI\r
28AllocateCodePages (\r
e7108d0e 29 IN UINTN Pages\r
6ac97ad3
AB
30 )\r
31{\r
e7108d0e
MK
32 VOID *Alloc;\r
33 EFI_PEI_HOB_POINTERS Hob;\r
6ac97ad3
AB
34\r
35 Alloc = AllocatePages (Pages);\r
36 if (Alloc == NULL) {\r
37 return NULL;\r
38 }\r
39\r
40 // find the HOB we just created, and change the type to EfiBootServicesCode\r
41 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);\r
42 while (Hob.Raw != NULL) {\r
43 if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == (UINTN)Alloc) {\r
44 Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiBootServicesCode;\r
45 return Alloc;\r
46 }\r
e7108d0e 47\r
6ac97ad3
AB
48 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob));\r
49 }\r
50\r
51 ASSERT (FALSE);\r
52\r
53 FreePages (Alloc, Pages);\r
54 return NULL;\r
55}\r
56\r
1e57a462 57EFI_STATUS\r
58EFIAPI\r
59LoadPeCoffImage (\r
e7108d0e
MK
60 IN VOID *PeCoffImage,\r
61 OUT EFI_PHYSICAL_ADDRESS *ImageAddress,\r
62 OUT UINT64 *ImageSize,\r
63 OUT EFI_PHYSICAL_ADDRESS *EntryPoint\r
1e57a462 64 )\r
65{\r
66 RETURN_STATUS Status;\r
67 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
e7108d0e 68 VOID *Buffer;\r
1e57a462 69\r
70 ZeroMem (&ImageContext, sizeof (ImageContext));\r
3402aac7 71\r
1e57a462 72 ImageContext.Handle = PeCoffImage;\r
73 ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
74\r
75 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
76 ASSERT_EFI_ERROR (Status);\r
3402aac7 77\r
1e57a462 78 //\r
79 // Allocate Memory for the image\r
80 //\r
e7108d0e 81 Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES ((UINT32)ImageContext.ImageSize));\r
1e57a462 82 ASSERT (Buffer != 0);\r
83\r
1e57a462 84 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
85\r
86 //\r
87 // Load the image to our new buffer\r
88 //\r
89 Status = PeCoffLoaderLoadImage (&ImageContext);\r
90 ASSERT_EFI_ERROR (Status);\r
91\r
92 //\r
93 // Relocate the image in our new buffer\r
94 //\r
95 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
96 ASSERT_EFI_ERROR (Status);\r
97\r
1e57a462 98 *ImageAddress = ImageContext.ImageAddress;\r
99 *ImageSize = ImageContext.ImageSize;\r
100 *EntryPoint = ImageContext.EntryPoint;\r
101\r
102 //\r
103 // Flush not needed for all architectures. We could have a processor specific\r
104 // function in this library that does the no-op if needed.\r
105 //\r
106 InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize);\r
107\r
108 return Status;\r
109}\r
110\r
3402aac7 111typedef\r
1e57a462 112VOID\r
e7108d0e 113(EFIAPI *DXE_CORE_ENTRY_POINT)(\r
1e57a462 114 IN VOID *HobStart\r
115 );\r
116\r
117EFI_STATUS\r
118EFIAPI\r
119LoadDxeCoreFromFfsFile (\r
120 IN EFI_PEI_FILE_HANDLE FileHandle,\r
121 IN UINTN StackSize\r
122 )\r
123{\r
e7108d0e
MK
124 EFI_STATUS Status;\r
125 VOID *PeCoffImage;\r
126 EFI_PHYSICAL_ADDRESS ImageAddress;\r
127 UINT64 ImageSize;\r
128 EFI_PHYSICAL_ADDRESS EntryPoint;\r
129 VOID *BaseOfStack;\r
130 VOID *TopOfStack;\r
131 VOID *Hob;\r
132 EFI_FV_FILE_INFO FvFileInfo;\r
1e57a462 133\r
0826808d 134 Status = FfsFindSectionDataWithHook (EFI_SECTION_PE32, NULL, FileHandle, &PeCoffImage);\r
e7108d0e 135 if (EFI_ERROR (Status)) {\r
1e57a462 136 return Status;\r
137 }\r
138\r
1e57a462 139 Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);\r
e7108d0e 140 // For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);\r
1e57a462 141 ASSERT_EFI_ERROR (Status);\r
142\r
143 //\r
144 // Extract the DxeCore GUID file name.\r
145 //\r
146 Status = FfsGetFileInfo (FileHandle, &FvFileInfo);\r
147 ASSERT_EFI_ERROR (Status);\r
148\r
e7108d0e 149 BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32)ImageSize) * EFI_PAGE_SIZE, EntryPoint);\r
3402aac7 150\r
a1878955 151 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));\r
1e57a462 152\r
153 Hob = GetHobList ();\r
154 if (StackSize == 0) {\r
155 // User the current stack\r
3402aac7 156\r
e7108d0e 157 ((DXE_CORE_ENTRY_POINT)(UINTN)EntryPoint)(Hob);\r
1e57a462 158 } else {\r
1e57a462 159 //\r
160 // Allocate 128KB for the Stack\r
161 //\r
162 BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (StackSize));\r
163 ASSERT (BaseOfStack != NULL);\r
3402aac7 164\r
1e57a462 165 //\r
166 // Compute the top of the stack we were allocated. Pre-allocate a UINTN\r
167 // for safety.\r
168 //\r
e7108d0e 169 TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (StackSize) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);\r
1e57a462 170 TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
171\r
172 //\r
173 // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.\r
3402aac7 174 //\r
e7108d0e 175 UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)BaseOfStack, StackSize);\r
1e57a462 176\r
177 SwitchStack (\r
178 (SWITCH_STACK_ENTRY_POINT)(UINTN)EntryPoint,\r
179 Hob,\r
180 NULL,\r
181 TopOfStack\r
182 );\r
1e57a462 183 }\r
3402aac7 184\r
1e57a462 185 // Should never get here as DXE Core does not return\r
a1878955 186 DEBUG ((DEBUG_ERROR, "DxeCore returned\n"));\r
1e57a462 187 ASSERT (FALSE);\r
3402aac7 188\r
1e57a462 189 return EFI_DEVICE_ERROR;\r
190}\r
191\r
1e57a462 192EFI_STATUS\r
193EFIAPI\r
194LoadDxeCoreFromFv (\r
79243308 195 IN UINTN *FvInstance OPTIONAL,\r
1e57a462 196 IN UINTN StackSize\r
197 )\r
198{\r
e7108d0e
MK
199 EFI_STATUS Status;\r
200 EFI_PEI_FV_HANDLE VolumeHandle;\r
201 EFI_PEI_FILE_HANDLE FileHandle = NULL;\r
1e57a462 202\r
203 if (FvInstance != NULL) {\r
204 //\r
205 // Caller passed in a specific FV to try, so only try that one\r
206 //\r
207 Status = FfsFindNextVolume (*FvInstance, &VolumeHandle);\r
208 if (!EFI_ERROR (Status)) {\r
209 Status = FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);\r
210 }\r
211 } else {\r
212 Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
213 }\r
214\r
215 if (!EFI_ERROR (Status)) {\r
216 return LoadDxeCoreFromFfsFile (FileHandle, StackSize);\r
3402aac7
RC
217 }\r
218\r
219 return Status;\r
1e57a462 220}\r
221\r
1e57a462 222EFI_STATUS\r
223EFIAPI\r
224DecompressFirstFv (\r
225 VOID\r
226 )\r
227{\r
e7108d0e
MK
228 EFI_STATUS Status;\r
229 EFI_PEI_FV_HANDLE VolumeHandle;\r
230 EFI_PEI_FILE_HANDLE FileHandle;\r
1e57a462 231\r
232 Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &VolumeHandle, &FileHandle);\r
233 if (!EFI_ERROR (Status)) {\r
234 Status = FfsProcessFvFile (FileHandle);\r
235 }\r
3402aac7 236\r
1e57a462 237 return Status;\r
238}\r