3 Copyright (c) 2006 - 2010, 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
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.
25 #include "LzmaDecompress.h"
32 CHAR8 PrintBuffer
[256];
33 AsciiSPrint (PrintBuffer
, 256, "## FATEL ERROR ##: Fail to load DUET images! System hang!\n");
39 UINT32 BiosMemoryMapBaseAddress
42 BIOS_MEMORY_MAP
*BiosMemoryMap
;
43 EFILDR_IMAGE
*EFILDRImage
;
44 EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor
[EFI_MAX_MEMORY_DESCRIPTORS
];
46 UINTN NumberOfMemoryMapEntries
;
47 UINT32 DestinationSize
;
51 EFI_MAIN_ENTRYPOINT EfiMainEntrypoint
;
52 CHAR8 PrintBuffer
[256];
53 STATIC EFILDRHANDOFF Handoff
;
59 AsciiSPrint (PrintBuffer
, 256, "Enter DUET Loader...\n");
60 PrintString (PrintBuffer
);
62 AsciiSPrint (PrintBuffer
, 256, "BiosMemoryMapBaseAddress = 0x%x\n", BiosMemoryMapBaseAddress
);
63 PrintString (PrintBuffer
);
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.
69 BiosMemoryMap
= (BIOS_MEMORY_MAP
*)(UINTN
)(BiosMemoryMapBaseAddress
);
70 NumberOfMemoryMapEntries
= 0;
71 GenMemoryMap (&NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, BiosMemoryMap
);
73 AsciiSPrint (PrintBuffer
, 256, "Get %d entries of memory map!\n", NumberOfMemoryMapEntries
);
74 PrintString (PrintBuffer
);
77 // Get information on where the image is in memory
80 //EFILDRHeader = (EFILDR_HEADER *)(UINTN)(EFILDR_HEADER_ADDRESS);
81 EFILDRImage
= (EFILDR_IMAGE
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ sizeof(EFILDR_HEADER
));
85 // Point to the 4th image (Bfv)
91 // Decompress the image
94 AsciiSPrint (PrintBuffer
, 256, "Decompress BFV image, Image Address=0x%x Offset=0x%x\n",
95 (UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
97 PrintString (PrintBuffer
);
98 Status
= LzmaUefiDecompressGetInfo (
99 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
105 if (EFI_ERROR (Status
)) {
106 AsciiSPrint (PrintBuffer
, 256, "Fail to get decompress information for BFV!\n");
107 PrintString (PrintBuffer
);
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
),
117 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
118 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000)
122 if (EFI_ERROR (Status
)) {
123 AsciiSPrint (PrintBuffer
, 256, "Fail to decompress BFV!\n");
124 PrintString (PrintBuffer
);
128 BfvPageNumber
= EFI_SIZE_TO_PAGES (DestinationSize
);
129 BfvBase
= (UINTN
) FindSpace (BfvPageNumber
, &NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, EfiRuntimeServicesData
, EFI_MEMORY_WB
);
133 ZeroMem ((VOID
*)(UINTN
)BfvBase
, BfvPageNumber
* EFI_PAGE_SIZE
);
134 CopyMem ((VOID
*)(UINTN
)BfvBase
, (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
, DestinationSize
);
139 // Point to the 2nd image (DxeIpl)
145 // Decompress the image
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
);
152 Status
= LzmaUefiDecompressGetInfo (
153 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
158 if (EFI_ERROR (Status
)) {
159 AsciiSPrint (PrintBuffer
, 256, "Fail to get decompress information for DxeIpl!\n");
160 PrintString (PrintBuffer
);
164 Status
= LzmaUefiDecompress (
165 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
167 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
168 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000)
170 if (EFI_ERROR (Status
)) {
171 AsciiSPrint (PrintBuffer
, 256, "Fail to decompress DxeIpl image\n");
172 PrintString (PrintBuffer
);
176 AsciiSPrint (PrintBuffer
, 256, "Start load DxeIpl PE image\n");
177 PrintString (PrintBuffer
);
180 // Load and relocate the EFI PE/COFF Firmware Image
182 Status
= EfiLdrPeCoffLoadPeImage (
183 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
185 &NumberOfMemoryMapEntries
,
188 if (EFI_ERROR (Status
)) {
189 AsciiSPrint (PrintBuffer
, 256, "Fail to load and relocate DxeIpl PE image!\n");
190 PrintString (PrintBuffer
);
193 AsciiSPrint (PrintBuffer
, 256, "DxeIpl PE image is successed loaded at 0x%x, entry=0x%x\n",
194 (UINTN
)DxeIplImage
.ImageBasePage
, (UINTN
)DxeIplImage
.EntryPoint
);
195 PrintString (PrintBuffer
);
197 // PrintString("Image.NoPages = ");
198 // PrintValue(Image.NoPages);
199 // PrintString("\n");
204 // Point to the 3rd image (DxeMain)
210 // Decompress the image
212 AsciiSPrint (PrintBuffer
, 256, "Decompress DXEMain FV image, Image Address=0x%x! Offset=0x%x\n",
213 (UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
214 EFILDRImage
->Offset
);
215 PrintString (PrintBuffer
);
217 Status
= LzmaUefiDecompressGetInfo (
218 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
223 if (EFI_ERROR (Status
)) {
224 AsciiSPrint (PrintBuffer
, 256, "Fail to get decompress information for DXEMain FV image!\n");
225 PrintString (PrintBuffer
);
229 Status
= LzmaUefiDecompress (
230 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
232 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
233 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000)
235 if (EFI_ERROR (Status
)) {
240 // Load and relocate the EFI PE/COFF Firmware Image
242 Status
= EfiLdrPeCoffLoadPeImage (
243 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
245 &NumberOfMemoryMapEntries
,
248 if (EFI_ERROR (Status
)) {
251 AsciiSPrint (PrintBuffer
, 256, "DxeCore PE image is successed loaded at 0x%x, entry=0x%x\n",
252 (UINTN
)DxeCoreImage
.ImageBasePage
, (UINTN
)DxeCoreImage
.EntryPoint
);
253 PrintString (PrintBuffer
);
258 // Display the table of memory descriptors.
261 // PrintString("\nEFI Memory Descriptors\n");
265 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
266 PrintString("Type = ");
267 PrintValue(EfiMemoryDescriptor[Index].Type);
268 PrintString(" Start = ");
269 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));
270 PrintString(" NumberOfPages = ");
271 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));
278 // Jump to EFI Firmware
281 if (DxeIplImage
.EntryPoint
!= NULL
) {
283 Handoff
.MemDescCount
= NumberOfMemoryMapEntries
;
284 Handoff
.MemDesc
= EfiMemoryDescriptor
;
285 Handoff
.BfvBase
= (VOID
*)(UINTN
)BfvBase
;
286 Handoff
.BfvSize
= BfvPageNumber
* EFI_PAGE_SIZE
;
287 Handoff
.DxeIplImageBase
= (VOID
*)(UINTN
)DxeIplImage
.ImageBasePage
;
288 Handoff
.DxeIplImageSize
= DxeIplImage
.NoPages
* EFI_PAGE_SIZE
;
289 Handoff
.DxeCoreImageBase
= (VOID
*)(UINTN
)DxeCoreImage
.ImageBasePage
;
290 Handoff
.DxeCoreImageSize
= DxeCoreImage
.NoPages
* EFI_PAGE_SIZE
;
291 Handoff
.DxeCoreEntryPoint
= (VOID
*)(UINTN
)DxeCoreImage
.EntryPoint
;
293 AsciiSPrint (PrintBuffer
, 256, "Transfer to DxeIpl ...Address=0x%x\n", (UINTN
)DxeIplImage
.EntryPoint
);
294 PrintString (PrintBuffer
);
296 EfiMainEntrypoint
= (EFI_MAIN_ENTRYPOINT
)(UINTN
)DxeIplImage
.EntryPoint
;
297 EfiMainEntrypoint (&Handoff
);
303 // There was a problem loading the image, so HALT the system.
312 UINT32 BiosMemoryMapBaseAddress
315 EfiLoader(BiosMemoryMapBaseAddress
);