]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Library/PrePiLib/PrePiLib.c
EmbeddedPkg: Replace BSD License with BSD+Patent License
[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
19 IN VOID *Pe32Data,\r
20 IN EFI_PHYSICAL_ADDRESS *ImageAddress,\r
21 IN UINT64 *ImageSize,\r
22 IN EFI_PHYSICAL_ADDRESS *EntryPoint\r
23 );\r
24\r
6ac97ad3
AB
25STATIC\r
26VOID*\r
27EFIAPI\r
28AllocateCodePages (\r
29 IN UINTN Pages\r
30 )\r
31{\r
32 VOID *Alloc;\r
33 EFI_PEI_HOB_POINTERS Hob;\r
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
47 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob));\r
48 }\r
49\r
50 ASSERT (FALSE);\r
51\r
52 FreePages (Alloc, Pages);\r
53 return NULL;\r
54}\r
55\r
1e57a462 56\r
57EFI_STATUS\r
58EFIAPI\r
59LoadPeCoffImage (\r
60 IN VOID *PeCoffImage,\r
61 OUT EFI_PHYSICAL_ADDRESS *ImageAddress,\r
62 OUT UINT64 *ImageSize,\r
63 OUT EFI_PHYSICAL_ADDRESS *EntryPoint\r
64 )\r
65{\r
66 RETURN_STATUS Status;\r
67 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
68 VOID *Buffer;\r
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 //\r
80 // Allocate Memory for the image\r
81 //\r
6ac97ad3 82 Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize));\r
1e57a462 83 ASSERT (Buffer != 0);\r
84\r
85\r
86 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
87\r
88 //\r
89 // Load the image to our new buffer\r
90 //\r
91 Status = PeCoffLoaderLoadImage (&ImageContext);\r
92 ASSERT_EFI_ERROR (Status);\r
93\r
94 //\r
95 // Relocate the image in our new buffer\r
96 //\r
97 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
98 ASSERT_EFI_ERROR (Status);\r
99\r
100\r
101 *ImageAddress = ImageContext.ImageAddress;\r
102 *ImageSize = ImageContext.ImageSize;\r
103 *EntryPoint = ImageContext.EntryPoint;\r
104\r
105 //\r
106 // Flush not needed for all architectures. We could have a processor specific\r
107 // function in this library that does the no-op if needed.\r
108 //\r
109 InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize);\r
110\r
111 return Status;\r
112}\r
113\r
114\r
115\r
3402aac7 116typedef\r
1e57a462 117VOID\r
118(EFIAPI *DXE_CORE_ENTRY_POINT) (\r
119 IN VOID *HobStart\r
120 );\r
121\r
122EFI_STATUS\r
123EFIAPI\r
124LoadDxeCoreFromFfsFile (\r
125 IN EFI_PEI_FILE_HANDLE FileHandle,\r
126 IN UINTN StackSize\r
127 )\r
128{\r
129 EFI_STATUS Status;\r
130 VOID *PeCoffImage;\r
131 EFI_PHYSICAL_ADDRESS ImageAddress;\r
132 UINT64 ImageSize;\r
133 EFI_PHYSICAL_ADDRESS EntryPoint;\r
134 VOID *BaseOfStack;\r
135 VOID *TopOfStack;\r
136 VOID *Hob;\r
137 EFI_FV_FILE_INFO FvFileInfo;\r
138\r
139 Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage);\r
140 if (EFI_ERROR (Status)) {\r
141 return Status;\r
142 }\r
143\r
3402aac7 144\r
1e57a462 145 Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);\r
146// For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);\r
147 ASSERT_EFI_ERROR (Status);\r
148\r
149 //\r
150 // Extract the DxeCore GUID file name.\r
151 //\r
152 Status = FfsGetFileInfo (FileHandle, &FvFileInfo);\r
153 ASSERT_EFI_ERROR (Status);\r
154\r
155 BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32) ImageSize) * EFI_PAGE_SIZE, EntryPoint);\r
3402aac7 156\r
1e57a462 157 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));\r
158\r
159 Hob = GetHobList ();\r
160 if (StackSize == 0) {\r
161 // User the current stack\r
3402aac7 162\r
1e57a462 163 ((DXE_CORE_ENTRY_POINT)(UINTN)EntryPoint) (Hob);\r
164 } else {\r
3402aac7 165\r
1e57a462 166 //\r
167 // Allocate 128KB for the Stack\r
168 //\r
169 BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (StackSize));\r
170 ASSERT (BaseOfStack != NULL);\r
3402aac7 171\r
1e57a462 172 //\r
173 // Compute the top of the stack we were allocated. Pre-allocate a UINTN\r
174 // for safety.\r
175 //\r
176 TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (StackSize) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);\r
177 TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
178\r
179 //\r
180 // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.\r
3402aac7 181 //\r
1e57a462 182 UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, StackSize);\r
183\r
184 SwitchStack (\r
185 (SWITCH_STACK_ENTRY_POINT)(UINTN)EntryPoint,\r
186 Hob,\r
187 NULL,\r
188 TopOfStack\r
189 );\r
190\r
191 }\r
3402aac7 192\r
1e57a462 193 // Should never get here as DXE Core does not return\r
194 DEBUG ((EFI_D_ERROR, "DxeCore returned\n"));\r
195 ASSERT (FALSE);\r
3402aac7 196\r
1e57a462 197 return EFI_DEVICE_ERROR;\r
198}\r
199\r
200\r
201\r
202EFI_STATUS\r
203EFIAPI\r
204LoadDxeCoreFromFv (\r
205 IN UINTN *FvInstance, OPTIONAL\r
206 IN UINTN StackSize\r
207 )\r
208{\r
209 EFI_STATUS Status;\r
210 EFI_PEI_FV_HANDLE VolumeHandle;\r
211 EFI_PEI_FILE_HANDLE FileHandle = NULL;\r
212\r
213 if (FvInstance != NULL) {\r
214 //\r
215 // Caller passed in a specific FV to try, so only try that one\r
216 //\r
217 Status = FfsFindNextVolume (*FvInstance, &VolumeHandle);\r
218 if (!EFI_ERROR (Status)) {\r
219 Status = FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);\r
220 }\r
221 } else {\r
222 Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
223 }\r
224\r
225 if (!EFI_ERROR (Status)) {\r
226 return LoadDxeCoreFromFfsFile (FileHandle, StackSize);\r
3402aac7
RC
227 }\r
228\r
229 return Status;\r
1e57a462 230}\r
231\r
232\r
233EFI_STATUS\r
234EFIAPI\r
235DecompressFirstFv (\r
236 VOID\r
237 )\r
238{\r
239 EFI_STATUS Status;\r
240 EFI_PEI_FV_HANDLE VolumeHandle;\r
241 EFI_PEI_FILE_HANDLE FileHandle;\r
242\r
243 Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &VolumeHandle, &FileHandle);\r
244 if (!EFI_ERROR (Status)) {\r
245 Status = FfsProcessFvFile (FileHandle);\r
246 }\r
3402aac7 247\r
1e57a462 248 return Status;\r
249}\r
250\r
251\r