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