BDS enhancement: enumerate & show all legacy boot options in Boot Manager so that user is able to boot any devices in the same type in Boot Manager without changing the legacy dev order.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11279 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
niruiyu 2011-01-28 02:36:26 +00:00
parent fbd26c4b17
commit 22d1f97835
8 changed files with 781 additions and 673 deletions

View File

@ -36,4 +36,55 @@ BdsBuildLegacyDevNameString (
OUT CHAR16 *BootString
);
/**
Group the legacy boot options in the BootOption.
The routine assumes the boot options in the beginning that covers all the device
types are ordered properly and re-position the following boot options just after
the corresponding boot options with the same device type.
For example:
1. Input = [Harddisk1 CdRom2 Efi1 Harddisk0 CdRom0 CdRom1 Harddisk2 Efi0]
Assuming [Harddisk1 CdRom2 Efi1] is ordered properly
Output = [Harddisk1 Harddisk0 Harddisk2 CdRom2 CdRom0 CdRom1 Efi1 Efi0]
2. Input = [Efi1 Efi0 CdRom1 Harddisk0 Harddisk1 Harddisk2 CdRom0 CdRom2]
Assuming [Efi1 Efi0 CdRom1 Harddisk0] is ordered properly
Output = [Efi1 Efi0 CdRom1 CdRom0 CdRom2 Harddisk0 Harddisk1 Harddisk2]
@param BootOption Pointer to buffer containing Boot Option Numbers
@param BootOptionCount Count of the Boot Option Numbers
**/
VOID
GroupMultipleLegacyBootOption4SameType (
UINT16 *BootOption,
UINTN BootOptionCount
);
/**
Re-order the Boot Option according to the DevOrder.
The routine re-orders the Boot Option in BootOption array according to
the order specified by DevOrder.
@param BootOption Pointer to buffer containing the Boot Option Numbers
@param BootOptionCount Count of the Boot Option Numbers
@param DevOrder Pointer to buffer containing the BBS Index,
high 8-bit value 0xFF indicating a disabled boot option
@param DevOrderCount Count of the BBS Index
@param EnBootOption Pointer to buffer receiving the enabled Boot Option Numbers
@param EnBootOptionCount Count of the enabled Boot Option Numbers
@param DisBootOption Pointer to buffer receiving the disabled Boot Option Numbers
@param DisBootOptionCount Count of the disabled Boot Option Numbers
**/
VOID
OrderLegacyBootOption4SameType (
UINT16 *BootOption,
UINTN BootOptionCount,
UINT16 *DevOrder,
UINTN DevOrderCount,
UINT16 *EnBootOption,
UINTN *EnBootOptionCount,
UINT16 *DisBootOption,
UINTN *DisBootOptionCount
);
#endif

View File

@ -1441,59 +1441,3 @@ FormSetDispatcher (
}
/**
Deletete the Boot Option from EFI Variable. The Boot Order Arrray
is also updated.
@param OptionNumber The number of Boot option want to be deleted.
@param BootOrder The Boot Order array.
@param BootOrderSize The size of the Boot Order Array.
@retval EFI_SUCCESS The Boot Option Variable was found and removed
@retval EFI_UNSUPPORTED The Boot Option Variable store was inaccessible
@retval EFI_NOT_FOUND The Boot Option Variable was not found
**/
EFI_STATUS
EFIAPI
BdsDeleteBootOption (
IN UINTN OptionNumber,
IN OUT UINT16 *BootOrder,
IN OUT UINTN *BootOrderSize
)
{
UINT16 BootOption[100];
UINTN Index;
EFI_STATUS Status;
UINTN Index2Del;
Status = EFI_SUCCESS;
Index2Del = 0;
UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);
Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);
//
// adjust boot order array
//
for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {
if (BootOrder[Index] == OptionNumber) {
Index2Del = Index;
break;
}
}
if (Index != *BootOrderSize / sizeof (UINT16)) {
for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {
if (Index >= Index2Del) {
BootOrder[Index] = BootOrder[Index + 1];
}
}
*BootOrderSize -= sizeof (UINT16);
}
return Status;
}

View File

