]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/Variable.c
ArmPkg/CompilerIntrinsicsLib: Added memset() to AArch64
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / Variable.c
1 /** @file
2 Variable operation that will be used by bootmaint
3
4 Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "BootMaint.h"
16
17 /**
18 Delete Boot Option that represent a Deleted state in BootOptionMenu.
19 After deleting this boot option, call Var_ChangeBootOrder to
20 make sure BootOrder is in valid state.
21
22 @retval EFI_SUCCESS If all boot load option EFI Variables corresponding to
23 BM_LOAD_CONTEXT marked for deletion is deleted.
24 @retval EFI_NOT_FOUND If can not find the boot option want to be deleted.
25 @return Others If failed to update the "BootOrder" variable after deletion.
26
27 **/
28 EFI_STATUS
29 Var_DelBootOption (
30 VOID
31 )
32 {
33 BM_MENU_ENTRY *NewMenuEntry;
34 BM_LOAD_CONTEXT *NewLoadContext;
35 UINT16 BootString[10];
36 EFI_STATUS Status;
37 UINTN Index;
38 UINTN Index2;
39
40 Status = EFI_SUCCESS;
41 Index2 = 0;
42 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
43 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));
44 if (NULL == NewMenuEntry) {
45 return EFI_NOT_FOUND;
46 }
47
48 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
49 if (!NewLoadContext->Deleted) {
50 continue;
51 }
52
53 UnicodeSPrint (
54 BootString,
55 sizeof (BootString),
56 L"Boot%04x",
57 NewMenuEntry->OptionNumber
58 );
59
60 EfiLibDeleteVariable (BootString, &gEfiGlobalVariableGuid);
61 Index2++;
62 //
63 // If current Load Option is the same as BootNext,
64 // must delete BootNext in order to make sure
65 // there will be no panic on next boot
66 //
67 if (NewLoadContext->IsBootNext) {
68 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
69 }
70
71 RemoveEntryList (&NewMenuEntry->Link);
72 BOpt_DestroyMenuEntry (NewMenuEntry);
73 NewMenuEntry = NULL;
74 }
75
76 BootOptionMenu.MenuNumber -= Index2;
77
78 Status = Var_ChangeBootOrder ();
79 return Status;
80 }
81
82 /**
83 After any operation on Boot####, there will be a discrepancy in BootOrder.
84 Since some are missing but in BootOrder, while some are present but are
85 not reflected by BootOrder. Then a function rebuild BootOrder from
86 scratch by content from BootOptionMenu is needed.
87
88
89
90
91 @retval EFI_SUCCESS The boot order is updated successfully.
92 @return EFI_STATUS other than EFI_SUCCESS if failed to
93 Set the "BootOrder" EFI Variable.
94
95 **/
96 EFI_STATUS
97 Var_ChangeBootOrder (
98 VOID
99 )
100 {
101
102 EFI_STATUS Status;
103 BM_MENU_ENTRY *NewMenuEntry;
104 UINT16 *BootOrderList;
105 UINT16 *BootOrderListPtr;
106 UINTN BootOrderListSize;
107 UINTN Index;
108
109 BootOrderList = NULL;
110 BootOrderListSize = 0;
111
112 //
113 // First check whether BootOrder is present in current configuration
114 //
115 BootOrderList = BdsLibGetVariableAndSize (
116 L"BootOrder",
117 &gEfiGlobalVariableGuid,
118 &BootOrderListSize
119 );
120
121 //
122 // If exists, delete it to hold new BootOrder
123 //
124 if (BootOrderList != NULL) {
125 EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
126 FreePool (BootOrderList);
127 BootOrderList = NULL;
128 }
129 //
130 // Maybe here should be some check method to ensure that
131 // no new added boot options will be added
132 // but the setup engine now will give only one callback
133 // that is to say, user are granted only one chance to
134 // decide whether the boot option will be added or not
135 // there should be no indictor to show whether this
136 // is a "new" boot option
137 //
138 BootOrderListSize = BootOptionMenu.MenuNumber;
139
140 if (BootOrderListSize > 0) {
141 BootOrderList = AllocateZeroPool (BootOrderListSize * sizeof (UINT16));
142 ASSERT (BootOrderList != NULL);
143 BootOrderListPtr = BootOrderList;
144
145 //
146 // Get all current used Boot#### from BootOptionMenu.
147 // OptionNumber in each BM_LOAD_OPTION is really its
148 // #### value.
149 //
150 for (Index = 0; Index < BootOrderListSize; Index++) {
151 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
152 *BootOrderList = (UINT16) NewMenuEntry->OptionNumber;
153 BootOrderList++;
154 }
155
156 BootOrderList = BootOrderListPtr;
157
158 //
159 // After building the BootOrderList, write it back
160 //
161 Status = gRT->SetVariable (
162 L"BootOrder",
163 &gEfiGlobalVariableGuid,
164 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
165 BootOrderListSize * sizeof (UINT16),
166 BootOrderList
167 );
168 if (EFI_ERROR (Status)) {
169 return Status;
170 }
171 }
172 return EFI_SUCCESS;
173 }
174
175 /**
176 Delete Load Option that represent a Deleted state in BootOptionMenu.
177 After deleting this Driver option, call Var_ChangeDriverOrder to
178 make sure DriverOrder is in valid state.
179
180 @retval EFI_SUCCESS Load Option is successfully updated.
181 @retval EFI_NOT_FOUND Fail to find the driver option want to be deleted.
182 @return Other value than EFI_SUCCESS if failed to update "Driver Order" EFI
183 Variable.
184
185 **/
186 EFI_STATUS
187 Var_DelDriverOption (
188 VOID
189 )
190 {
191 BM_MENU_ENTRY *NewMenuEntry;
192 BM_LOAD_CONTEXT *NewLoadContext;
193 UINT16 DriverString[12];
194 EFI_STATUS Status;
195 UINTN Index;
196 UINTN Index2;
197
198 Status = EFI_SUCCESS;
199 Index2 = 0;
200 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
201 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));
202 if (NULL == NewMenuEntry) {
203 return EFI_NOT_FOUND;
204 }
205
206 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
207 if (!NewLoadContext->Deleted) {
208 continue;
209 }
210
211 UnicodeSPrint (
212 DriverString,
213 sizeof (DriverString),
214 L"Driver%04x",
215 NewMenuEntry->OptionNumber
216 );
217
218 EfiLibDeleteVariable (DriverString, &gEfiGlobalVariableGuid);
219 Index2++;
220
221 RemoveEntryList (&NewMenuEntry->Link);
222 BOpt_DestroyMenuEntry (NewMenuEntry);
223 NewMenuEntry = NULL;
224 }
225
226 DriverOptionMenu.MenuNumber -= Index2;
227
228 Status = Var_ChangeDriverOrder ();
229 return Status;
230 }
231
232 /**
233 After any operation on Driver####, there will be a discrepancy in
234 DriverOrder. Since some are missing but in DriverOrder, while some
235 are present but are not reflected by DriverOrder. Then a function
236 rebuild DriverOrder from scratch by content from DriverOptionMenu is
237 needed.
238
239 @retval EFI_SUCCESS The driver order is updated successfully.
240 @return Other status than EFI_SUCCESS if failed to set the "DriverOrder" EFI Variable.
241
242 **/
243 EFI_STATUS
244 Var_ChangeDriverOrder (
245 VOID
246 )
247 {
248 EFI_STATUS Status;
249 BM_MENU_ENTRY *NewMenuEntry;
250 UINT16 *DriverOrderList;
251 UINT16 *DriverOrderListPtr;
252 UINTN DriverOrderListSize;
253 UINTN Index;
254
255 DriverOrderList = NULL;
256 DriverOrderListSize = 0;
257
258 //
259 // First check whether DriverOrder is present in current configuration
260 //
261 DriverOrderList = BdsLibGetVariableAndSize (
262 L"DriverOrder",
263 &gEfiGlobalVariableGuid,
264 &DriverOrderListSize
265 );
266
267 //
268 // If exists, delete it to hold new DriverOrder
269 //
270 if (DriverOrderList != NULL) {
271 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
272 FreePool (DriverOrderList);
273 DriverOrderList = NULL;
274 }
275
276 DriverOrderListSize = DriverOptionMenu.MenuNumber;
277
278 if (DriverOrderListSize > 0) {
279 DriverOrderList = AllocateZeroPool (DriverOrderListSize * sizeof (UINT16));
280 ASSERT (DriverOrderList != NULL);
281 DriverOrderListPtr = DriverOrderList;
282
283 //
284 // Get all current used Driver#### from DriverOptionMenu.
285 // OptionNumber in each BM_LOAD_OPTION is really its
286 // #### value.
287 //
288 for (Index = 0; Index < DriverOrderListSize; Index++) {
289 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
290 *DriverOrderList = (UINT16) NewMenuEntry->OptionNumber;
291 DriverOrderList++;
292 }
293
294 DriverOrderList = DriverOrderListPtr;
295
296 //
297 // After building the DriverOrderList, write it back
298 //
299 Status = gRT->SetVariable (
300 L"DriverOrder",
301 &gEfiGlobalVariableGuid,
302 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
303 DriverOrderListSize * sizeof (UINT16),
304 DriverOrderList
305 );
306 if (EFI_ERROR (Status)) {
307 return Status;
308 }
309 }
310 return EFI_SUCCESS;
311 }
312
313 /**
314 Update the device path of "ConOut", "ConIn" and "ErrOut"
315 based on the new BaudRate, Data Bits, parity and Stop Bits
316 set.
317
318 **/
319 VOID
320 Var_UpdateAllConsoleOption (
321 VOID
322 )
323 {
324 EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;
325 EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;
326 EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;
327 EFI_STATUS Status;
328
329 OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);
330 InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);
331 ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);
332 if (OutDevicePath != NULL) {
333 ChangeVariableDevicePath (OutDevicePath);
334 Status = gRT->SetVariable (
335 L"ConOut",
336 &gEfiGlobalVariableGuid,
337 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
338 GetDevicePathSize (OutDevicePath),
339 OutDevicePath
340 );
341 ASSERT (!EFI_ERROR (Status));
342 }
343
344 if (InpDevicePath != NULL) {
345 ChangeVariableDevicePath (InpDevicePath);
346 Status = gRT->SetVariable (
347 L"ConIn",
348 &gEfiGlobalVariableGuid,
349 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
350 GetDevicePathSize (InpDevicePath),
351 InpDevicePath
352 );
353 ASSERT (!EFI_ERROR (Status));
354 }
355
356 if (ErrDevicePath != NULL) {
357 ChangeVariableDevicePath (ErrDevicePath);
358 Status = gRT->SetVariable (
359 L"ErrOut",
360 &gEfiGlobalVariableGuid,
361 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
362 GetDevicePathSize (ErrDevicePath),
363 ErrDevicePath
364 );
365 ASSERT (!EFI_ERROR (Status));
366 }
367 }
368
369 /**
370 This function delete and build multi-instance device path for
371 specified type of console device.
372
373 This function clear the EFI variable defined by ConsoleName and
374 gEfiGlobalVariableGuid. It then build the multi-instance device
375 path by appending the device path of the Console (In/Out/Err) instance
376 in ConsoleMenu. Then it scan all corresponding console device by
377 scanning Terminal (built from device supporting Serial I/O instances)
378 devices in TerminalMenu. At last, it save a EFI variable specifed
379 by ConsoleName and gEfiGlobalVariableGuid.
380
381 @param ConsoleName The name for the console device type. They are
382 usually "ConIn", "ConOut" and "ErrOut".
383 @param ConsoleMenu The console memu which is a list of console devices.
384 @param UpdatePageId The flag specifying which type of console device
385 to be processed.
386
387 @retval EFI_SUCCESS The function complete successfully.
388 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
389
390 **/
391 EFI_STATUS
392 Var_UpdateConsoleOption (
393 IN UINT16 *ConsoleName,
394 IN BM_MENU_OPTION *ConsoleMenu,
395 IN UINT16 UpdatePageId
396 )
397 {
398 EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
399 BM_MENU_ENTRY *NewMenuEntry;
400 BM_CONSOLE_CONTEXT *NewConsoleContext;
401 BM_TERMINAL_CONTEXT *NewTerminalContext;
402 EFI_STATUS Status;
403 VENDOR_DEVICE_PATH Vendor;
404 EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath;
405 UINTN Index;
406
407 ConDevicePath = EfiLibGetVariable (ConsoleName, &gEfiGlobalVariableGuid);
408 if (ConDevicePath != NULL) {
409 EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);
410 FreePool (ConDevicePath);
411 ConDevicePath = NULL;
412 };
413
414 //
415 // First add all console input device from console input menu
416 //
417 for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {
418 NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
419
420 NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
421 if (NewConsoleContext->IsActive) {
422 ConDevicePath = AppendDevicePathInstance (
423 ConDevicePath,
424 NewConsoleContext->DevicePath
425 );
426 }
427 }
428
429 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
430 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
431
432 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
433 if (((NewTerminalContext->IsConIn != 0) && (UpdatePageId == FORM_CON_IN_ID)) ||
434 ((NewTerminalContext->IsConOut != 0) && (UpdatePageId == FORM_CON_OUT_ID)) ||
435 ((NewTerminalContext->IsStdErr != 0) && (UpdatePageId == FORM_CON_ERR_ID))
436 ) {
437 Vendor.Header.Type = MESSAGING_DEVICE_PATH;
438 Vendor.Header.SubType = MSG_VENDOR_DP;
439
440 ASSERT (NewTerminalContext->TerminalType < (sizeof (TerminalTypeGuid) / sizeof (TerminalTypeGuid[0])));
441 CopyMem (
442 &Vendor.Guid,
443 &TerminalTypeGuid[NewTerminalContext->TerminalType],
444 sizeof (EFI_GUID)
445 );
446 SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
447 TerminalDevicePath = AppendDevicePathNode (
448 NewTerminalContext->DevicePath,
449 (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
450 );
451 ASSERT (TerminalDevicePath != NULL);
452 ChangeTerminalDevicePath (&TerminalDevicePath, TRUE);
453 ConDevicePath = AppendDevicePathInstance (
454 ConDevicePath,
455 TerminalDevicePath
456 );
457 }
458 }
459
460 if (ConDevicePath != NULL) {
461 Status = gRT->SetVariable (
462 ConsoleName,
463 &gEfiGlobalVariableGuid,
464 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
465 GetDevicePathSize (ConDevicePath),
466 ConDevicePath
467 );
468 if (EFI_ERROR (Status)) {
469 return Status;
470 }
471 }
472
473 return EFI_SUCCESS;
474
475 }
476
477 /**
478 This function delete and build multi-instance device path ConIn
479 console device.
480
481 @retval EFI_SUCCESS The function complete successfully.
482 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
483 **/
484 EFI_STATUS
485 Var_UpdateConsoleInpOption (
486 VOID
487 )
488 {
489 return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);
490 }
491
492 /**
493 This function delete and build multi-instance device path ConOut
494 console device.
495
496 @retval EFI_SUCCESS The function complete successfully.
497 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
498 **/
499 EFI_STATUS
500 Var_UpdateConsoleOutOption (
501 VOID
502 )
503 {
504 return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);
505 }
506
507 /**
508 This function delete and build multi-instance device path ErrOut
509 console device.
510
511 @retval EFI_SUCCESS The function complete successfully.
512 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
513 **/
514 EFI_STATUS
515 Var_UpdateErrorOutOption (
516 VOID
517 )
518 {
519 return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);
520 }
521
522 /**
523 This function create a currently loaded Drive Option from
524 the BMM. It then appends this Driver Option to the end of
525 the "DriverOrder" list. It append this Driver Opotion to the end
526 of DriverOptionMenu.
527
528 @param CallbackData The BMM context data.
529 @param HiiHandle The HII handle associated with the BMM formset.
530 @param DescriptionData The description of this driver option.
531 @param OptionalData The optional load option.
532 @param ForceReconnect If to force reconnect.
533
534 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
535 @retval EFI_SUCCESS If function completes successfully.
536
537 **/
538 EFI_STATUS
539 Var_UpdateDriverOption (
540 IN BMM_CALLBACK_DATA *CallbackData,
541 IN EFI_HII_HANDLE HiiHandle,
542 IN UINT16 *DescriptionData,
543 IN UINT16 *OptionalData,
544 IN UINT8 ForceReconnect
545 )
546 {
547 UINT16 Index;
548 UINT16 *DriverOrderList;
549 UINT16 *NewDriverOrderList;
550 UINT16 DriverString[12];
551 UINTN DriverOrderListSize;
552 VOID *Buffer;
553 UINTN BufferSize;
554 UINT8 *Ptr;
555 BM_MENU_ENTRY *NewMenuEntry;
556 BM_LOAD_CONTEXT *NewLoadContext;
557 BOOLEAN OptionalDataExist;
558 EFI_STATUS Status;
559
560 OptionalDataExist = FALSE;
561
562 Index = BOpt_GetDriverOptionNumber ();
563 UnicodeSPrint (
564 DriverString,
565 sizeof (DriverString),
566 L"Driver%04x",
567 Index
568 );
569
570 if (*DescriptionData == 0x0000) {
571 StrCpy (DescriptionData, DriverString);
572 }
573
574 BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescriptionData);
575 BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList);
576
577 if (*OptionalData != 0x0000) {
578 OptionalDataExist = TRUE;
579 BufferSize += StrSize (OptionalData);
580 }
581
582 Buffer = AllocateZeroPool (BufferSize);
583 if (NULL == Buffer) {
584 return EFI_OUT_OF_RESOURCES;
585 }
586
587 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
588 if (NULL == NewMenuEntry) {
589 FreePool (Buffer);
590 return EFI_OUT_OF_RESOURCES;
591 }
592
593 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
594 NewLoadContext->Deleted = FALSE;
595 NewLoadContext->LoadOptionSize = BufferSize;
596 Ptr = (UINT8 *) Buffer;
597 NewLoadContext->LoadOption = Ptr;
598 *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE | (ForceReconnect << 1);
599 NewLoadContext->Attributes = *((UINT32 *) Ptr);
600 NewLoadContext->IsActive = TRUE;
601 NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
602
603 Ptr += sizeof (UINT32);
604 *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
605 NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
606
607 Ptr += sizeof (UINT16);
608 CopyMem (
609 Ptr,
610 DescriptionData,
611 StrSize (DescriptionData)
612 );
613
614 NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));
615 ASSERT (NewLoadContext->Description != NULL);
616 NewMenuEntry->DisplayString = NewLoadContext->Description;
617 CopyMem (
618 NewLoadContext->Description,
619 (VOID *) Ptr,
620 StrSize (DescriptionData)
621 );
622
623 Ptr += StrSize (DescriptionData);
624 CopyMem (
625 Ptr,
626 CallbackData->LoadContext->FilePathList,
627 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
628 );
629
630 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
631 ASSERT (NewLoadContext->FilePathList != NULL);
632
633 CopyMem (
634 NewLoadContext->FilePathList,
635 (VOID *) Ptr,
636 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
637 );
638
639 NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);
640 NewMenuEntry->OptionNumber = Index;
641 NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
642 CallbackData,
643 DriverOptionStrDepository
644 );
645 NewMenuEntry->DisplayStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->DisplayString, NULL);
646
647 NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
648 CallbackData,
649 DriverOptionHelpStrDepository
650 );
651 NewMenuEntry->HelpStringToken = HiiSetString (HiiHandle, 0, NewMenuEntry->HelpString, NULL);
652
653 if (OptionalDataExist) {
654 Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
655
656 CopyMem (
657 Ptr,
658 OptionalData,
659 StrSize (OptionalData)
660 );
661 }
662
663 Status = gRT->SetVariable (
664 DriverString,
665 &gEfiGlobalVariableGuid,
666 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
667 BufferSize,
668 Buffer
669 );
670 ASSERT_EFI_ERROR (Status);
671 DriverOrderList = BdsLibGetVariableAndSize (
672 L"DriverOrder",
673 &gEfiGlobalVariableGuid,
674 &DriverOrderListSize
675 );
676 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16));
677 ASSERT (NewDriverOrderList != NULL);
678 if (DriverOrderList != NULL) {
679 CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize);
680 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
681 }
682 NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index;
683
684 Status = gRT->SetVariable (
685 L"DriverOrder",
686 &gEfiGlobalVariableGuid,
687 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
688 DriverOrderListSize + sizeof (UINT16),
689 NewDriverOrderList
690 );
691 ASSERT_EFI_ERROR (Status);
692 if (DriverOrderList != NULL) {
693 FreePool (DriverOrderList);
694 }
695 DriverOrderList = NULL;
696 FreePool (NewDriverOrderList);
697 InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
698 DriverOptionMenu.MenuNumber++;
699
700 *DescriptionData = 0x0000;
701 *OptionalData = 0x0000;
702 return EFI_SUCCESS;
703 }
704
705 /**
706 This function create a currently loaded Boot Option from
707 the BMM. It then appends this Boot Option to the end of
708 the "BootOrder" list. It also append this Boot Opotion to the end
709 of BootOptionMenu.
710
711 @param CallbackData The BMM context data.
712 @param NvRamMap The file explorer formset internal state.
713
714 @retval EFI_OUT_OF_RESOURCES If not enought memory to complete the operation.
715 @retval EFI_SUCCESS If function completes successfully.
716
717 **/
718 EFI_STATUS
719 Var_UpdateBootOption (
720 IN BMM_CALLBACK_DATA *CallbackData,
721 IN FILE_EXPLORER_NV_DATA *NvRamMap
722 )
723 {
724 UINT16 *BootOrderList;
725 UINT16 *NewBootOrderList;
726 UINTN BootOrderListSize;
727 UINT16 BootString[10];
728 VOID *Buffer;
729 UINTN BufferSize;
730 UINT8 *Ptr;
731 UINT16 Index;
732 BM_MENU_ENTRY *NewMenuEntry;
733 BM_LOAD_CONTEXT *NewLoadContext;
734 BOOLEAN OptionalDataExist;
735 EFI_STATUS Status;
736
737 OptionalDataExist = FALSE;
738
739 Index = BOpt_GetBootOptionNumber () ;
740 UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);
741
742 if (NvRamMap->DescriptionData[0] == 0x0000) {
743 StrCpy (NvRamMap->DescriptionData, BootString);
744 }
745
746 BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->DescriptionData);
747 BufferSize += GetDevicePathSize (CallbackData->LoadContext->FilePathList);
748
749 if (NvRamMap->OptionalData[0] != 0x0000) {
750 OptionalDataExist = TRUE;
751 BufferSize += StrSize (NvRamMap->OptionalData);
752 }
753
754 Buffer = AllocateZeroPool (BufferSize);
755 if (NULL == Buffer) {
756 return EFI_OUT_OF_RESOURCES;
757 }
758
759 NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
760 if (NULL == NewMenuEntry) {
761 return EFI_OUT_OF_RESOURCES;
762 }
763
764 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
765 NewLoadContext->Deleted = FALSE;
766 NewLoadContext->LoadOptionSize = BufferSize;
767 Ptr = (UINT8 *) Buffer;
768 NewLoadContext->LoadOption = Ptr;
769 *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
770 NewLoadContext->Attributes = *((UINT32 *) Ptr);
771 NewLoadContext->IsActive = TRUE;
772 NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
773
774 Ptr += sizeof (UINT32);
775 *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
776 NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
777 Ptr += sizeof (UINT16);
778
779 CopyMem (
780 Ptr,
781 NvRamMap->DescriptionData,
782 StrSize (NvRamMap->DescriptionData)
783 );
784
785 NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->DescriptionData));
786 ASSERT (NewLoadContext->Description != NULL);
787
788 NewMenuEntry->DisplayString = NewLoadContext->Description;
789 CopyMem (
790 NewLoadContext->Description,
791 (VOID *) Ptr,
792 StrSize (NvRamMap->DescriptionData)
793 );
794
795 Ptr += StrSize (NvRamMap->DescriptionData);
796 CopyMem (
797 Ptr,
798 CallbackData->LoadContext->FilePathList,
799 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
800 );
801
802 NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
803 ASSERT (NewLoadContext->FilePathList != NULL);
804
805 CopyMem (
806 NewLoadContext->FilePathList,
807 (VOID *) Ptr,
808 GetDevicePathSize (CallbackData->LoadContext->FilePathList)
809 );
810
811 NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);
812 NewMenuEntry->OptionNumber = Index;
813 NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
814 CallbackData,
815 BootOptionStrDepository
816 );
817 NewMenuEntry->DisplayStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->DisplayString, NULL);
818
819 NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
820 CallbackData,
821 BootOptionHelpStrDepository
822 );
823 NewMenuEntry->HelpStringToken = HiiSetString (CallbackData->FeHiiHandle, 0, NewMenuEntry->HelpString, NULL);
824
825 if (OptionalDataExist) {
826 Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
827
828 CopyMem (Ptr, NvRamMap->OptionalData, StrSize (NvRamMap->OptionalData));
829 }
830
831 Status = gRT->SetVariable (
832 BootString,
833 &gEfiGlobalVariableGuid,
834 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
835 BufferSize,
836 Buffer
837 );
838 ASSERT_EFI_ERROR (Status);
839
840 BootOrderList = BdsLibGetVariableAndSize (
841 L"BootOrder",
842 &gEfiGlobalVariableGuid,
843 &BootOrderListSize
844 );
845 ASSERT (BootOrderList != NULL);
846 NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16));
847 ASSERT (NewBootOrderList != NULL);
848 CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);
849 NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;
850
851 if (BootOrderList != NULL) {
852 FreePool (BootOrderList);
853 }
854
855 Status = gRT->SetVariable (
856 L"BootOrder",
857 &gEfiGlobalVariableGuid,
858 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
859 BootOrderListSize + sizeof (UINT16),
860 NewBootOrderList
861 );
862 ASSERT_EFI_ERROR (Status);
863
864 FreePool (NewBootOrderList);
865 NewBootOrderList = NULL;
866 InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
867 BootOptionMenu.MenuNumber++;
868
869 NvRamMap->DescriptionData[0] = 0x0000;
870 NvRamMap->OptionalData[0] = 0x0000;
871 return EFI_SUCCESS;
872 }
873
874 /**
875 This function update the "BootNext" EFI Variable. If there is
876 no "BootNext" specified in BMM, this EFI Variable is deleted.
877 It also update the BMM context data specified the "BootNext"
878 vaule.
879
880 @param CallbackData The BMM context data.
881
882 @retval EFI_SUCCESS The function complete successfully.
883 @return The EFI variable can be saved. See gRT->SetVariable
884 for detail return information.
885
886 **/
887 EFI_STATUS
888 Var_UpdateBootNext (
889 IN BMM_CALLBACK_DATA *CallbackData
890 )
891 {
892 BM_MENU_ENTRY *NewMenuEntry;
893 BM_LOAD_CONTEXT *NewLoadContext;
894 BMM_FAKE_NV_DATA *CurrentFakeNVMap;
895 UINT16 Index;
896 EFI_STATUS Status;
897
898 Status = EFI_SUCCESS;
899 CurrentFakeNVMap = &CallbackData->BmmFakeNvData;
900 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
901 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
902 ASSERT (NULL != NewMenuEntry);
903
904 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
905 NewLoadContext->IsBootNext = FALSE;
906 }
907
908 if (CurrentFakeNVMap->BootNext == BootOptionMenu.MenuNumber) {
909 EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
910 return EFI_SUCCESS;
911 }
912
913 NewMenuEntry = BOpt_GetMenuEntry (
914 &BootOptionMenu,
915 CurrentFakeNVMap->BootNext
916 );
917 ASSERT (NewMenuEntry != NULL);
918
919 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
920 Status = gRT->SetVariable (
921 L"BootNext",
922 &gEfiGlobalVariableGuid,
923 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
924 sizeof (UINT16),
925 &NewMenuEntry->OptionNumber
926 );
927 NewLoadContext->IsBootNext = TRUE;
928 CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;
929 return Status;
930 }
931
932 /**
933 This function update the "BootOrder" EFI Variable based on
934 BMM Formset's NV map. It then refresh BootOptionMenu
935 with the new "BootOrder" list.
936
937 @param CallbackData The BMM context data.
938
939 @retval EFI_SUCCESS The function complete successfully.
940 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
941 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
942
943 **/
944 EFI_STATUS
945 Var_UpdateBootOrder (
946 IN BMM_CALLBACK_DATA *CallbackData
947 )
948 {
949 EFI_STATUS Status;
950 UINT16 Index;
951 UINT16 OrderIndex;
952 UINT16 *BootOrderList;
953 UINTN BootOrderListSize;
954 UINT16 OptionNumber;
955
956 BootOrderList = NULL;
957 BootOrderListSize = 0;
958
959 //
960 // First check whether BootOrder is present in current configuration
961 //
962 BootOrderList = BdsLibGetVariableAndSize (
963 L"BootOrder",
964 &gEfiGlobalVariableGuid,
965 &BootOrderListSize
966 );
967 if (BootOrderList == NULL) {
968 return EFI_OUT_OF_RESOURCES;
969 }
970
971 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.OptionOrder) / sizeof (CallbackData->BmmFakeNvData.OptionOrder[0])));
972
973 for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.OptionOrder[OrderIndex] != 0); OrderIndex++) {
974 for (Index = OrderIndex; Index < BootOrderListSize / sizeof (UINT16); Index++) {
975 if ((BootOrderList[Index] == (UINT16) (CallbackData->BmmFakeNvData.OptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) {
976 OptionNumber = BootOrderList[Index];
977 CopyMem (&BootOrderList[OrderIndex + 1], &BootOrderList[OrderIndex], (Index - OrderIndex) * sizeof (UINT16));
978 BootOrderList[OrderIndex] = OptionNumber;
979 }
980 }
981 }
982
983 Status = gRT->SetVariable (
984 L"BootOrder",
985 &gEfiGlobalVariableGuid,
986 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
987 BootOrderListSize,
988 BootOrderList
989 );
990 FreePool (BootOrderList);
991
992 GroupMultipleLegacyBootOption4SameType ();
993
994 BOpt_FreeMenu (&BootOptionMenu);
995 BOpt_GetBootOptions (CallbackData);
996
997 return Status;
998
999 }
1000
1001 /**
1002 This function update the "DriverOrder" EFI Variable based on
1003 BMM Formset's NV map. It then refresh DriverOptionMenu
1004 with the new "DriverOrder" list.
1005
1006 @param CallbackData The BMM context data.
1007
1008 @retval EFI_SUCCESS The function complete successfully.
1009 @retval EFI_OUT_OF_RESOURCES Not enough memory to complete the function.
1010 @return The EFI variable can not be saved. See gRT->SetVariable for detail return information.
1011
1012 **/
1013 EFI_STATUS
1014 Var_UpdateDriverOrder (
1015 IN BMM_CALLBACK_DATA *CallbackData
1016 )
1017 {
1018 EFI_STATUS Status;
1019 UINT16 Index;
1020 UINT16 *DriverOrderList;
1021 UINT16 *NewDriverOrderList;
1022 UINTN DriverOrderListSize;
1023
1024 DriverOrderList = NULL;
1025 DriverOrderListSize = 0;
1026
1027 //
1028 // First check whether DriverOrder is present in current configuration
1029 //
1030 DriverOrderList = BdsLibGetVariableAndSize (
1031 L"DriverOrder",
1032 &gEfiGlobalVariableGuid,
1033 &DriverOrderListSize
1034 );
1035
1036 NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);
1037
1038 if (NewDriverOrderList == NULL) {
1039 return EFI_OUT_OF_RESOURCES;
1040 }
1041 //
1042 // If exists, delete it to hold new DriverOrder
1043 //
1044 if (DriverOrderList != NULL) {
1045 EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
1046 FreePool (DriverOrderList);
1047 }
1048
1049 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.OptionOrder) / sizeof (CallbackData->BmmFakeNvData.OptionOrder[0])));
1050 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
1051 NewDriverOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.OptionOrder[Index] - 1);
1052 }
1053
1054 Status = gRT->SetVariable (
1055 L"DriverOrder",
1056 &gEfiGlobalVariableGuid,
1057 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
1058 DriverOrderListSize,
1059 NewDriverOrderList
1060 );
1061 if (EFI_ERROR (Status)) {
1062 return Status;
1063 }
1064
1065 BOpt_FreeMenu (&DriverOptionMenu);
1066 BOpt_GetDriverOptions (CallbackData);
1067 return EFI_SUCCESS;
1068 }
1069
1070 /**
1071 Update the legacy BBS boot option. VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid EFI Variable
1072 is udpated with the new Legacy Boot order. The EFI Variable of "Boot####" and gEfiGlobalVariableGuid
1073 is also updated.
1074
1075 @param CallbackData The context data for BMM.
1076
1077 @return EFI_SUCCESS The function completed successfully.
1078 @retval EFI_NOT_FOUND If VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid EFI Variable can be found.
1079 @retval EFI_OUT_OF_RESOURCES Fail to allocate memory resource
1080 **/
1081 EFI_STATUS
1082 Var_UpdateBBSOption (
1083 IN BMM_CALLBACK_DATA *CallbackData
1084 )
1085 {
1086 UINTN Index;
1087 UINTN Index2;
1088 VOID *BootOptionVar;
1089 CHAR16 VarName[100];
1090 UINTN OptionSize;
1091 EFI_STATUS Status;
1092 UINT32 *Attribute;
1093 BM_MENU_OPTION *OptionMenu;
1094 UINT8 *LegacyDev;
1095 UINT8 *VarData;
1096 UINTN VarSize;
1097 LEGACY_DEV_ORDER_ENTRY *DevOrder;
1098 UINT8 *OriginalPtr;
1099 UINT8 *DisMap;
1100 UINTN Pos;
1101 UINTN Bit;
1102 UINT16 *NewOrder;
1103 UINT16 Tmp;
1104 UINT16 *EnBootOption;
1105 UINTN EnBootOptionCount;
1106 UINT16 *DisBootOption;
1107 UINTN DisBootOptionCount;
1108
1109 DisMap = NULL;
1110 NewOrder = NULL;
1111
1112 switch (CallbackData->BmmPreviousPageId) {
1113 case FORM_SET_FD_ORDER_ID:
1114 OptionMenu = (BM_MENU_OPTION *) &LegacyFDMenu;
1115 LegacyDev = CallbackData->BmmFakeNvData.LegacyFD;
1116 CallbackData->BbsType = BBS_FLOPPY;
1117 break;
1118
1119 case FORM_SET_HD_ORDER_ID:
1120 OptionMenu = (BM_MENU_OPTION *) &LegacyHDMenu;
1121 LegacyDev = CallbackData->BmmFakeNvData.LegacyHD;
1122 CallbackData->BbsType = BBS_HARDDISK;
1123 break;
1124
1125 case FORM_SET_CD_ORDER_ID:
1126 OptionMenu = (BM_MENU_OPTION *) &LegacyCDMenu;
1127 LegacyDev = CallbackData->BmmFakeNvData.LegacyCD;
1128 CallbackData->BbsType = BBS_CDROM;
1129 break;
1130
1131 case FORM_SET_NET_ORDER_ID:
1132 OptionMenu = (BM_MENU_OPTION *) &LegacyNETMenu;
1133 LegacyDev = CallbackData->BmmFakeNvData.LegacyNET;
1134 CallbackData->BbsType = BBS_EMBED_NETWORK;
1135 break;
1136
1137 default:
1138 ASSERT (FORM_SET_BEV_ORDER_ID == CallbackData->BmmPreviousPageId);
1139 OptionMenu = (BM_MENU_OPTION *) &LegacyBEVMenu;
1140 LegacyDev = CallbackData->BmmFakeNvData.LegacyBEV;
1141 CallbackData->BbsType = BBS_BEV_DEVICE;
1142 break;
1143 }
1144
1145 DisMap = CallbackData->BmmOldFakeNVData.DisableMap;
1146 Status = EFI_SUCCESS;
1147
1148
1149 //
1150 // Update the Variable "LegacyDevOrder"
1151 //
1152 VarData = (UINT8 *) BdsLibGetVariableAndSize (
1153 VAR_LEGACY_DEV_ORDER,
1154 &gEfiLegacyDevOrderVariableGuid,
1155 &VarSize
1156 );
1157
1158 if (VarData == NULL) {
1159 return EFI_NOT_FOUND;
1160 }
1161
1162 OriginalPtr = VarData;
1163 DevOrder = (LEGACY_DEV_ORDER_ENTRY *) VarData;
1164
1165 while (VarData < OriginalPtr + VarSize) {
1166 if (DevOrder->BbsType == CallbackData->BbsType) {
1167 break;
1168 }
1169
1170 VarData += sizeof (BBS_TYPE) + DevOrder->Length;
1171 DevOrder = (LEGACY_DEV_ORDER_ENTRY *) VarData;
1172 }
1173
1174 if (VarData >= OriginalPtr + VarSize) {
1175 FreePool (OriginalPtr);
1176 return EFI_NOT_FOUND;
1177 }
1178
1179 NewOrder = AllocateZeroPool (DevOrder->Length - sizeof (DevOrder->Length));
1180 if (NewOrder == NULL) {
1181 FreePool (OriginalPtr);
1182 return EFI_OUT_OF_RESOURCES;
1183 }
1184
1185 for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
1186 if (0xFF == LegacyDev[Index]) {
1187 break;
1188 }
1189
1190 NewOrder[Index] = LegacyDev[Index];
1191 }
1192 //
1193 // Only the enable/disable state of each boot device with same device type can be changed,
1194 // so we can count on the index information in DevOrder.
1195 // DisMap bit array is the only reliable source to check a device's en/dis state,
1196 // so we use DisMap to set en/dis state of each item in NewOrder array
1197 //
1198 for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {
1199 Tmp = (UINT16) (DevOrder->Data[Index2] & 0xFF);
1200 Pos = Tmp / 8;
1201 Bit = 7 - (Tmp % 8);
1202 if ((DisMap[Pos] & (1 << Bit)) != 0) {
1203 NewOrder[Index] = (UINT16) (0xFF00 | Tmp);
1204 Index++;
1205 }
1206 }
1207
1208 CopyMem (
1209 DevOrder->Data,
1210 NewOrder,
1211 DevOrder->Length - sizeof (DevOrder->Length)
1212 );
1213 FreePool (NewOrder);
1214
1215 Status = gRT->SetVariable (
1216 VAR_LEGACY_DEV_ORDER,
1217 &gEfiLegacyDevOrderVariableGuid,
1218 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
1219 VarSize,
1220 OriginalPtr
1221 );
1222
1223
1224 //
1225 // Update BootOrder and Boot####.Attribute
1226 //
1227 // 1. Re-order the Option Number in BootOrder according to Legacy Dev Order
1228 //
1229 ASSERT (OptionMenu->MenuNumber == DevOrder->Length / sizeof (UINT16) - 1);
1230
1231 OrderLegacyBootOption4SameType (
1232 DevOrder->Data,
1233 DevOrder->Length / sizeof (UINT16) - 1,
1234 &EnBootOption,
1235 &EnBootOptionCount,
1236 &DisBootOption,
1237 &DisBootOptionCount
1238 );
1239
1240 //
1241 // 2. Deactivate the DisBootOption and activate the EnBootOption
1242 //
1243 for (Index = 0; Index < DisBootOptionCount; Index++) {
1244 UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", DisBootOption[Index]);
1245 BootOptionVar = BdsLibGetVariableAndSize (
1246 VarName,
1247 &gEfiGlobalVariableGuid,
1248 &OptionSize
1249 );
1250 if (BootOptionVar != NULL) {
1251 Attribute = (UINT32 *) BootOptionVar;
1252 *Attribute &= ~LOAD_OPTION_ACTIVE;
1253
1254 Status = gRT->SetVariable (
1255 VarName,
1256 &gEfiGlobalVariableGuid,
1257 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
1258 OptionSize,
1259 BootOptionVar
1260 );
1261
1262 FreePool (BootOptionVar);
1263 }
1264 }
1265
1266 for (Index = 0; Index < EnBootOptionCount; Index++) {
1267 UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", EnBootOption[Index]);
1268 BootOptionVar = BdsLibGetVariableAndSize (
1269 VarName,
1270 &gEfiGlobalVariableGuid,
1271 &OptionSize
1272 );
1273 if (BootOptionVar != NULL) {
1274 Attribute = (UINT32 *) BootOptionVar;
1275 *Attribute |= LOAD_OPTION_ACTIVE;
1276
1277 Status = gRT->SetVariable (
1278 VarName,
1279 &gEfiGlobalVariableGuid,
1280 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
1281 OptionSize,
1282 BootOptionVar
1283 );
1284
1285 FreePool (BootOptionVar);
1286 }
1287 }
1288
1289 BOpt_GetBootOptions (CallbackData);
1290
1291 FreePool (OriginalPtr);
1292 FreePool (EnBootOption);
1293 FreePool (DisBootOption);
1294 return Status;
1295 }
1296
1297 /**
1298 Update the Text Mode of Console.
1299
1300 @param CallbackData The context data for BMM.
1301
1302 @retval EFI_SUCCSS If the Text Mode of Console is updated.
1303 @return Other value if the Text Mode of Console is not updated.
1304
1305 **/
1306 EFI_STATUS
1307 Var_UpdateConMode (
1308 IN BMM_CALLBACK_DATA *CallbackData
1309 )
1310 {
1311 EFI_STATUS Status;
1312 UINTN Mode;
1313 CONSOLE_OUT_MODE ModeInfo;
1314
1315 Mode = CallbackData->BmmFakeNvData.ConsoleOutMode;
1316
1317 Status = gST->ConOut->QueryMode (gST->ConOut, Mode, &(ModeInfo.Column), &(ModeInfo.Row));
1318 if (!EFI_ERROR(Status)) {
1319 PcdSet32 (PcdSetupConOutColumn, (UINT32) ModeInfo.Column);
1320 PcdSet32 (PcdSetupConOutRow, (UINT32) ModeInfo.Row);
1321 }
1322
1323 return EFI_SUCCESS;
1324 }