]> git.proxmox.com Git - mirror_edk2.git/blame - UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
UefiPayloadPkg: Enhance UEFI payload for coreboot and Slim Bootloader
[mirror_edk2.git] / UefiPayloadPkg / Library / PlatformBootManagerLib / PlatformBootManager.c
CommitLineData
04af8bf2
DG
1/** @file\r
2 This file include all platform action which can be customized\r
3 by IBV/OEM.\r
4\r
5Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
6SPDX-License-Identifier: BSD-2-Clause-Patent\r
7\r
8**/\r
9\r
10#include "PlatformBootManager.h"\r
11#include "PlatformConsole.h"\r
12\r
13VOID\r
14InstallReadyToLock (\r
15 VOID\r
16 )\r
17{\r
18 EFI_STATUS Status;\r
19 EFI_HANDLE Handle;\r
20 EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;\r
21\r
22 DEBUG((DEBUG_INFO,"InstallReadyToLock entering......\n"));\r
23 //\r
24 // Inform the SMM infrastructure that we're entering BDS and may run 3rd party code hereafter\r
25 // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth\r
26 //\r
27 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);\r
28 DEBUG((DEBUG_INFO,"All EndOfDxe callbacks have returned successfully\n"));\r
29\r
30 //\r
31 // Install DxeSmmReadyToLock protocol in order to lock SMM\r
32 //\r
33 Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **) &SmmAccess);\r
34 if (!EFI_ERROR (Status)) {\r
35 Handle = NULL;\r
36 Status = gBS->InstallProtocolInterface (\r
37 &Handle,\r
38 &gEfiDxeSmmReadyToLockProtocolGuid,\r
39 EFI_NATIVE_INTERFACE,\r
40 NULL\r
41 );\r
42 ASSERT_EFI_ERROR (Status);\r
43 }\r
44\r
45 DEBUG((DEBUG_INFO,"InstallReadyToLock end\n"));\r
46 return;\r
47}\r
48\r
49/**\r
50 Return the index of the load option in the load option array.\r
51\r
52 The function consider two load options are equal when the\r
53 OptionType, Attributes, Description, FilePath and OptionalData are equal.\r
54\r
55 @param Key Pointer to the load option to be found.\r
56 @param Array Pointer to the array of load options to be found.\r
57 @param Count Number of entries in the Array.\r
58\r
59 @retval -1 Key wasn't found in the Array.\r
60 @retval 0 ~ Count-1 The index of the Key in the Array.\r
61**/\r
62INTN\r
63PlatformFindLoadOption (\r
64 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,\r
65 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,\r
66 IN UINTN Count\r
67)\r
68{\r
69 UINTN Index;\r
70\r
71 for (Index = 0; Index < Count; Index++) {\r
72 if ((Key->OptionType == Array[Index].OptionType) &&\r
73 (Key->Attributes == Array[Index].Attributes) &&\r
74 (StrCmp (Key->Description, Array[Index].Description) == 0) &&\r
75 (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&\r
76 (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&\r
77 (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {\r
78 return (INTN) Index;\r
79 }\r
80 }\r
81\r
82 return -1;\r
83}\r
84\r
85/**\r
86 Register a boot option using a file GUID in the FV.\r
87\r
88 @param FileGuid The file GUID name in FV.\r
89 @param Description The boot option description.\r
90 @param Attributes The attributes used for the boot option loading.\r
91**/\r
92VOID\r
93PlatformRegisterFvBootOption (\r
94 EFI_GUID *FileGuid,\r
95 CHAR16 *Description,\r
96 UINT32 Attributes\r
97)\r
98{\r
99 EFI_STATUS Status;\r
100 UINTN OptionIndex;\r
101 EFI_BOOT_MANAGER_LOAD_OPTION NewOption;\r
102 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
103 UINTN BootOptionCount;\r
104 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
105 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
106 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
107\r
108 Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);\r
109 ASSERT_EFI_ERROR (Status);\r
110\r
111 EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);\r
112 DevicePath = AppendDevicePathNode (\r
113 DevicePathFromHandle (LoadedImage->DeviceHandle),\r
114 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
115 );\r
116\r
117 Status = EfiBootManagerInitializeLoadOption (\r
118 &NewOption,\r
119 LoadOptionNumberUnassigned,\r
120 LoadOptionTypeBoot,\r
121 Attributes,\r
122 Description,\r
123 DevicePath,\r
124 NULL,\r
125 0\r
126 );\r
127 if (!EFI_ERROR (Status)) {\r
128 BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
129\r
130 OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);\r
131\r
132 if (OptionIndex == -1) {\r
133 Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);\r
134 ASSERT_EFI_ERROR (Status);\r
135 }\r
136 EfiBootManagerFreeLoadOption (&NewOption);\r
137 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
138 }\r
139}\r
140\r
141/**\r
142 Do the platform specific action before the console is connected.\r
143\r
144 Such as:\r
145 Update console variable;\r
146 Register new Driver#### or Boot####;\r
147 Signal ReadyToLock event.\r
148**/\r
149VOID\r
150EFIAPI\r
151PlatformBootManagerBeforeConsole (\r
152 VOID\r
153)\r
154{\r
155 EFI_INPUT_KEY Enter;\r
156 EFI_INPUT_KEY F2;\r
157 EFI_INPUT_KEY Down;\r
158 EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
159\r
160 PlatformConsoleInit ();\r
161\r
162 //\r
163 // Register ENTER as CONTINUE key\r
164 //\r
165 Enter.ScanCode = SCAN_NULL;\r
166 Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
167 EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);\r
168\r
169 //\r
170 // Map F2 to Boot Manager Menu\r
171 //\r
172 F2.ScanCode = SCAN_F2;\r
173 F2.UnicodeChar = CHAR_NULL;\r
174 EfiBootManagerGetBootManagerMenu (&BootOption);\r
175 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);\r
176\r
177 //\r
178 // Also add Down key to Boot Manager Menu since some serial terminals don't support F2 key.\r
179 //\r
180 Down.ScanCode = SCAN_DOWN;\r
181 Down.UnicodeChar = CHAR_NULL;\r
182 EfiBootManagerGetBootManagerMenu (&BootOption);\r
183 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &Down, NULL);\r
184\r
185 //\r
186 // Install ready to lock.\r
187 // This needs to be done before option rom dispatched.\r
188 //\r
189 InstallReadyToLock ();\r
190\r
191 //\r
192 // Dispatch deferred images after EndOfDxe event and ReadyToLock installation.\r
193 //\r
194 EfiBootManagerDispatchDeferredImages ();\r
195}\r
196\r
197/**\r
198 Do the platform specific action after the console is connected.\r
199\r
200 Such as:\r
201 Dynamically switch output mode;\r
202 Signal console ready platform customized event;\r
203 Run diagnostics like memory testing;\r
204 Connect certain devices;\r
205 Dispatch additional option roms.\r
206**/\r
207VOID\r
208EFIAPI\r
209PlatformBootManagerAfterConsole (\r
210 VOID\r
211)\r
212{\r
213 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;\r
214 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;\r
215\r
216 Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;\r
217 White.Blue = White.Green = White.Red = White.Reserved = 0xFF;\r
218\r
219 EfiBootManagerConnectAll ();\r
220 EfiBootManagerRefreshAllBootOption ();\r
221\r
222 //\r
223 // Register UEFI Shell\r
224 //\r
225 PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE);\r
226\r
227 Print (\r
228 L"\n"\r
229 L"F2 or Down to enter Boot Manager Menu.\n"\r
230 L"ENTER to boot directly.\n"\r
231 L"\n"\r
232 );\r
233\r
234}\r
235\r
236/**\r
237 This function is called each second during the boot manager waits the timeout.\r
238\r
239 @param TimeoutRemain The remaining timeout.\r
240**/\r
241VOID\r
242EFIAPI\r
243PlatformBootManagerWaitCallback (\r
244 UINT16 TimeoutRemain\r
245)\r
246{\r
247 return;\r
248}\r
249\r
250/**\r
251 The function is called when no boot option could be launched,\r
252 including platform recovery options and options pointing to applications\r
253 built into firmware volumes.\r
254\r
255 If this function returns, BDS attempts to enter an infinite loop.\r
256**/\r
257VOID\r
258EFIAPI\r
259PlatformBootManagerUnableToBoot (\r
260 VOID\r
261 )\r
262{\r
263 return;\r
264}\r
265\r