+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- BBSsupport.c\r
-\r
-Abstract:\r
-\r
- This function deal with the legacy boot option, it create, delete\r
- and manage the legacy boot option, all legacy boot option is getting from\r
- the legacy BBS table.\r
-\r
---*/\r
-\r
-#include "BBSsupport.h"\r
-\r
-EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {\r
- {\r
- END_DEVICE_PATH_TYPE,\r
- END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
- {\r
- END_DEVICE_PATH_LENGTH,\r
- 0\r
- }\r
- }\r
-};\r
-\r
-VOID\r
-AsciiToUnicodeSize (\r
- IN UINT8 *a,\r
- IN UINTN Size,\r
- OUT UINT16 *u\r
- )\r
-/*++\r
-\r
- Routine Description:\r
-\r
- Translate the first n characters of an Ascii string to\r
- Unicode characters. The count n is indicated by parameter\r
- Size. If Size is greater than the length of string, then\r
- the entire string is translated.\r
-\r
- Arguments:\r
-\r
- a - Pointer to input Ascii string.\r
- Size - The number of characters to translate.\r
- u - Pointer to output Unicode string buffer.\r
-\r
- Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- UINTN i;\r
-\r
- i = 0;\r
- while (a[i] != 0) {\r
- u[i] = (CHAR16) a[i];\r
- if (i == Size) {\r
- break;\r
- }\r
-\r
- i++;\r
- }\r
- u[i] = 0;\r
-}\r
-\r
-VOID\r
-BdsBuildLegacyDevNameString (\r
- IN BBS_TABLE *CurBBSEntry,\r
- IN UINTN Index,\r
- IN UINTN BufSize,\r
- OUT CHAR16 *BootString\r
- )\r
-{\r
- CHAR16 *Fmt;\r
- CHAR16 *Type;\r
- UINT8 *StringDesc;\r
- CHAR16 temp[80];\r
-\r
- switch (Index) {\r
- //\r
- // Primary Master\r
- //\r
- case 1:\r
- Fmt = L"Primary Master %s";\r
- break;\r
-\r
- //\r
- // Primary Slave\r
- //\r
- case 2:\r
- Fmt = L"Primary Slave %s";\r
- break;\r
-\r
- //\r
- // Secondary Master\r
- //\r
- case 3:\r
- Fmt = L"Secondary Master %s";\r
- break;\r
-\r
- //\r
- // Secondary Slave\r
- //\r
- case 4:\r
- Fmt = L"Secondary Slave %s";\r
- break;\r
-\r
- default:\r
- Fmt = L"%s";\r
- break;\r
- }\r
-\r
- switch (CurBBSEntry->DeviceType) {\r
- case BBS_FLOPPY:\r
- Type = L"Floppy";\r
- break;\r
-\r
- case BBS_HARDDISK:\r
- Type = L"Harddisk";\r
- break;\r
-\r
- case BBS_CDROM:\r
- Type = L"CDROM";\r
- break;\r
-\r
- case BBS_PCMCIA:\r
- Type = L"PCMCIAe";\r
- break;\r
-\r
- case BBS_USB:\r
- Type = L"USB";\r
- break;\r
-\r
- case BBS_EMBED_NETWORK:\r
- Type = L"Network";\r
- break;\r
-\r
- case BBS_BEV_DEVICE:\r
- Type = L"BEVe";\r
- break;\r
-\r
- case BBS_UNKNOWN:\r
- default:\r
- Type = L"Unknown";\r
- break;\r
- }\r
- //\r
- // If current BBS entry has its description then use it.\r
- //\r
- StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset);\r
- if (NULL != StringDesc) {\r
- //\r
- // Only get fisrt 32 characters, this is suggested by BBS spec\r
- //\r
- AsciiToUnicodeSize (StringDesc, 32, temp);\r
- Fmt = L"%s";\r
- Type = temp;\r
- }\r
-\r
- UnicodeSPrint (BootString, BufSize, Fmt, Type);\r
-}\r
-\r
-EFI_STATUS\r
-BdsCreateLegacyBootOption (\r
- IN BBS_TABLE *CurrentBbsEntry,\r
- IN EFI_DEVICE_PATH_PROTOCOL *CurrentBbsDevPath,\r
- IN UINTN Index,\r
- IN OUT UINT16 **BootOrderList,\r
- IN OUT UINTN *BootOrderListSize\r
- )\r
-/*++\r
-\r
- Routine Description:\r
-\r
- Create a legacy boot option for the specified entry of\r
- BBS table, save it as variable, and append it to the boot\r
- order list.\r
-\r
- Arguments:\r
-\r
- CurrentBbsEntry - Pointer to current BBS table.\r
- CurrentBbsDevPath - Pointer to the Device Path Protocol instance of BBS\r
- Index - Index of the specified entry in BBS table.\r
- BootOrderList - On input, the original boot order list.\r
- On output, the new boot order list attached with the\r
- created node.\r
- BootOrderListSize - On input, the original size of boot order list.\r
- - On output, the size of new boot order list.\r
-\r
- Returns:\r
-\r
- EFI_SUCCESS - Boot Option successfully created.\r
- EFI_OUT_OF_RESOURCES - Fail to allocate necessary memory.\r
- Other - Error occurs while setting variable.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINT16 CurrentBootOptionNo;\r
- UINT16 BootString[10];\r
- UINT16 BootDesc[100];\r
- UINT16 *NewBootOrderList;\r
- UINTN BufferSize;\r
- VOID *Buffer;\r
- UINT8 *Ptr;\r
- UINT16 CurrentBbsDevPathSize;\r
- UINTN BootOrderIndex;\r
- UINTN BootOrderLastIndex;\r
- UINTN ArrayIndex;\r
- BOOLEAN IndexNotFound;\r
-\r
- if (NULL == (*BootOrderList)) {\r
- CurrentBootOptionNo = 0;\r
- } else {\r
- for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) {\r
- IndexNotFound = TRUE;\r
- for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) {\r
- if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) {\r
- IndexNotFound = FALSE;\r
- break;\r
- }\r
- }\r
-\r
- if (!IndexNotFound) {\r
- continue;\r
- } else {\r
- break;\r
- }\r
- }\r
-\r
- CurrentBootOptionNo = (UINT16) ArrayIndex;\r
- }\r
-\r
- UnicodeSPrint (\r
- BootString,\r
- sizeof (BootString),\r
- L"Boot%04x",\r
- CurrentBootOptionNo\r
- );\r
-\r
- BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc);\r
-\r
- CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath));\r
-\r
- BufferSize = sizeof (UINT32) +\r
- sizeof (UINT16) +\r
- StrSize (BootDesc) +\r
- CurrentBbsDevPathSize +\r
- sizeof (BBS_TABLE) +\r
- sizeof (UINT16);\r
-\r
- Buffer = AllocateZeroPool (BufferSize);\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Ptr = (UINT8 *) Buffer;\r
-\r
- *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;\r
- Ptr += sizeof (UINT32);\r
-\r
- *((UINT16 *) Ptr) = CurrentBbsDevPathSize;\r
- Ptr += sizeof (UINT16);\r
-\r
- CopyMem (\r
- Ptr,\r
- BootDesc,\r
- StrSize (BootDesc)\r
- );\r
- Ptr += StrSize (BootDesc);\r
-\r
- CopyMem (\r
- Ptr,\r
- CurrentBbsDevPath,\r
- CurrentBbsDevPathSize\r
- );\r
- Ptr += CurrentBbsDevPathSize;\r
-\r
- CopyMem (\r
- Ptr,\r
- CurrentBbsEntry,\r
- sizeof (BBS_TABLE)\r
- );\r
-\r
- Ptr += sizeof (BBS_TABLE);\r
- *((UINT16 *) Ptr) = (UINT16) Index;\r
-\r
- Status = gRT->SetVariable (\r
- BootString,\r
- &gEfiGlobalVariableGuid,\r
- VAR_FLAG,\r
- BufferSize,\r
- Buffer\r
- );\r
-\r
- SafeFreePool (Buffer);\r
- Buffer = NULL;\r
-\r
- NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof (UINT16));\r
- if (NULL == NewBootOrderList) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (NULL != *BootOrderList) {\r
- CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize);\r
- }\r
-\r
- SafeFreePool (*BootOrderList);\r
-\r
- BootOrderLastIndex = (UINTN) (*BootOrderListSize / sizeof (UINT16));\r
- NewBootOrderList[BootOrderLastIndex] = CurrentBootOptionNo;\r
- *BootOrderListSize += sizeof (UINT16);\r
- *BootOrderList = NewBootOrderList;\r
-\r
- return Status;\r
-}\r
-\r
-BOOLEAN\r
-BdsIsLegacyBootOption (\r
- IN UINT8 *BootOptionVar,\r
- OUT BBS_TABLE **BbsEntry,\r
- OUT UINT16 *BbsIndex\r
- )\r
-{\r
- UINT8 *Ptr;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- BOOLEAN Ret;\r
- UINT16 DevPathLen;\r
-\r
- Ptr = BootOptionVar;\r
- Ptr += sizeof (UINT32);\r
- DevPathLen = *(UINT16 *) Ptr;\r
- Ptr += sizeof (UINT16);\r
- Ptr += StrSize ((UINT16 *) Ptr);\r
- DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
- if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) {\r
- Ptr += DevPathLen;\r
- *BbsEntry = (BBS_TABLE *) Ptr;\r
- Ptr += sizeof (BBS_TABLE);\r
- *BbsIndex = *(UINT16 *) Ptr;\r
- Ret = TRUE;\r
- } else {\r
- *BbsEntry = NULL;\r
- Ret = FALSE;\r
- }\r
-\r
- return Ret;\r
-}\r
-\r
-EFI_STATUS\r
-BdsDeleteBootOption (\r
- IN UINTN OptionNumber,\r
- IN OUT UINT16 *BootOrder,\r
- IN OUT UINTN *BootOrderSize\r
- )\r
-{\r
- UINT16 BootOption[100];\r
- UINTN Index;\r
- EFI_STATUS Status;\r
- UINTN Index2Del;\r
-\r
- Status = EFI_SUCCESS;\r
- Index2Del = 0;\r
-\r
- UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber);\r
- Status = EfiLibDeleteVariable (BootOption, &gEfiGlobalVariableGuid);\r
- //\r
- // adjust boot order array\r
- //\r
- for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) {\r
- if (BootOrder[Index] == OptionNumber) {\r
- Index2Del = Index;\r
- break;\r
- }\r
- }\r
-\r
- if (Index != *BootOrderSize / sizeof (UINT16)) {\r
- for (Index = 0; Index < *BootOrderSize / sizeof (UINT16) - 1; Index++) {\r
- if (Index >= Index2Del) {\r
- BootOrder[Index] = BootOrder[Index + 1];\r
- }\r
- }\r
-\r
- *BootOrderSize -= sizeof (UINT16);\r
- }\r
-\r
- return Status;\r
-\r
-}\r
-\r
-EFI_STATUS\r
-BdsDeleteAllInvalidLegacyBootOptions (\r
- VOID\r
- )\r
-/*++\r
-\r
- Routine Description:\r
-\r
- Delete all the invalid legacy boot options.\r
-\r
- Arguments:\r
-\r
- None.\r
-\r
- Returns:\r
-\r
- EFI_SUCCESS - All invalide legacy boot options are deleted.\r
- EFI_OUT_OF_RESOURCES - Fail to allocate necessary memory.\r
- EFI_NOT_FOUND - Fail to retrive variable of boot order.\r
- Other - Error occurs while setting variable or locating\r
- protocol.\r
-\r
---*/\r
-{\r
- UINT16 *BootOrder;\r
- UINT8 *BootOptionVar;\r
- UINTN BootOrderSize;\r
- UINTN BootOptionSize;\r
- EFI_STATUS Status;\r
- UINT16 HddCount;\r
- UINT16 BbsCount;\r
- HDD_INFO *LocalHddInfo;\r
- BBS_TABLE *LocalBbsTable;\r
- BBS_TABLE *BbsEntry;\r
- UINT16 BbsIndex;\r
- EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
- UINTN Index;\r
- UINT16 BootOption[10];\r
- UINT16 BootDesc[100];\r
- BOOLEAN DescStringMatch;\r
-\r
- Status = EFI_SUCCESS;\r
- BootOrder = NULL;\r
- BootOrderSize = 0;\r
- HddCount = 0;\r
- BbsCount = 0;\r
- LocalHddInfo = NULL;\r
- LocalBbsTable = NULL;\r
- BbsEntry = NULL;\r
-\r
- Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID**) &LegacyBios);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- LegacyBios->GetBbsInfo (\r
- LegacyBios,\r
- &HddCount,\r
- &LocalHddInfo,\r
- &BbsCount,\r
- &LocalBbsTable\r
- );\r
-\r
- BootOrder = BdsLibGetVariableAndSize (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- &BootOrderSize\r
- );\r
- if (NULL == BootOrder) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Index = 0;\r
- while (Index < BootOrderSize / sizeof (UINT16)) {\r
- UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);\r
- BootOptionVar = BdsLibGetVariableAndSize (\r
- BootOption,\r
- &gEfiGlobalVariableGuid,\r
- &BootOptionSize\r
- );\r
- if (NULL == BootOptionVar) {\r
- SafeFreePool (BootOrder);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) {\r
- SafeFreePool (BootOptionVar);\r
- Index++;\r
- continue;\r
- }\r
- \r
- //\r
- // Check if BBS Description String is changed\r
- //\r
- DescStringMatch = FALSE;\r
- \r
- BdsBuildLegacyDevNameString (\r
- &LocalBbsTable[BbsIndex], \r
- BbsIndex, \r
- sizeof(BootDesc), \r
- BootDesc\r
- );\r
- \r
- if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) == 0) {\r
- DescStringMatch = TRUE;\r
- }\r
-\r
- if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) ||\r
- (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM) ||\r
- (LocalBbsTable[BbsIndex].BootPriority == BBS_LOWEST_PRIORITY)) &&\r
- (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) &&\r
- DescStringMatch) {\r
- Index++;\r
- continue;\r
- }\r
-\r
- SafeFreePool (BootOptionVar);\r
- //\r
- // should delete\r
- //\r
- BdsDeleteBootOption (\r
- BootOrder[Index],\r
- BootOrder,\r
- &BootOrderSize\r
- );\r
- }\r
-\r
- if (BootOrderSize) {\r
- Status = gRT->SetVariable (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- VAR_FLAG,\r
- BootOrderSize,\r
- BootOrder\r
- );\r
- } else {\r
- EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);\r
- }\r
-\r
- SafeFreePool (BootOrder);\r
-\r
- return Status;\r
-}\r
-\r
-BOOLEAN\r
-BdsFindLegacyBootOptionByDevType (\r
- IN UINT16 *BootOrder,\r
- IN UINTN BootOptionNum,\r
- IN UINT16 DevType,\r
- OUT UINT32 *Attribute,\r
- OUT UINT16 *BbsIndex,\r
- OUT UINTN *OptionNumber\r
- )\r
-{\r
- UINTN Index;\r
- UINTN BootOrderIndex;\r
- UINT16 BootOption[100];\r
- UINTN BootOptionSize;\r
- UINT8 *BootOptionVar;\r
- BBS_TABLE *BbsEntry;\r
- BOOLEAN Found;\r
-\r
- BbsEntry = NULL;\r
- Found = FALSE;\r
-\r
- if (NULL == BootOrder) {\r
- return Found;\r
- }\r
-\r
- for (BootOrderIndex = 0; BootOrderIndex < BootOptionNum; BootOrderIndex++) {\r
- Index = (UINTN) BootOrder[BootOrderIndex];\r
- UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", Index);\r
- BootOptionVar = BdsLibGetVariableAndSize (\r
- BootOption,\r
- &gEfiGlobalVariableGuid,\r
- &BootOptionSize\r
- );\r
- if (NULL == BootOptionVar) {\r
- continue;\r
- }\r
-\r
- if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) {\r
- SafeFreePool (BootOptionVar);\r
- continue;\r
- }\r
-\r
- if (BbsEntry->DeviceType != DevType) {\r
- SafeFreePool (BootOptionVar);\r
- continue;\r
- }\r
-\r
- *Attribute = *(UINT32 *) BootOptionVar;\r
- *OptionNumber = Index;\r
- Found = TRUE;\r
- SafeFreePool (BootOptionVar);\r
- break;\r
- }\r
-\r
- return Found;\r
-}\r
-\r
-EFI_STATUS\r
-BdsCreateOneLegacyBootOption (\r
- IN BBS_TABLE *BbsItem,\r
- IN UINTN Index,\r
- IN OUT UINT16 **BootOrderList,\r
- IN OUT UINTN *BootOrderListSize\r
- )\r
-{\r
- BBS_BBS_DEVICE_PATH BbsDevPathNode;\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
-\r
- DevPath = NULL;\r
-\r
- BbsDevPathNode.Header.Type = BBS_DEVICE_PATH;\r
- BbsDevPathNode.Header.SubType = BBS_BBS_DP;\r
- SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH));\r
- BbsDevPathNode.DeviceType = BbsItem->DeviceType;\r
- CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16));\r
-\r
- DevPath = AppendDevicePathNode (\r
- EndDevicePath,\r
- (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode\r
- );\r
- if (NULL == DevPath) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Status = BdsCreateLegacyBootOption (\r
- BbsItem,\r
- DevPath,\r
- Index,\r
- BootOrderList,\r
- BootOrderListSize\r
- );\r
- BbsItem->BootPriority = 0x00;\r
-\r
- gBS->FreePool (DevPath);\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-BdsAddNonExistingLegacyBootOptions (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Add the legacy boot options from BBS table if they do not exist.\r
-\r
-Arguments:\r
-\r
- None.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - The boot options are added successfully or they are already in boot options.\r
- others - An error occurred when creating legacy boot options.\r
-\r
---*/\r
-{\r
- UINT16 *BootOrder;\r
- UINTN BootOrderSize;\r
- EFI_STATUS Status;\r
- UINT16 HddCount;\r
- UINT16 BbsCount;\r
- HDD_INFO *LocalHddInfo;\r
- BBS_TABLE *LocalBbsTable;\r
- UINT16 BbsIndex;\r
- EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
- UINTN Index;\r
- UINT32 Attribute;\r
- UINTN OptionNumber;\r
- BOOLEAN Ret;\r
-\r
- BootOrder = NULL;\r
- HddCount = 0;\r
- BbsCount = 0;\r
- LocalHddInfo = NULL;\r
- LocalBbsTable = NULL;\r
-\r
- Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID**)&LegacyBios);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- LegacyBios->GetBbsInfo (\r
- LegacyBios,\r
- &HddCount,\r
- &LocalHddInfo,\r
- &BbsCount,\r
- &LocalBbsTable\r
- );\r
-\r
- BootOrder = BdsLibGetVariableAndSize (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- &BootOrderSize\r
- );\r
- if (NULL == BootOrder) {\r
- BootOrderSize = 0;\r
- }\r
-\r
- for (Index = 0; Index < BbsCount; Index++) {\r
- if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
- (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)\r
- ) {\r
- continue;\r
- }\r
-\r
- Ret = BdsFindLegacyBootOptionByDevType (\r
- BootOrder,\r
- BootOrderSize / sizeof (UINT16),\r
- LocalBbsTable[Index].DeviceType,\r
- &Attribute,\r
- &BbsIndex,\r
- &OptionNumber\r
- );\r
- if (Ret && (Attribute & LOAD_OPTION_ACTIVE) != 0) {\r
- continue;\r
- }\r
-\r
- if (Ret) {\r
- if (Index != BbsIndex) {\r
- BdsDeleteBootOption (\r
- OptionNumber,\r
- BootOrder,\r
- &BootOrderSize\r
- );\r
- } else {\r
- continue;\r
- }\r
- }\r
- //\r
- // Not found such type of legacy device in boot options or we found but it's disabled\r
- // so we have to create one and put it to the tail of boot order list\r
- //\r
- Status = BdsCreateOneLegacyBootOption (\r
- &LocalBbsTable[Index],\r
- Index,\r
- &BootOrder,\r
- &BootOrderSize\r
- );\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- }\r
-\r
- if (BootOrderSize > 0) {\r
- Status = gRT->SetVariable (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- VAR_FLAG,\r
- BootOrderSize,\r
- BootOrder\r
- );\r
- } else {\r
- EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);\r
- }\r
-\r
- if (BootOrder != NULL) {\r
- SafeFreePool (BootOrder);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-UINT16 *\r
-BdsFillDevOrderBuf (\r
- IN BBS_TABLE *BbsTable,\r
- IN BBS_TYPE BbsType,\r
- IN UINTN BbsCount,\r
- IN UINT16 *Buf\r
- )\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < BbsCount; Index++) {\r
- if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {\r
- continue;\r
- }\r
-\r
- if (BbsTable[Index].DeviceType != BbsType) {\r
- continue;\r
- }\r
-\r
- *Buf = (UINT16) (Index & 0xFF);\r
- Buf++;\r
- }\r
-\r
- return Buf;\r
-}\r
-\r
-EFI_STATUS\r
-BdsCreateDevOrder (\r
- IN BBS_TABLE *BbsTable,\r
- IN UINT16 BbsCount\r
- )\r
-{\r
- UINTN Index;\r
- UINTN FDCount;\r
- UINTN HDCount;\r
- UINTN CDCount;\r
- UINTN NETCount;\r
- UINTN BEVCount;\r
- UINTN TotalSize;\r
- UINTN HeaderSize;\r
- UINT8 *DevOrder;\r
- UINT8 *Ptr;\r
- EFI_STATUS Status;\r
-\r
- FDCount = 0;\r
- HDCount = 0;\r
- CDCount = 0;\r
- NETCount = 0;\r
- BEVCount = 0;\r
- TotalSize = 0;\r
- HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16);\r
- DevOrder = NULL;\r
- Ptr = NULL;\r
- Status = EFI_SUCCESS;\r
-\r
- for (Index = 0; Index < BbsCount; Index++) {\r
- if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {\r
- continue;\r
- }\r
-\r
- switch (BbsTable[Index].DeviceType) {\r
- case BBS_FLOPPY:\r
- FDCount++;\r
- break;\r
-\r
- case BBS_HARDDISK:\r
- HDCount++;\r
- break;\r
-\r
- case BBS_CDROM:\r
- CDCount++;\r
- break;\r
-\r
- case BBS_EMBED_NETWORK:\r
- NETCount++;\r
- break;\r
-\r
- case BBS_BEV_DEVICE:\r
- BEVCount++;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);\r
- TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);\r
- TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);\r
- TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);\r
- TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);\r
-\r
- DevOrder = AllocateZeroPool (TotalSize);\r
- if (NULL == DevOrder) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Ptr = DevOrder;\r
-\r
- *((BBS_TYPE *) Ptr) = BBS_FLOPPY;\r
- Ptr += sizeof (BBS_TYPE);\r
- *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));\r
- Ptr += sizeof (UINT16);\r
- if (FDCount) {\r
- Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, (UINT16 *) Ptr);\r
- }\r
-\r
- *((BBS_TYPE *) Ptr) = BBS_HARDDISK;\r
- Ptr += sizeof (BBS_TYPE);\r
- *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
- Ptr += sizeof (UINT16);\r
- if (HDCount) {\r
- Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, (UINT16 *) Ptr);\r
- }\r
-\r
- *((BBS_TYPE *) Ptr) = BBS_CDROM;\r
- Ptr += sizeof (BBS_TYPE);\r
- *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
- Ptr += sizeof (UINT16);\r
- if (CDCount) {\r
- Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, (UINT16 *) Ptr);\r
- }\r
-\r
- *((BBS_TYPE *) Ptr) = BBS_EMBED_NETWORK;\r
- Ptr += sizeof (BBS_TYPE);\r
- *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
- Ptr += sizeof (UINT16);\r
- if (NETCount) {\r
- Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, (UINT16 *) Ptr);\r
- }\r
-\r
- *((BBS_TYPE *) Ptr) = BBS_BEV_DEVICE;\r
- Ptr += sizeof (BBS_TYPE);\r
- *((UINT16 *) Ptr) = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
- Ptr += sizeof (UINT16);\r
- if (BEVCount) {\r
- Ptr = (UINT8 *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, (UINT16 *) Ptr);\r
- }\r
-\r
- Status = gRT->SetVariable (\r
- VarLegacyDevOrder,\r
- &EfiLegacyDevOrderGuid,\r
- VAR_FLAG,\r
- TotalSize,\r
- DevOrder\r
- );\r
- SafeFreePool (DevOrder);\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-BdsUpdateLegacyDevOrder (\r
- VOID\r
- )\r
-/*++\r
-Format of LegacyDevOrder variable:\r
-|-----------------------------------------------------------------------------------------------------------------\r
-| BBS_FLOPPY | Length | Index0 | Index1 | ... | BBS_HARDDISK | Length | Index0 | Index1 | ... | BBS_CDROM | Length | Index0 | ...\r
-|-----------------------------------------------------------------------------------------------------------------\r
-\r
-Length is a 16 bit integer, it indicates how many Indexes follows, including the size of itself.\r
-Index# is a 16 bit integer, the low byte of it stands for the index in BBS table\r
- the high byte of it only have two value 0 and 0xFF, 0xFF means this device has been\r
- disabled by user.\r
---*/\r
-{\r
- UINT8 *DevOrder;\r
- UINT8 *NewDevOrder;\r
- UINTN DevOrderSize;\r
- EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
- EFI_STATUS Status;\r
- UINT16 HddCount;\r
- UINT16 BbsCount;\r
- HDD_INFO *LocalHddInfo;\r
- BBS_TABLE *LocalBbsTable;\r
- UINTN Index;\r
- UINTN Index2;\r
- UINTN *Idx;\r
- UINTN FDCount;\r
- UINTN HDCount;\r
- UINTN CDCount;\r
- UINTN NETCount;\r
- UINTN BEVCount;\r
- UINTN TotalSize;\r
- UINTN HeaderSize;\r
- UINT8 *Ptr;\r
- UINT8 *NewPtr;\r
- UINT16 *NewFDPtr;\r
- UINT16 *NewHDPtr;\r
- UINT16 *NewCDPtr;\r
- UINT16 *NewNETPtr;\r
- UINT16 *NewBEVPtr;\r
- UINT16 *NewDevPtr;\r
- UINT16 Length;\r
- UINT16 tmp;\r
- UINTN FDIndex;\r
- UINTN HDIndex;\r
- UINTN CDIndex;\r
- UINTN NETIndex;\r
- UINTN BEVIndex;\r
-\r
- LocalHddInfo = NULL;\r
- LocalBbsTable = NULL;\r
- Idx = NULL;\r
- FDCount = 0;\r
- HDCount = 0;\r
- CDCount = 0;\r
- NETCount = 0;\r
- BEVCount = 0;\r
- TotalSize = 0;\r
- HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16);\r
- FDIndex = 0;\r
- HDIndex = 0;\r
- CDIndex = 0;\r
- NETIndex = 0;\r
- BEVIndex = 0;\r
- NewDevPtr = NULL;\r
-\r
- Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID**) &LegacyBios);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- LegacyBios->GetBbsInfo (\r
- LegacyBios,\r
- &HddCount,\r
- &LocalHddInfo,\r
- &BbsCount,\r
- &LocalBbsTable\r
- );\r
-\r
- DevOrder = (UINT8 *) BdsLibGetVariableAndSize (\r
- VarLegacyDevOrder,\r
- &EfiLegacyDevOrderGuid,\r
- &DevOrderSize\r
- );\r
- if (NULL == DevOrder) {\r
- return BdsCreateDevOrder (LocalBbsTable, BbsCount);\r
- }\r
- //\r
- // First we figure out how many boot devices with same device type respectively\r
- //\r
- for (Index = 0; Index < BbsCount; Index++) {\r
- if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
- (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) ||\r
- (LocalBbsTable[Index].BootPriority == BBS_LOWEST_PRIORITY)\r
- ) {\r
- continue;\r
- }\r
-\r
- switch (LocalBbsTable[Index].DeviceType) {\r
- case BBS_FLOPPY:\r
- FDCount++;\r
- break;\r
-\r
- case BBS_HARDDISK:\r
- HDCount++;\r
- break;\r
-\r
- case BBS_CDROM:\r
- CDCount++;\r
- break;\r
-\r
- case BBS_EMBED_NETWORK:\r
- NETCount++;\r
- break;\r
-\r
- case BBS_BEV_DEVICE:\r
- BEVCount++;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- TotalSize += (HeaderSize + FDCount * sizeof (UINT16));\r
- TotalSize += (HeaderSize + HDCount * sizeof (UINT16));\r
- TotalSize += (HeaderSize + CDCount * sizeof (UINT16));\r
- TotalSize += (HeaderSize + NETCount * sizeof (UINT16));\r
- TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));\r
-\r
- NewDevOrder = AllocateZeroPool (TotalSize);\r
- if (NULL == NewDevOrder) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- NewFDPtr = (UINT16 *) (NewDevOrder + HeaderSize);\r
- NewHDPtr = (UINT16 *) ((UINT8 *) NewFDPtr + FDCount * sizeof (UINT16) + HeaderSize);\r
- NewCDPtr = (UINT16 *) ((UINT8 *) NewHDPtr + HDCount * sizeof (UINT16) + HeaderSize);\r
- NewNETPtr = (UINT16 *) ((UINT8 *) NewCDPtr + CDCount * sizeof (UINT16) + HeaderSize);\r
- NewBEVPtr = (UINT16 *) ((UINT8 *) NewNETPtr + NETCount * sizeof (UINT16) + HeaderSize);\r
-\r
- //\r
- // copy FD\r
- //\r
- Ptr = DevOrder;\r
- NewPtr = NewDevOrder;\r
- *((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);\r
- Ptr += sizeof (BBS_TYPE);\r
- NewPtr += sizeof (BBS_TYPE);\r
- Length = *((UINT16 *) Ptr);\r
- *((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));\r
- Ptr += sizeof (UINT16);\r
-\r
- for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
- if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
- LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
- LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
- LocalBbsTable[*Ptr].DeviceType != BBS_FLOPPY\r
- ) {\r
- Ptr += sizeof (UINT16);\r
- continue;\r
- }\r
-\r
- NewFDPtr[FDIndex] = *(UINT16 *) Ptr;\r
- FDIndex++;\r
- Ptr += sizeof (UINT16);\r
- }\r
- //\r
- // copy HD\r
- //\r
- NewPtr = (UINT8 *) NewHDPtr - HeaderSize;\r
- *((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);\r
- Ptr += sizeof (BBS_TYPE);\r
- NewPtr += sizeof (BBS_TYPE);\r
- Length = *((UINT16 *) Ptr);\r
- *((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));\r
- Ptr += sizeof (UINT16);\r
-\r
- for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
- if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
- LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
- LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
- LocalBbsTable[*Ptr].DeviceType != BBS_HARDDISK\r
- ) {\r
- Ptr += sizeof (UINT16);\r
- continue;\r
- }\r
-\r
- NewHDPtr[HDIndex] = *(UINT16 *) Ptr;\r
- HDIndex++;\r
- Ptr += sizeof (UINT16);\r
- }\r
- //\r
- // copy CD\r
- //\r
- NewPtr = (UINT8 *) NewCDPtr - HeaderSize;\r
- *((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);\r
- Ptr += sizeof (BBS_TYPE);\r
- NewPtr += sizeof (BBS_TYPE);\r
- Length = *((UINT16 *) Ptr);\r
- *((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));\r
- Ptr += sizeof (UINT16);\r
-\r
- for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
- if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
- LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
- LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
- LocalBbsTable[*Ptr].DeviceType != BBS_CDROM\r
- ) {\r
- Ptr += sizeof (UINT16);\r
- continue;\r
- }\r
-\r
- NewCDPtr[CDIndex] = *(UINT16 *) Ptr;\r
- CDIndex++;\r
- Ptr += sizeof (UINT16);\r
- }\r
- //\r
- // copy NET\r
- //\r
- NewPtr = (UINT8 *) NewNETPtr - HeaderSize;\r
- *((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);\r
- Ptr += sizeof (BBS_TYPE);\r
- NewPtr += sizeof (BBS_TYPE);\r
- Length = *((UINT16 *) Ptr);\r
- *((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));\r
- Ptr += sizeof (UINT16);\r
-\r
- for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
- if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
- LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
- LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
- LocalBbsTable[*Ptr].DeviceType != BBS_EMBED_NETWORK\r
- ) {\r
- Ptr += sizeof (UINT16);\r
- continue;\r
- }\r
-\r
- NewNETPtr[NETIndex] = *(UINT16 *) Ptr;\r
- NETIndex++;\r
- Ptr += sizeof (UINT16);\r
- }\r
- //\r
- // copy BEV\r
- //\r
- NewPtr = (UINT8 *) NewBEVPtr - HeaderSize;\r
- *((BBS_TYPE *) NewPtr) = *((BBS_TYPE *) Ptr);\r
- Ptr += sizeof (BBS_TYPE);\r
- NewPtr += sizeof (BBS_TYPE);\r
- Length = *((UINT16 *) Ptr);\r
- *((UINT16 *) NewPtr) = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));\r
- Ptr += sizeof (UINT16);\r
-\r
- for (Index = 0; Index < Length / sizeof (UINT16) - 1; Index++) {\r
- if (LocalBbsTable[*Ptr].BootPriority == BBS_IGNORE_ENTRY ||\r
- LocalBbsTable[*Ptr].BootPriority == BBS_DO_NOT_BOOT_FROM ||\r
- LocalBbsTable[*Ptr].BootPriority == BBS_LOWEST_PRIORITY ||\r
- LocalBbsTable[*Ptr].DeviceType != BBS_BEV_DEVICE\r
- ) {\r
- Ptr += sizeof (UINT16);\r
- continue;\r
- }\r
-\r
- NewBEVPtr[BEVIndex] = *(UINT16 *) Ptr;\r
- BEVIndex++;\r
- Ptr += sizeof (UINT16);\r
- }\r
-\r
- for (Index = 0; Index < BbsCount; Index++) {\r
- if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||\r
- (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) ||\r
- (LocalBbsTable[Index].BootPriority == BBS_LOWEST_PRIORITY)\r
- ) {\r
- continue;\r
- }\r
-\r
- switch (LocalBbsTable[Index].DeviceType) {\r
- case BBS_FLOPPY:\r
- Idx = &FDIndex;\r
- NewDevPtr = NewFDPtr;\r
- break;\r
-\r
- case BBS_HARDDISK:\r
- Idx = &HDIndex;\r
- NewDevPtr = NewHDPtr;\r
- break;\r
-\r
- case BBS_CDROM:\r
- Idx = &CDIndex;\r
- NewDevPtr = NewCDPtr;\r
- break;\r
-\r
- case BBS_EMBED_NETWORK:\r
- Idx = &NETIndex;\r
- NewDevPtr = NewNETPtr;\r
- break;\r
-\r
- case BBS_BEV_DEVICE:\r
- Idx = &BEVIndex;\r
- NewDevPtr = NewBEVPtr;\r
- break;\r
-\r
- default:\r
- Idx = NULL;\r
- break;\r
- }\r
- //\r
- // at this point we have copied those valid indexes to new buffer\r
- // and we should check if there is any new appeared boot device\r
- //\r
- if (Idx) {\r
- for (Index2 = 0; Index2 < *Idx; Index2++) {\r
- if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {\r
- break;\r
- }\r
- }\r
-\r
- if (Index2 == *Idx) {\r
- //\r
- // Index2 == *Idx means we didn't find Index\r
- // so Index is a new appeared device's index in BBS table\r
- // save it.\r
- //\r
- NewDevPtr[*Idx] = (UINT16) (Index & 0xFF);\r
- (*Idx)++;\r
- }\r
- }\r
- }\r
-\r
- if (FDCount) {\r
- //\r
- // Just to make sure that disabled indexes are all at the end of the array\r
- //\r
- for (Index = 0; Index < FDIndex - 1; Index++) {\r
- if (0xFF00 != (NewFDPtr[Index] & 0xFF00)) {\r
- continue;\r
- }\r
-\r
- for (Index2 = Index + 1; Index2 < FDIndex; Index2++) {\r
- if (0 == (NewFDPtr[Index2] & 0xFF00)) {\r
- tmp = NewFDPtr[Index];\r
- NewFDPtr[Index] = NewFDPtr[Index2];\r
- NewFDPtr[Index2] = tmp;\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (HDCount) {\r
- //\r
- // Just to make sure that disabled indexes are all at the end of the array\r
- //\r
- for (Index = 0; Index < HDIndex - 1; Index++) {\r
- if (0xFF00 != (NewHDPtr[Index] & 0xFF00)) {\r
- continue;\r
- }\r
-\r
- for (Index2 = Index + 1; Index2 < HDIndex; Index2++) {\r
- if (0 == (NewHDPtr[Index2] & 0xFF00)) {\r
- tmp = NewHDPtr[Index];\r
- NewHDPtr[Index] = NewHDPtr[Index2];\r
- NewHDPtr[Index2] = tmp;\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (CDCount) {\r
- //\r
- // Just to make sure that disabled indexes are all at the end of the array\r
- //\r
- for (Index = 0; Index < CDIndex - 1; Index++) {\r
- if (0xFF00 != (NewCDPtr[Index] & 0xFF00)) {\r
- continue;\r
- }\r
-\r
- for (Index2 = Index + 1; Index2 < CDIndex; Index2++) {\r
- if (0 == (NewCDPtr[Index2] & 0xFF00)) {\r
- tmp = NewCDPtr[Index];\r
- NewCDPtr[Index] = NewCDPtr[Index2];\r
- NewCDPtr[Index2] = tmp;\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (NETCount) {\r
- //\r
- // Just to make sure that disabled indexes are all at the end of the array\r
- //\r
- for (Index = 0; Index < NETIndex - 1; Index++) {\r
- if (0xFF00 != (NewNETPtr[Index] & 0xFF00)) {\r
- continue;\r
- }\r
-\r
- for (Index2 = Index + 1; Index2 < NETIndex; Index2++) {\r
- if (0 == (NewNETPtr[Index2] & 0xFF00)) {\r
- tmp = NewNETPtr[Index];\r
- NewNETPtr[Index] = NewNETPtr[Index2];\r
- NewNETPtr[Index2] = tmp;\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (BEVCount) {\r
- //\r
- // Just to make sure that disabled indexes are all at the end of the array\r
- //\r
- for (Index = 0; Index < BEVIndex - 1; Index++) {\r
- if (0xFF00 != (NewBEVPtr[Index] & 0xFF00)) {\r
- continue;\r
- }\r
-\r
- for (Index2 = Index + 1; Index2 < BEVIndex; Index2++) {\r
- if (0 == (NewBEVPtr[Index2] & 0xFF00)) {\r
- tmp = NewBEVPtr[Index];\r
- NewBEVPtr[Index] = NewBEVPtr[Index2];\r
- NewBEVPtr[Index2] = tmp;\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- SafeFreePool (DevOrder);\r
-\r
- Status = gRT->SetVariable (\r
- VarLegacyDevOrder,\r
- &EfiLegacyDevOrderGuid,\r
- VAR_FLAG,\r
- TotalSize,\r
- NewDevOrder\r
- );\r
- SafeFreePool (NewDevOrder);\r
-\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-BdsSetBootPriority4SameTypeDev (\r
- IN UINT16 DeviceType,\r
- IN OUT BBS_TABLE *LocalBbsTable,\r
- IN OUT UINT16 *Priority\r
- )\r
-/*++\r
-DeviceType - BBS_FLOPPY, BBS_HARDDISK, BBS_CDROM and so on\r
-LocalBbsTable - BBS table instance\r
-Priority - As input arg, it is the start point of boot priority, as output arg, it is the start point of boot\r
- priority can be used next time.\r
---*/\r
-{\r
- UINT8 *DevOrder;\r
-\r
- UINT8 *OrigBuffer;\r
- UINT16 *DevIndex;\r
- UINTN DevOrderSize;\r
- UINTN DevCount;\r
- UINTN Index;\r
-\r
- DevOrder = BdsLibGetVariableAndSize (\r
- VarLegacyDevOrder,\r
- &EfiLegacyDevOrderGuid,\r
- &DevOrderSize\r
- );\r
- if (NULL == DevOrder) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- OrigBuffer = DevOrder;\r
- while (DevOrder < OrigBuffer + DevOrderSize) {\r
- if (DeviceType == * (BBS_TYPE *) DevOrder) {\r
- break;\r
- }\r
-\r
- DevOrder += sizeof (BBS_TYPE);\r
- DevOrder += *(UINT16 *) DevOrder;\r
- }\r
-\r
- if (DevOrder >= OrigBuffer + DevOrderSize) {\r
- SafeFreePool (OrigBuffer);\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- DevOrder += sizeof (BBS_TYPE);\r
- DevCount = (*((UINT16 *) DevOrder) - sizeof (UINT16)) / sizeof (UINT16);\r
- DevIndex = (UINT16 *) (DevOrder + sizeof (UINT16));\r
- //\r
- // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled.\r
- //\r
- for (Index = 0; Index < DevCount; Index++) {\r
- if ((DevIndex[Index] & 0xFF00) == 0xFF00) {\r
- //\r
- // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY;\r
- //\r
- } else {\r
- LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = *Priority;\r
- (*Priority)++;\r
- }\r
- }\r
-\r
- SafeFreePool (OrigBuffer);\r
- return EFI_SUCCESS;\r
-}\r
-\r
-VOID\r
-PrintBbsTable (\r
- IN BBS_TABLE *LocalBbsTable\r
- )\r
-{\r
- UINT16 Idx;\r
-\r
- DEBUG ((EFI_D_ERROR, "\n"));\r
- DEBUG ((EFI_D_ERROR, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n"));\r
- DEBUG ((EFI_D_ERROR, "=============================================\n"));\r
- for (Idx = 0; Idx < MAX_BBS_ENTRIES; Idx++) {\r
- if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) ||\r
- (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) ||\r
- (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY)\r
- ) {\r
- continue;\r
- }\r
-\r
- DEBUG (\r
- (EFI_D_ERROR,\r
- " %02x: %04x %02x/%02x/%02x %02x/02%x %04x %04x %04x:%04x\n",\r
- (UINTN) Idx,\r
- (UINTN) LocalBbsTable[Idx].BootPriority,\r
- (UINTN) LocalBbsTable[Idx].Bus,\r
- (UINTN) LocalBbsTable[Idx].Device,\r
- (UINTN) LocalBbsTable[Idx].Function,\r
- (UINTN) LocalBbsTable[Idx].Class,\r
- (UINTN) LocalBbsTable[Idx].SubClass,\r
- (UINTN) LocalBbsTable[Idx].DeviceType,\r
- (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags,\r
- (UINTN) LocalBbsTable[Idx].BootHandlerSegment,\r
- (UINTN) LocalBbsTable[Idx].BootHandlerOffset,\r
- (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset),\r
- (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset))\r
- );\r
- }\r
-\r
- DEBUG ((EFI_D_ERROR, "\n"));\r
-}\r
-\r
-EFI_STATUS\r
-BdsRefreshBbsTableForBoot (\r
- IN BDS_COMMON_OPTION *Entry\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT16 HddCount;\r
- UINT16 BbsCount;\r
- HDD_INFO *LocalHddInfo;\r
- BBS_TABLE *LocalBbsTable;\r
- UINT16 DevType;\r
- EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
- UINTN Index;\r
- UINT16 Priority;\r
- UINT16 *BootOrder;\r
- UINTN BootOrderSize;\r
- UINT8 *BootOptionVar;\r
- UINTN BootOptionSize;\r
- UINT16 BootOption[100];\r
- UINT8 *Ptr;\r
- UINT16 DevPathLen;\r
- EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
-\r
- HddCount = 0;\r
- BbsCount = 0;\r
- LocalHddInfo = NULL;\r
- LocalBbsTable = NULL;\r
- DevType = BBS_UNKNOWN;\r
-\r
- Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID**) &LegacyBios);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- LegacyBios->GetBbsInfo (\r
- LegacyBios,\r
- &HddCount,\r
- &LocalHddInfo,\r
- &BbsCount,\r
- &LocalBbsTable\r
- );\r
- //\r
- // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY\r
- // We will set them according to the settings setup by user\r
- //\r
- for (Index = 0; Index < BbsCount; Index++) {\r
- if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) ||\r
- (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) ||\r
- (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) {\r
- LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY;\r
- }\r
- }\r
- //\r
- // boot priority always starts at 0\r
- //\r
- Priority = 0;\r
- if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) {\r
- //\r
- // If Entry stands for a legacy boot option, we prioritize the devices with the same type first.\r
- //\r
- DevType = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType;\r
- Status = BdsSetBootPriority4SameTypeDev (\r
- DevType,\r
- LocalBbsTable,\r
- &Priority\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
- //\r
- // we have to set the boot priority for other BBS entries with different device types\r
- //\r
- BootOrder = (UINT16 *) BdsLibGetVariableAndSize (\r
- L"BootOrder",\r
- &gEfiGlobalVariableGuid,\r
- &BootOrderSize\r
- );\r
- for (Index = 0; BootOrder && Index < BootOrderSize / sizeof (UINT16); Index++) {\r
- UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]);\r
- BootOptionVar = BdsLibGetVariableAndSize (\r
- BootOption,\r
- &gEfiGlobalVariableGuid,\r
- &BootOptionSize\r
- );\r
- if (NULL == BootOptionVar) {\r
- continue;\r
- }\r
-\r
- Ptr = BootOptionVar;\r
-\r
- Ptr += sizeof (UINT32);\r
- DevPathLen = *(UINT16 *) Ptr;\r
- Ptr += sizeof (UINT16);\r
- Ptr += StrSize ((UINT16 *) Ptr);\r
- DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;\r
- if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) {\r
- SafeFreePool (BootOptionVar);\r
- continue;\r
- }\r
-\r
- Ptr += DevPathLen;\r
- if (DevType == ((BBS_TABLE *) Ptr)->DeviceType) {\r
- //\r
- // We don't want to process twice for a device type\r
- //\r
- SafeFreePool (BootOptionVar);\r
- continue;\r
- }\r
-\r
- Status = BdsSetBootPriority4SameTypeDev (\r
- ((BBS_TABLE *) Ptr)->DeviceType,\r
- LocalBbsTable,\r
- &Priority\r
- );\r
- SafeFreePool (BootOptionVar);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- }\r
-\r
- if (BootOrder) {\r
- SafeFreePool (BootOrder);\r
- }\r
- //\r
- // For debug\r
- //\r
- PrintBbsTable (LocalBbsTable);\r
-\r
- return Status;\r
-}\r