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