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