3 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4 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"
33 "%s## FATAL ERROR ##: Fail to load DUET images! System hang!\n",
41 UINT32 BiosMemoryMapBaseAddress
44 BIOS_MEMORY_MAP
*BiosMemoryMap
;
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 EFILDRHANDOFF Handoff
;
61 PrintString ("Enter DUET Loader...\n");
62 PrintString ("BiosMemoryMapBaseAddress = %x\n", (UINTN
) BiosMemoryMapBaseAddress
);
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.
68 BiosMemoryMap
= (BIOS_MEMORY_MAP
*) (UINTN
) BiosMemoryMapBaseAddress
;
69 NumberOfMemoryMapEntries
= 0;
70 GenMemoryMap (&NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, BiosMemoryMap
);
72 PrintString ("Get %d entries of memory map!\n", NumberOfMemoryMapEntries
);
75 // Get information on where the image is in memory
77 EFILDRImage
= (EFILDR_IMAGE
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ sizeof(EFILDR_HEADER
));
81 // Point to the 4th image (Bfv)
86 // Decompress the image
89 "Decompress BFV image, Image Address = %x Offset = %x\n",
90 (UINTN
) (EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
91 (UINTN
) EFILDRImage
->Offset
93 Status
= LzmaUefiDecompressGetInfo (
94 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
100 if (EFI_ERROR (Status
)) {
101 SystemHang ("Failed to get decompress information for BFV!\n");
104 PrintString ("BFV decompress: DestinationSize = %x, ScratchSize = %x\n", (UINTN
) DestinationSize
, (UINTN
) ScratchSize
);
105 Status
= LzmaUefiDecompress (
106 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
108 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
109 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000)
113 if (EFI_ERROR (Status
)) {
114 SystemHang ("Failed to decompress BFV!\n");
117 BfvPageNumber
= EFI_SIZE_TO_PAGES (DestinationSize
);
118 BfvBase
= (UINTN
) FindSpace (BfvPageNumber
, &NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, EfiRuntimeServicesData
, EFI_MEMORY_WB
);
120 SystemHang ("Failed to find free space to hold decompressed BFV\n");
122 ZeroMem ((VOID
*)(UINTN
)BfvBase
, BfvPageNumber
* EFI_PAGE_SIZE
);
123 CopyMem ((VOID
*)(UINTN
)BfvBase
, (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
, DestinationSize
);
128 // Point to the 2nd image (DxeIpl)
134 // Decompress the image
137 "Decompress DxeIpl image, Image Address = %x Offset = %x\n",
138 (UINTN
) (EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
139 (UINTN
) EFILDRImage
->Offset
142 Status
= LzmaUefiDecompressGetInfo (
143 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
148 if (EFI_ERROR (Status
)) {
149 SystemHang ("Failed to get decompress information for DxeIpl!\n");
152 Status
= LzmaUefiDecompress (
153 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
155 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
156 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000)
158 if (EFI_ERROR (Status
)) {
159 SystemHang ("Failed to decompress DxeIpl image\n");
162 PrintString ("Start load DxeIpl PE image\n");
165 // Load and relocate the EFI PE/COFF Firmware Image
167 Status
= EfiLdrPeCoffLoadPeImage (
168 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
170 &NumberOfMemoryMapEntries
,
173 if (EFI_ERROR (Status
)) {
174 SystemHang ("Failed to load and relocate DxeIpl PE image!\n");
177 "DxeIpl PE image is successed loaded at %lx, entry=%p\n",
178 DxeIplImage
.ImageBasePage
,
179 DxeIplImage
.EntryPoint
185 // Point to the 3rd image (DxeMain)
190 // Decompress the image
193 "Decompress DxeMain FV image, Image Address = %x Offset = %x\n",
194 (UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
195 (UINTN
) EFILDRImage
->Offset
198 Status
= LzmaUefiDecompressGetInfo (
199 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
204 if (EFI_ERROR (Status
)) {
205 SystemHang ("Failed to get decompress information for DxeMain FV image!\n");
208 Status
= LzmaUefiDecompress (
209 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
211 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
212 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000)
214 if (EFI_ERROR (Status
)) {
215 SystemHang ("Failed to decompress DxeMain FV image!\n");
219 // Load and relocate the EFI PE/COFF Firmware Image
221 Status
= EfiLdrPeCoffLoadPeImage (
222 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
224 &NumberOfMemoryMapEntries
,
227 if (EFI_ERROR (Status
)) {
228 SystemHang ("Failed to load/relocate DxeMain!\n");
231 "DxeCore PE image is successed loaded at %lx, entry=%p\n",
232 DxeCoreImage
.ImageBasePage
,
233 DxeCoreImage
.EntryPoint
239 // Display the table of memory descriptors.
241 PrintString ("\nEFI Memory Descriptors\n");
242 for (Index
= 0; Index
< NumberOfMemoryMapEntries
; Index
++) {
244 "Type = %x Start = %08lx NumberOfPages = %08lx\n",
245 EfiMemoryDescriptor
[Index
].Type
, EfiMemoryDescriptor
[Index
].PhysicalStart
, EfiMemoryDescriptor
[Index
].NumberOfPages
250 // Jump to EFI Firmware
253 if (DxeIplImage
.EntryPoint
!= NULL
) {
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
;
265 PrintString ("Transfer to DxeIpl ...EntryPoint = %p\n", DxeIplImage
.EntryPoint
);
267 EfiMainEntrypoint
= (EFI_MAIN_ENTRYPOINT
) DxeIplImage
.EntryPoint
;
268 EfiMainEntrypoint (&Handoff
);
274 // There was a problem loading the image, so HALT the system.
277 SystemHang ("Failed to jump to DxeIpl!\n");
283 UINT32 BiosMemoryMapBaseAddress
286 SerialPortInitialize ();
287 EfiLoader(BiosMemoryMapBaseAddress
);