CorebootPayloadPkg: Notify EndOfDxe and install ReadyToLock protocol.
[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_BOOT_MANAGER_LOAD_OPTION BootOption;
185
186 PlatformConsoleInit ();
187
188 //
189 // Register ENTER as CONTINUE key
190 //
191 Enter.ScanCode = SCAN_NULL;
192 Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
193 EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
194
195 //
196 // Map F2 to Boot Manager Menu
197 //
198 F2.ScanCode = SCAN_F2;
199 F2.UnicodeChar = CHAR_NULL;
200 EfiBootManagerGetBootManagerMenu (&BootOption);
201 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);
202
203 //
204 // Register UEFI Shell
205 //
206 PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE);
207
208 //
209 // Install ready to lock.
210 // This needs to be done before option rom dispatched.
211 //
212 InstallReadyToLock ();
213 }
214
215 /**
216 Do the platform specific action after the console is connected.
217
218 Such as:
219 Dynamically switch output mode;
220 Signal console ready platform customized event;
221 Run diagnostics like memory testing;
222 Connect certain devices;
223 Dispatch aditional option roms.
224 **/
225 VOID
226 EFIAPI
227 PlatformBootManagerAfterConsole (
228 VOID
229 )
230 {
231 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
232 EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;
233
234 Black.Blue = Black.Green = Black.Red = Black.Reserved = 0;
235 White.Blue = White.Green = White.Red = White.Reserved = 0xFF;
236
237 EfiBootManagerConnectAll ();
238 EfiBootManagerRefreshAllBootOption ();
239
240 Print (
241 L"\n"
242 L"F2 to enter Boot Manager Menu.\n"
243 L"ENTER to boot directly.\n"
244 L"\n"
245 );
246
247 }
248
249 /**
250 This function is called each second during the boot manager waits the timeout.
251
252 @param TimeoutRemain The remaining timeout.
253 **/
254 VOID
255 EFIAPI
256 PlatformBootManagerWaitCallback (
257 UINT16 TimeoutRemain
258 )
259 {
260 return;
261 }