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