VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/Csm/LegacyBootMaintUiLib/LegacyBootMaintUi.c@ 105254

最後變更 在這個檔案從105254是 99404,由 vboxsync 提交於 23 月 前

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 46.0 KB
 
1/** @file
2 Legacy Boot Maintenance UI implementation.
3
4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5(C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
6SPDX-License-Identifier: BSD-2-Clause-Patent
7
8**/
9
10#include "LegacyBootMaintUi.h"
11
12LEGACY_BOOT_OPTION_CALLBACK_DATA *mLegacyBootOptionPrivate = NULL;
13EFI_GUID mLegacyBootOptionGuid = LEGACY_BOOT_OPTION_FORMSET_GUID;
14CHAR16 mLegacyBootStorageName[] = L"LegacyBootData";
15BBS_TYPE mBbsType[] = { BBS_FLOPPY, BBS_HARDDISK, BBS_CDROM, BBS_EMBED_NETWORK, BBS_BEV_DEVICE, BBS_UNKNOWN };
16BOOLEAN mFirstEnterLegacyForm = FALSE;
17
18///
19/// Legacy FD Info from LegacyBios.GetBbsInfo()
20///
21LEGACY_MENU_OPTION LegacyFDMenu = {
22 LEGACY_MENU_OPTION_SIGNATURE,
23 { NULL },
24 0
25};
26
27///
28/// Legacy HD Info from LegacyBios.GetBbsInfo()
29///
30LEGACY_MENU_OPTION LegacyHDMenu = {
31 LEGACY_MENU_OPTION_SIGNATURE,
32 { NULL },
33 0
34};
35
36///
37/// Legacy CD Info from LegacyBios.GetBbsInfo()
38///
39LEGACY_MENU_OPTION LegacyCDMenu = {
40 LEGACY_MENU_OPTION_SIGNATURE,
41 { NULL },
42 0
43};
44
45///
46/// Legacy NET Info from LegacyBios.GetBbsInfo()
47///
48LEGACY_MENU_OPTION LegacyNETMenu = {
49 LEGACY_MENU_OPTION_SIGNATURE,
50 { NULL },
51 0
52};
53
54///
55/// Legacy NET Info from LegacyBios.GetBbsInfo()
56///
57LEGACY_MENU_OPTION LegacyBEVMenu = {
58 LEGACY_MENU_OPTION_SIGNATURE,
59 { NULL },
60 0
61};
62
63VOID *mLegacyStartOpCodeHandle = NULL;
64VOID *mLegacyEndOpCodeHandle = NULL;
65EFI_IFR_GUID_LABEL *mLegacyStartLabel = NULL;
66EFI_IFR_GUID_LABEL *mLegacyEndLabel = NULL;
67
68HII_VENDOR_DEVICE_PATH mLegacyBootOptionHiiVendorDevicePath = {
69 {
70 {
71 HARDWARE_DEVICE_PATH,
72 HW_VENDOR_DP,
73 {
74 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
75 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
76 }
77 },
78 { 0x6bc75598, 0x89b4, 0x483d, { 0x91, 0x60, 0x7f, 0x46, 0x9a, 0x96, 0x35, 0x31 }
79 }
80 },
81 {
82 END_DEVICE_PATH_TYPE,
83 END_ENTIRE_DEVICE_PATH_SUBTYPE,
84 {
85 (UINT8)(END_DEVICE_PATH_LENGTH),
86 (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
87 }
88 }
89};
90
91/**
92
93 Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().
94
95**/
96VOID
97GetLegacyOptions (
98 VOID
99 );
100
101/**
102
103 Base on the L"LegacyDevOrder" variable to build the current order data.
104
105**/
106VOID
107GetLegacyOptionsOrder (
108 VOID
109 );
110
111/**
112 Re-order the Boot Option according to the DevOrder.
113
114 The routine re-orders the Boot Option in BootOption array according to
115 the order specified by DevOrder.
116
117 @param DevOrder Pointer to buffer containing the BBS Index,
118 high 8-bit value 0xFF indicating a disabled boot option
119 @param DevOrderCount Count of the BBS Index
120 @param EnBootOption Callee allocated buffer containing the enabled Boot Option Numbers
121 @param EnBootOptionCount Count of the enabled Boot Option Numbers
122 @param DisBootOption Callee allocated buffer containing the disabled Boot Option Numbers
123 @param DisBootOptionCount Count of the disabled Boot Option Numbers
124
125 @return EFI_SUCCESS The function completed successfully.
126 @retval other Contain some error, details see the status return by gRT->SetVariable.
127**/
128EFI_STATUS
129OrderLegacyBootOption4SameType (
130 UINT16 *DevOrder,
131 UINTN DevOrderCount,
132 UINT16 **EnBootOption,
133 UINTN *EnBootOptionCount,
134 UINT16 **DisBootOption,
135 UINTN *DisBootOptionCount
136 )
137{
138 EFI_STATUS Status;
139 UINT16 *NewBootOption;
140 UINT16 *BootOrder;
141 UINTN BootOrderSize;
142 UINTN Index;
143 UINTN StartPosition;
144
145 EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
146
147 CHAR16 OptionName[sizeof ("Boot####")];
148 UINT16 *BbsIndexArray;
149 UINT16 *DeviceTypeArray;
150
151 GetEfiGlobalVariable2 (L"BootOrder", (VOID **)&BootOrder, &BootOrderSize);
152 ASSERT (BootOrder != NULL);
153
154 BbsIndexArray = AllocatePool (BootOrderSize);
155 DeviceTypeArray = AllocatePool (BootOrderSize);
156 *EnBootOption = AllocatePool (BootOrderSize);
157 *DisBootOption = AllocatePool (BootOrderSize);
158 *DisBootOptionCount = 0;
159 *EnBootOptionCount = 0;
160 Index = 0;
161 Status = EFI_SUCCESS;
162
163 ASSERT (BbsIndexArray != NULL);
164 ASSERT (DeviceTypeArray != NULL);
165 ASSERT (*EnBootOption != NULL);
166 ASSERT (*DisBootOption != NULL);
167
168 for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
169 UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder[Index]);
170 Status = EfiBootManagerVariableToLoadOption (OptionName, &BootOption);
171 ASSERT_EFI_ERROR (Status);
172
173 if ((DevicePathType (BootOption.FilePath) == BBS_DEVICE_PATH) &&
174 (DevicePathSubType (BootOption.FilePath) == BBS_BBS_DP))
175 {
176 //
177 // Legacy Boot Option
178 //
179 ASSERT (BootOption.OptionalDataSize == sizeof (LEGACY_BOOT_OPTION_BBS_DATA));
180
181 DeviceTypeArray[Index] = ((BBS_BBS_DEVICE_PATH *)BootOption.FilePath)->DeviceType;
182 BbsIndexArray[Index] = ((LEGACY_BOOT_OPTION_BBS_DATA *)BootOption.OptionalData)->BbsIndex;
183 } else {
184 DeviceTypeArray[Index] = BBS_TYPE_UNKNOWN;
185 BbsIndexArray[Index] = 0xFFFF;
186 }
187
188 EfiBootManagerFreeLoadOption (&BootOption);
189 }
190
191 //
192 // Record the corresponding Boot Option Numbers according to the DevOrder
193 // Record the EnBootOption and DisBootOption according to the DevOrder
194 //
195 StartPosition = BootOrderSize / sizeof (UINT16);
196 NewBootOption = AllocatePool (DevOrderCount * sizeof (UINT16));
197 ASSERT (NewBootOption != NULL);
198 while (DevOrderCount-- != 0) {
199 for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) {
200 if (BbsIndexArray[Index] == (DevOrder[DevOrderCount] & 0xFF)) {
201 StartPosition = MIN (StartPosition, Index);
202 NewBootOption[DevOrderCount] = BootOrder[Index];
203
204 if ((DevOrder[DevOrderCount] & 0xFF00) == 0xFF00) {
205 (*DisBootOption)[*DisBootOptionCount] = BootOrder[Index];
206 (*DisBootOptionCount)++;
207 } else {
208 (*EnBootOption)[*EnBootOptionCount] = BootOrder[Index];
209 (*EnBootOptionCount)++;
210 }
211
212 break;
213 }
214 }
215 }
216
217 //
218 // Overwrite the old BootOption
219 //
220 CopyMem (&BootOrder[StartPosition], NewBootOption, (*DisBootOptionCount + *EnBootOptionCount) * sizeof (UINT16));
221 Status = gRT->SetVariable (
222 L"BootOrder",
223 &gEfiGlobalVariableGuid,
224 VAR_FLAG,
225 BootOrderSize,
226 BootOrder
227 );
228
229 FreePool (NewBootOption);
230 FreePool (DeviceTypeArray);
231 FreePool (BbsIndexArray);
232
233 return Status;
234}
235
236/**
237 Update the legacy BBS boot option. L"LegacyDevOrder" and gEfiLegacyDevOrderVariableGuid EFI Variable
238 is updated with the new Legacy Boot order. The EFI Variable of "Boot####" and gEfiGlobalVariableGuid
239 is also updated.
240
241 @param NVMapData The data for legacy BBS boot.
242
243 @return EFI_SUCCESS The function completed successfully.
244 @retval EFI_NOT_FOUND If L"LegacyDevOrder" and gEfiLegacyDevOrderVariableGuid EFI Variable can not be found.
245 @retval EFI_OUT_OF_RESOURCES Fail to allocate memory resource
246 @retval other Contain some error, details see the status return by gRT->SetVariable.
247**/
248EFI_STATUS
249UpdateBBSOption (
250 IN LEGACY_BOOT_NV_DATA *NVMapData
251 )
252{
253 UINTN Index;
254 UINTN Index2;
255 UINTN CurrentType;
256 VOID *BootOptionVar;
257 CHAR16 VarName[100];
258 UINTN OptionSize;
259 EFI_STATUS Status;
260 UINT32 *Attribute;
261 LEGACY_MENU_OPTION *OptionMenu;
262 UINT16 *LegacyDev;
263 UINT16 *InitialLegacyDev;
264 UINT8 *VarData;
265 UINTN VarSize;
266 LEGACY_DEV_ORDER_ENTRY *DevOrder;
267 UINT8 *OriginalPtr;
268 UINT8 *DisMap;
269 UINTN Pos;
270 UINTN Bit;
271 UINT16 *NewOrder;
272 UINT16 Tmp;
273 UINT16 *EnBootOption;
274 UINTN EnBootOptionCount;
275 UINT16 *DisBootOption;
276 UINTN DisBootOptionCount;
277 UINTN BufferSize;
278
279 DisMap = NULL;
280 NewOrder = NULL;
281 CurrentType = 0;
282 EnBootOption = NULL;
283 DisBootOption = NULL;
284
285 DisMap = mLegacyBootOptionPrivate->MaintainMapData->DisableMap;
286 Status = EFI_SUCCESS;
287
288 //
289 // Update the Variable "LegacyDevOrder"
290 //
291 GetVariable2 (VAR_LEGACY_DEV_ORDER, &gEfiLegacyDevOrderVariableGuid, (VOID **)&VarData, &VarSize);
292 if (VarData == NULL) {
293 return EFI_NOT_FOUND;
294 }
295
296 OriginalPtr = VarData;
297
298 while (mBbsType[CurrentType] != BBS_UNKNOWN) {
299 switch (mBbsType[CurrentType]) {
300 case BBS_FLOPPY:
301 OptionMenu = (LEGACY_MENU_OPTION *)&LegacyFDMenu;
302 LegacyDev = NVMapData->LegacyFD;
303 InitialLegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyFD;
304 BufferSize = sizeof (NVMapData->LegacyFD);
305 break;
306
307 case BBS_HARDDISK:
308 OptionMenu = (LEGACY_MENU_OPTION *)&LegacyHDMenu;
309 LegacyDev = NVMapData->LegacyHD;
310 InitialLegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyHD;
311
312 BufferSize = sizeof (NVMapData->LegacyHD);
313 break;
314
315 case BBS_CDROM:
316 OptionMenu = (LEGACY_MENU_OPTION *)&LegacyCDMenu;
317 LegacyDev = NVMapData->LegacyCD;
318 InitialLegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyCD;
319 BufferSize = sizeof (NVMapData->LegacyCD);
320 break;
321
322 case BBS_EMBED_NETWORK:
323 OptionMenu = (LEGACY_MENU_OPTION *)&LegacyNETMenu;
324 LegacyDev = NVMapData->LegacyNET;
325 InitialLegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyNET;
326 BufferSize = sizeof (NVMapData->LegacyNET);
327 break;
328
329 default:
330 ASSERT (mBbsType[CurrentType] == BBS_BEV_DEVICE);
331 OptionMenu = (LEGACY_MENU_OPTION *)&LegacyBEVMenu;
332 LegacyDev = NVMapData->LegacyBEV;
333 InitialLegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyBEV;
334 BufferSize = sizeof (NVMapData->LegacyBEV);
335 break;
336 }
337
338 //
339 // Check whether has value changed.
340 //
341 if (CompareMem (LegacyDev, InitialLegacyDev, BufferSize) == 0) {
342 CurrentType++;
343 continue;
344 }
345
346 DevOrder = (LEGACY_DEV_ORDER_ENTRY *)OriginalPtr;
347 while (VarData < OriginalPtr + VarSize) {
348 if (DevOrder->BbsType == mBbsType[CurrentType]) {
349 break;
350 }
351
352 VarData += sizeof (BBS_TYPE) + DevOrder->Length;
353 DevOrder = (LEGACY_DEV_ORDER_ENTRY *)VarData;
354 }
355
356 if (VarData >= OriginalPtr + VarSize) {
357 FreePool (OriginalPtr);
358 return EFI_NOT_FOUND;
359 }
360
361 NewOrder = AllocateZeroPool (DevOrder->Length - sizeof (DevOrder->Length));
362 if (NewOrder == NULL) {
363 FreePool (OriginalPtr);
364 return EFI_OUT_OF_RESOURCES;
365 }
366
367 for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
368 if (0xFF == LegacyDev[Index]) {
369 break;
370 }
371
372 NewOrder[Index] = LegacyDev[Index];
373 }
374
375 //
376 // Only the enable/disable state of each boot device with same device type can be changed,
377 // so we can count on the index information in DevOrder.
378 // DisMap bit array is the only reliable source to check a device's en/dis state,
379 // so we use DisMap to set en/dis state of each item in NewOrder array
380 //
381 for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {
382 Tmp = (UINT16)(DevOrder->Data[Index2] & 0xFF);
383 Pos = Tmp / 8;
384 Bit = 7 - (Tmp % 8);
385 if ((DisMap[Pos] & (1 << Bit)) != 0) {
386 NewOrder[Index] = (UINT16)(0xFF00 | Tmp);
387 Index++;
388 }
389 }
390
391 CopyMem (
392 DevOrder->Data,
393 NewOrder,
394 DevOrder->Length - sizeof (DevOrder->Length)
395 );
396 FreePool (NewOrder);
397
398 //
399 // Update BootOrder and Boot####.Attribute
400 //
401 // 1. Re-order the Option Number in BootOrder according to Legacy Dev Order
402 //
403 ASSERT (OptionMenu->MenuNumber == DevOrder->Length / sizeof (UINT16) - 1);
404
405 Status = OrderLegacyBootOption4SameType (
406 DevOrder->Data,
407 DevOrder->Length / sizeof (UINT16) - 1,
408 &EnBootOption,
409 &EnBootOptionCount,
410 &DisBootOption,
411 &DisBootOptionCount
412 );
413 if (EFI_ERROR (Status)) {
414 goto Fail;
415 }
416
417 //
418 // 2. Deactivate the DisBootOption and activate the EnBootOption
419 //
420 for (Index = 0; Index < DisBootOptionCount; Index++) {
421 UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", DisBootOption[Index]);
422 GetEfiGlobalVariable2 (VarName, (VOID **)&BootOptionVar, &OptionSize);
423 if (BootOptionVar != NULL) {
424 Attribute = (UINT32 *)BootOptionVar;
425 *Attribute &= ~LOAD_OPTION_ACTIVE;
426
427 Status = gRT->SetVariable (
428 VarName,
429 &gEfiGlobalVariableGuid,
430 VAR_FLAG,
431 OptionSize,
432 BootOptionVar
433 );
434
435 FreePool (BootOptionVar);
436 }
437 }
438
439 for (Index = 0; Index < EnBootOptionCount; Index++) {
440 UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", EnBootOption[Index]);
441 GetEfiGlobalVariable2 (VarName, (VOID **)&BootOptionVar, &OptionSize);
442 if (BootOptionVar != NULL) {
443 Attribute = (UINT32 *)BootOptionVar;
444 *Attribute |= LOAD_OPTION_ACTIVE;
445
446 Status = gRT->SetVariable (
447 VarName,
448 &gEfiGlobalVariableGuid,
449 VAR_FLAG,
450 OptionSize,
451 BootOptionVar
452 );
453
454 FreePool (BootOptionVar);
455 }
456 }
457
458 FreePool (EnBootOption);
459 FreePool (DisBootOption);
460
461 CurrentType++;
462 }
463
464 Status = gRT->SetVariable (
465 VAR_LEGACY_DEV_ORDER,
466 &gEfiLegacyDevOrderVariableGuid,
467 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
468 VarSize,
469 OriginalPtr
470 );
471
472Fail:
473 if (EnBootOption != NULL) {
474 FreePool (EnBootOption);
475 }
476
477 if (DisBootOption != NULL) {
478 FreePool (DisBootOption);
479 }
480
481 FreePool (OriginalPtr);
482 return Status;
483}
484
485/**
486 This function allows a caller to extract the current configuration for one
487 or more named elements from the target driver.
488
489
490 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
491 @param Request A null-terminated Unicode string in <ConfigRequest> format.
492 @param Progress On return, points to a character in the Request string.
493 Points to the string's null terminator if request was successful.
494 Points to the most recent '&' before the first failing name/value
495 pair (or the beginning of the string if the failure is in the
496 first name/value pair) if the request was not successful.
497 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
498 has all values filled in for the names in the Request string.
499 String to be allocated by the called function.
500
501 @retval EFI_SUCCESS The Results is filled with the requested values.
502 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
503 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
504 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
505
506**/
507EFI_STATUS
508EFIAPI
509LegacyBootOptionExtractConfig (
510 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
511 IN CONST EFI_STRING Request,
512 OUT EFI_STRING *Progress,
513 OUT EFI_STRING *Results
514 )
515{
516 if ((Progress == NULL) || (Results == NULL)) {
517 return EFI_INVALID_PARAMETER;
518 }
519
520 *Progress = Request;
521 return EFI_NOT_FOUND;
522}
523
524/**
525 This function processes the results of changes in configuration.
526
527
528 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
529 @param Configuration A null-terminated Unicode string in <ConfigResp> format.
530 @param Progress A pointer to a string filled in with the offset of the most
531 recent '&' before the first failing name/value pair (or the
532 beginning of the string if the failure is in the first
533 name/value pair) or the terminating NULL if all was successful.
534
535 @retval EFI_SUCCESS The Results is processed successfully.
536 @retval EFI_INVALID_PARAMETER Configuration is NULL.
537 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
538
539**/
540EFI_STATUS
541EFIAPI
542LegacyBootOptionRouteConfig (
543 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
544 IN CONST EFI_STRING Configuration,
545 OUT EFI_STRING *Progress
546 )
547{
548 EFI_STATUS Status;
549 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;
550 LEGACY_BOOT_NV_DATA *CurrentNVMapData;
551 UINTN BufferSize;
552
553 if ((Configuration == NULL) || (Progress == NULL)) {
554 return EFI_INVALID_PARAMETER;
555 }
556
557 *Progress = Configuration;
558
559 //
560 // Check routing data in <ConfigHdr>.
561 // Note: there is no name for Name/Value storage, only GUID will be checked
562 //
563 if (!HiiIsConfigHdrMatch (Configuration, &mLegacyBootOptionGuid, mLegacyBootStorageName)) {
564 return EFI_NOT_FOUND;
565 }
566
567 Status = gBS->LocateProtocol (
568 &gEfiHiiConfigRoutingProtocolGuid,
569 NULL,
570 (VOID **)&ConfigRouting
571 );
572 if (EFI_ERROR (Status)) {
573 return Status;
574 }
575
576 //
577 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
578 //
579 CurrentNVMapData = &mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData;
580 Status = ConfigRouting->ConfigToBlock (
581 ConfigRouting,
582 Configuration,
583 (UINT8 *)CurrentNVMapData,
584 &BufferSize,
585 Progress
586 );
587 ASSERT_EFI_ERROR (Status);
588
589 Status = UpdateBBSOption (CurrentNVMapData);
590
591 return Status;
592}
593
594/**
595 Refresh the global UpdateData structure.
596
597**/
598VOID
599RefreshLegacyUpdateData (
600 VOID
601 )
602{
603 //
604 // Free current updated date
605 //
606 if (mLegacyStartOpCodeHandle != NULL) {
607 HiiFreeOpCodeHandle (mLegacyStartOpCodeHandle);
608 }
609
610 if (mLegacyEndOpCodeHandle != NULL) {
611 HiiFreeOpCodeHandle (mLegacyEndOpCodeHandle);
612 }
613
614 //
615 // Create new OpCode Handle
616 //
617 mLegacyStartOpCodeHandle = HiiAllocateOpCodeHandle ();
618 mLegacyEndOpCodeHandle = HiiAllocateOpCodeHandle ();
619
620 //
621 // Create Hii Extend Label OpCode as the start opcode
622 //
623 mLegacyStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
624 mLegacyStartOpCodeHandle,
625 &gEfiIfrTianoGuid,
626 NULL,
627 sizeof (EFI_IFR_GUID_LABEL)
628 );
629 mLegacyStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
630
631 mLegacyStartLabel->Number = FORM_BOOT_LEGACY_DEVICE_ID;
632
633 //
634 // Create Hii Extend Label OpCode as the start opcode
635 //
636 mLegacyEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
637 mLegacyEndOpCodeHandle,
638 &gEfiIfrTianoGuid,
639 NULL,
640 sizeof (EFI_IFR_GUID_LABEL)
641 );
642 mLegacyEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
643
644 mLegacyEndLabel->Number = FORM_BOOT_LEGACY_LABEL_END;
645}
646
647/**
648 Get the Menu Entry from the list in Menu Entry List.
649
650 If MenuNumber is great or equal to the number of Menu
651 Entry in the list, then ASSERT.
652
653 @param MenuOption The Menu Entry List to read the menu entry.
654 @param MenuNumber The index of Menu Entry.
655
656 @return The Menu Entry.
657
658**/
659LEGACY_MENU_ENTRY *
660GetMenuEntry (
661 LEGACY_MENU_OPTION *MenuOption,
662 UINTN MenuNumber
663 )
664{
665 LEGACY_MENU_ENTRY *NewMenuEntry;
666 UINTN Index;
667 LIST_ENTRY *List;
668
669 ASSERT (MenuNumber < MenuOption->MenuNumber);
670
671 List = MenuOption->Head.ForwardLink;
672 for (Index = 0; Index < MenuNumber; Index++) {
673 List = List->ForwardLink;
674 }
675
676 NewMenuEntry = CR (List, LEGACY_MENU_ENTRY, Link, LEGACY_MENU_ENTRY_SIGNATURE);
677
678 return NewMenuEntry;
679}
680
681/**
682 Create string tokens for a menu from its help strings and display strings
683
684 @param HiiHandle Hii Handle of the package to be updated.
685 @param MenuOption The Menu whose string tokens need to be created
686
687**/
688VOID
689CreateLegacyMenuStringToken (
690 IN EFI_HII_HANDLE HiiHandle,
691 IN LEGACY_MENU_OPTION *MenuOption
692 )
693{
694 LEGACY_MENU_ENTRY *NewMenuEntry;
695 UINTN Index;
696
697 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
698 NewMenuEntry = GetMenuEntry (MenuOption, Index);
699
700 NewMenuEntry->DisplayStringToken = HiiSetString (
701 HiiHandle,
702 0,
703 NewMenuEntry->DisplayString,
704 NULL
705 );
706
707 if (NULL == NewMenuEntry->HelpString) {
708 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
709 } else {
710 NewMenuEntry->HelpStringToken = HiiSetString (
711 HiiHandle,
712 0,
713 NewMenuEntry->HelpString,
714 NULL
715 );
716 }
717 }
718}
719
720/**
721 Create a dynamic page so that Legacy Device boot order
722 can be set for specified device type.
723
724 @param UpdatePageId The form ID. It also specifies the legacy device type.
725
726
727**/
728VOID
729UpdateLegacyDeviceOrderPage (
730 IN UINT16 UpdatePageId
731 )
732{
733 LEGACY_MENU_OPTION *OptionMenu;
734 LEGACY_MENU_ENTRY *NewMenuEntry;
735 EFI_STRING_ID StrRef;
736 EFI_STRING_ID StrRefHelp;
737 UINT16 *Default;
738 UINT16 Index;
739 UINT16 Key;
740 CHAR16 String[100];
741 CHAR16 *TypeStr;
742 CHAR16 *TypeStrHelp;
743 CHAR16 *FormTitle;
744 VOID *OptionsOpCodeHandle;
745 VOID *DefaultOpCodeHandle;
746
747 Key = 0;
748 StrRef = 0;
749 StrRefHelp = 0;
750 OptionMenu = NULL;
751 TypeStr = NULL;
752 TypeStrHelp = NULL;
753 Default = NULL;
754
755 RefreshLegacyUpdateData ();
756
757 //
758 // Create oneof option list
759 //
760 switch (UpdatePageId) {
761 case FORM_FLOPPY_BOOT_ID:
762 OptionMenu = (LEGACY_MENU_OPTION *)&LegacyFDMenu;
763 Key = (UINT16)LEGACY_FD_QUESTION_ID;
764 TypeStr = STR_FLOPPY;
765 TypeStrHelp = STR_FLOPPY_HELP;
766 FormTitle = STR_FLOPPY_TITLE;
767 Default = mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData.LegacyFD;
768 break;
769
770 case FORM_HARDDISK_BOOT_ID:
771 OptionMenu = (LEGACY_MENU_OPTION *)&LegacyHDMenu;
772 Key = (UINT16)LEGACY_HD_QUESTION_ID;
773 TypeStr = STR_HARDDISK;
774 TypeStrHelp = STR_HARDDISK_HELP;
775 FormTitle = STR_HARDDISK_TITLE;
776 Default = mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData.LegacyHD;
777 break;
778
779 case FORM_CDROM_BOOT_ID:
780 OptionMenu = (LEGACY_MENU_OPTION *)&LegacyCDMenu;
781 Key = (UINT16)LEGACY_CD_QUESTION_ID;
782 TypeStr = STR_CDROM;
783 TypeStrHelp = STR_CDROM_HELP;
784 FormTitle = STR_CDROM_TITLE;
785 Default = mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData.LegacyCD;
786 break;
787
788 case FORM_NET_BOOT_ID:
789 OptionMenu = (LEGACY_MENU_OPTION *)&LegacyNETMenu;
790 Key = (UINT16)LEGACY_NET_QUESTION_ID;
791 TypeStr = STR_NET;
792 TypeStrHelp = STR_NET_HELP;
793 FormTitle = STR_NET_TITLE;
794 Default = mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData.LegacyNET;
795 break;
796
797 case FORM_BEV_BOOT_ID:
798 OptionMenu = (LEGACY_MENU_OPTION *)&LegacyBEVMenu;
799 Key = (UINT16)LEGACY_BEV_QUESTION_ID;
800 TypeStr = STR_BEV;
801 TypeStrHelp = STR_BEV_HELP;
802 FormTitle = STR_BEV_TITLE;
803 Default = mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData.LegacyBEV;
804 break;
805
806 default:
807 DEBUG ((DEBUG_ERROR, "Invalid command ID for updating page!\n"));
808 return;
809 }
810
811 HiiSetString (mLegacyBootOptionPrivate->HiiHandle, STRING_TOKEN (STR_ORDER_CHANGE_PROMPT), FormTitle, NULL);
812
813 CreateLegacyMenuStringToken (mLegacyBootOptionPrivate->HiiHandle, OptionMenu);
814
815 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
816 ASSERT (OptionsOpCodeHandle != NULL);
817
818 for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
819 NewMenuEntry = GetMenuEntry (OptionMenu, Index);
820 //
821 // Create OneOf for each legacy device
822 //
823 HiiCreateOneOfOptionOpCode (
824 OptionsOpCodeHandle,
825 NewMenuEntry->DisplayStringToken,
826 0,
827 EFI_IFR_TYPE_NUM_SIZE_16,
828 ((LEGACY_DEVICE_CONTEXT *)NewMenuEntry->VariableContext)->BbsIndex
829 );
830 }
831
832 //
833 // Create OneOf for item "Disabled"
834 //
835 HiiCreateOneOfOptionOpCode (
836 OptionsOpCodeHandle,
837 STRING_TOKEN (STR_DISABLE_LEGACY_DEVICE),
838 0,
839 EFI_IFR_TYPE_NUM_SIZE_16,
840 0xFF
841 );
842
843 //
844 // Create oneof tag here for FD/HD/CD #1 #2
845 //
846 for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
847 DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
848 ASSERT (DefaultOpCodeHandle != NULL);
849
850 HiiCreateDefaultOpCode (
851 DefaultOpCodeHandle,
852 EFI_HII_DEFAULT_CLASS_STANDARD,
853 EFI_IFR_TYPE_NUM_SIZE_16,
854 *Default++
855 );
856
857 //
858 // Create the string for oneof tag
859 //
860 UnicodeSPrint (String, sizeof (String), TypeStr, Index);
861 StrRef = HiiSetString (mLegacyBootOptionPrivate->HiiHandle, 0, String, NULL);
862
863 UnicodeSPrint (String, sizeof (String), TypeStrHelp, Index);
864 StrRefHelp = HiiSetString (mLegacyBootOptionPrivate->HiiHandle, 0, String, NULL);
865
866 HiiCreateOneOfOpCode (
867 mLegacyStartOpCodeHandle,
868 (EFI_QUESTION_ID)(Key + Index),
869 VARSTORE_ID_LEGACY_BOOT,
870 (UINT16)(Key + Index * 2 - CONFIG_OPTION_OFFSET),
871 StrRef,
872 StrRefHelp,
873 EFI_IFR_FLAG_CALLBACK,
874 EFI_IFR_NUMERIC_SIZE_2,
875 OptionsOpCodeHandle,
876 DefaultOpCodeHandle // NULL //
877 );
878
879 HiiFreeOpCodeHandle (DefaultOpCodeHandle);
880 }
881
882 HiiUpdateForm (
883 mLegacyBootOptionPrivate->HiiHandle,
884 &mLegacyBootOptionGuid,
885 LEGACY_ORDER_CHANGE_FORM_ID,
886 mLegacyStartOpCodeHandle,
887 mLegacyEndOpCodeHandle
888 );
889
890 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
891}
892
893/**
894 Adjust question value when one question value has been changed.
895
896 @param QuestionId The question id for the value changed question.
897 @param Value The value for the changed question.
898
899**/
900VOID
901AdjustOptionValue (
902 IN UINT16 QuestionId,
903 IN EFI_IFR_TYPE_VALUE *Value
904 )
905{
906 UINTN Number;
907 UINT16 *Default;
908 LEGACY_BOOT_NV_DATA *CurrentNVMap;
909 UINT16 *CurrentVal;
910 UINTN Index;
911 UINTN Index2;
912 UINTN Index3;
913 UINTN NewValuePos;
914 UINTN OldValue;
915 UINTN NewValue;
916 UINT8 *DisMap;
917 UINTN Pos;
918 UINTN Bit;
919
920 Number = 0;
921 CurrentVal = 0;
922 Default = NULL;
923 NewValue = 0;
924 NewValuePos = 0;
925 OldValue = 0;
926
927 //
928 // Update Select FD/HD/CD/NET/BEV Order Form
929 //
930 ASSERT ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER));
931
932 CurrentNVMap = &mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData;
933 HiiGetBrowserData (&mLegacyBootOptionGuid, mLegacyBootStorageName, sizeof (LEGACY_BOOT_NV_DATA), (UINT8 *)CurrentNVMap);
934 DisMap = mLegacyBootOptionPrivate->MaintainMapData->DisableMap;
935
936 if ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_FD_QUESTION_ID + MAX_MENU_NUMBER)) {
937 Number = (UINT16)LegacyFDMenu.MenuNumber;
938 CurrentVal = CurrentNVMap->LegacyFD;
939 Default = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyFD;
940 } else if ((QuestionId >= LEGACY_HD_QUESTION_ID) && (QuestionId < LEGACY_HD_QUESTION_ID + MAX_MENU_NUMBER)) {
941 Number = (UINT16)LegacyHDMenu.MenuNumber;
942 CurrentVal = CurrentNVMap->LegacyHD;
943 Default = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyHD;
944 } else if ((QuestionId >= LEGACY_CD_QUESTION_ID) && (QuestionId < LEGACY_CD_QUESTION_ID + MAX_MENU_NUMBER)) {
945 Number = (UINT16)LegacyCDMenu.MenuNumber;
946 CurrentVal = CurrentNVMap->LegacyCD;
947 Default = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyCD;
948 } else if ((QuestionId >= LEGACY_NET_QUESTION_ID) && (QuestionId < LEGACY_NET_QUESTION_ID + MAX_MENU_NUMBER)) {
949 Number = (UINT16)LegacyNETMenu.MenuNumber;
950 CurrentVal = CurrentNVMap->LegacyNET;
951 Default = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyNET;
952 } else if ((QuestionId >= LEGACY_BEV_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER)) {
953 Number = (UINT16)LegacyBEVMenu.MenuNumber;
954 CurrentVal = CurrentNVMap->LegacyBEV;
955 Default = mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData.LegacyBEV;
956 }
957
958 //
959 // First, find the different position
960 // if there is change, it should be only one
961 //
962 for (Index = 0; Index < Number; Index++) {
963 if (CurrentVal[Index] != Default[Index]) {
964 OldValue = Default[Index];
965 NewValue = CurrentVal[Index];
966 break;
967 }
968 }
969
970 if (Index != Number) {
971 //
972 // there is change, now process
973 //
974 if (0xFF == NewValue) {
975 //
976 // This item will be disable
977 // Just move the items behind this forward to overlap it
978 //
979 Pos = OldValue / 8;
980 Bit = 7 - (OldValue % 8);
981 DisMap[Pos] = (UINT8)(DisMap[Pos] | (UINT8)(1 << Bit));
982 for (Index2 = Index; Index2 < Number - 1; Index2++) {
983 CurrentVal[Index2] = CurrentVal[Index2 + 1];
984 }
985
986 CurrentVal[Index2] = 0xFF;
987 } else {
988 for (Index2 = 0; Index2 < Number; Index2++) {
989 if (Index2 == Index) {
990 continue;
991 }
992
993 if (Default[Index2] == NewValue) {
994 //
995 // If NewValue is in OldLegacyDev array
996 // remember its old position
997 //
998 NewValuePos = Index2;
999 break;
1000 }
1001 }
1002
1003 if (Index2 != Number) {
1004 //
1005 // We will change current item to an existing item
1006 // (It's hard to describe here, please read code, it's like a cycle-moving)
1007 //
1008 for (Index2 = NewValuePos; Index2 != Index;) {
1009 if (NewValuePos < Index) {
1010 CurrentVal[Index2] = Default[Index2 + 1];
1011 Index2++;
1012 } else {
1013 CurrentVal[Index2] = Default[Index2 - 1];
1014 Index2--;
1015 }
1016 }
1017 } else {
1018 //
1019 // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
1020 // so we should modify DisMap to reflect the change
1021 //
1022 Pos = NewValue / 8;
1023 Bit = 7 - (NewValue % 8);
1024 DisMap[Pos] = (UINT8)(DisMap[Pos] & (~(UINT8)(1 << Bit)));
1025 if (0xFF != OldValue) {
1026 //
1027 // Because NewValue is a item that was disabled before
1028 // so after changing the OldValue should be disabled
1029 // actually we are doing a swap of enable-disable states of two items
1030 //
1031 Pos = OldValue / 8;
1032 Bit = 7 - (OldValue % 8);
1033 DisMap[Pos] = (UINT8)(DisMap[Pos] | (UINT8)(1 << Bit));
1034 }
1035 }
1036 }
1037
1038 //
1039 // To prevent DISABLE appears in the middle of the list
1040 // we should perform a re-ordering
1041 //
1042 Index3 = Index;
1043 Index = 0;
1044 while (Index < Number) {
1045 if (0xFF != CurrentVal[Index]) {
1046 Index++;
1047 continue;
1048 }
1049
1050 Index2 = Index;
1051 Index2++;
1052 while (Index2 < Number) {
1053 if (0xFF != CurrentVal[Index2]) {
1054 break;
1055 }
1056
1057 Index2++;
1058 }
1059
1060 if (Index2 < Number) {
1061 CurrentVal[Index] = CurrentVal[Index2];
1062 CurrentVal[Index2] = 0xFF;
1063 }
1064
1065 Index++;
1066 }
1067
1068 //
1069 // Return correct question value.
1070 //
1071 Value->u16 = CurrentVal[Index3];
1072 CopyMem (Default, CurrentVal, sizeof (UINT16) * Number);
1073 }
1074
1075 //
1076 // Pass changed uncommitted data back to Form Browser
1077 //
1078 HiiSetBrowserData (&mLegacyBootOptionGuid, mLegacyBootStorageName, sizeof (LEGACY_BOOT_NV_DATA), (UINT8 *)CurrentNVMap, NULL);
1079}
1080
1081/**
1082 This call back function is registered with Boot Manager formset.
1083 When user selects a boot option, this call back function will
1084 be triggered. The boot option is saved for later processing.
1085
1086
1087 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1088 @param Action Specifies the type of action taken by the browser.
1089 @param QuestionId A unique value which is sent to the original exporting driver
1090 so that it can identify the type of data to expect.
1091 @param Type The type of value for the question.
1092 @param Value A pointer to the data being sent to the original exporting driver.
1093 @param ActionRequest On return, points to the action requested by the callback function.
1094
1095 @retval EFI_SUCCESS The callback successfully handled the action.
1096 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
1097
1098**/
1099EFI_STATUS
1100EFIAPI
1101LegacyBootOptionCallback (
1102 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1103 IN EFI_BROWSER_ACTION Action,
1104 IN EFI_QUESTION_ID QuestionId,
1105 IN UINT8 Type,
1106 IN EFI_IFR_TYPE_VALUE *Value,
1107 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
1108 )
1109{
1110 if ((Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_FORM_OPEN)) {
1111 //
1112 // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.
1113 //
1114 return EFI_UNSUPPORTED;
1115 }
1116
1117 if ((Value == NULL) || (ActionRequest == NULL)) {
1118 return EFI_INVALID_PARAMETER;
1119 }
1120
1121 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
1122 if (QuestionId == FORM_FLOPPY_BOOT_ID) {
1123 if (!mFirstEnterLegacyForm) {
1124 //
1125 // The legacyBootMaintUiLib depends on the LegacyBootManagerLib to realize its functionality.
1126 // We need to do the legacy boot options related actions after the LegacyBootManagerLib has been initialized.
1127 // Opening the legacy menus is the appropriate time that the LegacyBootManagerLib has already been initialized.
1128 //
1129 mFirstEnterLegacyForm = TRUE;
1130 GetLegacyOptions ();
1131 GetLegacyOptionsOrder ();
1132 }
1133 }
1134 }
1135
1136 if (Action == EFI_BROWSER_ACTION_CHANGING) {
1137 switch (QuestionId) {
1138 case FORM_FLOPPY_BOOT_ID:
1139 case FORM_HARDDISK_BOOT_ID:
1140 case FORM_CDROM_BOOT_ID:
1141 case FORM_NET_BOOT_ID:
1142 case FORM_BEV_BOOT_ID:
1143 UpdateLegacyDeviceOrderPage (QuestionId);
1144 break;
1145
1146 default:
1147 break;
1148 }
1149 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
1150 if ((Value == NULL) || (ActionRequest == NULL)) {
1151 return EFI_INVALID_PARAMETER;
1152 }
1153
1154 if ((QuestionId >= LEGACY_FD_QUESTION_ID) && (QuestionId < LEGACY_BEV_QUESTION_ID + MAX_MENU_NUMBER)) {
1155 AdjustOptionValue (QuestionId, Value);
1156 }
1157 }
1158
1159 return EFI_SUCCESS;
1160}
1161
1162/**
1163 Create a menu entry by given menu type.
1164
1165 @param MenuType The Menu type to be created.
1166
1167 @retval NULL If failed to create the menu.
1168 @return the new menu entry.
1169
1170**/
1171LEGACY_MENU_ENTRY *
1172CreateMenuEntry (
1173 VOID
1174 )
1175{
1176 LEGACY_MENU_ENTRY *MenuEntry;
1177
1178 //
1179 // Create new menu entry
1180 //
1181 MenuEntry = AllocateZeroPool (sizeof (LEGACY_MENU_ENTRY));
1182 if (MenuEntry == NULL) {
1183 return NULL;
1184 }
1185
1186 MenuEntry->VariableContext = AllocateZeroPool (sizeof (LEGACY_DEVICE_CONTEXT));
1187 if (MenuEntry->VariableContext == NULL) {
1188 FreePool (MenuEntry);
1189 return NULL;
1190 }
1191
1192 MenuEntry->Signature = LEGACY_MENU_ENTRY_SIGNATURE;
1193 return MenuEntry;
1194}
1195
1196/**
1197
1198 Base on the L"LegacyDevOrder" variable to build the current order data.
1199
1200**/
1201VOID
1202GetLegacyOptionsOrder (
1203 VOID
1204 )
1205{
1206 UINTN VarSize;
1207 UINT8 *VarData;
1208 UINT8 *VarTmp;
1209 LEGACY_DEV_ORDER_ENTRY *DevOrder;
1210 UINT16 *LegacyDev;
1211 UINTN Index;
1212 LEGACY_MENU_OPTION *OptionMenu;
1213 UINT16 VarDevOrder;
1214 UINTN Pos;
1215 UINTN Bit;
1216 UINT8 *DisMap;
1217 UINTN TotalLength;
1218
1219 LegacyDev = NULL;
1220 OptionMenu = NULL;
1221
1222 DisMap = ZeroMem (mLegacyBootOptionPrivate->MaintainMapData->DisableMap, sizeof (mLegacyBootOptionPrivate->MaintainMapData->DisableMap));
1223
1224 //
1225 // Get Device Order from variable
1226 //
1227 GetVariable2 (VAR_LEGACY_DEV_ORDER, &gEfiLegacyDevOrderVariableGuid, (VOID **)&VarData, &VarSize);
1228 VarTmp = VarData;
1229 if (NULL != VarData) {
1230 DevOrder = (LEGACY_DEV_ORDER_ENTRY *)VarData;
1231 while (VarData < VarTmp + VarSize) {
1232 switch (DevOrder->BbsType) {
1233 case BBS_FLOPPY:
1234 LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyFD;
1235 OptionMenu = &LegacyFDMenu;
1236 break;
1237
1238 case BBS_HARDDISK:
1239 LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyHD;
1240 OptionMenu = &LegacyHDMenu;
1241 break;
1242
1243 case BBS_CDROM:
1244 LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyCD;
1245 OptionMenu = &LegacyCDMenu;
1246 break;
1247
1248 case BBS_EMBED_NETWORK:
1249 LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyNET;
1250 OptionMenu = &LegacyNETMenu;
1251 break;
1252
1253 case BBS_BEV_DEVICE:
1254 LegacyDev = mLegacyBootOptionPrivate->MaintainMapData->InitialNvData.LegacyBEV;
1255 OptionMenu = &LegacyBEVMenu;
1256 break;
1257
1258 case BBS_UNKNOWN:
1259 default:
1260 ASSERT (FALSE);
1261 DEBUG ((DEBUG_ERROR, "Unsupported device type found!\n"));
1262 break;
1263 }
1264
1265 //
1266 // Create oneof tag here for FD/HD/CD #1 #2
1267 //
1268 for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
1269 TotalLength = sizeof (BBS_TYPE) + sizeof (UINT16) + Index * sizeof (UINT16);
1270 VarDevOrder = *(UINT16 *)((UINT8 *)DevOrder + TotalLength);
1271
1272 if (0xFF00 == (VarDevOrder & 0xFF00)) {
1273 LegacyDev[Index] = 0xFF;
1274 Pos = (VarDevOrder & 0xFF) / 8;
1275 Bit = 7 - ((VarDevOrder & 0xFF) % 8);
1276 DisMap[Pos] = (UINT8)(DisMap[Pos] | (UINT8)(1 << Bit));
1277 } else {
1278 LegacyDev[Index] = VarDevOrder & 0xFF;
1279 }
1280 }
1281
1282 VarData++;
1283 VarData += *(UINT16 *)VarData;
1284 DevOrder = (LEGACY_DEV_ORDER_ENTRY *)VarData;
1285 }
1286 }
1287
1288 CopyMem (&mLegacyBootOptionPrivate->MaintainMapData->LastTimeNvData, &mLegacyBootOptionPrivate->MaintainMapData->InitialNvData, sizeof (LEGACY_BOOT_NV_DATA));
1289 CopyMem (&mLegacyBootOptionPrivate->MaintainMapData->CurrentNvData, &mLegacyBootOptionPrivate->MaintainMapData->InitialNvData, sizeof (LEGACY_BOOT_NV_DATA));
1290}
1291
1292/**
1293
1294 Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo().
1295
1296**/
1297VOID
1298GetLegacyOptions (
1299 VOID
1300 )
1301{
1302 LEGACY_MENU_ENTRY *NewMenuEntry;
1303 LEGACY_DEVICE_CONTEXT *NewLegacyDevContext;
1304 EFI_BOOT_MANAGER_LOAD_OPTION *BootOption;
1305 UINTN BootOptionCount;
1306 UINT16 Index;
1307 UINTN FDNum;
1308 UINTN HDNum;
1309 UINTN CDNum;
1310 UINTN NETNum;
1311 UINTN BEVNum;
1312
1313 //
1314 // Initialize Bbs Table Context from BBS info data
1315 //
1316 InitializeListHead (&LegacyFDMenu.Head);
1317 InitializeListHead (&LegacyHDMenu.Head);
1318 InitializeListHead (&LegacyCDMenu.Head);
1319 InitializeListHead (&LegacyNETMenu.Head);
1320 InitializeListHead (&LegacyBEVMenu.Head);
1321
1322 FDNum = 0;
1323 HDNum = 0;
1324 CDNum = 0;
1325 NETNum = 0;
1326 BEVNum = 0;
1327
1328 EfiBootManagerConnectAll ();
1329
1330 //
1331 // for better user experience
1332 // 1. User changes HD configuration (e.g.: unplug HDD), here we have a chance to remove the HDD boot option
1333 // 2. User enables/disables UEFI PXE, here we have a chance to add/remove EFI Network boot option
1334 //
1335 EfiBootManagerRefreshAllBootOption ();
1336
1337 BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
1338 for (Index = 0; Index < BootOptionCount; Index++) {
1339 if ((DevicePathType (BootOption[Index].FilePath) != BBS_DEVICE_PATH) ||
1340 (DevicePathSubType (BootOption[Index].FilePath) != BBS_BBS_DP)
1341 )
1342 {
1343 continue;
1344 }
1345
1346 ASSERT (BootOption[Index].OptionalDataSize == sizeof (LEGACY_BOOT_OPTION_BBS_DATA));
1347 NewMenuEntry = CreateMenuEntry ();
1348 ASSERT (NewMenuEntry != NULL);
1349
1350 NewLegacyDevContext = (LEGACY_DEVICE_CONTEXT *)NewMenuEntry->VariableContext;
1351 NewLegacyDevContext->BbsIndex = ((LEGACY_BOOT_OPTION_BBS_DATA *)BootOption[Index].OptionalData)->BbsIndex;
1352 NewLegacyDevContext->Description = AllocateCopyPool (StrSize (BootOption[Index].Description), BootOption[Index].Description);
1353 ASSERT (NewLegacyDevContext->Description != NULL);
1354
1355 NewMenuEntry->DisplayString = NewLegacyDevContext->Description;
1356 NewMenuEntry->HelpString = NULL;
1357
1358 switch (((BBS_BBS_DEVICE_PATH *)BootOption[Index].FilePath)->DeviceType) {
1359 case BBS_TYPE_FLOPPY:
1360 InsertTailList (&LegacyFDMenu.Head, &NewMenuEntry->Link);
1361 FDNum++;
1362 break;
1363
1364 case BBS_TYPE_HARDDRIVE:
1365 InsertTailList (&LegacyHDMenu.Head, &NewMenuEntry->Link);
1366 HDNum++;
1367 break;
1368
1369 case BBS_TYPE_CDROM:
1370 InsertTailList (&LegacyCDMenu.Head, &NewMenuEntry->Link);
1371 CDNum++;
1372 break;
1373
1374 case BBS_TYPE_EMBEDDED_NETWORK:
1375 InsertTailList (&LegacyNETMenu.Head, &NewMenuEntry->Link);
1376 NETNum++;
1377 break;
1378
1379 case BBS_TYPE_BEV:
1380 InsertTailList (&LegacyBEVMenu.Head, &NewMenuEntry->Link);
1381 BEVNum++;
1382 break;
1383 }
1384 }
1385
1386 EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);
1387
1388 LegacyFDMenu.MenuNumber = FDNum;
1389 LegacyHDMenu.MenuNumber = HDNum;
1390 LegacyCDMenu.MenuNumber = CDNum;
1391 LegacyNETMenu.MenuNumber = NETNum;
1392 LegacyBEVMenu.MenuNumber = BEVNum;
1393}
1394
1395/**
1396
1397 Install Boot Manager Menu driver.
1398
1399 @param ImageHandle The image handle.
1400 @param SystemTable The system table.
1401
1402 @retval EFI_SUCCESS Install Boot manager menu success.
1403 @retval Other Return error status.
1404
1405**/
1406EFI_STATUS
1407EFIAPI
1408LegacyBootMaintUiLibConstructor (
1409 IN EFI_HANDLE ImageHandle,
1410 IN EFI_SYSTEM_TABLE *SystemTable
1411 )
1412{
1413 EFI_STATUS Status;
1414 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
1415 LEGACY_BOOT_OPTION_CALLBACK_DATA *LegacyBootOptionData;
1416
1417 Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **)&LegacyBios);
1418 if (!EFI_ERROR (Status)) {
1419 //
1420 // Create LegacyBootOptionData structures for Driver Callback
1421 //
1422 LegacyBootOptionData = AllocateZeroPool (sizeof (LEGACY_BOOT_OPTION_CALLBACK_DATA));
1423 ASSERT (LegacyBootOptionData != NULL);
1424
1425 LegacyBootOptionData->MaintainMapData = AllocateZeroPool (sizeof (LEGACY_BOOT_MAINTAIN_DATA));
1426 ASSERT (LegacyBootOptionData->MaintainMapData != NULL);
1427
1428 LegacyBootOptionData->ConfigAccess.ExtractConfig = LegacyBootOptionExtractConfig;
1429 LegacyBootOptionData->ConfigAccess.RouteConfig = LegacyBootOptionRouteConfig;
1430 LegacyBootOptionData->ConfigAccess.Callback = LegacyBootOptionCallback;
1431
1432 //
1433 // Install Device Path Protocol and Config Access protocol to driver handle
1434 //
1435 Status = gBS->InstallMultipleProtocolInterfaces (
1436 &LegacyBootOptionData->DriverHandle,
1437 &gEfiDevicePathProtocolGuid,
1438 &mLegacyBootOptionHiiVendorDevicePath,
1439 &gEfiHiiConfigAccessProtocolGuid,
1440 &LegacyBootOptionData->ConfigAccess,
1441 NULL
1442 );
1443 ASSERT_EFI_ERROR (Status);
1444
1445 //
1446 // Publish our HII data
1447 //
1448 LegacyBootOptionData->HiiHandle = HiiAddPackages (
1449 &mLegacyBootOptionGuid,
1450 LegacyBootOptionData->DriverHandle,
1451 LegacyBootMaintUiVfrBin,
1452 LegacyBootMaintUiLibStrings,
1453 NULL
1454 );
1455 ASSERT (LegacyBootOptionData->HiiHandle != NULL);
1456
1457 mLegacyBootOptionPrivate = LegacyBootOptionData;
1458 }
1459
1460 return EFI_SUCCESS;
1461}
1462
1463/**
1464 Destructor of Customized Display Library Instance.
1465
1466 @param ImageHandle The firmware allocated handle for the EFI image.
1467 @param SystemTable A pointer to the EFI System Table.
1468
1469 @retval EFI_SUCCESS The destructor completed successfully.
1470 @retval Other value The destructor did not complete successfully.
1471
1472**/
1473EFI_STATUS
1474EFIAPI
1475LegacyBootMaintUiLibDestructor (
1476 IN EFI_HANDLE ImageHandle,
1477 IN EFI_SYSTEM_TABLE *SystemTable
1478 )
1479{
1480 EFI_STATUS Status;
1481
1482 if ((mLegacyBootOptionPrivate != NULL) && (mLegacyBootOptionPrivate->DriverHandle != NULL)) {
1483 Status = gBS->UninstallMultipleProtocolInterfaces (
1484 mLegacyBootOptionPrivate->DriverHandle,
1485 &gEfiDevicePathProtocolGuid,
1486 &mLegacyBootOptionHiiVendorDevicePath,
1487 &gEfiHiiConfigAccessProtocolGuid,
1488 &mLegacyBootOptionPrivate->ConfigAccess,
1489 NULL
1490 );
1491 ASSERT_EFI_ERROR (Status);
1492
1493 HiiRemovePackages (mLegacyBootOptionPrivate->HiiHandle);
1494
1495 FreePool (mLegacyBootOptionPrivate->MaintainMapData);
1496 FreePool (mLegacyBootOptionPrivate);
1497 }
1498
1499 return EFI_SUCCESS;
1500}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette