]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/EfiLdr/EfiLoader.c
f9804e7ffb35edb12757aa5aa2ddb0619d485464
[mirror_edk2.git] / DuetPkg / EfiLdr / EfiLoader.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13 EfiLoader.c
14
15 Abstract:
16
17 Revision History:
18
19 --*/
20
21 #include "EfiLdr.h"
22 #include "Support.h"
23 #include "Debug.h"
24 #include "PeLoader.h"
25 #include "TianoDecompress.h"
26
27 VOID
28 SystemHang(
29 VOID
30 )
31 {
32 CHAR8 PrintBuffer[256];
33 AsciiSPrint (PrintBuffer, 256, "## FATEL ERROR ##: Fail to load DUET images! System hang!\n");
34 CpuDeadLoop();
35 }
36
37 VOID
38 EfiLoader (
39 UINT32 BiosMemoryMapBaseAddress
40 )
41 {
42 BIOS_MEMORY_MAP *BiosMemoryMap;
43 //EFILDR_HEADER *EFILDRHeader;
44 EFILDR_IMAGE *EFILDRImage;
45 EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor[EFI_MAX_MEMORY_DESCRIPTORS];
46 EFI_STATUS Status;
47 UINTN NumberOfMemoryMapEntries;
48 UINT32 DestinationSize;
49 UINT32 ScratchSize;
50 UINTN BfvPageNumber;
51 UINTN BfvBase;
52 EFI_MAIN_ENTRYPOINT EfiMainEntrypoint;
53 CHAR8 PrintBuffer[256];
54 STATIC EFILDRHANDOFF Handoff;
55
56 ClearScreen();
57
58 PrintHeader ('A');
59
60 AsciiSPrint (PrintBuffer, 256, "Enter DUET Loader ...\n", BiosMemoryMapBaseAddress);
61 PrintString (PrintBuffer);
62
63 AsciiSPrint (PrintBuffer, 256, "BiosMemoryMapBaseAddress = 0x%x\n", BiosMemoryMapBaseAddress);
64 PrintString (PrintBuffer);
65
66 //
67 // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then
68 // round the start address up to the next page, and round the length down to a page boundry.
69 //
70 BiosMemoryMap = (BIOS_MEMORY_MAP *)(UINTN)(BiosMemoryMapBaseAddress);
71 NumberOfMemoryMapEntries = 0;
72 GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap);
73
74 AsciiSPrint (PrintBuffer, 256, "Get %d entries of memory map!\n", NumberOfMemoryMapEntries);
75 PrintString (PrintBuffer);
76
77 //
78 // Get information on where the image is in memory
79 //
80
81 //EFILDRHeader = (EFILDR_HEADER *)(UINTN)(EFILDR_HEADER_ADDRESS);
82 EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER));
83
84
85 //
86 // Point to the 4th image (Bfv)
87 //
88
89 EFILDRImage += 3;
90
91 //
92 // Decompress the image
93 //
94
95 AsciiSPrint (PrintBuffer, 256, "Decompress BFV image, Image Address=0x%x Offset=0x%x\n",
96 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
97 EFILDRImage->Offset);
98 PrintString (PrintBuffer);
99
100 Status = TianoGetInfo (
101 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
102 EFILDRImage->Length,
103 &DestinationSize,
104 &ScratchSize
105 );
106
107 if (EFI_ERROR (Status)) {
108 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for BFV!\n");
109 PrintString (PrintBuffer);
110 SystemHang();
111 }
112
113 AsciiSPrint (PrintBuffer, 256, "BFV decompress: DestinationSize=0x%X, ScratchSize=0x%X!\n",
114 DestinationSize, ScratchSize);
115 PrintString (PrintBuffer);
116
117 Status = TianoDecompress (
118 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
119 EFILDRImage->Length,
120 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
121 DestinationSize,
122 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
123 ScratchSize
124 );
125
126 if (EFI_ERROR (Status)) {
127 AsciiSPrint (PrintBuffer, 256, "Fail to decompress BFV!\n");
128 PrintString (PrintBuffer);
129 SystemHang();
130 }
131
132 BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize);
133 BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);
134 if (BfvBase == 0) {
135 SystemHang();
136 }
137 ZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE);
138 CopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize);
139
140 PrintHeader ('B');
141
142 //
143 // Point to the 2nd image (DxeIpl)
144 //
145
146 EFILDRImage -= 2;
147
148 //
149 // Decompress the image
150 //
151 AsciiSPrint (PrintBuffer, 256, "Decompress DxeIpl image, Image Address=0x%x Offset=0x%x\n",
152 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
153 EFILDRImage->Offset);
154 PrintString (PrintBuffer);
155
156 Status = TianoGetInfo (
157 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
158 EFILDRImage->Length,
159 &DestinationSize,
160 &ScratchSize
161 );
162 if (EFI_ERROR (Status)) {
163 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DxeIpl!\n");
164 PrintString (PrintBuffer);
165 SystemHang();
166 }
167
168 Status = TianoDecompress (
169 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
170 EFILDRImage->Length,
171 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
172 DestinationSize,
173 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
174 ScratchSize
175 );
176 if (EFI_ERROR (Status)) {
177 AsciiSPrint (PrintBuffer, 256, "Fail to decompress DxeIpl image\n");
178 PrintString (PrintBuffer);
179 SystemHang();
180 }
181
182 AsciiSPrint (PrintBuffer, 256, "Start load DxeIpl PE image\n");
183 PrintString (PrintBuffer);
184
185 //
186 // Load and relocate the EFI PE/COFF Firmware Image
187 //
188 Status = EfiLdrPeCoffLoadPeImage (
189 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
190 &DxeIplImage,
191 &NumberOfMemoryMapEntries,
192 EfiMemoryDescriptor
193 );
194 if (EFI_ERROR (Status)) {
195 AsciiSPrint (PrintBuffer, 256, "Fail to load and relocate DxeIpl PE image!\n");
196 PrintString (PrintBuffer);
197 SystemHang();
198 }
199 AsciiSPrint (PrintBuffer, 256, "DxeIpl PE image is successed loaded at 0x%x, entry=0x%x\n",
200 (UINTN)DxeIplImage.ImageBasePage, (UINTN)DxeIplImage.EntryPoint);
201 PrintString (PrintBuffer);
202
203 // PrintString("Image.NoPages = ");
204 // PrintValue(Image.NoPages);
205 // PrintString("\n");
206
207 PrintHeader ('C');
208
209 //
210 // Point to the 3rd image (DxeMain)
211 //
212
213 EFILDRImage++;
214
215 //
216 // Decompress the image
217 //
218 AsciiSPrint (PrintBuffer, 256, "Decompress DXEMain FV image, Image Address=0x%x! Offset=0x%x\n",
219 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
220 EFILDRImage->Offset);
221 PrintString (PrintBuffer);
222
223 Status = TianoGetInfo (
224 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
225 EFILDRImage->Length,
226 &DestinationSize,
227 &ScratchSize
228 );
229 if (EFI_ERROR (Status)) {
230 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DXEMain FV image!\n");
231 PrintString (PrintBuffer);
232 SystemHang();
233 }
234
235 Status = TianoDecompress (
236 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
237 EFILDRImage->Length,
238 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
239 DestinationSize,
240 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
241 ScratchSize
242 );
243 if (EFI_ERROR (Status)) {
244 SystemHang();
245 }
246
247 //
248 // Load and relocate the EFI PE/COFF Firmware Image
249 //
250 Status = EfiLdrPeCoffLoadPeImage (
251 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
252 &DxeCoreImage,
253 &NumberOfMemoryMapEntries,
254 EfiMemoryDescriptor
255 );
256 if (EFI_ERROR (Status)) {
257 SystemHang();
258 }
259 AsciiSPrint (PrintBuffer, 256, "DxeCore PE image is successed loaded at 0x%x, entry=0x%x\n",
260 (UINTN)DxeCoreImage.ImageBasePage, (UINTN)DxeCoreImage.EntryPoint);
261 PrintString (PrintBuffer);
262
263 PrintHeader ('E');
264
265 //
266 // Display the table of memory descriptors.
267 //
268
269 // PrintString("\nEFI Memory Descriptors\n");
270 /*
271 {
272 UINTN Index;
273 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
274 PrintString("Type = ");
275 PrintValue(EfiMemoryDescriptor[Index].Type);
276 PrintString(" Start = ");
277 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));
278 PrintString(" NumberOfPages = ");
279 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));
280 PrintString("\n");
281 }
282 }
283 */
284
285 //
286 // Jump to EFI Firmware
287 //
288
289 if (DxeIplImage.EntryPoint != NULL) {
290
291 Handoff.MemDescCount = NumberOfMemoryMapEntries;
292 Handoff.MemDesc = EfiMemoryDescriptor;
293 Handoff.BfvBase = (VOID *)(UINTN)BfvBase;
294 Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;
295 Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;
296 Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;
297 Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;
298 Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;
299 Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;
300
301 AsciiSPrint (PrintBuffer, 256, "Transfer to DxeIpl ...Address=0x%x\n", (UINTN)DxeIplImage.EntryPoint);
302 PrintString (PrintBuffer);
303
304 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT)(UINTN)DxeIplImage.EntryPoint;
305 EfiMainEntrypoint (&Handoff);
306 }
307
308 PrintHeader ('F');
309
310 //
311 // There was a problem loading the image, so HALT the system.
312 //
313
314 SystemHang();
315 }
316
317 EFI_STATUS
318 EFIAPI
319 _ModuleEntryPoint (
320 UINT32 BiosMemoryMapBaseAddress
321 )
322 {
323 EfiLoader(BiosMemoryMapBaseAddress);
324 return EFI_SUCCESS;
325 }
326
327