]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/BootMaintenanceManagerUiLib/Variable.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Library / BootMaintenanceManagerUiLib / Variable.c
CommitLineData
4af04335
DB
1/** @file\r
2Variable operation that will be used by bootmaint\r
3\r
d1102dba 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
4af04335
DB
6\r
7**/\r
8\r
9#include "BootMaintenanceManager.h"\r
10\r
11/**\r
12 Delete Boot Option that represent a Deleted state in BootOptionMenu.\r
4af04335 13\r
d1102dba 14 @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to\r
4af04335
DB
15 BM_LOAD_CONTEXT marked for deletion is deleted.\r
16 @retval EFI_NOT_FOUND If can not find the boot option want to be deleted.\r
d1102dba 17 @return Others If failed to update the "BootOrder" variable after deletion.\r
4af04335
DB
18\r
19**/\r
20EFI_STATUS\r
21Var_DelBootOption (\r
22 VOID\r
23 )\r
24{\r
1436aea4
MK
25 BM_MENU_ENTRY *NewMenuEntry;\r
26 BM_LOAD_CONTEXT *NewLoadContext;\r
27 EFI_STATUS Status;\r
28 UINTN Index;\r
29 UINTN Index2;\r
4af04335 30\r
1436aea4 31 Index2 = 0;\r
4af04335
DB
32 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
33 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));\r
34 if (NULL == NewMenuEntry) {\r
35 return EFI_NOT_FOUND;\r
36 }\r
37\r
1436aea4 38 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
4af04335
DB
39 if (!NewLoadContext->Deleted) {\r
40 continue;\r
41 }\r
42\r
1436aea4 43 Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber, LoadOptionTypeBoot);\r
bdc8cb0d 44 if (EFI_ERROR (Status)) {\r
1436aea4 45 return Status;\r
bdc8cb0d 46 }\r
1436aea4 47\r
4af04335
DB
48 Index2++;\r
49 //\r
50 // If current Load Option is the same as BootNext,\r
51 // must delete BootNext in order to make sure\r
52 // there will be no panic on next boot\r
53 //\r
54 if (NewLoadContext->IsBootNext) {\r
55 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);\r
56 }\r
57\r
58 RemoveEntryList (&NewMenuEntry->Link);\r
59 BOpt_DestroyMenuEntry (NewMenuEntry);\r
60 NewMenuEntry = NULL;\r
61 }\r
62\r
63 BootOptionMenu.MenuNumber -= Index2;\r
64\r
4af04335
DB
65 return EFI_SUCCESS;\r
66}\r
67\r
68/**\r
bdc8cb0d 69 Delete Load Option that represent a Deleted state in DriverOptionMenu.\r
4af04335
DB
70\r
71 @retval EFI_SUCCESS Load Option is successfully updated.\r
72 @retval EFI_NOT_FOUND Fail to find the driver option want to be deleted.\r
73 @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI\r
74 Variable.\r
75\r
76**/\r
77EFI_STATUS\r
78Var_DelDriverOption (\r
79 VOID\r
80 )\r
81{\r
1436aea4
MK
82 BM_MENU_ENTRY *NewMenuEntry;\r
83 BM_LOAD_CONTEXT *NewLoadContext;\r
84 EFI_STATUS Status;\r
85 UINTN Index;\r
86 UINTN Index2;\r
4af04335 87\r
1436aea4 88 Index2 = 0;\r
4af04335
DB
89 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
90 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));\r
91 if (NULL == NewMenuEntry) {\r
92 return EFI_NOT_FOUND;\r
93 }\r
94\r
1436aea4 95 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
4af04335
DB
96 if (!NewLoadContext->Deleted) {\r
97 continue;\r
98 }\r
1436aea4
MK
99\r
100 Status = EfiBootManagerDeleteLoadOptionVariable (NewMenuEntry->OptionNumber, LoadOptionTypeDriver);\r
bdc8cb0d
DB
101 if (EFI_ERROR (Status)) {\r
102 return Status;\r
103 }\r
4af04335 104\r
4af04335
DB
105 Index2++;\r
106\r
107 RemoveEntryList (&NewMenuEntry->Link);\r
108 BOpt_DestroyMenuEntry (NewMenuEntry);\r
109 NewMenuEntry = NULL;\r
110 }\r
111\r
112 DriverOptionMenu.MenuNumber -= Index2;\r
113\r
4af04335
DB
114 return EFI_SUCCESS;\r
115}\r
116\r
4af04335
DB
117/**\r
118 This function delete and build multi-instance device path for\r
119 specified type of console device.\r
120\r
121 This function clear the EFI variable defined by ConsoleName and\r
122 gEfiGlobalVariableGuid. It then build the multi-instance device\r
d1102dba 123 path by appending the device path of the Console (In/Out/Err) instance\r
4af04335
DB
124 in ConsoleMenu. Then it scan all corresponding console device by\r
125 scanning Terminal (built from device supporting Serial I/O instances)\r
126 devices in TerminalMenu. At last, it save a EFI variable specifed\r
127 by ConsoleName and gEfiGlobalVariableGuid.\r
128\r
129 @param ConsoleName The name for the console device type. They are\r
130 usually "ConIn", "ConOut" and "ErrOut".\r
131 @param ConsoleMenu The console memu which is a list of console devices.\r
132 @param UpdatePageId The flag specifying which type of console device\r
133 to be processed.\r
134\r
135 @retval EFI_SUCCESS The function complete successfully.\r
136 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
137\r
138**/\r
139EFI_STATUS\r
140Var_UpdateConsoleOption (\r
1436aea4
MK
141 IN UINT16 *ConsoleName,\r
142 IN BM_MENU_OPTION *ConsoleMenu,\r
143 IN UINT16 UpdatePageId\r
4af04335
DB
144 )\r
145{\r
146 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;\r
147 BM_MENU_ENTRY *NewMenuEntry;\r
148 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
149 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
150 EFI_STATUS Status;\r
151 VENDOR_DEVICE_PATH Vendor;\r
152 EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath;\r
153 UINTN Index;\r
154\r
1436aea4 155 GetEfiGlobalVariable2 (ConsoleName, (VOID **)&ConDevicePath, NULL);\r
4af04335
DB
156 if (ConDevicePath != NULL) {\r
157 EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);\r
158 FreePool (ConDevicePath);\r
159 ConDevicePath = NULL;\r
1436aea4 160 }\r
4af04335
DB
161\r
162 //\r
163 // First add all console input device from console input menu\r
164 //\r
165 for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {\r
166 NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);\r
167\r
1436aea4 168 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
4af04335
DB
169 if (NewConsoleContext->IsActive) {\r
170 ConDevicePath = AppendDevicePathInstance (\r
171 ConDevicePath,\r
172 NewConsoleContext->DevicePath\r
173 );\r
174 }\r
175 }\r
176\r
177 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
178 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
179\r
1436aea4 180 NewTerminalContext = (BM_TERMINAL_CONTEXT *)NewMenuEntry->VariableContext;\r
4af04335
DB
181 if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||\r
182 ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||\r
183 ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))\r
1436aea4
MK
184 )\r
185 {\r
4af04335
DB
186 Vendor.Header.Type = MESSAGING_DEVICE_PATH;\r
187 Vendor.Header.SubType = MSG_VENDOR_DP;\r
d1102dba 188\r
6eeeb288 189 ASSERT (NewTerminalContext->TerminalType < (ARRAY_SIZE (TerminalTypeGuid)));\r
4af04335
DB
190 CopyMem (\r
191 &Vendor.Guid,\r
192 &TerminalTypeGuid[NewTerminalContext->TerminalType],\r
193 sizeof (EFI_GUID)\r
194 );\r
195 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));\r
196 TerminalDevicePath = AppendDevicePathNode (\r
1436aea4
MK
197 NewTerminalContext->DevicePath,\r
198 (EFI_DEVICE_PATH_PROTOCOL *)&Vendor\r
199 );\r
4af04335
DB
200 ASSERT (TerminalDevicePath != NULL);\r
201 ChangeTerminalDevicePath (TerminalDevicePath, TRUE);\r
202 ConDevicePath = AppendDevicePathInstance (\r
203 ConDevicePath,\r
204 TerminalDevicePath\r
205 );\r
206 }\r
207 }\r
208\r
209 if (ConDevicePath != NULL) {\r
210 Status = gRT->SetVariable (\r
211 ConsoleName,\r
212 &gEfiGlobalVariableGuid,\r
213 VAR_FLAG,\r
214 GetDevicePathSize (ConDevicePath),\r
215 ConDevicePath\r
216 );\r
217 if (EFI_ERROR (Status)) {\r
218 return Status;\r
219 }\r
220 }\r
221\r
222 return EFI_SUCCESS;\r
4af04335
DB
223}\r
224\r
225/**\r
226 This function delete and build multi-instance device path ConIn\r
227 console device.\r
228\r
229 @retval EFI_SUCCESS The function complete successfully.\r
230 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
231**/\r
232EFI_STATUS\r
233Var_UpdateConsoleInpOption (\r
234 VOID\r
235 )\r
236{\r
237 return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);\r
238}\r
239\r
240/**\r
241 This function delete and build multi-instance device path ConOut\r
242 console device.\r
243\r
244 @retval EFI_SUCCESS The function complete successfully.\r
245 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
246**/\r
247EFI_STATUS\r
248Var_UpdateConsoleOutOption (\r
249 VOID\r
250 )\r
251{\r
252 return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);\r
253}\r
254\r
255/**\r
256 This function delete and build multi-instance device path ErrOut\r
257 console device.\r
258\r
259 @retval EFI_SUCCESS The function complete successfully.\r
d1102dba 260 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
4af04335
DB
261**/\r
262EFI_STATUS\r
263Var_UpdateErrorOutOption (\r
264 VOID\r
265 )\r
266{\r
267 return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);\r
268}\r
269\r
270/**\r
d1102dba
LG
271 This function create a currently loaded Drive Option from\r
272 the BMM. It then appends this Driver Option to the end of\r
4af04335
DB
273 the "DriverOrder" list. It append this Driver Opotion to the end\r
274 of DriverOptionMenu.\r
275\r
276 @param CallbackData The BMM context data.\r
277 @param HiiHandle The HII handle associated with the BMM formset.\r
278 @param DescriptionData The description of this driver option.\r
279 @param OptionalData The optional load option.\r
280 @param ForceReconnect If to force reconnect.\r
281\r
201fbce6
DB
282 @retval other Contain some errors when excuting this function.See function\r
283 EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl\r
284 for detail return information.\r
4af04335
DB
285 @retval EFI_SUCCESS If function completes successfully.\r
286\r
287**/\r
288EFI_STATUS\r
289Var_UpdateDriverOption (\r
1436aea4
MK
290 IN BMM_CALLBACK_DATA *CallbackData,\r
291 IN EFI_HII_HANDLE HiiHandle,\r
292 IN UINT16 *DescriptionData,\r
293 IN UINT16 *OptionalData,\r
294 IN UINT8 ForceReconnect\r
4af04335
DB
295 )\r
296{\r
1436aea4
MK
297 UINT16 Index;\r
298 UINT16 DriverString[12];\r
299 BM_MENU_ENTRY *NewMenuEntry;\r
300 BM_LOAD_CONTEXT *NewLoadContext;\r
301 BOOLEAN OptionalDataExist;\r
302 EFI_STATUS Status;\r
2ba36b2f
DB
303 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;\r
304 UINT8 *OptionalDesData;\r
305 UINT32 OptionalDataSize;\r
4af04335
DB
306\r
307 OptionalDataExist = FALSE;\r
1436aea4
MK
308 OptionalDesData = NULL;\r
309 OptionalDataSize = 0;\r
4af04335 310\r
1436aea4 311 Index = BOpt_GetDriverOptionNumber ();\r
4af04335
DB
312 UnicodeSPrint (\r
313 DriverString,\r
314 sizeof (DriverString),\r
315 L"Driver%04x",\r
316 Index\r
317 );\r
318\r
319 if (*DescriptionData == 0x0000) {\r
320 StrCpyS (DescriptionData, MAX_MENU_NUMBER, DriverString);\r
321 }\r
322\r
4af04335
DB
323 if (*OptionalData != 0x0000) {\r
324 OptionalDataExist = TRUE;\r
1436aea4
MK
325 OptionalDesData = (UINT8 *)OptionalData;\r
326 OptionalDataSize = (UINT32)StrSize (OptionalData);\r
4af04335
DB
327 }\r
328\r
329 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
330 if (NULL == NewMenuEntry) {\r
4af04335
DB
331 return EFI_OUT_OF_RESOURCES;\r
332 }\r
333\r
2ba36b2f
DB
334 Status = EfiBootManagerInitializeLoadOption (\r
335 &LoadOption,\r
336 Index,\r
337 LoadOptionTypeDriver,\r
338 LOAD_OPTION_ACTIVE | (ForceReconnect << 1),\r
339 DescriptionData,\r
340 CallbackData->LoadContext->FilePathList,\r
341 OptionalDesData,\r
342 OptionalDataSize\r
1436aea4
MK
343 );\r
344 if (EFI_ERROR (Status)) {\r
201fbce6
DB
345 return Status;\r
346 }\r
347\r
1436aea4 348 Status = EfiBootManagerAddLoadOptionVariable (&LoadOption, (UINTN)-1);\r
201fbce6 349 if (EFI_ERROR (Status)) {\r
1436aea4 350 EfiBootManagerFreeLoadOption (&LoadOption);\r
201fbce6 351 return Status;\r
2ba36b2f
DB
352 }\r
353\r
1436aea4
MK
354 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
355 NewLoadContext->Deleted = FALSE;\r
356 NewLoadContext->Attributes = LoadOption.Attributes;\r
2ba36b2f 357 NewLoadContext->FilePathListLength = (UINT16)GetDevicePathSize (LoadOption.FilePath);\r
4af04335
DB
358\r
359 NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));\r
360 ASSERT (NewLoadContext->Description != NULL);\r
361 NewMenuEntry->DisplayString = NewLoadContext->Description;\r
362 CopyMem (\r
363 NewLoadContext->Description,\r
2ba36b2f 364 LoadOption.Description,\r
4af04335
DB
365 StrSize (DescriptionData)\r
366 );\r
367\r
4af04335
DB
368 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));\r
369 ASSERT (NewLoadContext->FilePathList != NULL);\r
4af04335
DB
370 CopyMem (\r
371 NewLoadContext->FilePathList,\r
2ba36b2f 372 LoadOption.FilePath,\r
4af04335
DB
373 GetDevicePathSize (CallbackData->LoadContext->FilePathList)\r
374 );\r
375\r
1436aea4
MK
376 NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);\r
377 NewMenuEntry->OptionNumber = Index;\r
4af04335 378 NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL);\r
1436aea4 379 NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL);\r
4af04335
DB
380\r
381 if (OptionalDataExist) {\r
2ba36b2f 382 NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize);\r
48c18bd1 383 ASSERT (NewLoadContext->OptionalData != NULL);\r
4af04335 384 CopyMem (\r
2ba36b2f
DB
385 NewLoadContext->OptionalData,\r
386 LoadOption.OptionalData,\r
387 LoadOption.OptionalDataSize\r
4af04335
DB
388 );\r
389 }\r
390\r
4af04335
DB
391 InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);\r
392 DriverOptionMenu.MenuNumber++;\r
393\r
1436aea4 394 EfiBootManagerFreeLoadOption (&LoadOption);\r
2ba36b2f 395\r
4af04335
DB
396 return EFI_SUCCESS;\r
397}\r
398\r
399/**\r
d1102dba
LG
400 This function create a currently loaded Boot Option from\r
401 the BMM. It then appends this Boot Option to the end of\r
4af04335
DB
402 the "BootOrder" list. It also append this Boot Opotion to the end\r
403 of BootOptionMenu.\r
404\r
405 @param CallbackData The BMM context data.\r
406\r
201fbce6
DB
407 @retval other Contain some errors when excuting this function. See function\r
408 EfiBootManagerInitializeLoadOption/EfiBootManagerAddLoadOptionVariabl\r
409 for detail return information.\r
4af04335
DB
410 @retval EFI_SUCCESS If function completes successfully.\r
411\r
412**/\r
413EFI_STATUS\r
414Var_UpdateBootOption (\r
1436aea4 415 IN BMM_CALLBACK_DATA *CallbackData\r
4af04335
DB
416 )\r
417{\r
1436aea4
MK
418 UINT16 BootString[10];\r
419 UINT16 Index;\r
420 BM_MENU_ENTRY *NewMenuEntry;\r
421 BM_LOAD_CONTEXT *NewLoadContext;\r
422 BOOLEAN OptionalDataExist;\r
423 EFI_STATUS Status;\r
424 BMM_FAKE_NV_DATA *NvRamMap;\r
2ba36b2f
DB
425 EFI_BOOT_MANAGER_LOAD_OPTION LoadOption;\r
426 UINT8 *OptionalData;\r
427 UINT32 OptionalDataSize;\r
4af04335
DB
428\r
429 OptionalDataExist = FALSE;\r
1436aea4
MK
430 NvRamMap = &CallbackData->BmmFakeNvData;\r
431 OptionalData = NULL;\r
432 OptionalDataSize = 0;\r
4af04335 433\r
1436aea4 434 Index = BOpt_GetBootOptionNumber ();\r
4af04335
DB
435 UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);\r
436\r
437 if (NvRamMap->BootDescriptionData[0] == 0x0000) {\r
438 StrCpyS (NvRamMap->BootDescriptionData, sizeof (NvRamMap->BootDescriptionData) / sizeof (NvRamMap->BootDescriptionData[0]), BootString);\r
439 }\r
440\r
4af04335
DB
441 if (NvRamMap->BootOptionalData[0] != 0x0000) {\r
442 OptionalDataExist = TRUE;\r
1436aea4
MK
443 OptionalData = (UINT8 *)NvRamMap->BootOptionalData;\r
444 OptionalDataSize = (UINT32)StrSize (NvRamMap->BootOptionalData);\r
4af04335
DB
445 }\r
446\r
447 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);\r
448 if (NULL == NewMenuEntry) {\r
449 return EFI_OUT_OF_RESOURCES;\r
450 }\r
451\r
2ba36b2f
DB
452 Status = EfiBootManagerInitializeLoadOption (\r
453 &LoadOption,\r
454 Index,\r
455 LoadOptionTypeBoot,\r
456 LOAD_OPTION_ACTIVE,\r
457 NvRamMap->BootDescriptionData,\r
458 CallbackData->LoadContext->FilePathList,\r
459 OptionalData,\r
460 OptionalDataSize\r
1436aea4
MK
461 );\r
462 if (EFI_ERROR (Status)) {\r
201fbce6
DB
463 return Status;\r
464 }\r
465\r
1436aea4 466 Status = EfiBootManagerAddLoadOptionVariable (&LoadOption, (UINTN)-1);\r
201fbce6 467 if (EFI_ERROR (Status)) {\r
1436aea4 468 EfiBootManagerFreeLoadOption (&LoadOption);\r
201fbce6 469 return Status;\r
2ba36b2f
DB
470 }\r
471\r
1436aea4
MK
472 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
473 NewLoadContext->Deleted = FALSE;\r
474 NewLoadContext->Attributes = LoadOption.Attributes;\r
475 NewLoadContext->FilePathListLength = (UINT16)GetDevicePathSize (LoadOption.FilePath);\r
4af04335
DB
476\r
477 NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->BootDescriptionData));\r
478 ASSERT (NewLoadContext->Description != NULL);\r
479\r
480 NewMenuEntry->DisplayString = NewLoadContext->Description;\r
2ba36b2f 481\r
4af04335
DB
482 CopyMem (\r
483 NewLoadContext->Description,\r
2ba36b2f 484 LoadOption.Description,\r
4af04335
DB
485 StrSize (NvRamMap->BootDescriptionData)\r
486 );\r
487\r
4af04335
DB
488 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));\r
489 ASSERT (NewLoadContext->FilePathList != NULL);\r
4af04335
DB
490 CopyMem (\r
491 NewLoadContext->FilePathList,\r
2ba36b2f 492 LoadOption.FilePath,\r
4af04335
DB
493 GetDevicePathSize (CallbackData->LoadContext->FilePathList)\r
494 );\r
495\r
1436aea4
MK
496 NewMenuEntry->HelpString = UiDevicePathToStr (NewLoadContext->FilePathList);\r
497 NewMenuEntry->OptionNumber = Index;\r
4af04335 498 NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->DisplayString, NULL);\r
1436aea4 499 NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, NewMenuEntry->HelpString, NULL);\r
4af04335
DB
500\r
501 if (OptionalDataExist) {\r
2ba36b2f 502 NewLoadContext->OptionalData = AllocateZeroPool (LoadOption.OptionalDataSize);\r
48c18bd1 503 ASSERT (NewLoadContext->OptionalData != NULL);\r
2ba36b2f
DB
504 CopyMem (\r
505 NewLoadContext->OptionalData,\r
506 LoadOption.OptionalData,\r
507 LoadOption.OptionalDataSize\r
508 );\r
4af04335
DB
509 }\r
510\r
4af04335
DB
511 InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);\r
512 BootOptionMenu.MenuNumber++;\r
513\r
1436aea4 514 EfiBootManagerFreeLoadOption (&LoadOption);\r
2ba36b2f 515\r
4af04335
DB
516 return EFI_SUCCESS;\r
517}\r
518\r
519/**\r
d1102dba 520 This function update the "BootNext" EFI Variable. If there is\r
4af04335
DB
521 no "BootNext" specified in BMM, this EFI Variable is deleted.\r
522 It also update the BMM context data specified the "BootNext"\r
523 vaule.\r
524\r
525 @param CallbackData The BMM context data.\r
526\r
527 @retval EFI_SUCCESS The function complete successfully.\r
d1102dba 528 @return The EFI variable can be saved. See gRT->SetVariable\r
4af04335
DB
529 for detail return information.\r
530\r
531**/\r
532EFI_STATUS\r
533Var_UpdateBootNext (\r
1436aea4 534 IN BMM_CALLBACK_DATA *CallbackData\r
4af04335
DB
535 )\r
536{\r
537 BM_MENU_ENTRY *NewMenuEntry;\r
538 BM_LOAD_CONTEXT *NewLoadContext;\r
539 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
540 UINT16 Index;\r
541 EFI_STATUS Status;\r
542\r
1436aea4
MK
543 Status = EFI_SUCCESS;\r
544 CurrentFakeNVMap = &CallbackData->BmmFakeNvData;\r
4af04335
DB
545 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
546 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
547 ASSERT (NULL != NewMenuEntry);\r
548\r
1436aea4
MK
549 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
550 NewLoadContext->IsBootNext = FALSE;\r
4af04335
DB
551 }\r
552\r
f7986526 553 if (CurrentFakeNVMap->BootNext == NONE_BOOTNEXT_VALUE) {\r
4af04335
DB
554 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);\r
555 return EFI_SUCCESS;\r
556 }\r
557\r
558 NewMenuEntry = BOpt_GetMenuEntry (\r
1436aea4
MK
559 &BootOptionMenu,\r
560 CurrentFakeNVMap->BootNext\r
561 );\r
4af04335
DB
562 ASSERT (NewMenuEntry != NULL);\r
563\r
1436aea4
MK
564 NewLoadContext = (BM_LOAD_CONTEXT *)NewMenuEntry->VariableContext;\r
565 Status = gRT->SetVariable (\r
566 L"BootNext",\r
567 &gEfiGlobalVariableGuid,\r
568 VAR_FLAG,\r
569 sizeof (UINT16),\r
570 &NewMenuEntry->OptionNumber\r
571 );\r
4af04335
DB
572 NewLoadContext->IsBootNext = TRUE;\r
573 CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;\r
574 return Status;\r
575}\r
576\r
577/**\r
578 This function update the "BootOrder" EFI Variable based on\r
579 BMM Formset's NV map. It then refresh BootOptionMenu\r
580 with the new "BootOrder" list.\r
581\r
582 @param CallbackData The BMM context data.\r
583\r
584 @retval EFI_SUCCESS The function complete successfully.\r
585 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.\r
586 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
587\r
588**/\r
589EFI_STATUS\r
590Var_UpdateBootOrder (\r
1436aea4 591 IN BMM_CALLBACK_DATA *CallbackData\r
4af04335
DB
592 )\r
593{\r
594 EFI_STATUS Status;\r
595 UINT16 Index;\r
596 UINT16 OrderIndex;\r
597 UINT16 *BootOrder;\r
598 UINTN BootOrderSize;\r
599 UINT16 OptionNumber;\r
600\r
601 //\r
602 // First check whether BootOrder is present in current configuration\r
603 //\r
1436aea4 604 GetEfiGlobalVariable2 (L"BootOrder", (VOID **)&BootOrder, &BootOrderSize);\r
4af04335
DB
605 if (BootOrder == NULL) {\r
606 return EFI_OUT_OF_RESOURCES;\r
607 }\r
608\r
609 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.BootOptionOrder) / sizeof (CallbackData->BmmFakeNvData.BootOptionOrder[0])));\r
610\r
611 //\r
612 // OptionOrder is subset of BootOrder\r
613 //\r
614 for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] != 0); OrderIndex++) {\r
615 for (Index = OrderIndex; Index < BootOrderSize / sizeof (UINT16); Index++) {\r
1436aea4 616 if ((BootOrder[Index] == (UINT16)(CallbackData->BmmFakeNvData.BootOptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) {\r
4af04335
DB
617 OptionNumber = BootOrder[Index];\r
618 CopyMem (&BootOrder[OrderIndex + 1], &BootOrder[OrderIndex], (Index - OrderIndex) * sizeof (UINT16));\r
619 BootOrder[OrderIndex] = OptionNumber;\r
620 }\r
621 }\r
622 }\r
623\r
624 Status = gRT->SetVariable (\r
625 L"BootOrder",\r
626 &gEfiGlobalVariableGuid,\r
627 VAR_FLAG,\r
628 BootOrderSize,\r
629 BootOrder\r
630 );\r
631 FreePool (BootOrder);\r
d1102dba 632\r
4af04335
DB
633 BOpt_FreeMenu (&BootOptionMenu);\r
634 BOpt_GetBootOptions (CallbackData);\r
635\r
636 return Status;\r
4af04335
DB
637}\r
638\r
639/**\r
640 This function update the "DriverOrder" EFI Variable based on\r
641 BMM Formset's NV map. It then refresh DriverOptionMenu\r
642 with the new "DriverOrder" list.\r
643\r
644 @param CallbackData The BMM context data.\r
645\r
646 @retval EFI_SUCCESS The function complete successfully.\r
647 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.\r
648 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.\r
649\r
650**/\r
651EFI_STATUS\r
652Var_UpdateDriverOrder (\r
1436aea4 653 IN BMM_CALLBACK_DATA *CallbackData\r
4af04335
DB
654 )\r
655{\r
656 EFI_STATUS Status;\r
657 UINT16 Index;\r
658 UINT16 *DriverOrderList;\r
659 UINT16 *NewDriverOrderList;\r
660 UINTN DriverOrderListSize;\r
661\r
662 DriverOrderList = NULL;\r
663 DriverOrderListSize = 0;\r
664\r
665 //\r
666 // First check whether DriverOrder is present in current configuration\r
667 //\r
1436aea4 668 GetEfiGlobalVariable2 (L"DriverOrder", (VOID **)&DriverOrderList, &DriverOrderListSize);\r
4af04335
DB
669 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);\r
670\r
671 if (NewDriverOrderList == NULL) {\r
672 return EFI_OUT_OF_RESOURCES;\r
673 }\r
1436aea4 674\r
4af04335
DB
675 //\r
676 // If exists, delete it to hold new DriverOrder\r
677 //\r
678 if (DriverOrderList != NULL) {\r
679 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);\r
680 FreePool (DriverOrderList);\r
681 }\r
682\r
683 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder) / sizeof (CallbackData->BmmFakeNvData.DriverOptionOrder[0])));\r
684 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
1436aea4 685 NewDriverOrderList[Index] = (UINT16)(CallbackData->BmmFakeNvData.DriverOptionOrder[Index] - 1);\r
4af04335
DB
686 }\r
687\r
688 Status = gRT->SetVariable (\r
689 L"DriverOrder",\r
690 &gEfiGlobalVariableGuid,\r
691 VAR_FLAG,\r
692 DriverOrderListSize,\r
693 NewDriverOrderList\r
694 );\r
695 if (EFI_ERROR (Status)) {\r
696 return Status;\r
697 }\r
698\r
699 BOpt_FreeMenu (&DriverOptionMenu);\r
700 BOpt_GetDriverOptions (CallbackData);\r
701 return EFI_SUCCESS;\r
702}\r
703\r
704/**\r
705 Update the Text Mode of Console.\r
706\r
707 @param CallbackData The context data for BMM.\r
708\r
709 @retval EFI_SUCCSS If the Text Mode of Console is updated.\r
710 @return Other value if the Text Mode of Console is not updated.\r
711\r
712**/\r
713EFI_STATUS\r
714Var_UpdateConMode (\r
1436aea4 715 IN BMM_CALLBACK_DATA *CallbackData\r
4af04335
DB
716 )\r
717{\r
718 EFI_STATUS Status;\r
719 UINTN Mode;\r
720 CONSOLE_OUT_MODE ModeInfo;\r
721\r
722 Mode = CallbackData->BmmFakeNvData.ConsoleOutMode;\r
723\r
724 Status = gST->ConOut->QueryMode (gST->ConOut, Mode, &(ModeInfo.Column), &(ModeInfo.Row));\r
1436aea4
MK
725 if (!EFI_ERROR (Status)) {\r
726 Status = PcdSet32S (PcdSetupConOutColumn, (UINT32)ModeInfo.Column);\r
4af04335 727 if (!EFI_ERROR (Status)) {\r
1436aea4 728 Status = PcdSet32S (PcdSetupConOutRow, (UINT32)ModeInfo.Row);\r
4af04335
DB
729 }\r
730 }\r
731\r
732 return Status;\r
733}\r