]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/EfiLdr/EfiLoader.c
1, Use PrintLib in Duet loader
[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
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
196 // PrintString("Image.NoPages = ");
197 // PrintValue(Image.NoPages);
198 // PrintString("\n");
199
200 PrintHeader ('C');
201
202 //
203 // Point to the 3rd image (DxeMain)
204 //
205
206 EFILDRImage++;
207
208 //
209 // Decompress the image
210 //
211
212 Status = TianoGetInfo (
213 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
214 EFILDRImage->Length,
215 &DestinationSize,
216 &ScratchSize
217 );
218 if (EFI_ERROR (Status)) {
219 SystemHang();
220 }
221
222 Status = TianoDecompress (
223 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
224 EFILDRImage->Length,
225 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
226 DestinationSize,
227 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),
228 ScratchSize
229 );
230 if (EFI_ERROR (Status)) {
231 SystemHang();
232 }
233
234 //
235 // Load and relocate the EFI PE/COFF Firmware Image
236 //
237 Status = EfiLdrPeCoffLoadPeImage (
238 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
239 &DxeCoreImage,
240 &NumberOfMemoryMapEntries,
241 EfiMemoryDescriptor
242 );
243 if (EFI_ERROR (Status)) {
244 SystemHang();
245 }
246
247 PrintHeader ('E');
248
249 //
250 // Display the table of memory descriptors.
251 //
252
253 // PrintString("\nEFI Memory Descriptors\n");
254 /*
255 {
256 UINTN Index;
257 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
258 PrintString("Type = ");
259 PrintValue(EfiMemoryDescriptor[Index].Type);
260 PrintString(" Start = ");
261 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));
262 PrintString(" NumberOfPages = ");
263 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));
264 PrintString("\n");
265 }
266 }
267 */
268
269 //
270 // Jump to EFI Firmware
271 //
272
273 if (DxeIplImage.EntryPoint != NULL) {
274
275 Handoff.MemDescCount = NumberOfMemoryMapEntries;
276 Handoff.MemDesc = EfiMemoryDescriptor;
277 Handoff.BfvBase = (VOID *)(UINTN)BfvBase;
278 Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;
279 Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;
280 Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;
281 Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;
282 Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;
283 Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;
284
285 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT)(UINTN)DxeIplImage.EntryPoint;
286 EfiMainEntrypoint (&Handoff);
287 }
288
289 PrintHeader ('F');
290
291 //
292 // There was a problem loading the image, so HALT the system.
293 //
294
295 SystemHang();
296 }
297