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
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 "TianoDecompress.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_HEADER *EFILDRHeader;
44 EFILDR_IMAGE
*EFILDRImage
;
45 EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor
[EFI_MAX_MEMORY_DESCRIPTORS
];
47 UINTN NumberOfMemoryMapEntries
;
48 UINT32 DestinationSize
;
52 EFI_MAIN_ENTRYPOINT EfiMainEntrypoint
;
53 CHAR8 PrintBuffer
[256];
54 STATIC EFILDRHANDOFF Handoff
;
62 AsciiSPrint (PrintBuffer
, 256, "Enter DUET Loader ...\n", BiosMemoryMapBaseAddress
);
63 PrintString (PrintBuffer
);
65 AsciiSPrint (PrintBuffer
, 256, "BiosMemoryMapBaseAddress = 0x%x\n", BiosMemoryMapBaseAddress
);
66 PrintString (PrintBuffer
);
69 // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then
70 // round the start address up to the next page, and round the length down to a page boundry.
72 BiosMemoryMap
= (BIOS_MEMORY_MAP
*)(UINTN
)(BiosMemoryMapBaseAddress
);
73 NumberOfMemoryMapEntries
= 0;
74 GenMemoryMap (&NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, BiosMemoryMap
);
76 AsciiSPrint (PrintBuffer
, 256, "Get %d entries of memory map!\n", NumberOfMemoryMapEntries
);
77 PrintString (PrintBuffer
);
80 // Get information on where the image is in memory
83 //EFILDRHeader = (EFILDR_HEADER *)(UINTN)(EFILDR_HEADER_ADDRESS);
84 EFILDRImage
= (EFILDR_IMAGE
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ sizeof(EFILDR_HEADER
));
88 // Point to the 4th image (Bfv)
94 // Decompress the image
97 AsciiSPrint (PrintBuffer
, 256, "Decompress BFV image, Image Address=0x%x Offset=0x%x\n",
98 (UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
100 PrintString (PrintBuffer
);
102 Status
= TianoGetInfo (
103 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
109 if (EFI_ERROR (Status
)) {
110 AsciiSPrint (PrintBuffer
, 256, "Fail to get decompress information for BFV!\n");
111 PrintString (PrintBuffer
);
115 AsciiSPrint (PrintBuffer
, 256, "BFV decompress: DestinationSize=0x%X, ScratchSize=0x%X!\n",
116 DestinationSize
, ScratchSize
);
117 PrintString (PrintBuffer
);
119 Status
= TianoDecompress (
120 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
122 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
124 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000),
128 if (EFI_ERROR (Status
)) {
129 AsciiSPrint (PrintBuffer
, 256, "Fail to decompress BFV!\n");
130 PrintString (PrintBuffer
);
134 BfvPageNumber
= EFI_SIZE_TO_PAGES (DestinationSize
);
135 BfvBase
= (UINTN
) FindSpace (BfvPageNumber
, &NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, EfiRuntimeServicesData
, EFI_MEMORY_WB
);
139 ZeroMem ((VOID
*)(UINTN
)BfvBase
, BfvPageNumber
* EFI_PAGE_SIZE
);
140 CopyMem ((VOID
*)(UINTN
)BfvBase
, (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
, DestinationSize
);
145 // Point to the 2nd image (DxeIpl)
151 // Decompress the image
153 AsciiSPrint (PrintBuffer
, 256, "Decompress DxeIpl image, Image Address=0x%x Offset=0x%x\n",
154 (UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
155 EFILDRImage
->Offset
);
156 PrintString (PrintBuffer
);
158 Status
= TianoGetInfo (
159 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
164 if (EFI_ERROR (Status
)) {
165 AsciiSPrint (PrintBuffer
, 256, "Fail to get decompress information for DxeIpl!\n");
166 PrintString (PrintBuffer
);
170 Status
= TianoDecompress (
171 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
173 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
175 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000),
178 if (EFI_ERROR (Status
)) {
179 AsciiSPrint (PrintBuffer
, 256, "Fail to decompress DxeIpl image\n");
180 PrintString (PrintBuffer
);
184 AsciiSPrint (PrintBuffer
, 256, "Start load DxeIpl PE image\n");
185 PrintString (PrintBuffer
);
188 // Load and relocate the EFI PE/COFF Firmware Image
190 Status
= EfiLdrPeCoffLoadPeImage (
191 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
193 &NumberOfMemoryMapEntries
,
196 if (EFI_ERROR (Status
)) {
197 AsciiSPrint (PrintBuffer
, 256, "Fail to load and relocate DxeIpl PE image!\n");
198 PrintString (PrintBuffer
);
201 AsciiSPrint (PrintBuffer
, 256, "DxeIpl PE image is successed loaded at 0x%x, entry=0x%x\n",
202 (UINTN
)DxeIplImage
.ImageBasePage
, (UINTN
)DxeIplImage
.EntryPoint
);
203 PrintString (PrintBuffer
);
205 // PrintString("Image.NoPages = ");
206 // PrintValue(Image.NoPages);
207 // PrintString("\n");
212 // Point to the 3rd image (DxeMain)
218 // Decompress the image
220 AsciiSPrint (PrintBuffer
, 256, "Decompress DXEMain FV image, Image Address=0x%x! Offset=0x%x\n",
221 (UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
222 EFILDRImage
->Offset
);
223 PrintString (PrintBuffer
);
225 Status
= TianoGetInfo (
226 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
231 if (EFI_ERROR (Status
)) {
232 AsciiSPrint (PrintBuffer
, 256, "Fail to get decompress information for DXEMain FV image!\n");
233 PrintString (PrintBuffer
);
237 Status
= TianoDecompress (
238 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
240 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
242 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000),
245 if (EFI_ERROR (Status
)) {
250 // Load and relocate the EFI PE/COFF Firmware Image
252 Status
= EfiLdrPeCoffLoadPeImage (
253 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
255 &NumberOfMemoryMapEntries
,
258 if (EFI_ERROR (Status
)) {
261 AsciiSPrint (PrintBuffer
, 256, "DxeCore PE image is successed loaded at 0x%x, entry=0x%x\n",
262 (UINTN
)DxeCoreImage
.ImageBasePage
, (UINTN
)DxeCoreImage
.EntryPoint
);
263 PrintString (PrintBuffer
);
268 // Display the table of memory descriptors.
271 // PrintString("\nEFI Memory Descriptors\n");
275 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
276 PrintString("Type = ");
277 PrintValue(EfiMemoryDescriptor[Index].Type);
278 PrintString(" Start = ");
279 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));
280 PrintString(" NumberOfPages = ");
281 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));
288 // Jump to EFI Firmware
291 if (DxeIplImage
.EntryPoint
!= NULL
) {
293 Handoff
.MemDescCount
= NumberOfMemoryMapEntries
;
294 Handoff
.MemDesc
= EfiMemoryDescriptor
;
295 Handoff
.BfvBase
= (VOID
*)(UINTN
)BfvBase
;
296 Handoff
.BfvSize
= BfvPageNumber
* EFI_PAGE_SIZE
;
297 Handoff
.DxeIplImageBase
= (VOID
*)(UINTN
)DxeIplImage
.ImageBasePage
;
298 Handoff
.DxeIplImageSize
= DxeIplImage
.NoPages
* EFI_PAGE_SIZE
;
299 Handoff
.DxeCoreImageBase
= (VOID
*)(UINTN
)DxeCoreImage
.ImageBasePage
;
300 Handoff
.DxeCoreImageSize
= DxeCoreImage
.NoPages
* EFI_PAGE_SIZE
;
301 Handoff
.DxeCoreEntryPoint
= (VOID
*)(UINTN
)DxeCoreImage
.EntryPoint
;
303 AsciiSPrint (PrintBuffer
, 256, "Transfer to DxeIpl ...Address=0x%x\n", (UINTN
)DxeIplImage
.EntryPoint
);
304 PrintString (PrintBuffer
);
306 EfiMainEntrypoint
= (EFI_MAIN_ENTRYPOINT
)(UINTN
)DxeIplImage
.EntryPoint
;
307 EfiMainEntrypoint (&Handoff
);
313 // There was a problem loading the image, so HALT the system.
322 UINT32 BiosMemoryMapBaseAddress
325 EfiLoader(BiosMemoryMapBaseAddress
);