]> git.proxmox.com Git - mirror_edk2.git/blame - QuarkPlatformPkg/Library/PlatformBootManagerLib/PlatformBootManager.c
QuarkPlatformPkg: Add new package for Galileo boards
[mirror_edk2.git] / QuarkPlatformPkg / Library / PlatformBootManagerLib / PlatformBootManager.c
CommitLineData
b303605e
MK
1/** @file\r
2This file include all platform action which can be customized\r
3by IBV/OEM.\r
4\r
5Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\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 "PlatformBootManager.h"\r
17\r
18EFI_GUID mUefiShellFileGuid = {0x7C04A583, 0x9E3E, 0x4f1c, {0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }};\r
19\r
20/**\r
21 Return the index of the load option in the load option array.\r
22\r
23 The function consider two load options are equal when the\r
24 OptionType, Attributes, Description, FilePath and OptionalData are equal.\r
25\r
26 @param Key Pointer to the load option to be found.\r
27 @param Array Pointer to the array of load options to be found.\r
28 @param Count Number of entries in the Array.\r
29\r
30 @retval -1 Key wasn't found in the Array.\r
31 @retval 0 ~ Count-1 The index of the Key in the Array.\r
32**/\r
33INTN\r
34PlatformFindLoadOption (\r
35 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,\r
36 IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,\r
37 IN UINTN Count\r
38 )\r
39{\r
40 UINTN Index;\r
41\r
42 for (Index = 0; Index < Count; Index++) {\r
43 if ((Key->OptionType == Array[Index].OptionType) &&\r
44 (Key->Attributes == Array[Index].Attributes) &&\r
45 (StrCmp (Key->Description, Array[Index].Description) == 0) &&\r
46 (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&\r
47 (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&\r
48 (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {\r
49 return (INTN) Index;\r
50 }\r
51 }\r
52\r
53 return -1;\r
54}\r
55\r
56VOID\r
57PlatformRegisterFvBootOption (\r
58 EFI_GUID *FileGuid,\r
59 CHAR16 *Description,\r
60 UINT32 Attributes\r
61 )\r
62{\r
63 EFI_STATUS Status;\r
64 EFI_HANDLE *HandleBuffer;\r
65 UINTN HandleCount;\r
66 UINTN IndexFv;\r
67 EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
68 CHAR16 *UiSection;\r
69 UINTN UiSectionLength;\r
70 UINT32 AuthenticationStatus;\r
71 EFI_HANDLE FvHandle;\r
72 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
73 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
74 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
75 UINTN BootOptionCount;\r
76 UINTN OptionIndex;\r
77 EFI_BOOT_MANAGER_LOAD_OPTION NewOption;\r
78\r
79 //\r
80 // Locate all available FVs.\r
81 //\r
82 HandleBuffer = NULL;\r
83 Status = gBS->LocateHandleBuffer (\r
84 ByProtocol,\r
85 &gEfiFirmwareVolume2ProtocolGuid,\r
86 NULL,\r
87 &HandleCount,\r
88 &HandleBuffer\r
89 );\r
90 if (EFI_ERROR (Status)) {\r
91 return;\r
92 }\r
93\r
94 //\r
95 // Go through FVs one by one to find the required FFS file\r
96 //\r
97 for (IndexFv = 0, FvHandle = NULL; IndexFv < HandleCount && FvHandle == NULL; IndexFv++) {\r
98 Status = gBS->HandleProtocol (\r
99 HandleBuffer[IndexFv],\r
100 &gEfiFirmwareVolume2ProtocolGuid,\r
101 (VOID **)&Fv\r
102 );\r
103 if (EFI_ERROR (Status)) {\r
104 continue;\r
105 }\r
106\r
107 //\r
108 // Attempt to read a EFI_SECTION_USER_INTERFACE section from the required FFS file\r
109 //\r
110 UiSection = NULL;\r
111 Status = Fv->ReadSection (\r
112 Fv,\r
113 FileGuid,\r
114 EFI_SECTION_USER_INTERFACE,\r
115 0,\r
116 (VOID **) &UiSection,\r
117 &UiSectionLength,\r
118 &AuthenticationStatus\r
119 );\r
120 if (EFI_ERROR (Status)) {\r
121 continue;\r
122 }\r
123 FreePool (UiSection);\r
124\r
125 //\r
126 // Save the handle of the FV where the FFS file was found\r
127 //\r
128 FvHandle = HandleBuffer[IndexFv];\r
129 }\r
130\r
131 //\r
132 // Free the buffer of FV handles\r
133 //\r
134 FreePool (HandleBuffer);\r
135\r
136 //\r
137 // If the FFS file was not found, then return\r
138 //\r
139 if (FvHandle == NULL) {\r
140 return;\r
141 }\r
142\r
143 //\r
144 // Create a device path for the FFS file that was found\r
145 //\r
146 EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);\r
147 DevicePath = AppendDevicePathNode (\r
148 DevicePathFromHandle (FvHandle),\r
149 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
150 );\r
151\r
152 //\r
153 // Create and add a new load option for the FFS file that was found\r
154 //\r
155 Status = EfiBootManagerInitializeLoadOption (\r
156 &NewOption,\r
157 LoadOptionNumberUnassigned,\r
158 LoadOptionTypeBoot,\r
159 Attributes,\r
160 Description,\r
161 DevicePath,\r
162 NULL,\r
163 0\r
164 );\r
165 if (!EFI_ERROR (Status)) {\r
166 BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
167\r
168 OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);\r
169\r
170 if (OptionIndex == -1) {\r
171 Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);\r
172 ASSERT_EFI_ERROR (Status);\r
173 }\r
174 EfiBootManagerFreeLoadOption (&NewOption);\r
175 EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
176 }\r
177}\r
178\r
179VOID\r
180EFIAPI\r
181InternalBdsEmptyCallbackFuntion (\r
182 IN EFI_EVENT Event,\r
183 IN VOID *Context\r
184 )\r
185{\r
186 return;\r
187}\r
188\r
189/**\r
190 Do the platform specific action before the console is connected.\r
191\r
192 Such as:\r
193 Update console variable;\r
194 Register new Driver#### or Boot####;\r
195 Signal ReadyToLock event.\r
196**/\r
197VOID\r
198EFIAPI\r
199PlatformBootManagerBeforeConsole (\r
200 VOID\r
201 )\r
202{\r
203 EFI_STATUS Status;\r
204 UINTN Index;\r
205 EFI_INPUT_KEY Enter;\r
206 EFI_INPUT_KEY F2;\r
207 EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
208 EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;\r
209 EFI_HANDLE Handle;\r
210 EFI_EVENT EndOfDxeEvent;\r
211\r
212 //\r
213 // Update the console variables.\r
214 //\r
215 for (Index = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {\r
216 if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
217 EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);\r
218 }\r
219\r
220 if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
221 EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);\r
222 }\r
223\r
224 if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
225 EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);\r
226 }\r
227 }\r
228\r
229 //\r
230 // Register ENTER as CONTINUE key\r
231 //\r
232 Enter.ScanCode = SCAN_NULL;\r
233 Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
234 EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);\r
235\r
236 //\r
237 // Map F2 to Boot Manager Menu\r
238 //\r
239 F2.ScanCode = SCAN_F2;\r
240 F2.UnicodeChar = CHAR_NULL;\r
241 EfiBootManagerGetBootManagerMenu (&BootOption);\r
242 EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);\r
243\r
244 //\r
245 // Register UEFI Shell\r
246 //\r
247 PlatformRegisterFvBootOption (&mUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE);\r
248\r
249 //\r
250 // Prepare for S3\r
251 //\r
252 Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **)&AcpiS3Save);\r
253 if (!EFI_ERROR (Status)) {\r
254 AcpiS3Save->S3Save (AcpiS3Save, NULL);\r
255 }\r
256\r
257 //\r
258 // Inform PI SMM drivers that BDS may run 3rd party code\r
259 // Create and signal End of DXE event group\r
260 //\r
261 Status = gBS->CreateEventEx (\r
262 EVT_NOTIFY_SIGNAL,\r
263 TPL_CALLBACK,\r
264 InternalBdsEmptyCallbackFuntion,\r
265 NULL,\r
266 &gEfiEndOfDxeEventGroupGuid,\r
267 &EndOfDxeEvent\r
268 );\r
269 ASSERT_EFI_ERROR (Status);\r
270 gBS->SignalEvent (EndOfDxeEvent);\r
271 gBS->CloseEvent (EndOfDxeEvent);\r
272\r
273 DEBUG((EFI_D_INFO,"All EndOfDxe callbacks have returned successfully\n"));\r
274\r
275 //\r
276 // Install SMM Ready To Lock protocol so all resources can be locked down\r
277 // before BDS runs 3rd party code. This action must be done last so all\r
278 // other SMM driver signals are processed before this final lock down action.\r
279 //\r
280 Handle = NULL;\r
281 Status = gBS->InstallProtocolInterface (\r
282 &Handle,\r
283 &gEfiDxeSmmReadyToLockProtocolGuid,\r
284 EFI_NATIVE_INTERFACE,\r
285 NULL\r
286 );\r
287 ASSERT_EFI_ERROR (Status);\r
288}\r
289\r
290/**\r
291 Do the platform specific action after the console is connected.\r
292\r
293 Such as:\r
294 Dynamically switch output mode;\r
295 Signal console ready platform customized event;\r
296 Run diagnostics like memory testing;\r
297 Connect certain devices;\r
298 Dispatch additional option ROMs\r
299**/\r
300VOID\r
301EFIAPI\r
302PlatformBootManagerAfterConsole (\r
303 VOID\r
304 )\r
305{\r
306 EFI_STATUS Status;\r
307\r
308 Print (\r
309 L"\n"\r
310 L"F2 to enter Boot Manager Menu.\n"\r
311 L"ENTER to boot directly.\n"\r
312 L"\n"\r
313 );\r
314\r
315 //\r
316 // Use a DynamicHii type pcd to save the boot status, which is used to\r
317 // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.\r
318 //\r
319 if (PcdGetBool(PcdBootState)) {\r
320 Status = PcdSetBoolS (PcdBootState, FALSE);\r
321 ASSERT_EFI_ERROR (Status);\r
322 }\r
323}\r
324\r
325/**\r
326 This function is called each second during the boot manager waits the timeout.\r
327\r
328 @param TimeoutRemain The remaining timeout.\r
329**/\r
330VOID\r
331EFIAPI\r
332PlatformBootManagerWaitCallback (\r
333 UINT16 TimeoutRemain\r
334 )\r
335{\r
336 Print (L"\r%-2d seconds remained...", TimeoutRemain);\r
337}\r