]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - DuetPkg/EfiLdr/EfiLoader.c
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8633 6f19259b...
[mirror_edk2.git] / DuetPkg / EfiLdr / EfiLoader.c
... / ...
CommitLineData
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
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 STATIC EFILDRHANDOFF Handoff;\r
54\r
55 ClearScreen();\r
56 \r
57 PrintHeader ('A');\r
58
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
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 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, \r
117 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
118 );\r
119 \r
120\r
121 if (EFI_ERROR (Status)) {\r
122 AsciiSPrint (PrintBuffer, 256, "Fail to decompress BFV!\n");\r
123 PrintString (PrintBuffer);\r
124 SystemHang();\r
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
130 SystemHang();\r
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
135 PrintHeader ('B');\r
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
146 AsciiSPrint (PrintBuffer, 256, "Decompress DxeIpl image, Image Address=0x%x Offset=0x%x\n", \r
147 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
148 EFILDRImage->Offset);\r
149 PrintString (PrintBuffer);\r
150\r
151 Status = LzmaUefiDecompressGetInfo (\r
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
158 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DxeIpl!\n");\r
159 PrintString (PrintBuffer);\r
160 SystemHang();\r
161 }\r
162\r
163 Status = LzmaUefiDecompress (\r
164 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
165 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
166 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
167 );\r
168 if (EFI_ERROR (Status)) {\r
169 AsciiSPrint (PrintBuffer, 256, "Fail to decompress DxeIpl image\n");\r
170 PrintString (PrintBuffer);\r
171 SystemHang();\r
172 }\r
173\r
174 AsciiSPrint (PrintBuffer, 256, "Start load DxeIpl PE image\n");\r
175 PrintString (PrintBuffer); \r
176\r
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
187 AsciiSPrint (PrintBuffer, 256, "Fail to load and relocate DxeIpl PE image!\n");\r
188 PrintString (PrintBuffer);\r
189 SystemHang();\r
190 }\r
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
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
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
214\r
215 Status = LzmaUefiDecompressGetInfo (\r
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
222 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DXEMain FV image!\n");\r
223 PrintString (PrintBuffer);\r
224 SystemHang();\r
225 }\r
226\r
227 Status = LzmaUefiDecompress (\r
228 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
229 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
230 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
231 );\r
232 if (EFI_ERROR (Status)) {\r
233 SystemHang();\r
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
246 SystemHang();\r
247 }\r
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
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
290 AsciiSPrint (PrintBuffer, 256, "Transfer to DxeIpl ...Address=0x%x\n", (UINTN)DxeIplImage.EntryPoint);\r
291 PrintString (PrintBuffer);\r
292 \r
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
303 SystemHang();\r
304}\r
305\r
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