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"
27 EFILDR_LOADED_IMAGE DxeCoreImage
;
28 EFILDR_LOADED_IMAGE DxeIplImage
;
36 "%s## FATAL ERROR ##: Fail to load DUET images! System hang!\n",
44 UINT32 BiosMemoryMapBaseAddress
47 BIOS_MEMORY_MAP
*BiosMemoryMap
;
48 EFILDR_IMAGE
*EFILDRImage
;
49 EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor
[EFI_MAX_MEMORY_DESCRIPTORS
];
51 UINTN NumberOfMemoryMapEntries
;
52 UINT32 DestinationSize
;
56 EFI_MAIN_ENTRYPOINT EfiMainEntrypoint
;
57 EFILDRHANDOFF Handoff
;
64 PrintString ("Enter DUET Loader...\n");
65 PrintString ("BiosMemoryMapBaseAddress = %x\n", (UINTN
) BiosMemoryMapBaseAddress
);
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 boundary.
71 BiosMemoryMap
= (BIOS_MEMORY_MAP
*) (UINTN
) BiosMemoryMapBaseAddress
;
72 NumberOfMemoryMapEntries
= 0;
73 GenMemoryMap (&NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, BiosMemoryMap
);
75 PrintString ("Get %d entries of memory map!\n", NumberOfMemoryMapEntries
);
78 // Get information on where the image is in memory
80 EFILDRImage
= (EFILDR_IMAGE
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ sizeof(EFILDR_HEADER
));
84 // Point to the 4th image (Bfv)
89 // Decompress the image
92 "Decompress BFV image, Image Address = %x Offset = %x\n",
93 (UINTN
) (EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
94 (UINTN
) EFILDRImage
->Offset
96 Status
= LzmaUefiDecompressGetInfo (
97 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
103 if (EFI_ERROR (Status
)) {
104 SystemHang ("Failed to get decompress information for BFV!\n");
107 PrintString ("BFV decompress: DestinationSize = %x, ScratchSize = %x\n", (UINTN
) DestinationSize
, (UINTN
) ScratchSize
);
108 Status
= LzmaUefiDecompress (
109 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
111 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
112 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000)
116 if (EFI_ERROR (Status
)) {
117 SystemHang ("Failed to decompress BFV!\n");
120 BfvPageNumber
= EFI_SIZE_TO_PAGES (DestinationSize
);
121 BfvBase
= (UINTN
) FindSpace (BfvPageNumber
, &NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, EfiRuntimeServicesData
, EFI_MEMORY_WB
);
123 SystemHang ("Failed to find free space to hold decompressed BFV\n");
125 ZeroMem ((VOID
*)(UINTN
)BfvBase
, BfvPageNumber
* EFI_PAGE_SIZE
);
126 CopyMem ((VOID
*)(UINTN
)BfvBase
, (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
, DestinationSize
);
131 // Point to the 2nd image (DxeIpl)
137 // Decompress the image
140 "Decompress DxeIpl image, Image Address = %x Offset = %x\n",
141 (UINTN
) (EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
142 (UINTN
) EFILDRImage
->Offset
145 Status
= LzmaUefiDecompressGetInfo (
146 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
151 if (EFI_ERROR (Status
)) {
152 SystemHang ("Failed to get decompress information for DxeIpl!\n");
155 Status
= LzmaUefiDecompress (
156 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
158 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
159 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000)
161 if (EFI_ERROR (Status
)) {
162 SystemHang ("Failed to decompress DxeIpl image\n");
165 PrintString ("Start load DxeIpl PE image\n");
168 // Load and relocate the EFI PE/COFF Firmware Image
170 Status
= EfiLdrPeCoffLoadPeImage (
171 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
173 &NumberOfMemoryMapEntries
,
176 if (EFI_ERROR (Status
)) {
177 SystemHang ("Failed to load and relocate DxeIpl PE image!\n");
180 "DxeIpl PE image is successed loaded at %lx, entry=%p\n",
181 DxeIplImage
.ImageBasePage
,
182 DxeIplImage
.EntryPoint
188 // Point to the 3rd image (DxeMain)
193 // Decompress the image
196 "Decompress DxeMain FV image, Image Address = %x Offset = %x\n",
197 (UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
198 (UINTN
) EFILDRImage
->Offset
201 Status
= LzmaUefiDecompressGetInfo (
202 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
207 if (EFI_ERROR (Status
)) {
208 SystemHang ("Failed to get decompress information for DxeMain FV image!\n");
211 Status
= LzmaUefiDecompress (
212 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
214 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
215 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000)
217 if (EFI_ERROR (Status
)) {
218 SystemHang ("Failed to decompress DxeMain FV image!\n");
222 // Load and relocate the EFI PE/COFF Firmware Image
224 Status
= EfiLdrPeCoffLoadPeImage (
225 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
227 &NumberOfMemoryMapEntries
,
230 if (EFI_ERROR (Status
)) {
231 SystemHang ("Failed to load/relocate DxeMain!\n");
234 "DxeCore PE image is successed loaded at %lx, entry=%p\n",
235 DxeCoreImage
.ImageBasePage
,
236 DxeCoreImage
.EntryPoint
242 // Display the table of memory descriptors.
244 PrintString ("\nEFI Memory Descriptors\n");
245 for (Index
= 0; Index
< NumberOfMemoryMapEntries
; Index
++) {
247 "Type = %x Start = %08lx NumberOfPages = %08lx\n",
248 EfiMemoryDescriptor
[Index
].Type
, EfiMemoryDescriptor
[Index
].PhysicalStart
, EfiMemoryDescriptor
[Index
].NumberOfPages
253 // Jump to EFI Firmware
256 if (DxeIplImage
.EntryPoint
!= NULL
) {
258 Handoff
.MemDescCount
= NumberOfMemoryMapEntries
;
259 Handoff
.MemDesc
= EfiMemoryDescriptor
;
260 Handoff
.BfvBase
= (VOID
*)(UINTN
)BfvBase
;
261 Handoff
.BfvSize
= BfvPageNumber
* EFI_PAGE_SIZE
;
262 Handoff
.DxeIplImageBase
= (VOID
*)(UINTN
)DxeIplImage
.ImageBasePage
;
263 Handoff
.DxeIplImageSize
= DxeIplImage
.NoPages
* EFI_PAGE_SIZE
;
264 Handoff
.DxeCoreImageBase
= (VOID
*)(UINTN
)DxeCoreImage
.ImageBasePage
;
265 Handoff
.DxeCoreImageSize
= DxeCoreImage
.NoPages
* EFI_PAGE_SIZE
;
266 Handoff
.DxeCoreEntryPoint
= (VOID
*)(UINTN
)DxeCoreImage
.EntryPoint
;
268 PrintString ("Transfer to DxeIpl ...EntryPoint = %p\n", DxeIplImage
.EntryPoint
);
270 EfiMainEntrypoint
= (EFI_MAIN_ENTRYPOINT
) DxeIplImage
.EntryPoint
;
271 EfiMainEntrypoint (&Handoff
);
277 // There was a problem loading the image, so HALT the system.
280 SystemHang ("Failed to jump to DxeIpl!\n");
286 UINT32 BiosMemoryMapBaseAddress
289 SerialPortInitialize ();
290 EfiLoader(BiosMemoryMapBaseAddress
);