]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/EfiLdr/EfiLoader.c
Change DUET DxeIpl to use SerialPort instead of manipulating serial port directly.
[mirror_edk2.git] / DuetPkg / EfiLdr / EfiLoader.c
CommitLineData
9071550e 1/*++\r
2\r
b68b78e6 3Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
b1f700a8 4This program and the accompanying materials \r
9071550e 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
8b85412a 25#include "LzmaDecompress.h"\r
3da85e63 26\r
3da85e63 27VOID\r
b68b78e6
RN
28SystemHang (\r
29 CHAR8 *Message\r
3da85e63 30 )\r
31{\r
b68b78e6
RN
32 PrintString (\r
33 "%s## FATAL ERROR ##: Fail to load DUET images! System hang!\n",\r
34 Message\r
35 );\r
3da85e63 36 CpuDeadLoop();\r
37}\r
9071550e 38\r
39VOID\r
40EfiLoader (\r
41 UINT32 BiosMemoryMapBaseAddress\r
42 )\r
43{\r
44 BIOS_MEMORY_MAP *BiosMemoryMap; \r
9071550e 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
dcb428da 54 EFILDRHANDOFF Handoff;\r
b68b78e6 55 UINTN Index;\r
9071550e 56\r
9071550e 57 ClearScreen();\r
3da85e63 58 \r
59 PrintHeader ('A');\r
b68b78e6
RN
60 \r
61 PrintString ("Enter DUET Loader...\n");\r
62 PrintString ("BiosMemoryMapBaseAddress = %x\n", (UINTN) BiosMemoryMapBaseAddress);\r
9071550e 63\r
64 //\r
65 // Add all EfiConventionalMemory descriptors to the table. If there are partial pages, then\r
66 // round the start address up to the next page, and round the length down to a page boundry.\r
67 //\r
b68b78e6 68 BiosMemoryMap = (BIOS_MEMORY_MAP *) (UINTN) BiosMemoryMapBaseAddress;\r
9071550e 69 NumberOfMemoryMapEntries = 0;\r
70 GenMemoryMap (&NumberOfMemoryMapEntries, EfiMemoryDescriptor, BiosMemoryMap);\r
71\r
b68b78e6 72 PrintString ("Get %d entries of memory map!\n", NumberOfMemoryMapEntries);\r
3da85e63 73\r
9071550e 74 //\r
75 // Get information on where the image is in memory\r
76 //\r
9071550e 77 EFILDRImage = (EFILDR_IMAGE *)(UINTN)(EFILDR_HEADER_ADDRESS + sizeof(EFILDR_HEADER));\r
78\r
9071550e 79\r
80 //\r
81 // Point to the 4th image (Bfv)\r
82 //\r
9071550e 83 EFILDRImage += 3;\r
84\r
85 //\r
86 // Decompress the image\r
87 //\r
b68b78e6
RN
88 PrintString (\r
89 "Decompress BFV image, Image Address = %x Offset = %x\n", \r
90 (UINTN) (EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
91 (UINTN) EFILDRImage->Offset\r
92 );\r
8b85412a 93 Status = LzmaUefiDecompressGetInfo (\r
9071550e 94 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
95 EFILDRImage->Length,\r
96 &DestinationSize, \r
97 &ScratchSize\r
98 );\r
3da85e63 99\r
9071550e 100 if (EFI_ERROR (Status)) {\r
b68b78e6 101 SystemHang ("Failed to get decompress information for BFV!\n");\r
9071550e 102 }\r
f8e01ca8 103 \r
b68b78e6 104 PrintString ("BFV decompress: DestinationSize = %x, ScratchSize = %x\n", (UINTN) DestinationSize, (UINTN) ScratchSize);\r
8b85412a 105 Status = LzmaUefiDecompress (\r
106 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
3ae5030e 107 EFILDRImage->Length,\r
8b85412a 108 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, \r
109 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
110 );\r
f8e01ca8 111 \r
3da85e63 112\r
9071550e 113 if (EFI_ERROR (Status)) {\r
b68b78e6 114 SystemHang ("Failed to decompress BFV!\n");\r
9071550e 115 }\r
116\r
117 BfvPageNumber = EFI_SIZE_TO_PAGES (DestinationSize);\r
118 BfvBase = (UINTN) FindSpace (BfvPageNumber, &NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);\r
119 if (BfvBase == 0) {\r
b68b78e6 120 SystemHang ("Failed to find free space to hold decompressed BFV\n");\r
9071550e 121 }\r
122 ZeroMem ((VOID *)(UINTN)BfvBase, BfvPageNumber * EFI_PAGE_SIZE);\r
123 CopyMem ((VOID *)(UINTN)BfvBase, (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS, DestinationSize);\r
124\r
3da85e63 125 PrintHeader ('B');\r
9071550e 126\r
127 //\r
128 // Point to the 2nd image (DxeIpl)\r
129 //\r
130 \r
131 EFILDRImage -= 2;\r
132\r
133 //\r
134 // Decompress the image\r
135 //\r
b68b78e6
RN
136 PrintString (\r
137 "Decompress DxeIpl image, Image Address = %x Offset = %x\n", \r
138 (UINTN) (EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
139 (UINTN) EFILDRImage->Offset\r
140 );\r
9071550e 141\r
8b85412a 142 Status = LzmaUefiDecompressGetInfo (\r
9071550e 143 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
144 EFILDRImage->Length,\r
145 &DestinationSize, \r
146 &ScratchSize\r
147 );\r
148 if (EFI_ERROR (Status)) {\r
b68b78e6 149 SystemHang ("Failed to get decompress information for DxeIpl!\n");\r
9071550e 150 }\r
151\r
8b85412a 152 Status = LzmaUefiDecompress (\r
9071550e 153 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
3ae5030e 154 EFILDRImage->Length,\r
9071550e 155 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
8b85412a 156 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
9071550e 157 );\r
158 if (EFI_ERROR (Status)) {\r
b68b78e6 159 SystemHang ("Failed to decompress DxeIpl image\n");\r
9071550e 160 }\r
161\r
b68b78e6 162 PrintString ("Start load DxeIpl PE image\n"); \r
3da85e63 163\r
9071550e 164 //\r
165 // Load and relocate the EFI PE/COFF Firmware Image \r
166 //\r
167 Status = EfiLdrPeCoffLoadPeImage (\r
168 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), \r
169 &DxeIplImage, \r
170 &NumberOfMemoryMapEntries, \r
171 EfiMemoryDescriptor\r
172 );\r
173 if (EFI_ERROR (Status)) {\r
b68b78e6 174 SystemHang ("Failed to load and relocate DxeIpl PE image!\n");\r
9071550e 175 }\r
b68b78e6
RN
176 PrintString (\r
177 "DxeIpl PE image is successed loaded at %lx, entry=%p\n",\r
178 DxeIplImage.ImageBasePage,\r
179 DxeIplImage.EntryPoint\r
180 );\r
9071550e 181\r
182PrintHeader ('C');\r
183\r
184 //\r
185 // Point to the 3rd image (DxeMain)\r
186 //\r
9071550e 187 EFILDRImage++;\r
188\r
189 //\r
190 // Decompress the image\r
191 //\r
b68b78e6
RN
192 PrintString (\r
193 "Decompress DxeMain FV image, Image Address = %x Offset = %x\n",\r
194 (UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
195 (UINTN) EFILDRImage->Offset\r
196 );\r
9071550e 197\r
8b85412a 198 Status = LzmaUefiDecompressGetInfo (\r
9071550e 199 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
200 EFILDRImage->Length,\r
201 &DestinationSize, \r
202 &ScratchSize\r
203 );\r
204 if (EFI_ERROR (Status)) {\r
b68b78e6 205 SystemHang ("Failed to get decompress information for DxeMain FV image!\n");\r
9071550e 206 }\r
207\r
8b85412a 208 Status = LzmaUefiDecompress (\r
9071550e 209 (VOID *)(UINTN)(EFILDR_HEADER_ADDRESS + EFILDRImage->Offset),\r
3ae5030e 210 EFILDRImage->Length,\r
9071550e 211 (VOID *)(UINTN)EFI_DECOMPRESSED_BUFFER_ADDRESS,\r
8b85412a 212 (VOID *)(UINTN)((EFI_DECOMPRESSED_BUFFER_ADDRESS + DestinationSize + 0x1000) & 0xfffff000)\r
9071550e 213 );\r
214 if (EFI_ERROR (Status)) {\r
b68b78e6 215 SystemHang ("Failed to decompress DxeMain FV image!\n");\r
9071550e 216 }\r
217\r
218 //\r
219 // Load and relocate the EFI PE/COFF Firmware Image \r
220 //\r
221 Status = EfiLdrPeCoffLoadPeImage (\r
222 (VOID *)(UINTN)(EFI_DECOMPRESSED_BUFFER_ADDRESS), \r
223 &DxeCoreImage, \r
224 &NumberOfMemoryMapEntries, \r
225 EfiMemoryDescriptor\r
226 );\r
227 if (EFI_ERROR (Status)) {\r
b68b78e6 228 SystemHang ("Failed to load/relocate DxeMain!\n");\r
9071550e 229 }\r
b68b78e6
RN
230 PrintString (\r
231 "DxeCore PE image is successed loaded at %lx, entry=%p\n",\r
232 DxeCoreImage.ImageBasePage,\r
233 DxeCoreImage.EntryPoint\r
234 );\r
9071550e 235\r
236PrintHeader ('E');\r
237\r
238 //\r
239 // Display the table of memory descriptors.\r
240 //\r
b68b78e6 241 PrintString ("\nEFI Memory Descriptors\n"); \r
9071550e 242 for (Index = 0; Index < NumberOfMemoryMapEntries; Index++) {\r
b68b78e6
RN
243 PrintString (\r
244 "Type = %x Start = %08lx NumberOfPages = %08lx\n",\r
245 EfiMemoryDescriptor[Index].Type, EfiMemoryDescriptor[Index].PhysicalStart, EfiMemoryDescriptor[Index].NumberOfPages\r
246 );\r
9071550e 247 }\r
9071550e 248\r
249 //\r
250 // Jump to EFI Firmware\r
251 //\r
252\r
253 if (DxeIplImage.EntryPoint != NULL) {\r
254\r
255 Handoff.MemDescCount = NumberOfMemoryMapEntries;\r
256 Handoff.MemDesc = EfiMemoryDescriptor;\r
257 Handoff.BfvBase = (VOID *)(UINTN)BfvBase;\r
258 Handoff.BfvSize = BfvPageNumber * EFI_PAGE_SIZE;\r
259 Handoff.DxeIplImageBase = (VOID *)(UINTN)DxeIplImage.ImageBasePage;\r
260 Handoff.DxeIplImageSize = DxeIplImage.NoPages * EFI_PAGE_SIZE;\r
261 Handoff.DxeCoreImageBase = (VOID *)(UINTN)DxeCoreImage.ImageBasePage;\r
262 Handoff.DxeCoreImageSize = DxeCoreImage.NoPages * EFI_PAGE_SIZE;\r
263 Handoff.DxeCoreEntryPoint = (VOID *)(UINTN)DxeCoreImage.EntryPoint;\r
264\r
b68b78e6 265 PrintString ("Transfer to DxeIpl ...EntryPoint = %p\n", DxeIplImage.EntryPoint);\r
ff514e29 266 \r
b68b78e6 267 EfiMainEntrypoint = (EFI_MAIN_ENTRYPOINT) DxeIplImage.EntryPoint;\r
9071550e 268 EfiMainEntrypoint (&Handoff);\r
269 }\r
270\r
271PrintHeader ('F');\r
272\r
273 //\r
274 // There was a problem loading the image, so HALT the system.\r
275 //\r
276\r
b68b78e6 277 SystemHang ("Failed to jump to DxeIpl!\n");\r
9071550e 278}\r
279\r
c51b1cb6 280EFI_STATUS\r
281EFIAPI\r
282_ModuleEntryPoint (\r
283 UINT32 BiosMemoryMapBaseAddress\r
284 )\r
285{\r
b68b78e6 286 SerialPortInitialize ();\r
c51b1cb6 287 EfiLoader(BiosMemoryMapBaseAddress);\r
288 return EFI_SUCCESS;\r
289}\r
290\r
291\r