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