]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - DuetPkg/EfiLdr/EfiLoader.c
Implement Read() and Poll()
[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 "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
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
54 CHAR8 PrintBuffer[256];\r
55 static EFILDRHANDOFF Handoff;\r
56\r
57 ClearScreen();\r
58 \r
59 PrintHeader ('A');\r
60\r
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
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
75 AsciiSPrint (PrintBuffer, 256, "Get %d entries of memory map!\n", NumberOfMemoryMapEntries);\r
76 PrintString (PrintBuffer);\r
77\r
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
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
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
102 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
103 EFILDRImage->Length,\r
104 &DestinationSize, \r
105 &ScratchSize\r
106 );\r
107\r
108 if (EFI_ERROR (Status)) {\r
109 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for BFV!\n");\r
110 PrintString (PrintBuffer);\r
111 SystemHang();\r
112 }\r
113\r
114 Status = TianoDecompress (\r
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
122\r
123 if (EFI_ERROR (Status)) {\r
124 AsciiSPrint (PrintBuffer, 256, "Fail to decompress BFV!\n");\r
125 PrintString (PrintBuffer);\r
126 SystemHang();\r
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
132 SystemHang();\r
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
137 PrintHeader ('B');\r
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
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
151 PrintString (PrintBuffer);\r
152\r
153 Status = TianoGetInfo (\r
154 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
155 EFILDRImage->Length,\r
156 &DestinationSize, \r
157 &ScratchSize\r
158 );\r
159 if (EFI_ERROR (Status)) {\r
160 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DxeIpl!\n");\r
161 PrintString (PrintBuffer);\r
162 SystemHang();\r
163 }\r
164\r
165 Status = TianoDecompress (\r
166 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
167 EFILDRImage->Length,\r
168 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
169 DestinationSize, \r
170 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),\r
171 ScratchSize\r
172 );\r
173 if (EFI_ERROR (Status)) {\r
174 AsciiSPrint (PrintBuffer, 256, "Fail to decompress DxeIpl image\n");\r
175 PrintString (PrintBuffer);\r
176 SystemHang();\r
177 }\r
178\r
179 AsciiSPrint (PrintBuffer, 256, "Start load DxeIpl PE image\n");\r
180 PrintString (PrintBuffer); \r
181\r
182 //\r
183 // Load and relocate the EFI PE/COFF Firmware Image \r
184 //\r
185 Status = EfiLdrPeCoffLoadPeImage (\r
186 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), \r
187 &DxeIplImage, \r
188 &NumberOfMemoryMapEntries, \r
189 EfiMemoryDescriptor\r
190 );\r
191 if (EFI_ERROR (Status)) {\r
192 AsciiSPrint (PrintBuffer, 256, "Fail to load and relocate DxeIpl PE image!\n");\r
193 PrintString (PrintBuffer);\r
194 SystemHang();\r
195 }\r
196 AsciiSPrint (PrintBuffer, 256, "DxeIpl PE image is successed loaded at 0x%x, entry=0x%x\n",\r
197 (UINTN)DxeIplImage.ImageBasePage, (UINTN)DxeIplImage.EntryPoint);\r
198 PrintString (PrintBuffer); \r
199\r
200// PrintString("Image.NoPages = "); \r
201// PrintValue(Image.NoPages);\r
202// PrintString("\n");\r
203\r
204PrintHeader ('C');\r
205\r
206 //\r
207 // Point to the 3rd image (DxeMain)\r
208 //\r
209 \r
210 EFILDRImage++;\r
211\r
212 //\r
213 // Decompress the image\r
214 //\r
215 AsciiSPrint (PrintBuffer, 256, "Decompress DXEMain FV image, Image Address=0x%x! Offset=0x%x\n", \r
216 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
217 EFILDRImage->Offset);\r
218 PrintString (PrintBuffer);\r
219\r
220 Status = TianoGetInfo (\r
221 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
222 EFILDRImage->Length,\r
223 &DestinationSize, \r
224 &ScratchSize\r
225 );\r
226 if (EFI_ERROR (Status)) {\r
227 AsciiSPrint (PrintBuffer, 256, "Fail to get decompress information for DXEMain FV image!\n");\r
228 PrintString (PrintBuffer);\r
229 SystemHang();\r
230 }\r
231\r
232 Status = TianoDecompress (\r
233 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
234 EFILDRImage->Length,\r
235 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
236 DestinationSize, \r
237 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000),\r
238 ScratchSize\r
239 );\r
240 if (EFI_ERROR (Status)) {\r
241 SystemHang();\r
242 }\r
243\r
244 //\r
245 // Load and relocate the EFI PE/COFF Firmware Image \r
246 //\r
247 Status = EfiLdrPeCoffLoadPeImage (\r
248 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), \r
249 &DxeCoreImage, \r
250 &NumberOfMemoryMapEntries, \r
251 EfiMemoryDescriptor\r
252 );\r
253 if (EFI_ERROR (Status)) {\r
254 SystemHang();\r
255 }\r
256 AsciiSPrint (PrintBuffer, 256, "DxeCore PE image is successed loaded at 0x%x, entry=0x%x\n",\r
257 (UINTN)DxeCoreImage.ImageBasePage, (UINTN)DxeCoreImage.EntryPoint);\r
258 PrintString (PrintBuffer); \r
259\r
260PrintHeader ('E');\r
261\r
262 //\r
263 // Display the table of memory descriptors.\r
264 //\r
265\r
266// PrintString("\nEFI Memory Descriptors\n"); \r
267/*\r
268 {\r
269 UINTN Index;\r
270 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {\r
271 PrintString("Type = "); \r
272 PrintValue(EfiMemoryDescriptor[Index].Type);\r
273 PrintString(" Start = "); \r
274 PrintValue((UINT32)(EfiMemoryDescriptor[Index].PhysicalStart));\r
275 PrintString(" NumberOfPages = "); \r
276 PrintValue((UINT32)(EfiMemoryDescriptor[Index].NumberOfPages));\r
277 PrintString("\n");\r
278 }\r
279 }\r
280*/\r
281\r
282 //\r
283 // Jump to EFI Firmware\r
284 //\r
285\r
286 if (DxeIplImage.EntryPoint != NULL) {\r
287\r
288 Handoff.MemDescCount = NumberOfMemoryMapEntries;\r
289 Handoff.MemDesc = EfiMemoryDescriptor;\r
290 Handoff.BfvBase = (VOID *)(UINTN)BfvBase;\r
291 Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;\r
292 Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;\r
293 Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;\r
294 Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;\r
295 Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;\r
296 Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;\r
297\r
298 AsciiSPrint (PrintBuffer, 256, "Transfer to DxeIpl ...Address=0x%x\n", (UINTN)DxeIplImage.EntryPoint);\r
299 PrintString (PrintBuffer);\r
300 \r
301 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT)(UINTN)DxeIplImage.EntryPoint;\r
302 EfiMainEntrypoint (&Handoff);\r
303 }\r
304\r
305PrintHeader ('F');\r
306\r
307 //\r
308 // There was a problem loading the image, so HALT the system.\r
309 //\r
310\r
311 SystemHang();\r
312}\r
313\r
314EFI_STATUS\r
315EFIAPI\r
316_ModuleEntryPoint (\r
317 UINT32 BiosMemoryMapBaseAddress\r
318 )\r
319{\r
320 EfiLoader(BiosMemoryMapBaseAddress);\r
321 return EFI_SUCCESS;\r
322}\r
323\r
324\r