]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/EfiLdr/EfiLoader.c
Remove exit from batch file
[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 CpuDeadLoop();
61
62 AsciiSPrint (PrintBuffer, 256, "Enter DUET Loader ...\n", BiosMemoryMapBaseAddress);
63 PrintString (PrintBuffer);
64
65 AsciiSPrint (PrintBuffer, 256, "BiosMemoryMapBaseAddress = 0x%x\n", BiosMemoryMapBaseAddress);
66 PrintString (PrintBuffer);
67
68 //
69 // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then
70 // round the start address up to the next page, and round the length down to a page boundry.
71 //
72 BiosMemoryMap = (BIOS_MEMORY_MAP *)(UINTN)(BiosMemoryMapBaseAddress);
73 NumberOfMemoryMapEntries = 0;
74 GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap);
75
76 AsciiSPrint (PrintBuffer, 256, "Get %d entries of memory map!\n", NumberOfMemoryMapEntries);
77 PrintString (PrintBuffer);
78
79 //
80 // Get information on where the image is in memory
81 //
82
83 //EFILDRHeader = (EFILDR_HEADER *)(UINTN)(EFILDR_HEADER_ADDRESS);
84 EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER));
85
86
87 //
88 // Point to the 4th image (Bfv)
89 //
90
91 EFILDRImage += 3;
92
93 //
94 // Decompress the image
95 //
96
97 AsciiSPrint (PrintBuffer, 256, "Decompress BFV image, Image Address=0x%x Offset=0x%x\n",
98 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
99 EFILDRImage->Offset);
100 PrintString (PrintBuffer);
101
102 Status = TianoGetInfo (
103 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
104 EFILDRImage->Length,
105 &DestinationSize,
106 &ScratchSize
107 );
108
109 if (EFI_ERROR (Status)) {
110 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for BFV!\n");
111 PrintString (PrintBuffer);
112 SystemHang();
113 }
114
115 AsciiSPrint (PrintBuffer, 256, "BFV decompress: DestinationSize=0x%X, ScratchSize=0x%X!\n",
116 DestinationSize, ScratchSize);
117 PrintString (PrintBuffer);
118
119 Status = TianoDecompress (
120 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
121 EFILDRImage->Length,
122 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
123 DestinationSize,
124 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
125 ScratchSize
126 );
127
128 if (EFI_ERROR (Status)) {
129 AsciiSPrint (PrintBuffer, 256, "Fail to decompress BFV!\n");
130 PrintString (PrintBuffer);
131 SystemHang();
132 }
133
134 BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize);
135 BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);
136 if (BfvBase == 0) {
137 SystemHang();
138 }
139 ZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE);
140 CopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize);
141
142 PrintHeader ('B');
143
144 //
145 // Point to the 2nd image (DxeIpl)
146 //
147
148 EFILDRImage -= 2;
149
150 //
151 // Decompress the image
152 //
153 AsciiSPrint (PrintBuffer, 256, "Decompress DxeIpl image, Image Address=0x%x Offset=0x%x\n",
154 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
155 EFILDRImage->Offset);
156 PrintString (PrintBuffer);
157
158 Status = TianoGetInfo (
159 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
160 EFILDRImage->Length,
161 &DestinationSize,
162 &ScratchSize
163 );
164 if (EFI_ERROR (Status)) {
165 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DxeIpl!\n");
166 PrintString (PrintBuffer);
167 SystemHang();
168 }
169
170 Status = TianoDecompress (
171 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
172 EFILDRImage->Length,
173 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
174 DestinationSize,
175 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
176 ScratchSize
177 );
178 if (EFI_ERROR (Status)) {
179 AsciiSPrint (PrintBuffer, 256, "Fail to decompress DxeIpl image\n");
180 PrintString (PrintBuffer);
181 SystemHang();
182 }
183
184 AsciiSPrint (PrintBuffer, 256, "Start load DxeIpl PE image\n");
185 PrintString (PrintBuffer);
186
187 //
188 // Load and relocate the EFI PE/COFF Firmware Image
189 //
190 Status = EfiLdrPeCoffLoadPeImage (
191 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
192 &DxeIplImage,
193 &NumberOfMemoryMapEntries,
194 EfiMemoryDescriptor
195 );
196 if (EFI_ERROR (Status)) {
197 AsciiSPrint (PrintBuffer, 256, "Fail to load and relocate DxeIpl PE image!\n");
198 PrintString (PrintBuffer);
199 SystemHang();
200 }
201 AsciiSPrint (PrintBuffer, 256, "DxeIpl PE image is successed loaded at 0x%x, entry=0x%x\n",
202 (UINTN)DxeIplImage.ImageBasePage, (UINTN)DxeIplImage.EntryPoint);
203 PrintString (PrintBuffer);
204
205 // PrintString("Image.NoPages = ");
206 // PrintValue(Image.NoPages);
207 // PrintString("\n");
208
209 PrintHeader ('C');
210
211 //
212 // Point to the 3rd image (DxeMain)
213 //
214
215 EFILDRImage++;
216
217 //
218 // Decompress the image
219 //
220 AsciiSPrint (PrintBuffer, 256, "Decompress DXEMain FV image, Image Address=0x%x! Offset=0x%x\n",
221 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
222 EFILDRImage->Offset);
223 PrintString (PrintBuffer);
224
225 Status = TianoGetInfo (
226 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
227 EFILDRImage->Length,
228 &DestinationSize,
229 &ScratchSize
230 );
231 if (EFI_ERROR (Status)) {
232 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DXEMain FV image!\n");
233 PrintString (PrintBuffer);
234 SystemHang();
235 }
236
237 Status = TianoDecompress (
238 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
239 EFILDRImage->Length,
240 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
241 DestinationSize,
242 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
243 ScratchSize
244 );
245 if (EFI_ERROR (Status)) {
246 SystemHang();
247 }
248
249 //
250 // Load and relocate the EFI PE/COFF Firmware Image
251 //
252 Status = EfiLdrPeCoffLoadPeImage (
253 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
254 &DxeCoreImage,
255 &NumberOfMemoryMapEntries,
256 EfiMemoryDescriptor
257 );
258 if (EFI_ERROR (Status)) {
259 SystemHang();
260 }
261 AsciiSPrint (PrintBuffer, 256, "DxeCore PE image is successed loaded at 0x%x, entry=0x%x\n",
262 (UINTN)DxeCoreImage.ImageBasePage, (UINTN)DxeCoreImage.EntryPoint);
263 PrintString (PrintBuffer);
264
265 PrintHeader ('E');
266
267 //
268 // Display the table of memory descriptors.
269 //
270
271 // PrintString("\nEFI Memory Descriptors\n");
272 /*
273 {
274 UINTN Index;
275 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
276 PrintString("Type = ");
277 PrintValue(EfiMemoryDescriptor[Index].Type);
278 PrintString(" Start = ");
279 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));
280 PrintString(" NumberOfPages = ");
281 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));
282 PrintString("\n");
283 }
284 }
285 */
286
287 //
288 // Jump to EFI Firmware
289 //
290
291 if (DxeIplImage.EntryPoint != NULL) {
292
293 Handoff.MemDescCount = NumberOfMemoryMapEntries;
294 Handoff.MemDesc = EfiMemoryDescriptor;
295 Handoff.BfvBase = (VOID *)(UINTN)BfvBase;
296 Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;
297 Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;
298 Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;
299 Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;
300 Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;
301 Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;
302
303 AsciiSPrint (PrintBuffer, 256, "Transfer to DxeIpl ...Address=0x%x\n", (UINTN)DxeIplImage.EntryPoint);
304 PrintString (PrintBuffer);
305
306 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT)(UINTN)DxeIplImage.EntryPoint;
307 EfiMainEntrypoint (&Handoff);
308 }
309
310 PrintHeader ('F');
311
312 //
313 // There was a problem loading the image, so HALT the system.
314 //
315
316 SystemHang();
317 }
318
319 EFI_STATUS
320 EFIAPI
321 _ModuleEntryPoint (
322 UINT32 BiosMemoryMapBaseAddress
323 )
324 {
325 EfiLoader(BiosMemoryMapBaseAddress);
326 return EFI_SUCCESS;
327 }
328
329