]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/EfiLdr/EfiLoader.c
1, Use PrintLib in Duet loader
[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
27STATIC\r
28VOID\r
29SystemHang(\r
30 VOID\r
31 )\r
32{\r
33 CHAR8 PrintBuffer[256];\r
34 AsciiSPrint (PrintBuffer, 256, "## FATEL ERROR ##: Fail to load DUET images! System hang!\n");\r
35 CpuDeadLoop();\r
36}\r
9071550e 37\r
38VOID\r
39EfiLoader (\r
40 UINT32 BiosMemoryMapBaseAddress\r
41 )\r
42{\r
43 BIOS_MEMORY_MAP *BiosMemoryMap; \r
44 EFILDR_HEADER *EFILDRHeader;\r
45 EFILDR_IMAGE *EFILDRImage;\r
46 EFI_MEMORY_DESCRIPTOR EfiMemoryDescriptor[EFI_MAX_MEMORY_DESCRIPTORS];\r
47 EFI_STATUS Status;\r
48 UINTN NumberOfMemoryMapEntries;\r
49 UINT32 DestinationSize;\r
50 UINT32 ScratchSize;\r
51 UINTN BfvPageNumber;\r
52 UINTN BfvBase;\r
53 EFI_MAIN_ENTRYPOINT EfiMainEntrypoint;\r
3da85e63 54 CHAR8 PrintBuffer[256];\r
9071550e 55 static EFILDRHANDOFF Handoff;\r
56\r
9071550e 57 ClearScreen();\r
3da85e63 58 \r
59 PrintHeader ('A');\r
9071550e 60\r
3da85e63 61 AsciiSPrint (PrintBuffer, 256, "Enter DUET Loader ...\n", BiosMemoryMapBaseAddress);\r
62 PrintString (PrintBuffer);\r
63\r
64 AsciiSPrint (PrintBuffer, 256, "BiosMemoryMapBaseAddress = 0x%x\n", BiosMemoryMapBaseAddress);\r
65 PrintString (PrintBuffer);\r
9071550e 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 boundry.\r
70 //\r
71 BiosMemoryMap = (BIOS_MEMORY_MAP *)(UINTN)(BiosMemoryMapBaseAddress);\r
72 NumberOfMemoryMapEntries = 0;\r
73 GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap);\r
74\r
3da85e63 75 AsciiSPrint (PrintBuffer, 256, "Get %d entries of memory map!\n", NumberOfMemoryMapEntries);\r
76 PrintString (PrintBuffer);\r
77\r
9071550e 78 //\r
79 // Get information on where the image is in memory\r
80 //\r
81\r
82 EFILDRHeader = (EFILDR_HEADER *)(UINTN)(EFILDR_HEADER_ADDRESS);\r
83 EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER));\r
84\r
9071550e 85\r
86 //\r
87 // Point to the 4th image (Bfv)\r
88 //\r
89 \r
90 EFILDRImage += 3;\r
91\r
92 //\r
93 // Decompress the image\r
94 //\r
95\r
3da85e63 96 AsciiSPrint (PrintBuffer, 256, "Decompress BFV image, Image Address=0x%x! Offset=0x%x\n", \r
97 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
98 EFILDRImage->Offset);\r
99 PrintString (PrintBuffer);\r
100\r
101 Status = TianoGetInfo (\r
9071550e 102 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
103 EFILDRImage->Length,\r
104 &DestinationSize, \r
105 &ScratchSize\r
106 );\r
3da85e63 107\r
9071550e 108 if (EFI_ERROR (Status)) {\r
3da85e63 109 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for BFV!\n");\r
110 PrintString (PrintBuffer);\r
111 SystemHang();\r
9071550e 112 }\r
113\r
114 Status = TianoDecompress (\r
9071550e 115 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
116 EFILDRImage->Length,\r
117 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
118 DestinationSize, \r
119 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),\r
120 ScratchSize\r
121 );\r
3da85e63 122\r
9071550e 123 if (EFI_ERROR (Status)) {\r
3da85e63 124 AsciiSPrint (PrintBuffer, 256, "Fail to decompress BFV!\n");\r
125 PrintString (PrintBuffer);\r
126 SystemHang();\r
9071550e 127 }\r
128\r
129 BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize);\r
130 BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);\r
131 if (BfvBase == 0) {\r
3da85e63 132 SystemHang();\r
9071550e 133 }\r
134 ZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE);\r
135 CopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize);\r
136\r
3da85e63 137 PrintHeader ('B');\r
9071550e 138\r
139 //\r
140 // Point to the 2nd image (DxeIpl)\r
141 //\r
142 \r
143 EFILDRImage -= 2;\r
144\r
145 //\r
146 // Decompress the image\r
147 //\r
3da85e63 148 AsciiSPrint (PrintBuffer, 256, "Decompress DxeIpl image, Image Address=0x%x! Offset=0x%x\n", \r
149 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
150 EFILDRImage->Offset);\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
195\r
196// PrintString("Image.NoPages = "); \r
197// PrintValue(Image.NoPages);\r
198// PrintString("\n");\r
199\r
200PrintHeader ('C');\r
201\r
202 //\r
203 // Point to the 3rd image (DxeMain)\r
204 //\r
205 \r
206 EFILDRImage++;\r
207\r
208 //\r
209 // Decompress the image\r
210 //\r
211\r
3da85e63 212 Status = TianoGetInfo (\r
9071550e 213 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
214 EFILDRImage->Length,\r
215 &DestinationSize, \r
216 &ScratchSize\r
217 );\r
218 if (EFI_ERROR (Status)) {\r
3da85e63 219 SystemHang();\r
9071550e 220 }\r
221\r
222 Status = TianoDecompress (\r
9071550e 223 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
224 EFILDRImage->Length,\r
225 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
226 DestinationSize, \r
227 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),\r
228 ScratchSize\r
229 );\r
230 if (EFI_ERROR (Status)) {\r
3da85e63 231 SystemHang();\r
9071550e 232 }\r
233\r
234 //\r
235 // Load and relocate the EFI PE/COFF Firmware Image \r
236 //\r
237 Status = EfiLdrPeCoffLoadPeImage (\r
238 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), \r
239 &DxeCoreImage, \r
240 &NumberOfMemoryMapEntries, \r
241 EfiMemoryDescriptor\r
242 );\r
243 if (EFI_ERROR (Status)) {\r
3da85e63 244 SystemHang();\r
9071550e 245 }\r
246\r
247PrintHeader ('E');\r
248\r
249 //\r
250 // Display the table of memory descriptors.\r
251 //\r
252\r
253// PrintString("\nEFI Memory Descriptors\n"); \r
254/*\r
255 {\r
256 UINTN Index;\r
257 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {\r
258 PrintString("Type = "); \r
259 PrintValue(EfiMemoryDescriptor[Index].Type);\r
260 PrintString(" Start = "); \r
261 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));\r
262 PrintString(" NumberOfPages = "); \r
263 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));\r
264 PrintString("\n");\r
265 }\r
266 }\r
267*/\r
268\r
269 //\r
270 // Jump to EFI Firmware\r
271 //\r
272\r
273 if (DxeIplImage.EntryPoint != NULL) {\r
274\r
275 Handoff.MemDescCount = NumberOfMemoryMapEntries;\r
276 Handoff.MemDesc = EfiMemoryDescriptor;\r
277 Handoff.BfvBase = (VOID *)(UINTN)BfvBase;\r
278 Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;\r
279 Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;\r
280 Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;\r
281 Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;\r
282 Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;\r
283 Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;\r
284\r
285 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT)(UINTN)DxeIplImage.EntryPoint;\r
286 EfiMainEntrypoint (&Handoff);\r
287 }\r
288\r
289PrintHeader ('F');\r
290\r
291 //\r
292 // There was a problem loading the image, so HALT the system.\r
293 //\r
294\r
3da85e63 295 SystemHang();\r
9071550e 296}\r
297\r