]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/EfiLdr/EfiLoader.c
Update PeiLoadFilePpi produced by PeiCore to load only images with relocation into...
[mirror_edk2.git] / DuetPkg / EfiLdr / EfiLoader.c
CommitLineData
9071550e 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
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
3da85e63 27VOID\r
28SystemHang(\r
29 VOID\r
30 )\r
31{\r
32 CHAR8 PrintBuffer[256];\r
33 AsciiSPrint (PrintBuffer, 256, "## FATEL ERROR ##: Fail to load DUET images! System hang!\n");\r
34 CpuDeadLoop();\r
35}\r
9071550e 36\r
37VOID\r
38EfiLoader (\r
39 UINT32 BiosMemoryMapBaseAddress\r
40 )\r
41{\r
42 BIOS_MEMORY_MAP *BiosMemoryMap; \r
9071550e 43 EFILDR_IMAGE *EFILDRImage;\r
44 EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor[EFI_MAX_MEMORY_DESCRIPTORS];\r
45 EFI_STATUS Status;\r
46 UINTN NumberOfMemoryMapEntries;\r
47 UINT32 DestinationSize;\r
48 UINT32 ScratchSize;\r
49 UINTN BfvPageNumber;\r
50 UINTN BfvBase;\r
51 EFI_MAIN_ENTRYPOINT EfiMainEntrypoint;\r
3da85e63 52 CHAR8 PrintBuffer[256];\r
e56dd2ce 53 STATIC EFILDRHANDOFF Handoff;\r
9071550e 54\r
9071550e 55 ClearScreen();\r
3da85e63 56 \r
57 PrintHeader ('A');\r
49794755 58
3da85e63 59 AsciiSPrint (PrintBuffer, 256, "Enter DUET Loader ...\n", BiosMemoryMapBaseAddress);\r
60 PrintString (PrintBuffer);\r
61\r
62 AsciiSPrint (PrintBuffer, 256, "BiosMemoryMapBaseAddress = 0x%x\n", BiosMemoryMapBaseAddress);\r
63 PrintString (PrintBuffer);\r
9071550e 64\r
65 //\r
66 // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then\r
67 // round the start address up to the next page, and round the length down to a page boundry.\r
68 //\r
69 BiosMemoryMap = (BIOS_MEMORY_MAP *)(UINTN)(BiosMemoryMapBaseAddress);\r
70 NumberOfMemoryMapEntries = 0;\r
71 GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap);\r
72\r
3da85e63 73 AsciiSPrint (PrintBuffer, 256, "Get %d entries of memory map!\n", NumberOfMemoryMapEntries);\r
74 PrintString (PrintBuffer);\r
75\r
9071550e 76 //\r
77 // Get information on where the image is in memory\r
78 //\r
79\r
e188a609 80 //EFILDRHeader = (EFILDR_HEADER *)(UINTN)(EFILDR_HEADER_ADDRESS);\r
9071550e 81 EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER));\r
82\r
9071550e 83\r
84 //\r
85 // Point to the 4th image (Bfv)\r
86 //\r
87 \r
88 EFILDRImage += 3;\r
89\r
90 //\r
91 // Decompress the image\r
92 //\r
93\r
c5dfb477 94 AsciiSPrint (PrintBuffer, 256, "Decompress BFV image, Image Address=0x%x Offset=0x%x\n", \r
3da85e63 95 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
96 EFILDRImage->Offset);\r
97 PrintString (PrintBuffer);\r
8b85412a 98 Status = LzmaUefiDecompressGetInfo (\r
9071550e 99 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
100 EFILDRImage->Length,\r
101 &DestinationSize, \r
102 &ScratchSize\r
103 );\r
3da85e63 104\r
9071550e 105 if (EFI_ERROR (Status)) {\r
3da85e63 106 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for BFV!\n");\r
107 PrintString (PrintBuffer);\r
108 SystemHang();\r
9071550e 109 }\r
f8e01ca8 110 \r
111 AsciiSPrint (PrintBuffer, 256, "BFV decompress: DestinationSize=0x%X, ScratchSize=0x%X!\n",\r
112 DestinationSize, ScratchSize);\r
113 PrintString (PrintBuffer);\r
8b85412a 114 Status = LzmaUefiDecompress (\r
115 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
116 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, \r
117 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
118 );\r
f8e01ca8 119 \r
3da85e63 120\r
9071550e 121 if (EFI_ERROR (Status)) {\r
3da85e63 122 AsciiSPrint (PrintBuffer, 256, "Fail to decompress BFV!\n");\r
123 PrintString (PrintBuffer);\r
124 SystemHang();\r
9071550e 125 }\r
126\r
127 BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize);\r
128 BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);\r
129 if (BfvBase == 0) {\r
3da85e63 130 SystemHang();\r
9071550e 131 }\r
132 ZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE);\r
133 CopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize);\r
134\r
3da85e63 135 PrintHeader ('B');\r
9071550e 136\r
137 //\r
138 // Point to the 2nd image (DxeIpl)\r
139 //\r
140 \r
141 EFILDRImage -= 2;\r
142\r
143 //\r
144 // Decompress the image\r
145 //\r
c5dfb477 146 AsciiSPrint (PrintBuffer, 256, "Decompress DxeIpl image, Image Address=0x%x Offset=0x%x\n", \r
3da85e63 147 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
148 EFILDRImage->Offset);\r
ff514e29 149 PrintString (PrintBuffer);\r
9071550e 150\r
8b85412a 151 Status = LzmaUefiDecompressGetInfo (\r
9071550e 152 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
153 EFILDRImage->Length,\r
154 &DestinationSize, \r
155 &ScratchSize\r
156 );\r
157 if (EFI_ERROR (Status)) {\r
3da85e63 158 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DxeIpl!\n");\r
159 PrintString (PrintBuffer);\r
160 SystemHang();\r
9071550e 161 }\r
162\r
8b85412a 163 Status = LzmaUefiDecompress (\r
9071550e 164 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
9071550e 165 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
8b85412a 166 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
9071550e 167 );\r
168 if (EFI_ERROR (Status)) {\r
3da85e63 169 AsciiSPrint (PrintBuffer, 256, "Fail to decompress DxeIpl image\n");\r
170 PrintString (PrintBuffer);\r
171 SystemHang();\r
9071550e 172 }\r
173\r
3da85e63 174 AsciiSPrint (PrintBuffer, 256, "Start load DxeIpl PE image\n");\r
175 PrintString (PrintBuffer); \r
176\r
9071550e 177 //\r
178 // Load and relocate the EFI PE/COFF Firmware Image \r
179 //\r
180 Status = EfiLdrPeCoffLoadPeImage (\r
181 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), \r
182 &DxeIplImage, \r
183 &NumberOfMemoryMapEntries, \r
184 EfiMemoryDescriptor\r
185 );\r
186 if (EFI_ERROR (Status)) {\r
3da85e63 187 AsciiSPrint (PrintBuffer, 256, "Fail to load and relocate DxeIpl PE image!\n");\r
188 PrintString (PrintBuffer);\r
189 SystemHang();\r
9071550e 190 }\r
ff514e29 191 AsciiSPrint (PrintBuffer, 256, "DxeIpl PE image is successed loaded at 0x%x, entry=0x%x\n",\r
192 (UINTN)DxeIplImage.ImageBasePage, (UINTN)DxeIplImage.EntryPoint);\r
193 PrintString (PrintBuffer); \r
9071550e 194\r
195// PrintString("Image.NoPages = "); \r
196// PrintValue(Image.NoPages);\r
197// PrintString("\n");\r
198\r
199PrintHeader ('C');\r
200\r
201 //\r
202 // Point to the 3rd image (DxeMain)\r
203 //\r
204 \r
205 EFILDRImage++;\r
206\r
207 //\r
208 // Decompress the image\r
209 //\r
ff514e29 210 AsciiSPrint (PrintBuffer, 256, "Decompress DXEMain FV image, Image Address=0x%x! Offset=0x%x\n", \r
211 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
212 EFILDRImage->Offset);\r
213 PrintString (PrintBuffer);\r
9071550e 214\r
8b85412a 215 Status = LzmaUefiDecompressGetInfo (\r
9071550e 216 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
217 EFILDRImage->Length,\r
218 &DestinationSize, \r
219 &ScratchSize\r
220 );\r
221 if (EFI_ERROR (Status)) {\r
ff514e29 222 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DXEMain FV image!\n");\r
223 PrintString (PrintBuffer);\r
3da85e63 224 SystemHang();\r
9071550e 225 }\r
226\r
8b85412a 227 Status = LzmaUefiDecompress (\r
9071550e 228 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
9071550e 229 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
8b85412a 230 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
9071550e 231 );\r
232 if (EFI_ERROR (Status)) {\r
3da85e63 233 SystemHang();\r
9071550e 234 }\r
235\r
236 //\r
237 // Load and relocate the EFI PE/COFF Firmware Image \r
238 //\r
239 Status = EfiLdrPeCoffLoadPeImage (\r
240 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), \r
241 &DxeCoreImage, \r
242 &NumberOfMemoryMapEntries, \r
243 EfiMemoryDescriptor\r
244 );\r
245 if (EFI_ERROR (Status)) {\r
3da85e63 246 SystemHang();\r
9071550e 247 }\r
ff514e29 248 AsciiSPrint (PrintBuffer, 256, "DxeCore PE image is successed loaded at 0x%x, entry=0x%x\n",\r
249 (UINTN)DxeCoreImage.ImageBasePage, (UINTN)DxeCoreImage.EntryPoint);\r
250 PrintString (PrintBuffer); \r
9071550e 251\r
252PrintHeader ('E');\r
253\r
254 //\r
255 // Display the table of memory descriptors.\r
256 //\r
257\r
258// PrintString("\nEFI Memory Descriptors\n"); \r
259/*\r
260 {\r
261 UINTN Index;\r
262 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {\r
263 PrintString("Type = "); \r
264 PrintValue(EfiMemoryDescriptor[Index].Type);\r
265 PrintString(" Start = "); \r
266 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));\r
267 PrintString(" NumberOfPages = "); \r
268 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));\r
269 PrintString("\n");\r
270 }\r
271 }\r
272*/\r
273\r
274 //\r
275 // Jump to EFI Firmware\r
276 //\r
277\r
278 if (DxeIplImage.EntryPoint != NULL) {\r
279\r
280 Handoff.MemDescCount = NumberOfMemoryMapEntries;\r
281 Handoff.MemDesc = EfiMemoryDescriptor;\r
282 Handoff.BfvBase = (VOID *)(UINTN)BfvBase;\r
283 Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;\r
284 Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;\r
285 Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;\r
286 Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;\r
287 Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;\r
288 Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;\r
289\r
ff514e29 290 AsciiSPrint (PrintBuffer, 256, "Transfer to DxeIpl ...Address=0x%x\n", (UINTN)DxeIplImage.EntryPoint);\r
291 PrintString (PrintBuffer);\r
292 \r
9071550e 293 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT)(UINTN)DxeIplImage.EntryPoint;\r
294 EfiMainEntrypoint (&Handoff);\r
295 }\r
296\r
297PrintHeader ('F');\r
298\r
299 //\r
300 // There was a problem loading the image, so HALT the system.\r
301 //\r
302\r
3da85e63 303 SystemHang();\r
9071550e 304}\r
305\r
c51b1cb6 306EFI_STATUS\r
307EFIAPI\r
308_ModuleEntryPoint (\r
309 UINT32 BiosMemoryMapBaseAddress\r
310 )\r
311{\r
312 EfiLoader(BiosMemoryMapBaseAddress);\r
313 return EFI_SUCCESS;\r
314}\r
315\r
316\r