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