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"
33 CHAR8 PrintBuffer
[256];
34 AsciiSPrint (PrintBuffer
, 256, "## FATEL ERROR ##: Fail to load DUET images! System hang!\n");
40 UINT32 BiosMemoryMapBaseAddress
43 BIOS_MEMORY_MAP
*BiosMemoryMap
;
44 EFILDR_HEADER
*EFILDRHeader
;
45 EFILDR_IMAGE
*EFILDRImage
;
46 EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor
[EFI_MAX_MEMORY_DESCRIPTORS
];
48 UINTN NumberOfMemoryMapEntries
;
49 UINT32 DestinationSize
;
53 EFI_MAIN_ENTRYPOINT EfiMainEntrypoint
;
54 CHAR8 PrintBuffer
[256];
55 static EFILDRHANDOFF Handoff
;
61 AsciiSPrint (PrintBuffer
, 256, "Enter DUET Loader ...\n", BiosMemoryMapBaseAddress
);
62 PrintString (PrintBuffer
);
64 AsciiSPrint (PrintBuffer
, 256, "BiosMemoryMapBaseAddress = 0x%x\n", BiosMemoryMapBaseAddress
);
65 PrintString (PrintBuffer
);
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.
71 BiosMemoryMap
= (BIOS_MEMORY_MAP
*)(UINTN
)(BiosMemoryMapBaseAddress
);
72 NumberOfMemoryMapEntries
= 0;
73 GenMemoryMap (&NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, BiosMemoryMap
);
75 AsciiSPrint (PrintBuffer
, 256, "Get %d entries of memory map!\n", NumberOfMemoryMapEntries
);
76 PrintString (PrintBuffer
);
79 // Get information on where the image is in memory
82 EFILDRHeader
= (EFILDR_HEADER
*)(UINTN
)(EFILDR_HEADER_ADDRESS
);
83 EFILDRImage
= (EFILDR_IMAGE
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ sizeof(EFILDR_HEADER
));
87 // Point to the 4th image (Bfv)
93 // Decompress the image
96 AsciiSPrint (PrintBuffer
, 256, "Decompress BFV image, Image Address=0x%x! Offset=0x%x\n",
97 (UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
99 PrintString (PrintBuffer
);
101 Status
= TianoGetInfo (
102 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
108 if (EFI_ERROR (Status
)) {
109 AsciiSPrint (PrintBuffer
, 256, "Fail to get decompress information for BFV!\n");
110 PrintString (PrintBuffer
);
114 Status
= TianoDecompress (
115 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
117 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
119 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000),
123 if (EFI_ERROR (Status
)) {
124 AsciiSPrint (PrintBuffer
, 256, "Fail to decompress BFV!\n");
125 PrintString (PrintBuffer
);
129 BfvPageNumber
= EFI_SIZE_TO_PAGES (DestinationSize
);
130 BfvBase
= (UINTN
) FindSpace (BfvPageNumber
, &NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, EfiRuntimeServicesData
, EFI_MEMORY_WB
);
134 ZeroMem ((VOID
*)(UINTN
)BfvBase
, BfvPageNumber
* EFI_PAGE_SIZE
);
135 CopyMem ((VOID
*)(UINTN
)BfvBase
, (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
, DestinationSize
);
140 // Point to the 2nd image (DxeIpl)
146 // Decompress the image
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 PrintString (PrintBuffer
);
153 Status
= TianoGetInfo (
154 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
159 if (EFI_ERROR (Status
)) {
160 AsciiSPrint (PrintBuffer
, 256, "Fail to get decompress information for DxeIpl!\n");
161 PrintString (PrintBuffer
);
165 Status
= TianoDecompress (
166 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
168 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
170 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000),
173 if (EFI_ERROR (Status
)) {
174 AsciiSPrint (PrintBuffer
, 256, "Fail to decompress DxeIpl image\n");
175 PrintString (PrintBuffer
);
179 AsciiSPrint (PrintBuffer
, 256, "Start load DxeIpl PE image\n");
180 PrintString (PrintBuffer
);
183 // Load and relocate the EFI PE/COFF Firmware Image
185 Status
= EfiLdrPeCoffLoadPeImage (
186 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
188 &NumberOfMemoryMapEntries
,
191 if (EFI_ERROR (Status
)) {
192 AsciiSPrint (PrintBuffer
, 256, "Fail to load and relocate DxeIpl PE image!\n");
193 PrintString (PrintBuffer
);
196 AsciiSPrint (PrintBuffer
, 256, "DxeIpl PE image is successed loaded at 0x%x, entry=0x%x\n",
197 (UINTN
)DxeIplImage
.ImageBasePage
, (UINTN
)DxeIplImage
.EntryPoint
);
198 PrintString (PrintBuffer
);
200 // PrintString("Image.NoPages = ");
201 // PrintValue(Image.NoPages);
202 // PrintString("\n");
207 // Point to the 3rd image (DxeMain)
213 // Decompress the image
215 AsciiSPrint (PrintBuffer
, 256, "Decompress DXEMain FV image, Image Address=0x%x! Offset=0x%x\n",
216 (UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
217 EFILDRImage
->Offset
);
218 PrintString (PrintBuffer
);
220 Status
= TianoGetInfo (
221 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
226 if (EFI_ERROR (Status
)) {
227 AsciiSPrint (PrintBuffer
, 256, "Fail to get decompress information for DXEMain FV image!\n");
228 PrintString (PrintBuffer
);
232 Status
= TianoDecompress (
233 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
235 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
237 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000),
240 if (EFI_ERROR (Status
)) {
245 // Load and relocate the EFI PE/COFF Firmware Image
247 Status
= EfiLdrPeCoffLoadPeImage (
248 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
250 &NumberOfMemoryMapEntries
,
253 if (EFI_ERROR (Status
)) {
256 AsciiSPrint (PrintBuffer
, 256, "DxeCore PE image is successed loaded at 0x%x, entry=0x%x\n",
257 (UINTN
)DxeCoreImage
.ImageBasePage
, (UINTN
)DxeCoreImage
.EntryPoint
);
258 PrintString (PrintBuffer
);
263 // Display the table of memory descriptors.
266 // PrintString("\nEFI Memory Descriptors\n");
270 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
271 PrintString("Type = ");
272 PrintValue(EfiMemoryDescriptor[Index].Type);
273 PrintString(" Start = ");
274 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));
275 PrintString(" NumberOfPages = ");
276 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));
283 // Jump to EFI Firmware
286 if (DxeIplImage
.EntryPoint
!= NULL
) {
288 Handoff
.MemDescCount
= NumberOfMemoryMapEntries
;
289 Handoff
.MemDesc
= EfiMemoryDescriptor
;
290 Handoff
.BfvBase
= (VOID
*)(UINTN
)BfvBase
;
291 Handoff
.BfvSize
= BfvPageNumber
* EFI_PAGE_SIZE
;
292 Handoff
.DxeIplImageBase
= (VOID
*)(UINTN
)DxeIplImage
.ImageBasePage
;
293 Handoff
.DxeIplImageSize
= DxeIplImage
.NoPages
* EFI_PAGE_SIZE
;
294 Handoff
.DxeCoreImageBase
= (VOID
*)(UINTN
)DxeCoreImage
.ImageBasePage
;
295 Handoff
.DxeCoreImageSize
= DxeCoreImage
.NoPages
* EFI_PAGE_SIZE
;
296 Handoff
.DxeCoreEntryPoint
= (VOID
*)(UINTN
)DxeCoreImage
.EntryPoint
;
298 AsciiSPrint (PrintBuffer
, 256, "Transfer to DxeIpl ...Address=0x%x\n", (UINTN
)DxeIplImage
.EntryPoint
);
299 PrintString (PrintBuffer
);
301 EfiMainEntrypoint
= (EFI_MAIN_ENTRYPOINT
)(UINTN
)DxeIplImage
.EntryPoint
;
302 EfiMainEntrypoint (&Handoff
);
308 // There was a problem loading the image, so HALT the system.
317 UINT32 BiosMemoryMapBaseAddress
320 EfiLoader(BiosMemoryMapBaseAddress
);