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