]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Library/PrePiLib/PrePiLib.c
EmbeddedPkg/GdbSerialLib: avoid left shift of negative quantity
[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
1e57a462 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PrePi.h>\r
16\r
17//\r
18// Hack to work in NT32\r
19//\r
20EFI_STATUS\r
21\r
22EFIAPI\r
23\r
24SecWinNtPeiLoadFile (\r
25 IN VOID *Pe32Data,\r
26 IN EFI_PHYSICAL_ADDRESS *ImageAddress,\r
27 IN UINT64 *ImageSize,\r
28 IN EFI_PHYSICAL_ADDRESS *EntryPoint\r
29 );\r
30\r
6ac97ad3
AB
31STATIC\r
32VOID*\r
33EFIAPI\r
34AllocateCodePages (\r
35 IN UINTN Pages\r
36 )\r
37{\r
38 VOID *Alloc;\r
39 EFI_PEI_HOB_POINTERS Hob;\r
40\r
41 Alloc = AllocatePages (Pages);\r
42 if (Alloc == NULL) {\r
43 return NULL;\r
44 }\r
45\r
46 // find the HOB we just created, and change the type to EfiBootServicesCode\r
47 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);\r
48 while (Hob.Raw != NULL) {\r
49 if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == (UINTN)Alloc) {\r
50 Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiBootServicesCode;\r
51 return Alloc;\r
52 }\r
53 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, GET_NEXT_HOB (Hob));\r
54 }\r
55\r
56 ASSERT (FALSE);\r
57\r
58 FreePages (Alloc, Pages);\r
59 return NULL;\r
60}\r
61\r
1e57a462 62\r
63EFI_STATUS\r
64EFIAPI\r
65LoadPeCoffImage (\r
66 IN VOID *PeCoffImage,\r
67 OUT EFI_PHYSICAL_ADDRESS *ImageAddress,\r
68 OUT UINT64 *ImageSize,\r
69 OUT EFI_PHYSICAL_ADDRESS *EntryPoint\r
70 )\r
71{\r
72 RETURN_STATUS Status;\r
73 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
74 VOID *Buffer;\r
75\r
76 ZeroMem (&ImageContext, sizeof (ImageContext));\r
3402aac7 77\r
1e57a462 78 ImageContext.Handle = PeCoffImage;\r
79 ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
80\r
81 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
82 ASSERT_EFI_ERROR (Status);\r
3402aac7 83\r
1e57a462 84\r
85 //\r
86 // Allocate Memory for the image\r
87 //\r
6ac97ad3 88 Buffer = AllocateCodePages (EFI_SIZE_TO_PAGES((UINT32)ImageContext.ImageSize));\r
1e57a462 89 ASSERT (Buffer != 0);\r
90\r
91\r
92 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
93\r
94 //\r
95 // Load the image to our new buffer\r
96 //\r
97 Status = PeCoffLoaderLoadImage (&ImageContext);\r
98 ASSERT_EFI_ERROR (Status);\r
99\r
100 //\r
101 // Relocate the image in our new buffer\r
102 //\r
103 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
104 ASSERT_EFI_ERROR (Status);\r
105\r
106\r
107 *ImageAddress = ImageContext.ImageAddress;\r
108 *ImageSize = ImageContext.ImageSize;\r
109 *EntryPoint = ImageContext.EntryPoint;\r
110\r
111 //\r
112 // Flush not needed for all architectures. We could have a processor specific\r
113 // function in this library that does the no-op if needed.\r
114 //\r
115 InvalidateInstructionCacheRange ((VOID *)(UINTN)*ImageAddress, (UINTN)*ImageSize);\r
116\r
117 return Status;\r
118}\r
119\r
120\r
121\r
3402aac7 122typedef\r
1e57a462 123VOID\r
124(EFIAPI *DXE_CORE_ENTRY_POINT) (\r
125 IN VOID *HobStart\r
126 );\r
127\r
128EFI_STATUS\r
129EFIAPI\r
130LoadDxeCoreFromFfsFile (\r
131 IN EFI_PEI_FILE_HANDLE FileHandle,\r
132 IN UINTN StackSize\r
133 )\r
134{\r
135 EFI_STATUS Status;\r
136 VOID *PeCoffImage;\r
137 EFI_PHYSICAL_ADDRESS ImageAddress;\r
138 UINT64 ImageSize;\r
139 EFI_PHYSICAL_ADDRESS EntryPoint;\r
140 VOID *BaseOfStack;\r
141 VOID *TopOfStack;\r
142 VOID *Hob;\r
143 EFI_FV_FILE_INFO FvFileInfo;\r
144\r
145 Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage);\r
146 if (EFI_ERROR (Status)) {\r
147 return Status;\r
148 }\r
149\r
3402aac7 150\r
1e57a462 151 Status = LoadPeCoffImage (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);\r
152// For NT32 Debug Status = SecWinNtPeiLoadFile (PeCoffImage, &ImageAddress, &ImageSize, &EntryPoint);\r
153 ASSERT_EFI_ERROR (Status);\r
154\r
155 //\r
156 // Extract the DxeCore GUID file name.\r
157 //\r
158 Status = FfsGetFileInfo (FileHandle, &FvFileInfo);\r
159 ASSERT_EFI_ERROR (Status);\r
160\r
161 BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, EFI_SIZE_TO_PAGES ((UINT32) ImageSize) * EFI_PAGE_SIZE, EntryPoint);\r
3402aac7 162\r
1e57a462 163 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));\r
164\r
165 Hob = GetHobList ();\r
166 if (StackSize == 0) {\r
167 // User the current stack\r
3402aac7 168\r
1e57a462 169 ((DXE_CORE_ENTRY_POINT)(UINTN)EntryPoint) (Hob);\r
170 } else {\r
3402aac7 171\r
1e57a462 172 //\r
173 // Allocate 128KB for the Stack\r
174 //\r
175 BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (StackSize));\r
176 ASSERT (BaseOfStack != NULL);\r
3402aac7 177\r
1e57a462 178 //\r
179 // Compute the top of the stack we were allocated. Pre-allocate a UINTN\r
180 // for safety.\r
181 //\r
182 TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (StackSize) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);\r
183 TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
184\r
185 //\r
186 // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.\r
3402aac7 187 //\r
1e57a462 188 UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, StackSize);\r
189\r
190 SwitchStack (\r
191 (SWITCH_STACK_ENTRY_POINT)(UINTN)EntryPoint,\r
192 Hob,\r
193 NULL,\r
194 TopOfStack\r
195 );\r
196\r
197 }\r
3402aac7 198\r
1e57a462 199 // Should never get here as DXE Core does not return\r
200 DEBUG ((EFI_D_ERROR, "DxeCore returned\n"));\r
201 ASSERT (FALSE);\r
3402aac7 202\r
1e57a462 203 return EFI_DEVICE_ERROR;\r
204}\r
205\r
206\r
207\r
208EFI_STATUS\r
209EFIAPI\r
210LoadDxeCoreFromFv (\r
211 IN UINTN *FvInstance, OPTIONAL\r
212 IN UINTN StackSize\r
213 )\r
214{\r
215 EFI_STATUS Status;\r
216 EFI_PEI_FV_HANDLE VolumeHandle;\r
217 EFI_PEI_FILE_HANDLE FileHandle = NULL;\r
218\r
219 if (FvInstance != NULL) {\r
220 //\r
221 // Caller passed in a specific FV to try, so only try that one\r
222 //\r
223 Status = FfsFindNextVolume (*FvInstance, &VolumeHandle);\r
224 if (!EFI_ERROR (Status)) {\r
225 Status = FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);\r
226 }\r
227 } else {\r
228 Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);\r
229 }\r
230\r
231 if (!EFI_ERROR (Status)) {\r
232 return LoadDxeCoreFromFfsFile (FileHandle, StackSize);\r
3402aac7
RC
233 }\r
234\r
235 return Status;\r
1e57a462 236}\r
237\r
238\r
239EFI_STATUS\r
240EFIAPI\r
241DecompressFirstFv (\r
242 VOID\r
243 )\r
244{\r
245 EFI_STATUS Status;\r
246 EFI_PEI_FV_HANDLE VolumeHandle;\r
247 EFI_PEI_FILE_HANDLE FileHandle;\r
248\r
249 Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &VolumeHandle, &FileHandle);\r
250 if (!EFI_ERROR (Status)) {\r
251 Status = FfsProcessFvFile (FileHandle);\r
252 }\r
3402aac7 253\r
1e57a462 254 return Status;\r
255}\r
256\r
257\r