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.
28 UINT32 BiosMemoryMapBaseAddress
31 BIOS_MEMORY_MAP
*BiosMemoryMap
;
32 EFILDR_HEADER
*EFILDRHeader
;
33 EFILDR_IMAGE
*EFILDRImage
;
34 EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor
[EFI_MAX_MEMORY_DESCRIPTORS
];
36 UINTN NumberOfMemoryMapEntries
;
37 UINT32 DestinationSize
;
41 EFI_MAIN_ENTRYPOINT EfiMainEntrypoint
;
42 static EFILDRHANDOFF Handoff
;
47 PrintString("EFI Loader\n");
49 // PrintString("&BiosMemoryMapBaseAddress = ");
50 // PrintValue64 ((UINT64)(&BiosMemoryMapBaseAddress));
51 // PrintString(" BiosMemoryMapBaseAddress = ");
52 // PrintValue(BiosMemoryMapBaseAddress);
56 // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then
57 // round the start address up to the next page, and round the length down to a page boundry.
59 BiosMemoryMap
= (BIOS_MEMORY_MAP
*)(UINTN
)(BiosMemoryMapBaseAddress
);
60 NumberOfMemoryMapEntries
= 0;
61 GenMemoryMap (&NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, BiosMemoryMap
);
64 // Get information on where the image is in memory
67 EFILDRHeader
= (EFILDR_HEADER
*)(UINTN
)(EFILDR_HEADER_ADDRESS
);
68 EFILDRImage
= (EFILDR_IMAGE
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ sizeof(EFILDR_HEADER
));
73 // Point to the 4th image (Bfv)
79 // Decompress the image
82 Status
= UefiDecompressGetInfo (
84 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
89 if (EFI_ERROR (Status
)) {
93 Status
= TianoDecompress (
95 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
97 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
99 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000),
102 if (EFI_ERROR (Status
)) {
106 BfvPageNumber
= EFI_SIZE_TO_PAGES (DestinationSize
);
107 BfvBase
= (UINTN
) FindSpace (BfvPageNumber
, &NumberOfMemoryMapEntries
, EfiMemoryDescriptor
, EfiRuntimeServicesData
, EFI_MEMORY_WB
);
111 ZeroMem ((VOID
*)(UINTN
)BfvBase
, BfvPageNumber
* EFI_PAGE_SIZE
);
112 CopyMem ((VOID
*)(UINTN
)BfvBase
, (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
, DestinationSize
);
117 // Point to the 2nd image (DxeIpl)
123 // Decompress the image
126 Status
= UefiDecompressGetInfo (
128 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
133 if (EFI_ERROR (Status
)) {
137 Status
= TianoDecompress (
139 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
141 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
143 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000),
146 if (EFI_ERROR (Status
)) {
151 // Load and relocate the EFI PE/COFF Firmware Image
153 Status
= EfiLdrPeCoffLoadPeImage (
154 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
156 &NumberOfMemoryMapEntries
,
159 if (EFI_ERROR (Status
)) {
163 // PrintString("Image.NoPages = ");
164 // PrintValue(Image.NoPages);
165 // PrintString("\n");
170 // Point to the 3rd image (DxeMain)
176 // Decompress the image
179 Status
= UefiDecompressGetInfo (
181 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
186 if (EFI_ERROR (Status
)) {
190 Status
= TianoDecompress (
192 (VOID
*)(UINTN
)(EFILDR_HEADER_ADDRESS
+ EFILDRImage
->Offset
),
194 (VOID
*)(UINTN
)EFI_DECOMPRESSED_BUFFER_ADDRESS
,
196 (VOID
*)(UINTN
)((EFI_DECOMPRESSED_BUFFER_ADDRESS
+ DestinationSize
+ 0x1000) & 0xfffff000),
199 if (EFI_ERROR (Status
)) {
204 // Load and relocate the EFI PE/COFF Firmware Image
206 Status
= EfiLdrPeCoffLoadPeImage (
207 (VOID
*)(UINTN
)(EFI_DECOMPRESSED_BUFFER_ADDRESS
),
209 &NumberOfMemoryMapEntries
,
212 if (EFI_ERROR (Status
)) {
219 // Display the table of memory descriptors.
222 // PrintString("\nEFI Memory Descriptors\n");
226 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {
227 PrintString("Type = ");
228 PrintValue(EfiMemoryDescriptor[Index].Type);
229 PrintString(" Start = ");
230 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));
231 PrintString(" NumberOfPages = ");
232 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));
239 // Jump to EFI Firmware
242 if (DxeIplImage
.EntryPoint
!= NULL
) {
244 Handoff
.MemDescCount
= NumberOfMemoryMapEntries
;
245 Handoff
.MemDesc
= EfiMemoryDescriptor
;
246 Handoff
.BfvBase
= (VOID
*)(UINTN
)BfvBase
;
247 Handoff
.BfvSize
= BfvPageNumber
* EFI_PAGE_SIZE
;
248 Handoff
.DxeIplImageBase
= (VOID
*)(UINTN
)DxeIplImage
.ImageBasePage
;
249 Handoff
.DxeIplImageSize
= DxeIplImage
.NoPages
* EFI_PAGE_SIZE
;
250 Handoff
.DxeCoreImageBase
= (VOID
*)(UINTN
)DxeCoreImage
.ImageBasePage
;
251 Handoff
.DxeCoreImageSize
= DxeCoreImage
.NoPages
* EFI_PAGE_SIZE
;
252 Handoff
.DxeCoreEntryPoint
= (VOID
*)(UINTN
)DxeCoreImage
.EntryPoint
;
254 EfiMainEntrypoint
= (EFI_MAIN_ENTRYPOINT
)(UINTN
)DxeIplImage
.EntryPoint
;
255 EfiMainEntrypoint (&Handoff
);
261 // There was a problem loading the image, so HALT the system.