]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/EfiLdr/EfiLoader.c
DuetPkg: Removing ipf which is no longer supported from edk2.
[mirror_edk2.git] / DuetPkg / EfiLdr / EfiLoader.c
CommitLineData
9071550e 1/*++\r
2\r
b68b78e6 3Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
b1f700a8 4This program and the accompanying materials \r
9071550e 5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13 EfiLoader.c\r
14\r
15Abstract:\r
16\r
17Revision History:\r
18\r
19--*/\r
20\r
21#include "EfiLdr.h"\r
22#include "Support.h"\r
23#include "Debug.h"\r
24#include "PeLoader.h"\r
8b85412a 25#include "LzmaDecompress.h"\r
3da85e63 26\r
031950df
LG
27EFILDR_LOADED_IMAGE DxeCoreImage;\r
28EFILDR_LOADED_IMAGE DxeIplImage;\r
29\r
3da85e63 30VOID\r
b68b78e6
RN
31SystemHang (\r
32 CHAR8 *Message\r
3da85e63 33 )\r
34{\r
b68b78e6
RN
35 PrintString (\r
36 "%s## FATAL ERROR ##: Fail to load DUET images! System hang!\n",\r
37 Message\r
38 );\r
3da85e63 39 CpuDeadLoop();\r
40}\r
9071550e 41\r
42VOID\r
43EfiLoader (\r
44 UINT32 BiosMemoryMapBaseAddress\r
45 )\r
46{\r
47 BIOS_MEMORY_MAP *BiosMemoryMap; \r
9071550e 48 EFILDR_IMAGE *EFILDRImage;\r
49 EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor[EFI_MAX_MEMORY_DESCRIPTORS];\r
50 EFI_STATUS Status;\r
51 UINTN NumberOfMemoryMapEntries;\r
52 UINT32 DestinationSize;\r
53 UINT32 ScratchSize;\r
54 UINTN BfvPageNumber;\r
55 UINTN BfvBase;\r
56 EFI_MAIN_ENTRYPOINT EfiMainEntrypoint;\r
dcb428da 57 EFILDRHANDOFF Handoff;\r
b68b78e6 58 UINTN Index;\r
9071550e 59\r
9071550e 60 ClearScreen();\r
3da85e63 61 \r
62 PrintHeader ('A');\r
b68b78e6
RN
63 \r
64 PrintString ("Enter DUET Loader...\n");\r
65 PrintString ("BiosMemoryMapBaseAddress = %x\n", (UINTN) BiosMemoryMapBaseAddress);\r
9071550e 66\r
67 //\r
68 // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then\r
34f5c234 69 // round the start address up to the next page, and round the length down to a page boundary.\r
9071550e 70 //\r
b68b78e6 71 BiosMemoryMap = (BIOS_MEMORY_MAP *) (UINTN) BiosMemoryMapBaseAddress;\r
9071550e 72 NumberOfMemoryMapEntries = 0;\r
73 GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap);\r
74\r
b68b78e6 75 PrintString ("Get %d entries of memory map!\n", NumberOfMemoryMapEntries);\r
3da85e63 76\r
9071550e 77 //\r
78 // Get information on where the image is in memory\r
79 //\r
9071550e 80 EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER));\r
81\r
9071550e 82\r
83 //\r
84 // Point to the 4th image (Bfv)\r
85 //\r
9071550e 86 EFILDRImage += 3;\r
87\r
88 //\r
89 // Decompress the image\r
90 //\r
b68b78e6
RN
91 PrintString (\r
92 "Decompress BFV image, Image Address = %x Offset = %x\n", \r
93 (UINTN) (EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
94 (UINTN) EFILDRImage->Offset\r
95 );\r
8b85412a 96 Status = LzmaUefiDecompressGetInfo (\r
9071550e 97 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
98 EFILDRImage->Length,\r
99 &DestinationSize, \r
100 &ScratchSize\r
101 );\r
3da85e63 102\r
9071550e 103 if (EFI_ERROR (Status)) {\r
b68b78e6 104 SystemHang ("Failed to get decompress information for BFV!\n");\r
9071550e 105 }\r
f8e01ca8 106 \r
b68b78e6 107 PrintString ("BFV decompress: DestinationSize = %x, ScratchSize = %x\n", (UINTN) DestinationSize, (UINTN) ScratchSize);\r
8b85412a 108 Status = LzmaUefiDecompress (\r
109 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
3ae5030e 110 EFILDRImage->Length,\r
8b85412a 111 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, \r
112 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
113 );\r
f8e01ca8 114 \r
3da85e63 115\r
9071550e 116 if (EFI_ERROR (Status)) {\r
b68b78e6 117 SystemHang ("Failed to decompress BFV!\n");\r
9071550e 118 }\r
119\r
120 BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize);\r
121 BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);\r
122 if (BfvBase == 0) {\r
b68b78e6 123 SystemHang ("Failed to find free space to hold decompressed BFV\n");\r
9071550e 124 }\r
125 ZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE);\r
126 CopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize);\r
127\r
3da85e63 128 PrintHeader ('B');\r
9071550e 129\r
130 //\r
131 // Point to the 2nd image (DxeIpl)\r
132 //\r
133 \r
134 EFILDRImage -= 2;\r
135\r
136 //\r
137 // Decompress the image\r
138 //\r
b68b78e6
RN
139 PrintString (\r
140 "Decompress DxeIpl image, Image Address = %x Offset = %x\n", \r
141 (UINTN) (EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
142 (UINTN) EFILDRImage->Offset\r
143 );\r
9071550e 144\r
8b85412a 145 Status = LzmaUefiDecompressGetInfo (\r
9071550e 146 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
147 EFILDRImage->Length,\r
148 &DestinationSize, \r
149 &ScratchSize\r
150 );\r
151 if (EFI_ERROR (Status)) {\r
b68b78e6 152 SystemHang ("Failed to get decompress information for DxeIpl!\n");\r
9071550e 153 }\r
154\r
8b85412a 155 Status = LzmaUefiDecompress (\r
9071550e 156 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
3ae5030e 157 EFILDRImage->Length,\r
9071550e 158 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
8b85412a 159 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
9071550e 160 );\r
161 if (EFI_ERROR (Status)) {\r
b68b78e6 162 SystemHang ("Failed to decompress DxeIpl image\n");\r
9071550e 163 }\r
164\r
b68b78e6 165 PrintString ("Start load DxeIpl PE image\n"); \r
3da85e63 166\r
9071550e 167 //\r
168 // Load and relocate the EFI PE/COFF Firmware Image \r
169 //\r
170 Status = EfiLdrPeCoffLoadPeImage (\r
171 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), \r
172 &DxeIplImage, \r
173 &NumberOfMemoryMapEntries, \r
174 EfiMemoryDescriptor\r
175 );\r
176 if (EFI_ERROR (Status)) {\r
b68b78e6 177 SystemHang ("Failed to load and relocate DxeIpl PE image!\n");\r
9071550e 178 }\r
b68b78e6
RN
179 PrintString (\r
180 "DxeIpl PE image is successed loaded at %lx, entry=%p\n",\r
181 DxeIplImage.ImageBasePage,\r
182 DxeIplImage.EntryPoint\r
183 );\r
9071550e 184\r
185PrintHeader ('C');\r
186\r
187 //\r
188 // Point to the 3rd image (DxeMain)\r
189 //\r
9071550e 190 EFILDRImage++;\r
191\r
192 //\r
193 // Decompress the image\r
194 //\r
b68b78e6
RN
195 PrintString (\r
196 "Decompress DxeMain FV image, Image Address = %x Offset = %x\n",\r
197 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
198 (UINTN) EFILDRImage->Offset\r
199 );\r
9071550e 200\r
8b85412a 201 Status = LzmaUefiDecompressGetInfo (\r
9071550e 202 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
203 EFILDRImage->Length,\r
204 &DestinationSize, \r
205 &ScratchSize\r
206 );\r
207 if (EFI_ERROR (Status)) {\r
b68b78e6 208 SystemHang ("Failed to get decompress information for DxeMain FV image!\n");\r
9071550e 209 }\r
210\r
8b85412a 211 Status = LzmaUefiDecompress (\r
9071550e 212 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
3ae5030e 213 EFILDRImage->Length,\r
9071550e 214 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
8b85412a 215 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
9071550e 216 );\r
217 if (EFI_ERROR (Status)) {\r
b68b78e6 218 SystemHang ("Failed to decompress DxeMain FV image!\n");\r
9071550e 219 }\r
220\r
221 //\r
222 // Load and relocate the EFI PE/COFF Firmware Image \r
223 //\r
224 Status = EfiLdrPeCoffLoadPeImage (\r
225 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), \r
226 &DxeCoreImage, \r
227 &NumberOfMemoryMapEntries, \r
228 EfiMemoryDescriptor\r
229 );\r
230 if (EFI_ERROR (Status)) {\r
b68b78e6 231 SystemHang ("Failed to load/relocate DxeMain!\n");\r
9071550e 232 }\r
b68b78e6
RN
233 PrintString (\r
234 "DxeCore PE image is successed loaded at %lx, entry=%p\n",\r
235 DxeCoreImage.ImageBasePage,\r
236 DxeCoreImage.EntryPoint\r
237 );\r
9071550e 238\r
239PrintHeader ('E');\r
240\r
241 //\r
242 // Display the table of memory descriptors.\r
243 //\r
b68b78e6 244 PrintString ("\nEFI Memory Descriptors\n"); \r
9071550e 245 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {\r
b68b78e6
RN
246 PrintString (\r
247 "Type = %x Start = %08lx NumberOfPages = %08lx\n",\r
248 EfiMemoryDescriptor[Index].Type, EfiMemoryDescriptor[Index].PhysicalStart, EfiMemoryDescriptor[Index].NumberOfPages\r
249 );\r
9071550e 250 }\r
9071550e 251\r
252 //\r
253 // Jump to EFI Firmware\r
254 //\r
255\r
256 if (DxeIplImage.EntryPoint != NULL) {\r
257\r
258 Handoff.MemDescCount = NumberOfMemoryMapEntries;\r
259 Handoff.MemDesc = EfiMemoryDescriptor;\r
260 Handoff.BfvBase = (VOID *)(UINTN)BfvBase;\r
261 Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;\r
262 Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;\r
263 Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;\r
264 Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;\r
265 Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;\r
266 Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;\r
267\r
b68b78e6 268 PrintString ("Transfer to DxeIpl ...EntryPoint = %p\n", DxeIplImage.EntryPoint);\r
ff514e29 269 \r
b68b78e6 270 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT) DxeIplImage.EntryPoint;\r
9071550e 271 EfiMainEntrypoint (&Handoff);\r
272 }\r
273\r
274PrintHeader ('F');\r
275\r
276 //\r
277 // There was a problem loading the image, so HALT the system.\r
278 //\r
279\r
b68b78e6 280 SystemHang ("Failed to jump to DxeIpl!\n");\r
9071550e 281}\r
282\r
c51b1cb6 283EFI_STATUS\r
284EFIAPI\r
285_ModuleEntryPoint (\r
286 UINT32 BiosMemoryMapBaseAddress\r
287 )\r
288{\r
b68b78e6 289 SerialPortInitialize ();\r
c51b1cb6 290 EfiLoader(BiosMemoryMapBaseAddress);\r
291 return EFI_SUCCESS;\r
292}\r
293\r
294\r