@ -252,13 +252,23 @@ typedef struct {
} COM_ATTR;
#pragma pack(1)
///
/// For each legacy boot option in BBS table, a corresponding Boot#### variables is created.
/// The structure saves the mapping relationship between #### and the index in the BBS table.
///
typedef struct {
UINT16 BootOptionNumber;
UINT16 BbsIndex;
UINT16 BbsType;
} BOOT_OPTION_BBS_MAPPING;
typedef struct {
BBS_TYPE BbsType;
///
/// Length = sizeof (UINT16) + SIZEOF (Data)
///
UINT16 Length;
UINT16 *Data;
UINT16 Data[1];
} BM_LEGACY_DEV_ORDER_CONTEXT;
#pragma pack()
@ -304,10 +314,10 @@ typedef struct {
} BM_LOAD_CONTEXT;
typedef struct {
BBS_TABLE *BbsTable;
UINTN Index;
UINTN BbsCount;
UINT16 *Description;
BBS_TABLE *BbsEntry;
UINT16 BbsIndex;
UINT16 BbsCount;
CHAR16 *Description;
} BM_LEGACY_DEVICE_CONTEXT;
typedef struct {

View File

@ -5,7 +5,7 @@
Boot option manipulation
Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@ -529,6 +529,7 @@ BOpt_FreeMenu (
RemoveEntryList (&MenuEntry->Link);
BOpt_DestroyMenuEntry (MenuEntry);
}
FreeMenu->MenuNumber = 0;
}
/**
@ -707,7 +708,7 @@ BOpt_GetLegacyOptions (
HDD_INFO *HddInfo;
UINT16 BbsCount;
BBS_TABLE *BbsTable;
UINTN Index;
UINT16 Index;
CHAR16 DescString[100];
UINTN FDNum;
UINTN HDNum;
@ -766,8 +767,8 @@ BOpt_GetLegacyOptions (
}
NewLegacyDevContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;
NewLegacyDevContext->BbsTable = &BbsTable[Index];
NewLegacyDevContext->Index = Index;
NewLegacyDevContext->BbsEntry = &BbsTable[Index];
NewLegacyDevContext->BbsIndex = Index;
NewLegacyDevContext->BbsCount = BbsCount;
BdsBuildLegacyDevNameString (
&BbsTable[Index],
@ -775,12 +776,11 @@ BOpt_GetLegacyOptions (
sizeof (DescString),
DescString
);
NewLegacyDevContext->Description = AllocateZeroPool (StrSize (DescString));
NewLegacyDevContext->Description = AllocateCopyPool (StrSize (DescString), DescString);
if (NULL == NewLegacyDevContext->Description) {
break;
}
CopyMem (NewLegacyDevContext->Description, DescString, StrSize (DescString));
NewMenuEntry->DisplayString = NewLegacyDevContext->Description;
NewMenuEntry->HelpString = NULL;

View File

@ -535,10 +535,14 @@ UpdateOrderPage (
IN BMM_CALLBACK_DATA *CallbackData
)
{
BM_MENU_ENTRY *NewMenuEntry;
UINT16 Index;
VOID *OptionsOpCodeHandle;
BM_MENU_ENTRY *NewMenuEntry;
UINT16 Index;
UINT16 OptionOrderIndex;
VOID *OptionsOpCodeHandle;
UINTN DeviceType;
BM_LOAD_CONTEXT *NewLoadContext;
DeviceType = (UINTN) -1;
CallbackData->BmmAskSaveOrNot = TRUE;
UpdatePageStart (CallbackData);
@ -551,10 +555,10 @@ UpdateOrderPage (
ASSERT (OptionsOpCodeHandle != NULL);
for (
Index = 0;
Index = 0, OptionOrderIndex = 0;
(
(Index < OptionMenu->MenuNumber) &&
(Index <
(OptionOrderIndex <
(
sizeof (CallbackData->BmmFakeNvData.OptionOrder) /
sizeof (CallbackData->BmmFakeNvData.OptionOrder[0])
@ -563,7 +567,20 @@ UpdateOrderPage (
);
Index++
) {
NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
if (NewLoadContext->IsLegacy) {
if (((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType != DeviceType) {
DeviceType = ((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType;
} else {
//
// Only show one legacy boot option for the same device type
// assuming the boot options are grouped by the device type
//
continue;
}
}
HiiCreateOneOfOptionOpCode (
OptionsOpCodeHandle,
NewMenuEntry->DisplayStringToken,
@ -571,7 +588,7 @@ UpdateOrderPage (
EFI_IFR_TYPE_NUM_SIZE_32,
(UINT32) (NewMenuEntry->OptionNumber + 1)
);
CallbackData->BmmFakeNvData.OptionOrder[Index] = (UINT32) (NewMenuEntry->OptionNumber + 1);
CallbackData->BmmFakeNvData.OptionOrder[OptionOrderIndex++] = (UINT32) (NewMenuEntry->OptionNumber + 1);
}
if (OptionMenu->MenuNumber > 0) {
@ -1241,9 +1258,8 @@ UpdateSetLegacyDeviceOrderPage (
CallbackData->BmmAskSaveOrNot = TRUE;
UpdatePageStart (CallbackData);
DisMap = CallbackData->BmmOldFakeNVData.DisableMap;
DisMap = ZeroMem (CallbackData->BmmOldFakeNVData.DisableMap, sizeof (CallbackData->BmmOldFakeNVData.DisableMap));
SetMem (DisMap, 32, 0);
//
// Create oneof option list
//
@ -1311,19 +1327,19 @@ UpdateSetLegacyDeviceOrderPage (
for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
//
// Create OneOf for each legacy device, select the first one by default
// Create OneOf for each legacy device
//
HiiCreateOneOfOptionOpCode (
OptionsOpCodeHandle,
NewMenuEntry->DisplayStringToken,
(UINT8) ((Index == 0) ? EFI_IFR_OPTION_DEFAULT : 0),
0,
EFI_IFR_TYPE_NUM_SIZE_8,
(UINT8) ((BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext)->Index
(UINT8) ((BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext)->BbsIndex
);
}
//
// for item "Disabled"
// Create OneOf for item "Disabled"
//
HiiCreateOneOfOptionOpCode (
OptionsOpCodeHandle,

View File

@ -849,7 +849,6 @@ Var_UpdateBootOption (
NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;
if (BootOrderList != NULL) {
EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
FreePool (BootOrderList);
}
@ -949,9 +948,10 @@ Var_UpdateBootOrder (
{
EFI_STATUS Status;
UINT16 Index;
UINT16 OrderIndex;
UINT16 *BootOrderList;
UINT16 *NewBootOrderList;
UINTN BootOrderListSize;
UINT16 OptionNumber;
BootOrderList = NULL;
BootOrderListSize = 0;
@ -964,41 +964,40 @@ Var_UpdateBootOrder (
&gEfiGlobalVariableGuid,
&BootOrderListSize
);
NewBootOrderList = AllocateZeroPool (BootOrderListSize);
if (NewBootOrderList == NULL) {
if (BootOrderList == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// If exists, delete it to hold new BootOrder
//
if (BootOrderList != NULL) {
EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
FreePool (BootOrderList);
ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.OptionOrder) / sizeof (CallbackData->BmmFakeNvData.OptionOrder[0])));
for (OrderIndex = 0; (OrderIndex < BootOptionMenu.MenuNumber) && (CallbackData->BmmFakeNvData.OptionOrder[OrderIndex] != 0); OrderIndex++) {
for (Index = OrderIndex; Index < BootOrderListSize / sizeof (UINT16); Index++) {
if ((BootOrderList[Index] == (UINT16) (CallbackData->BmmFakeNvData.OptionOrder[OrderIndex] - 1)) && (OrderIndex != Index)) {
OptionNumber = BootOrderList[Index];
CopyMem (&BootOrderList[OrderIndex + 1], &BootOrderList[OrderIndex], (Index - OrderIndex) * sizeof (UINT16));
BootOrderList[OrderIndex] = OptionNumber;
}
}
}
ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CallbackData->BmmFakeNvData.OptionOrder) / sizeof (CallbackData->BmmFakeNvData.OptionOrder[0])));
for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
NewBootOrderList[Index] = (UINT16) (CallbackData->BmmFakeNvData.OptionOrder[Index] - 1);
}
GroupMultipleLegacyBootOption4SameType (
BootOrderList,
BootOrderListSize / sizeof (UINT16)
);
Status = gRT->SetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
VAR_FLAG,
BootOrderListSize,
NewBootOrderList
BootOrderList
);
FreePool (NewBootOrderList);
if (EFI_ERROR (Status)) {
return Status;
}
FreePool (BootOrderList);
BOpt_FreeMenu (&BootOptionMenu);
BOpt_GetBootOptions (CallbackData);
return EFI_SUCCESS;
return Status;
}
@ -1092,20 +1091,12 @@ Var_UpdateBBSOption (
VOID *BootOptionVar;
CHAR16 VarName[100];
UINTN OptionSize;
UINT8 *Ptr;
EFI_STATUS Status;
CHAR16 DescString[100];
CHAR8 DescAsciiString[100];
UINTN NewOptionSize;
UINT8 *NewOptionPtr;
UINT8 *TempPtr;
UINT32 *Attribute;
BM_MENU_OPTION *OptionMenu;
BM_LEGACY_DEVICE_CONTEXT *LegacyDeviceContext;
UINT8 *LegacyDev;
UINT8 *VarData;
UINTN VarSize;
BM_MENU_ENTRY *NewMenuEntry;
BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;
UINT8 *OriginalPtr;
UINT8 *DisMap;
@ -1113,56 +1104,51 @@ Var_UpdateBBSOption (
UINTN Bit;
UINT16 *NewOrder;
UINT16 Tmp;
UINT16 *EnBootOption;
UINTN EnBootOptionCount;
UINT16 *DisBootOption;
UINTN DisBootOptionCount;
UINT16 *BootOrder;
LegacyDeviceContext = NULL;
DisMap = NULL;
NewOrder = NULL;
if (FORM_SET_FD_ORDER_ID == CallbackData->BmmPreviousPageId) {
OptionMenu = (BM_MENU_OPTION *) &LegacyFDMenu;
LegacyDev = CallbackData->BmmFakeNvData.LegacyFD;
CallbackData->BbsType = BBS_FLOPPY;
} else {
if (FORM_SET_HD_ORDER_ID == CallbackData->BmmPreviousPageId) {
switch (CallbackData->BmmPreviousPageId) {
case FORM_SET_FD_ORDER_ID:
OptionMenu = (BM_MENU_OPTION *) &LegacyFDMenu;
LegacyDev = CallbackData->BmmFakeNvData.LegacyFD;
CallbackData->BbsType = BBS_FLOPPY;
break;
case FORM_SET_HD_ORDER_ID:
OptionMenu = (BM_MENU_OPTION *) &LegacyHDMenu;
LegacyDev = CallbackData->BmmFakeNvData.LegacyHD;
CallbackData->BbsType = BBS_HARDDISK;
} else {
if (FORM_SET_CD_ORDER_ID == CallbackData->BmmPreviousPageId) {
OptionMenu = (BM_MENU_OPTION *) &LegacyCDMenu;
LegacyDev = CallbackData->BmmFakeNvData.LegacyCD;
CallbackData->BbsType = BBS_CDROM;
} else {
if (FORM_SET_NET_ORDER_ID == CallbackData->BmmPreviousPageId) {
OptionMenu = (BM_MENU_OPTION *) &LegacyNETMenu;
LegacyDev = CallbackData->BmmFakeNvData.LegacyNET;
CallbackData->BbsType = BBS_EMBED_NETWORK;
} else {
OptionMenu = (BM_MENU_OPTION *) &LegacyBEVMenu;
LegacyDev = CallbackData->BmmFakeNvData.LegacyBEV;
CallbackData->BbsType = BBS_BEV_DEVICE;
}
}
}
break;
case FORM_SET_CD_ORDER_ID:
OptionMenu = (BM_MENU_OPTION *) &LegacyCDMenu;
LegacyDev = CallbackData->BmmFakeNvData.LegacyCD;
CallbackData->BbsType = BBS_CDROM;
break;
case FORM_SET_NET_ORDER_ID:
OptionMenu = (BM_MENU_OPTION *) &LegacyNETMenu;
LegacyDev = CallbackData->BmmFakeNvData.LegacyNET;
CallbackData->BbsType = BBS_EMBED_NETWORK;
break;
default:
ASSERT (FORM_SET_BEV_ORDER_ID == CallbackData->BmmPreviousPageId);
OptionMenu = (BM_MENU_OPTION *) &LegacyBEVMenu;
LegacyDev = CallbackData->BmmFakeNvData.LegacyBEV;
CallbackData->BbsType = BBS_BEV_DEVICE;
break;
}
DisMap = CallbackData->BmmOldFakeNVData.DisableMap;
Status = EFI_SUCCESS;
//
// Find the first device's context
// If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
// because we just use it to fill the desc string, and user can not see the string in UI
//
for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
LegacyDeviceContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;
if (0xFF != LegacyDev[0] && LegacyDev[0] == LegacyDeviceContext->Index) {
DEBUG ((DEBUG_ERROR, "DescStr: %s\n", LegacyDeviceContext->Description));
break;
}
}
ASSERT (LegacyDeviceContext != NULL);
//
// Update the Variable "LegacyDevOrder"
@ -1180,24 +1166,23 @@ Var_UpdateBBSOption (
OriginalPtr = VarData;
DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
while (VarData < VarData + VarSize) {
while (VarData < OriginalPtr + VarSize) {
if (DevOrder->BbsType == CallbackData->BbsType) {
break;
}
VarData += sizeof (BBS_TYPE);
VarData += *(UINT16 *) VarData;
VarData += sizeof (BBS_TYPE) + DevOrder->Length;
DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
}
if (VarData >= VarData + VarSize) {
if (VarData >= OriginalPtr + VarSize) {
FreePool (OriginalPtr);
return EFI_NOT_FOUND;
}
NewOrder = (UINT16 *) AllocateZeroPool (DevOrder->Length - sizeof (UINT16));
NewOrder = AllocateZeroPool (DevOrder->Length - sizeof (DevOrder->Length));
if (NewOrder == NULL) {
FreePool (VarData);
FreePool (OriginalPtr);
return EFI_OUT_OF_RESOURCES;
}
@ -1215,8 +1200,7 @@ Var_UpdateBBSOption (
// so we use DisMap to set en/dis state of each item in NewOrder array
//
for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {
Tmp = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index2 * sizeof (UINT16));
Tmp &= 0xFF;
Tmp = (UINT16) (DevOrder->Data[Index2] & 0xFF);
Pos = Tmp / 8;
Bit = 7 - (Tmp % 8);
if ((DisMap[Pos] & (1 << Bit)) != 0) {
@ -1226,9 +1210,9 @@ Var_UpdateBBSOption (
}
CopyMem (
(UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16),
DevOrder->Data,
NewOrder,
DevOrder->Length - sizeof (UINT16)
DevOrder->Length - sizeof (DevOrder->Length)
);
FreePool (NewOrder);
@ -1240,143 +1224,101 @@ Var_UpdateBBSOption (
OriginalPtr
);
FreePool (OriginalPtr);
//
// Update Optional Data of Boot####
// Update BootOrder and Boot####.Attribute
//
BootOptionVar = GetLegacyBootOptionVar (CallbackData->BbsType, &Index, &OptionSize);
// 1. Re-order the Option Number in BootOrder according to Legacy Dev Order
//
ASSERT (OptionMenu->MenuNumber == DevOrder->Length / sizeof (UINT16) - 1);
BootOrder = BdsLibGetVariableAndSize (
L"BootOrder",
&gEfiGlobalVariableGuid,
&VarSize
);
ASSERT (BootOrder != NULL);
if (BootOptionVar != NULL) {
CopyMem (
DescString,
LegacyDeviceContext->Description,
StrSize (LegacyDeviceContext->Description)
);
UnicodeStrToAsciiStr((CONST CHAR16*)&DescString, (CHAR8 *)&DescAsciiString);
NewOptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescString) +
sizeof (BBS_BBS_DEVICE_PATH);
NewOptionSize += AsciiStrLen (DescAsciiString) +
END_DEVICE_PATH_LENGTH + sizeof (BBS_TABLE) + sizeof (UINT16);
UnicodeSPrint (VarName, 100, L"Boot%04x", Index);
Ptr = BootOptionVar;
Attribute = (UINT32 *) Ptr;
*Attribute |= LOAD_OPTION_ACTIVE;
if (LegacyDev[0] == 0xFF) {
//
// Disable this legacy boot option
//
*Attribute &= ~LOAD_OPTION_ACTIVE;
}
Ptr += sizeof (UINT32);
Ptr += sizeof (UINT16);
Ptr += StrSize ((CHAR16 *) Ptr);
NewOptionPtr = AllocateZeroPool (NewOptionSize);
if (NewOptionPtr == NULL) {
return EFI_OUT_OF_RESOURCES;
}
TempPtr = NewOptionPtr;
//
// Attribute
//
CopyMem (
TempPtr,
BootOptionVar,
sizeof (UINT32)
);
TempPtr += sizeof (UINT32);
//
// BBS device path Length
//
*((UINT16 *) TempPtr) = (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) +
AsciiStrLen (DescAsciiString) +
END_DEVICE_PATH_LENGTH);
TempPtr += sizeof (UINT16);
//
// Description string
//
CopyMem (
TempPtr,
DescString,
StrSize (DescString)
);
TempPtr += StrSize (DescString);
//
// BBS device path
//
CopyMem (
TempPtr,
Ptr,
sizeof (BBS_BBS_DEVICE_PATH)
);
CopyMem (
((BBS_BBS_DEVICE_PATH*) TempPtr)->String,
DescAsciiString,
AsciiStrSize (DescAsciiString)
);
SetDevicePathNodeLength (
(EFI_DEVICE_PATH_PROTOCOL *) TempPtr,
sizeof (BBS_BBS_DEVICE_PATH) + AsciiStrLen (DescAsciiString)
);
TempPtr += sizeof (BBS_BBS_DEVICE_PATH) + AsciiStrLen (DescAsciiString);
//
// End node
//
CopyMem (
TempPtr,
EndDevicePath,
END_DEVICE_PATH_LENGTH
);
TempPtr += END_DEVICE_PATH_LENGTH;
//
// Now TempPtr point to optional data, i.e. Bbs Table
//
CopyMem (
TempPtr,
LegacyDeviceContext->BbsTable,
sizeof (BBS_TABLE)
);
//
// Now TempPtr point to BBS index
//
TempPtr += sizeof (BBS_TABLE);
*((UINT16 *) TempPtr) = (UINT16) LegacyDeviceContext->Index;
Status = gRT->SetVariable (
VarName,
DisBootOption = AllocatePool (VarSize);
ASSERT (DisBootOption != NULL);
EnBootOption = AllocatePool (VarSize);
ASSERT (EnBootOption != NULL);
OrderLegacyBootOption4SameType (
BootOrder,
VarSize / sizeof (UINT16),
DevOrder->Data,
DevOrder->Length / sizeof (UINT16) - 1,
EnBootOption,
&EnBootOptionCount,
DisBootOption,
&DisBootOptionCount
);
Status = gRT->SetVariable (
L"BootOrder",
&gEfiGlobalVariableGuid,
VAR_FLAG,
NewOptionSize,
NewOptionPtr
VarSize,
BootOrder
);
ASSERT_EFI_ERROR (Status);
FreePool (NewOptionPtr);
FreePool (BootOptionVar);
FreePool (BootOrder);
//
// 2. Deactivate the DisBootOption and activate the EnBootOption
//
for (Index = 0; Index < DisBootOptionCount; Index++) {
UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", DisBootOption[Index]);
BootOptionVar = BdsLibGetVariableAndSize (
VarName,
&gEfiGlobalVariableGuid,
&OptionSize
);
if (BootOptionVar != NULL) {
Attribute = (UINT32 *) BootOptionVar;
*Attribute &= ~LOAD_OPTION_ACTIVE;
Status = gRT->SetVariable (
VarName,
&gEfiGlobalVariableGuid,
VAR_FLAG,
OptionSize,
BootOptionVar
);
FreePool (BootOptionVar);
}
}
for (Index = 0; Index < EnBootOptionCount; Index++) {
UnicodeSPrint (VarName, sizeof (VarName), L"Boot%04x", EnBootOption[Index]);
BootOptionVar = BdsLibGetVariableAndSize (
VarName,
&gEfiGlobalVariableGuid,
&OptionSize
);
if (BootOptionVar != NULL) {
Attribute = (UINT32 *) BootOptionVar;
*Attribute |= LOAD_OPTION_ACTIVE;
Status = gRT->SetVariable (
VarName,
&gEfiGlobalVariableGuid,
VAR_FLAG,
OptionSize,
BootOptionVar
);
FreePool (BootOptionVar);
}
}
BOpt_GetBootOptions (CallbackData);
FreePool (OriginalPtr);
FreePool (EnBootOption);
FreePool (DisBootOption);
return Status;
}

View File

@ -1,7 +1,7 @@
/** @file
The platform boot manager reference implementation
Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@ -18,6 +18,17 @@ UINT16 mKeyInput;
EFI_GUID mBootManagerGuid = BOOT_MANAGER_FORMSET_GUID;
LIST_ENTRY mBootOptionsList;
BDS_COMMON_OPTION *gOption;
CHAR16 *mDeviceTypeStr[] = {
L"Legacy BEV",
L"Legacy Floppy",
L"Legacy Hard Drive",
L"Legacy CD ROM",
L"Legacy PCMCIA",
L"Legacy USB",
L"Legacy Embedded Network",
L"Legacy Unknown Device"
};
HII_VENDOR_DEVICE_PATH mBootManagerHiiVendorDevicePath = {
{
@ -207,8 +218,12 @@ CallBootManager (
VOID *EndOpCodeHandle;
EFI_IFR_GUID_LABEL *StartLabel;
EFI_IFR_GUID_LABEL *EndLabel;
UINT16 DeviceType;
BOOLEAN IsLegacyOption;
BOOLEAN NeedEndOp;
gOption = NULL;
DeviceType = (UINT16) -1;
gOption = NULL;
InitializeListHead (&mBootOptionsList);
//
@ -247,7 +262,7 @@ CallBootManager (
EndLabel->Number = LABEL_BOOT_OPTION_END;
mKeyInput = 0;
NeedEndOp = FALSE;
for (Link = GetFirstNode (&mBootOptionsList); !IsNull (&mBootOptionsList, Link); Link = GetNextNode (&mBootOptionsList, Link)) {
Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
@ -262,7 +277,38 @@ CallBootManager (
if ((Option->Attribute & LOAD_OPTION_HIDDEN) != 0) {
continue;
}
//
// Group the legacy boot option in the sub title created dynamically
//
IsLegacyOption = (BOOLEAN) (
(DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&
(DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)
);
if (!IsLegacyOption && NeedEndOp) {
NeedEndOp = FALSE;
HiiCreateEndOpCode (StartOpCodeHandle);
}
if (IsLegacyOption && DeviceType != ((BBS_BBS_DEVICE_PATH *) Option->DevicePath)->DeviceType) {
if (NeedEndOp) {
HiiCreateEndOpCode (StartOpCodeHandle);
}
DeviceType = ((BBS_BBS_DEVICE_PATH *) Option->DevicePath)->DeviceType;
Token = HiiSetString (
HiiHandle,
0,
mDeviceTypeStr[
MIN (DeviceType & 0xF, sizeof (mDeviceTypeStr) / sizeof (mDeviceTypeStr[0]) - 1)
],
NULL
);
HiiCreateSubTitleOpCode (StartOpCodeHandle, Token, 0, 0, 1);
NeedEndOp = TRUE;
}
ASSERT (Option->Description != NULL);
Token = HiiSetString (HiiHandle, 0, Option->Description, NULL);
@ -286,6 +332,10 @@ CallBootManager (
);
}
if (NeedEndOp) {
HiiCreateEndOpCode (StartOpCodeHandle);
}
HiiUpdateForm (
HiiHandle,
&mBootManagerGuid,