blob: 6913027650748ce29c6e17974c09099ec9922e4d [file] [log] [blame]
Vishal Bhoj82c80712015-12-15 21:13:33 +05301/*++
2
3Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4This program and the accompanying materials
5are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution. The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12Module Name:
13 EfiLoader.c
14
15Abstract:
16
17Revision 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
27VOID
28SystemHang (
29 CHAR8 *Message
30 )
31{
32 PrintString (
33 "%s## FATAL ERROR ##: Fail to load DUET images! System hang!\n",
34 Message
35 );
36 CpuDeadLoop();
37}
38
39VOID
40EfiLoader (
41 UINT32 BiosMemoryMapBaseAddress
42 )
43{
44 BIOS_MEMORY_MAP *BiosMemoryMap;
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 EFILDRHANDOFF Handoff;
55 UINTN Index;
56
57 ClearScreen();
58
59 PrintHeader ('A');
60
61 PrintString ("Enter DUET Loader...\n");
62 PrintString ("BiosMemoryMapBaseAddress = %x\n", (UINTN) BiosMemoryMapBaseAddress);
63
64 //
65 // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then
66 // round the start address up to the next page, and round the length down to a page boundry.
67 //
68 BiosMemoryMap = (BIOS_MEMORY_MAP *) (UINTN) BiosMemoryMapBaseAddress;
69 NumberOfMemoryMapEntries = 0;
70 GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap);
71
72 PrintString ("Get %d entries of memory map!\n", NumberOfMemoryMapEntries);
73
74 //
75 // Get information on where the image is in memory
76 //
77 EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER));
78
79
80 //
81 // Point to the 4th image (Bfv)
82 //
83 EFILDRImage += 3;
84
85 //
86 // Decompress the image
87 //
88 PrintString (
89 "Decompress BFV image, Image Address = %x Offset = %x\n",
90 (UINTN) (EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
91 (UINTN) EFILDRImage->Offset
92 );
93 Status = LzmaUefiDecompressGetInfo (
94 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
95 EFILDRImage->Length,
96 &DestinationSize,
97 &ScratchSize
98 );
99
100 if (EFI_ERROR (Status)) {
101 SystemHang ("Failed to get decompress information for BFV!\n");
102 }
103
104 PrintString ("BFV decompress: DestinationSize = %x, ScratchSize = %x\n", (UINTN) DestinationSize, (UINTN) ScratchSize);
105 Status = LzmaUefiDecompress (
106 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
107 EFILDRImage->Length,
108 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
109 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)
110 );
111
112
113 if (EFI_ERROR (Status)) {
114 SystemHang ("Failed to decompress BFV!\n");
115 }
116
117 BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize);
118 BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);
119 if (BfvBase == 0) {
120 SystemHang ("Failed to find free space to hold decompressed BFV\n");
121 }
122 ZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE);
123 CopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize);
124
125 PrintHeader ('B');
126
127 //
128 // Point to the 2nd image (DxeIpl)
129 //
130
131 EFILDRImage -= 2;
132
133 //
134 // Decompress the image
135 //
136 PrintString (
137 "Decompress DxeIpl image, Image Address = %x Offset = %x\n",
138 (UINTN) (EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
139 (UINTN) EFILDRImage->Offset
140 );
141
142 Status = LzmaUefiDecompressGetInfo (
143 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
144 EFILDRImage->Length,
145 &DestinationSize,
146 &ScratchSize
147 );
148 if (EFI_ERROR (Status)) {
149 SystemHang ("Failed to get decompress information for DxeIpl!\n");
150 }
151
152 Status = LzmaUefiDecompress (
153 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
154 EFILDRImage->Length,
155 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
156 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)
157 );
158 if (EFI_ERROR (Status)) {
159 SystemHang ("Failed to decompress DxeIpl image\n");
160 }
161
162 PrintString ("Start load DxeIpl PE image\n");
163
164 //
165 // Load and relocate the EFI PE/COFF Firmware Image
166 //
167 Status = EfiLdrPeCoffLoadPeImage (
168 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
169 &DxeIplImage,
170 &NumberOfMemoryMapEntries,
171 EfiMemoryDescriptor
172 );
173 if (EFI_ERROR (Status)) {
174 SystemHang ("Failed to load and relocate DxeIpl PE image!\n");
175 }
176 PrintString (
177 "DxeIpl PE image is successed loaded at %lx, entry=%p\n",
178 DxeIplImage.ImageBasePage,
179 DxeIplImage.EntryPoint
180 );
181
182PrintHeader ('C');
183
184 //
185 // Point to the 3rd image (DxeMain)
186 //
187 EFILDRImage++;
188
189 //
190 // Decompress the image
191 //
192 PrintString (
193 "Decompress DxeMain FV image, Image Address = %x Offset = %x\n",
194 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
195 (UINTN) EFILDRImage->Offset
196 );
197
198 Status = LzmaUefiDecompressGetInfo (
199 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
200 EFILDRImage->Length,
201 &DestinationSize,
202 &ScratchSize
203 );
204 if (EFI_ERROR (Status)) {
205 SystemHang ("Failed to get decompress information for DxeMain FV image!\n");
206 }
207
208 Status = LzmaUefiDecompress (
209 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),
210 EFILDRImage->Length,
211 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,
212 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)
213 );
214 if (EFI_ERROR (Status)) {
215 SystemHang ("Failed to decompress DxeMain FV image!\n");
216 }
217
218 //
219 // Load and relocate the EFI PE/COFF Firmware Image
220 //
221 Status = EfiLdrPeCoffLoadPeImage (
222 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS),
223 &DxeCoreImage,
224 &NumberOfMemoryMapEntries,
225 EfiMemoryDescriptor
226 );
227 if (EFI_ERROR (Status)) {
228 SystemHang ("Failed to load/relocate DxeMain!\n");
229 }
230 PrintString (
231 "DxeCore PE image is successed loaded at %lx, entry=%p\n",
232 DxeCoreImage.ImageBasePage,
233 DxeCoreImage.EntryPoint
234 );
235
236PrintHeader ('E');
237
238 //
239 // Display the table of memory descriptors.
240 //
241 PrintString ("\nEFI Memory Descriptors\n");
242 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
243 PrintString (
244 "Type = %x Start = %08lx NumberOfPages = %08lx\n",
245 EfiMemoryDescriptor[Index].Type, EfiMemoryDescriptor[Index].PhysicalStart, EfiMemoryDescriptor[Index].NumberOfPages
246 );
247 }
248
249 //
250 // Jump to EFI Firmware
251 //
252
253 if (DxeIplImage.EntryPoint != NULL) {
254
255 Handoff.MemDescCount = NumberOfMemoryMapEntries;
256 Handoff.MemDesc = EfiMemoryDescriptor;
257 Handoff.BfvBase = (VOID *)(UINTN)BfvBase;
258 Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;
259 Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;
260 Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;
261 Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;
262 Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;
263 Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;
264
265 PrintString ("Transfer to DxeIpl ...EntryPoint = %p\n", DxeIplImage.EntryPoint);
266
267 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT) DxeIplImage.EntryPoint;
268 EfiMainEntrypoint (&Handoff);
269 }
270
271PrintHeader ('F');
272
273 //
274 // There was a problem loading the image, so HALT the system.
275 //
276
277 SystemHang ("Failed to jump to DxeIpl!\n");
278}
279
280EFI_STATUS
281EFIAPI
282_ModuleEntryPoint (
283 UINT32 BiosMemoryMapBaseAddress
284 )
285{
286 SerialPortInitialize ();
287 EfiLoader(BiosMemoryMapBaseAddress);
288 return EFI_SUCCESS;
289}
290
291