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