]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/ArmVirtualizationPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c
ArmVirtualizationPkg: PlatformIntelBdsLib: adhere to QEMU's boot order
[mirror_edk2.git] / ArmPlatformPkg / ArmVirtualizationPkg / Library / PlatformIntelBdsLib / IntelBdsPlatform.c
CommitLineData
be8afe14
LE
1/** @file\r
2\r
3Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>\r
4Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>\r
5\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "IntelBdsPlatform.h"\r
17\r
274b4a8d
LE
18#include <Library/QemuBootOrderLib.h>\r
19\r
be8afe14
LE
20///\r
21/// Predefined platform default time out value\r
22///\r
23UINT16 gPlatformBootTimeOutDefault;\r
24\r
25EFI_STATUS\r
26EFIAPI\r
27PlatformIntelBdsConstructor (\r
28 IN EFI_HANDLE ImageHandle,\r
29 IN EFI_SYSTEM_TABLE *SystemTable\r
30 )\r
31{\r
32 gPlatformBootTimeOutDefault = (UINT16)PcdGet16 (PcdPlatformBootTimeOut);\r
33 return EFI_SUCCESS;\r
34}\r
35\r
36//\r
37// BDS Platform Functions\r
38//\r
39/**\r
40 Platform Bds init. Include the platform firmware vendor, revision\r
41 and so crc check.\r
42\r
43**/\r
44VOID\r
45EFIAPI\r
46PlatformBdsInit (\r
47 VOID\r
48 )\r
49{\r
50}\r
51\r
52STATIC\r
53EFI_STATUS\r
54GetConsoleDevicePathFromVariable (\r
55 IN CHAR16* ConsoleVarName,\r
56 IN CHAR16* DefaultConsolePaths,\r
57 OUT EFI_DEVICE_PATH** DevicePaths\r
58 )\r
59{\r
60 EFI_STATUS Status;\r
61 UINTN Size;\r
62 EFI_DEVICE_PATH_PROTOCOL* DevicePathInstances;\r
63 EFI_DEVICE_PATH_PROTOCOL* DevicePathInstance;\r
64 CHAR16* DevicePathStr;\r
65 CHAR16* NextDevicePathStr;\r
66 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;\r
67\r
68 Status = GetGlobalEnvironmentVariable (ConsoleVarName, NULL, NULL, (VOID**)&DevicePathInstances);\r
69 if (EFI_ERROR (Status)) {\r
70 // In case no default console device path has been defined we assume a driver handles the console (eg: SimpleTextInOutSerial)\r
71 if ((DefaultConsolePaths == NULL) || (DefaultConsolePaths[0] == L'\0')) {\r
72 *DevicePaths = NULL;\r
73 return EFI_SUCCESS;\r
74 }\r
75\r
76 Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);\r
77 ASSERT_EFI_ERROR (Status);\r
78\r
79 DevicePathInstances = NULL;\r
80\r
81 // Extract the Device Path instances from the multi-device path string\r
82 while ((DefaultConsolePaths != NULL) && (DefaultConsolePaths[0] != L'\0')) {\r
83 NextDevicePathStr = StrStr (DefaultConsolePaths, L";");\r
84 if (NextDevicePathStr == NULL) {\r
85 DevicePathStr = DefaultConsolePaths;\r
86 DefaultConsolePaths = NULL;\r
87 } else {\r
88 DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DefaultConsolePaths + 1) * sizeof (CHAR16), DefaultConsolePaths);\r
89 *(DevicePathStr + (NextDevicePathStr - DefaultConsolePaths)) = L'\0';\r
90 DefaultConsolePaths = NextDevicePathStr;\r
91 if (DefaultConsolePaths[0] == L';') {\r
92 DefaultConsolePaths++;\r
93 }\r
94 }\r
95\r
96 DevicePathInstance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr);\r
97 ASSERT (DevicePathInstance != NULL);\r
98 DevicePathInstances = AppendDevicePathInstance (DevicePathInstances, DevicePathInstance);\r
99\r
100 if (NextDevicePathStr != NULL) {\r
101 FreePool (DevicePathStr);\r
102 }\r
103 FreePool (DevicePathInstance);\r
104 }\r
105\r
106 // Set the environment variable with this device path multi-instances\r
107 Size = GetDevicePathSize (DevicePathInstances);\r
108 if (Size > 0) {\r
109 gRT->SetVariable (\r
110 ConsoleVarName,\r
111 &gEfiGlobalVariableGuid,\r
112 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
113 Size,\r
114 DevicePathInstances\r
115 );\r
116 } else {\r
117 Status = EFI_INVALID_PARAMETER;\r
118 }\r
119 }\r
120\r
121 if (!EFI_ERROR (Status)) {\r
122 *DevicePaths = DevicePathInstances;\r
123 }\r
124 return Status;\r
125}\r
126\r
127STATIC\r
128EFI_STATUS\r
129InitializeConsolePipe (\r
130 IN EFI_DEVICE_PATH *ConsoleDevicePaths,\r
131 IN EFI_GUID *Protocol,\r
132 OUT EFI_HANDLE *Handle,\r
133 OUT VOID* *Interface\r
134 )\r
135{\r
136 EFI_STATUS Status;\r
137 UINTN Size;\r
138 UINTN NoHandles;\r
139 EFI_HANDLE *Buffer;\r
140 EFI_DEVICE_PATH_PROTOCOL* DevicePath;\r
141\r
142 // Connect all the Device Path Consoles\r
143 while (ConsoleDevicePaths != NULL) {\r
144 DevicePath = GetNextDevicePathInstance (&ConsoleDevicePaths, &Size);\r
145\r
146 Status = BdsConnectDevicePath (DevicePath, Handle, NULL);\r
147 DEBUG_CODE_BEGIN ();\r
148 if (EFI_ERROR (Status)) {\r
149 // We convert back to the text representation of the device Path\r
150 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;\r
151 CHAR16* DevicePathTxt;\r
152 EFI_STATUS Status;\r
153\r
154 Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);\r
155 if (!EFI_ERROR (Status)) {\r
156 DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePath, TRUE, TRUE);\r
157\r
158 DEBUG ((EFI_D_ERROR, "Fail to start the console with the Device Path '%s'. (Error '%r')\n", DevicePathTxt, Status));\r
159\r
160 FreePool (DevicePathTxt);\r
161 }\r
162 }\r
163 DEBUG_CODE_END ();\r
164\r
165 // If the console splitter driver is not supported by the platform then use the first Device Path\r
166 // instance for the console interface.\r
167 if (!EFI_ERROR (Status) && (*Interface == NULL)) {\r
168 Status = gBS->HandleProtocol (*Handle, Protocol, Interface);\r
169 }\r
170 }\r
171\r
172 // No Device Path has been defined for this console interface. We take the first protocol implementation\r
173 if (*Interface == NULL) {\r
174 Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);\r
175 if (EFI_ERROR (Status)) {\r
176 BdsConnectAllDrivers ();\r
177 Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);\r
178 }\r
179\r
180 if (!EFI_ERROR (Status)) {\r
181 *Handle = Buffer[0];\r
182 Status = gBS->HandleProtocol (*Handle, Protocol, Interface);\r
183 ASSERT_EFI_ERROR (Status);\r
184 }\r
185 FreePool (Buffer);\r
186 } else {\r
187 Status = EFI_SUCCESS;\r
188 }\r
189\r
190 return Status;\r
191}\r
192\r
193/**\r
194 Connect the predefined platform default console device. Always try to find\r
195 and enable the vga device if have.\r
196\r
197 @param PlatformConsole Predefined platform default console device array.\r
198\r
199 @retval EFI_SUCCESS Success connect at least one ConIn and ConOut\r
200 device, there must have one ConOut device is\r
201 active vga device.\r
202 @return Return the status of BdsLibConnectAllDefaultConsoles ()\r
203\r
204**/\r
205EFI_STATUS\r
206PlatformBdsConnectConsole (\r
207 VOID\r
208 )\r
209{\r
210 EFI_STATUS Status;\r
211 EFI_DEVICE_PATH* ConOutDevicePaths;\r
212 EFI_DEVICE_PATH* ConInDevicePaths;\r
213 EFI_DEVICE_PATH* ConErrDevicePaths;\r
214\r
215 // By getting the Console Device Paths from the environment variables before initializing the console pipe, we\r
216 // create the 3 environment variables (ConIn, ConOut, ConErr) that allows to initialize all the console interface\r
217 // of newly installed console drivers\r
218 Status = GetConsoleDevicePathFromVariable (L"ConOut", (CHAR16*)PcdGetPtr (PcdDefaultConOutPaths), &ConOutDevicePaths);\r
219 ASSERT_EFI_ERROR (Status);\r
220 Status = GetConsoleDevicePathFromVariable (L"ConIn", (CHAR16*)PcdGetPtr (PcdDefaultConInPaths), &ConInDevicePaths);\r
221 ASSERT_EFI_ERROR (Status);\r
222 Status = GetConsoleDevicePathFromVariable (L"ErrOut", (CHAR16*)PcdGetPtr (PcdDefaultConOutPaths), &ConErrDevicePaths);\r
223 ASSERT_EFI_ERROR (Status);\r
224\r
225 // Initialize the Consoles\r
226 Status = InitializeConsolePipe (ConOutDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **)&gST->ConOut);\r
227 ASSERT_EFI_ERROR (Status);\r
228 Status = InitializeConsolePipe (ConInDevicePaths, &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **)&gST->ConIn);\r
229 ASSERT_EFI_ERROR (Status);\r
230 Status = InitializeConsolePipe (ConErrDevicePaths, &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **)&gST->StdErr);\r
231 if (EFI_ERROR (Status)) {\r
232 // In case of error, we reuse the console output for the error output\r
233 gST->StandardErrorHandle = gST->ConsoleOutHandle;\r
234 gST->StdErr = gST->ConOut;\r
235 }\r
236\r
237 return Status;\r
238}\r
239\r
240/**\r
241 Connect with predefined platform connect sequence,\r
242 the OEM/IBV can customize with their own connect sequence.\r
243**/\r
244VOID\r
245PlatformBdsConnectSequence (\r
246 VOID\r
247 )\r
248{\r
249}\r
250\r
251/**\r
252 Load the predefined driver option, OEM/IBV can customize this\r
253 to load their own drivers\r
254\r
255 @param BdsDriverLists - The header of the driver option link list.\r
256\r
257**/\r
258VOID\r
259PlatformBdsGetDriverOption (\r
260 IN OUT LIST_ENTRY *BdsDriverLists\r
261 )\r
262{\r
263}\r
264\r
265/**\r
266 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
267 can customize this function to support specific platform diagnostic.\r
268\r
269 @param MemoryTestLevel The memory test intensive level\r
270 @param QuietBoot Indicate if need to enable the quiet boot\r
271 @param BaseMemoryTest A pointer to BdsMemoryTest()\r
272\r
273**/\r
274VOID\r
275PlatformBdsDiagnostics (\r
276 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
277 IN BOOLEAN QuietBoot,\r
278 IN BASEM_MEMORY_TEST BaseMemoryTest\r
279 )\r
280{\r
281}\r
282\r
283/**\r
284 The function will execute with as the platform policy, current policy\r
285 is driven by boot mode. IBV/OEM can customize this code for their specific\r
286 policy action.\r
287\r
288 @param DriverOptionList The header of the driver option link list\r
289 @param BootOptionList The header of the boot option link list\r
290 @param ProcessCapsules A pointer to ProcessCapsules()\r
291 @param BaseMemoryTest A pointer to BaseMemoryTest()\r
292\r
293**/\r
294VOID\r
295EFIAPI\r
296PlatformBdsPolicyBehavior (\r
297 IN LIST_ENTRY *DriverOptionList,\r
298 IN LIST_ENTRY *BootOptionList,\r
299 IN PROCESS_CAPSULES ProcessCapsules,\r
300 IN BASEM_MEMORY_TEST BaseMemoryTest\r
301 )\r
302{\r
303 EFI_STATUS Status;\r
304\r
305 Status = PlatformBdsConnectConsole ();\r
306 ASSERT_EFI_ERROR (Status);\r
1b610ac2
LE
307\r
308 BdsLibConnectAll ();\r
309 BdsLibEnumerateAllBootOption (BootOptionList);\r
274b4a8d
LE
310\r
311 SetBootOrderFromQemu (BootOptionList);\r
312 //\r
313 // The BootOrder variable may have changed, reload the in-memory list with\r
314 // it.\r
315 //\r
316 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
317\r
1b610ac2 318 PlatformBdsEnterFrontPage (gPlatformBootTimeOutDefault, TRUE);\r
be8afe14
LE
319}\r
320\r
321/**\r
322 Hook point after a boot attempt succeeds. We don't expect a boot option to\r
323 return, so the UEFI 2.0 specification defines that you will default to an\r
324 interactive mode and stop processing the BootOrder list in this case. This\r
325 is also a platform implementation and can be customized by IBV/OEM.\r
326\r
327 @param Option Pointer to Boot Option that succeeded to boot.\r
328\r
329**/\r
330VOID\r
331EFIAPI\r
332PlatformBdsBootSuccess (\r
333 IN BDS_COMMON_OPTION *Option\r
334 )\r
335{\r
336}\r
337\r
338/**\r
339 Hook point after a boot attempt fails.\r
340\r
341 @param Option Pointer to Boot Option that failed to boot.\r
342 @param Status Status returned from failed boot.\r
343 @param ExitData Exit data returned from failed boot.\r
344 @param ExitDataSize Exit data size returned from failed boot.\r
345\r
346**/\r
347VOID\r
348EFIAPI\r
349PlatformBdsBootFail (\r
350 IN BDS_COMMON_OPTION *Option,\r
351 IN EFI_STATUS Status,\r
352 IN CHAR16 *ExitData,\r
353 IN UINTN ExitDataSize\r
354 )\r
355{\r
356}\r
357\r
358/**\r
359 This function locks platform flash that is not allowed to be updated during normal boot path.\r
360 The flash layout is platform specific.\r
361**/\r
362VOID\r
363EFIAPI\r
364PlatformBdsLockNonUpdatableFlash (\r
365 VOID\r
366 )\r
367{\r
368 return;\r
369}\r
370\r
371\r
372/**\r
373 Lock the ConsoleIn device in system table. All key\r
374 presses will be ignored until the Password is typed in. The only way to\r
375 disable the password is to type it in to a ConIn device.\r
376\r
377 @param Password Password used to lock ConIn device.\r
378\r
379 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.\r
380 @retval EFI_UNSUPPORTED Password not found\r
381\r
382**/\r
383EFI_STATUS\r
384EFIAPI\r
385LockKeyboards (\r
386 IN CHAR16 *Password\r
387 )\r
388{\r
389 return EFI_UNSUPPORTED;\r
390}\r