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