]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/EfiLdr/EfiLoader.c
88bce2f07429c3ee9edf54e5647f56282eb2b6f4
[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 Status = TianoDecompress (
114 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
115 EFILDRImage->Length,
116 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
117 DestinationSize,
118 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
119 ScratchSize
120 );
121
122 if (EFI_ERROR (Status)) {
123 AsciiSPrint (PrintBuffer, 256, "Fail to decompress BFV!\n");
124 PrintString (PrintBuffer);
125 SystemHang();
126 }
127
128 BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize);
129 BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);
130 if (BfvBase == 0) {
131 SystemHang();
132 }
133 ZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE);
134 CopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize);
135
136 PrintHeader ('B');
137
138 //
139 // Point to the 2nd image (DxeIpl)
140 //
141
142 EFILDRImage -= 2;
143
144 //
145 // Decompress the image
146 //
147 AsciiSPrint (PrintBuffer, 256, "Decompress DxeIpl image, Image Address=0x%x Offset=0x%x\n",
148 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
149 EFILDRImage->Offset);
150 PrintString (PrintBuffer);
151
152 Status = TianoGetInfo (
153 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
154 EFILDRImage->Length,
155 &DestinationSize,
156 &ScratchSize
157 );
158 if (EFI_ERROR (Status)) {
159 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DxeIpl!\n");
160 PrintString (PrintBuffer);
161 SystemHang();
162 }
163
164 Status = TianoDecompress (
165 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
166 EFILDRImage->Length,
167 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
168 DestinationSize,
169 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
170 ScratchSize
171 );
172 if (EFI_ERROR (Status)) {
173 AsciiSPrint (PrintBuffer, 256, "Fail to decompress DxeIpl image\n");
174 PrintString (PrintBuffer);
175 SystemHang();
176 }
177
178 AsciiSPrint (PrintBuffer, 256, "Start load DxeIpl PE image\n");
179 PrintString (PrintBuffer);
180
181 //
182 // Load and relocate the EFI PE/COFF Firmware Image
183 //
184 Status = EfiLdrPeCoffLoadPeImage (
185 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
186 &DxeIplImage,
187 &NumberOfMemoryMapEntries,
188 EfiMemoryDescriptor
189 );
190 if (EFI_ERROR (Status)) {
191 AsciiSPrint (PrintBuffer, 256, "Fail to load and relocate DxeIpl PE image!\n");
192 PrintString (PrintBuffer);
193 SystemHang();
194 }
195 AsciiSPrint (PrintBuffer, 256, "DxeIpl PE image is successed loaded at 0x%x, entry=0x%x\n",
196 (UINTN)DxeIplImage.ImageBasePage, (UINTN)DxeIplImage.EntryPoint);
197 PrintString (PrintBuffer);
198
199 // PrintString("Image.NoPages = ");
200 // PrintValue(Image.NoPages);
201 // PrintString("\n");
202
203 PrintHeader ('C');
204
205 //
206 // Point to the 3rd image (DxeMain)
207 //
208
209 EFILDRImage++;
210
211 //
212 // Decompress the image
213 //
214 AsciiSPrint (PrintBuffer, 256, "Decompress DXEMain FV image, Image Address=0x%x! Offset=0x%x\n",
215 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
216 EFILDRImage->Offset);
217 PrintString (PrintBuffer);
218
219 Status = TianoGetInfo (
220 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
221 EFILDRImage->Length,
222 &DestinationSize,
223 &ScratchSize
224 );
225 if (EFI_ERROR (Status)) {
226 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DXEMain FV image!\n");
227 PrintString (PrintBuffer);
228 SystemHang();
229 }
230
231 Status = TianoDecompress (
232 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
233 EFILDRImage->Length,
234 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
235 DestinationSize,
236 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
237 ScratchSize
238 );
239 if (EFI_ERROR (Status)) {
240 SystemHang();
241 }
242
243 //
244 // Load and relocate the EFI PE/COFF Firmware Image
245 //
246 Status = EfiLdrPeCoffLoadPeImage (
247 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
248 &DxeCoreImage,
249 &NumberOfMemoryMapEntries,
250 EfiMemoryDescriptor
251 );
252 if (EFI_ERROR (Status)) {
253 SystemHang();
254 }
255 AsciiSPrint (PrintBuffer, 256, "DxeCore PE image is successed loaded at 0x%x, entry=0x%x\n",
256 (UINTN)DxeCoreImage.ImageBasePage, (UINTN)DxeCoreImage.EntryPoint);
257 PrintString (PrintBuffer);
258
259 PrintHeader ('E');
260
261 //
262 // Display the table of memory descriptors.
263 //
264
265 // PrintString("\nEFI Memory Descriptors\n");
266 /*
267 {
268 UINTN Index;
269 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
270 PrintString("Type = ");
271 PrintValue(EfiMemoryDescriptor[Index].Type);
272 PrintString(" Start = ");
273 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));
274 PrintString(" NumberOfPages = ");
275 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));
276 PrintString("\n");
277 }
278 }
279 */
280
281 //
282 // Jump to EFI Firmware
283 //
284
285 if (DxeIplImage.EntryPoint != NULL) {
286
287 Handoff.MemDescCount = NumberOfMemoryMapEntries;
288 Handoff.MemDesc = EfiMemoryDescriptor;
289 Handoff.BfvBase = (VOID *)(UINTN)BfvBase;
290 Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;
291 Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;
292 Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;
293 Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;
294 Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;
295 Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;
296
297 AsciiSPrint (PrintBuffer, 256, "Transfer to DxeIpl ...Address=0x%x\n", (UINTN)DxeIplImage.EntryPoint);
298 PrintString (PrintBuffer);
299
300 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT)(UINTN)DxeIplImage.EntryPoint;
301 EfiMainEntrypoint (&Handoff);
302 }
303
304 PrintHeader ('F');
305
306 //
307 // There was a problem loading the image, so HALT the system.
308 //
309
310 SystemHang();
311 }
312
313 EFI_STATUS
314 EFIAPI
315 _ModuleEntryPoint (
316 UINT32 BiosMemoryMapBaseAddress
317 )
318 {
319 EfiLoader(BiosMemoryMapBaseAddress);
320 return EFI_SUCCESS;
321 }
322
323