]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - DuetPkg/EfiLdr/EfiLoader.c
BaseTools/BinToPcd: Fix Python 2.7.x compatibility issue
[mirror_edk2.git] / DuetPkg / EfiLdr / EfiLoader.c
... / ...
CommitLineData
1/*++\r
2\r
3Copyright (c) 2006 - 2011, 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
27EFILDR_LOADED_IMAGE DxeCoreImage;\r
28EFILDR_LOADED_IMAGE DxeIplImage;\r
29\r
30VOID\r
31SystemHang (\r
32 CHAR8 *Message\r
33 )\r
34{\r
35 PrintString (\r
36 "%s## FATAL ERROR ##: Fail to load DUET images! System hang!\n",\r
37 Message\r
38 );\r
39 CpuDeadLoop();\r
40}\r
41\r
42VOID\r
43EfiLoader (\r
44 UINT32 BiosMemoryMapBaseAddress\r
45 )\r
46{\r
47 BIOS_MEMORY_MAP *BiosMemoryMap; \r
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
57 EFILDRHANDOFF Handoff;\r
58 UINTN Index;\r
59\r
60 ClearScreen();\r
61 \r
62 PrintHeader ('A');\r
63 \r
64 PrintString ("Enter DUET Loader...\n");\r
65 PrintString ("BiosMemoryMapBaseAddress = %x\n", (UINTN) BiosMemoryMapBaseAddress);\r
66\r
67 //\r
68 // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then\r
69 // round the start address up to the next page, and round the length down to a page boundary.\r
70 //\r
71 BiosMemoryMap = (BIOS_MEMORY_MAP *) (UINTN) BiosMemoryMapBaseAddress;\r
72 NumberOfMemoryMapEntries = 0;\r
73 GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap);\r
74\r
75 PrintString ("Get %d entries of memory map!\n", NumberOfMemoryMapEntries);\r
76\r
77 //\r
78 // Get information on where the image is in memory\r
79 //\r
80 EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER));\r
81\r
82\r
83 //\r
84 // Point to the 4th image (Bfv)\r
85 //\r
86 EFILDRImage += 3;\r
87\r
88 //\r
89 // Decompress the image\r
90 //\r
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
96 Status = LzmaUefiDecompressGetInfo (\r
97 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
98 EFILDRImage->Length,\r
99 &DestinationSize, \r
100 &ScratchSize\r
101 );\r
102\r
103 if (EFI_ERROR (Status)) {\r
104 SystemHang ("Failed to get decompress information for BFV!\n");\r
105 }\r
106 \r
107 PrintString ("BFV decompress: DestinationSize = %x, ScratchSize = %x\n", (UINTN) DestinationSize, (UINTN) ScratchSize);\r
108 Status = LzmaUefiDecompress (\r
109 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
110 EFILDRImage->Length,\r
111 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, \r
112 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
113 );\r
114 \r
115\r
116 if (EFI_ERROR (Status)) {\r
117 SystemHang ("Failed to decompress BFV!\n");\r
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
123 SystemHang ("Failed to find free space to hold decompressed BFV\n");\r
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
128 PrintHeader ('B');\r
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
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
144\r
145 Status = LzmaUefiDecompressGetInfo (\r
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
152 SystemHang ("Failed to get decompress information for DxeIpl!\n");\r
153 }\r
154\r
155 Status = LzmaUefiDecompress (\r
156 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
157 EFILDRImage->Length,\r
158 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
159 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
160 );\r
161 if (EFI_ERROR (Status)) {\r
162 SystemHang ("Failed to decompress DxeIpl image\n");\r
163 }\r
164\r
165 PrintString ("Start load DxeIpl PE image\n"); \r
166\r
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
177 SystemHang ("Failed to load and relocate DxeIpl PE image!\n");\r
178 }\r
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
184\r
185PrintHeader ('C');\r
186\r
187 //\r
188 // Point to the 3rd image (DxeMain)\r
189 //\r
190 EFILDRImage++;\r
191\r
192 //\r
193 // Decompress the image\r
194 //\r
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
200\r
201 Status = LzmaUefiDecompressGetInfo (\r
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
208 SystemHang ("Failed to get decompress information for DxeMain FV image!\n");\r
209 }\r
210\r
211 Status = LzmaUefiDecompress (\r
212 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
213 EFILDRImage->Length,\r
214 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
215 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
216 );\r
217 if (EFI_ERROR (Status)) {\r
218 SystemHang ("Failed to decompress DxeMain FV image!\n");\r
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
231 SystemHang ("Failed to load/relocate DxeMain!\n");\r
232 }\r
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
238\r
239PrintHeader ('E');\r
240\r
241 //\r
242 // Display the table of memory descriptors.\r
243 //\r
244 PrintString ("\nEFI Memory Descriptors\n"); \r
245 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {\r
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
250 }\r
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
268 PrintString ("Transfer to DxeIpl ...EntryPoint = %p\n", DxeIplImage.EntryPoint);\r
269 \r
270 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT) DxeIplImage.EntryPoint;\r
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
280 SystemHang ("Failed to jump to DxeIpl!\n");\r
281}\r
282\r
283EFI_STATUS\r
284EFIAPI\r
285_ModuleEntryPoint (\r
286 UINT32 BiosMemoryMapBaseAddress\r
287 )\r
288{\r
289 SerialPortInitialize ();\r
290 EfiLoader(BiosMemoryMapBaseAddress);\r
291 return EFI_SUCCESS;\r
292}\r
293\r
294\r