UINTN mBootOptionBbsMappingCount = 0;
extern EFI_DEVICE_PATH EndDevicePath[];
+extern EFI_GUID gEfiLegacyBiosProtocolGuid;
+EFI_GUID gEfiLegacyDevOrderVariableGuid = { 0xa56074db, 0x65fe, 0x45f7, {0xbd, 0x21, 0x2d, 0x2b, 0xdd, 0x8e, 0x96, 0x52 }};
/**
return EFI_OUT_OF_RESOURCES;
}
}
-
+
//
// Skip Non-Legacy boot option
//
}
/**
- Add the legacy boot devices from BBS table into
- the legacy device boot order.
-
- @retval EFI_SUCCESS The boot devices are added successfully.
- @retval EFI_NOT_FOUND The legacy boot devices are not found.
- @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
- @retval EFI_DEVICE_ERROR Fail to add the legacy device boot order into EFI variable
- because of hardware error.
+ Fill the device order buffer.
+
+ @param BbsTable The BBS table.
+ @param BbsType The BBS Type.
+ @param BbsCount The BBS Count.
+ @param Buf device order buffer.
+
+ @return The device order buffer.
+
**/
-// EFI_STATUS
-// EFIAPI
-// BdsUpdateLegacyDevOrder (
-// VOID
-// )
-// {
-// LEGACY_DEV_ORDER_ENTRY *DevOrder;
-// LEGACY_DEV_ORDER_ENTRY *NewDevOrder;
-// LEGACY_DEV_ORDER_ENTRY *Ptr;
-// LEGACY_DEV_ORDER_ENTRY *NewPtr;
-// UINTN DevOrderSize;
-// EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
-// EFI_STATUS Status;
-// UINT16 HddCount;
-// UINT16 BbsCount;
-// HDD_INFO *LocalHddInfo;
-// BBS_TABLE *LocalBbsTable;
-// UINTN Index;
-// UINTN Index2;
-// UINTN *Idx;
-// UINTN FDCount;
-// UINTN HDCount;
-// UINTN CDCount;
-// UINTN NETCount;
-// UINTN BEVCount;
-// UINTN TotalSize;
-// UINTN HeaderSize;
-// UINT16 *NewFDPtr;
-// UINT16 *NewHDPtr;
-// UINT16 *NewCDPtr;
-// UINT16 *NewNETPtr;
-// UINT16 *NewBEVPtr;
-// UINT16 *NewDevPtr;
-// UINTN FDIndex;
-// UINTN HDIndex;
-// UINTN CDIndex;
-// UINTN NETIndex;
-// UINTN BEVIndex;
-//
-// Idx = NULL;
-// FDCount = 0;
-// HDCount = 0;
-// CDCount = 0;
-// NETCount = 0;
-// BEVCount = 0;
-// TotalSize = 0;
-// HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16);
-// FDIndex = 0;
-// HDIndex = 0;
-// CDIndex = 0;
-// NETIndex = 0;
-// BEVIndex = 0;
-// NewDevPtr = NULL;
-//
-// Status = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID **) &LegacyBios);
-// if (EFI_ERROR (Status)) {
-// return Status;
-// }
-//
-// Status = LegacyBios->GetBbsInfo (
-// LegacyBios,
-// &HddCount,
-// &LocalHddInfo,
-// &BbsCount,
-// &LocalBbsTable
-// );
-// if (EFI_ERROR (Status)) {
-// return Status;
-// }
-//
-// DevOrder = BdsLibGetVariableAndSize (
-// VAR_LEGACY_DEV_ORDER,
-// &gEfiLegacyDevOrderVariableGuid,
-// &DevOrderSize
-// );
-// if (NULL == DevOrder) {
-// return BdsCreateDevOrder (LocalBbsTable, BbsCount);
-// }
-// //
-// // First we figure out how many boot devices with same device type respectively
-// //
-// for (Index = 0; Index < BbsCount; Index++) {
-// if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
-// (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
-// ) {
-// continue;
-// }
-//
-// switch (LocalBbsTable[Index].DeviceType) {
-// case BBS_FLOPPY:
-// FDCount++;
-// break;
-//
-// case BBS_HARDDISK:
-// HDCount++;
-// break;
-//
-// case BBS_CDROM:
-// CDCount++;
-// break;
-//
-// case BBS_EMBED_NETWORK:
-// NETCount++;
-// break;
-//
-// case BBS_BEV_DEVICE:
-// BEVCount++;
-// break;
-//
-// default:
-// break;
-// }
-// }
-//
-// TotalSize += (HeaderSize + FDCount * sizeof (UINT16));
-// TotalSize += (HeaderSize + HDCount * sizeof (UINT16));
-// TotalSize += (HeaderSize + CDCount * sizeof (UINT16));
-// TotalSize += (HeaderSize + NETCount * sizeof (UINT16));
-// TotalSize += (HeaderSize + BEVCount * sizeof (UINT16));
-//
-// NewDevOrder = AllocateZeroPool (TotalSize);
-// if (NULL == NewDevOrder) {
-// return EFI_OUT_OF_RESOURCES;
-// }
-//
-//
-//
-// //
-// // copy FD
-// //
-// Ptr = DevOrder;
-// NewPtr = NewDevOrder;
-// NewPtr->BbsType = Ptr->BbsType;
-// NewPtr->Length = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16));
-// for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
-// if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY
-// ) {
-// continue;
-// }
-//
-// NewPtr->Data[FDIndex] = Ptr->Data[Index];
-// FDIndex++;
-// }
-// NewFDPtr = NewPtr->Data;
-//
-// //
-// // copy HD
-// //
-// Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
-// NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
-// NewPtr->BbsType = Ptr->BbsType;
-// NewPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
-// for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
-// if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK
-// ) {
-// continue;
-// }
-//
-// NewPtr->Data[HDIndex] = Ptr->Data[Index];
-// HDIndex++;
-// }
-// NewHDPtr = NewPtr->Data;
-//
-// //
-// // copy CD
-// //
-// Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
-// NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
-// NewPtr->BbsType = Ptr->BbsType;
-// NewPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
-// for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
-// if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM
-// ) {
-// continue;
-// }
-//
-// NewPtr->Data[CDIndex] = Ptr->Data[Index];
-// CDIndex++;
-// }
-// NewCDPtr = NewPtr->Data;
-//
-// //
-// // copy NET
-// //
-// Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
-// NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
-// NewPtr->BbsType = Ptr->BbsType;
-// NewPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
-// for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
-// if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK
-// ) {
-// continue;
-// }
-//
-// NewPtr->Data[NETIndex] = Ptr->Data[Index];
-// NETIndex++;
-// }
-// NewNETPtr = NewPtr->Data;
-//
-// //
-// // copy BEV
-// //
-// Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]);
-// NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]);
-// NewPtr->BbsType = Ptr->BbsType;
-// NewPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
-// for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) {
-// if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY ||
-// LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE
-// ) {
-// continue;
-// }
-//
-// NewPtr->Data[BEVIndex] = Ptr->Data[Index];
-// BEVIndex++;
-// }
-// NewBEVPtr = NewPtr->Data;
-//
-// for (Index = 0; Index < BbsCount; Index++) {
-// if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) ||
-// (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM)
-// ) {
-// continue;
-// }
-//
-// switch (LocalBbsTable[Index].DeviceType) {
-// case BBS_FLOPPY:
-// Idx = &FDIndex;
-// NewDevPtr = NewFDPtr;
-// break;
-//
-// case BBS_HARDDISK:
-// Idx = &HDIndex;
-// NewDevPtr = NewHDPtr;
-// break;
-//
-// case BBS_CDROM:
-// Idx = &CDIndex;
-// NewDevPtr = NewCDPtr;
-// break;
-//
-// case BBS_EMBED_NETWORK:
-// Idx = &NETIndex;
-// NewDevPtr = NewNETPtr;
-// break;
-//
-// case BBS_BEV_DEVICE:
-// Idx = &BEVIndex;
-// NewDevPtr = NewBEVPtr;
-// break;
-//
-// default:
-// Idx = NULL;
-// break;
-// }
-// //
-// // at this point we have copied those valid indexes to new buffer
-// // and we should check if there is any new appeared boot device
-// //
-// if (Idx != NULL) {
-// for (Index2 = 0; Index2 < *Idx; Index2++) {
-// if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) {
-// break;
-// }
-// }
-//
-// if (Index2 == *Idx) {
-// //
-// // Index2 == *Idx means we didn't find Index
-// // so Index is a new appeared device's index in BBS table
-// // insert it before disabled indexes.
-// //
-// for (Index2 = 0; Index2 < *Idx; Index2++) {
-// if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) {
-// break;
-// }
-// }
-// CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16));
-// NewDevPtr[Index2] = (UINT16) (Index & 0xFF);
-// (*Idx)++;
-// }
-// }
-// }
-//
-// FreePool (DevOrder);
-//
-// Status = gRT->SetVariable (
-// VAR_LEGACY_DEV_ORDER,
-// &gEfiLegacyDevOrderVariableGuid,
-// VAR_FLAG,
-// TotalSize,
-// NewDevOrder
-// );
-// FreePool (NewDevOrder);
-//
-// return Status;
-// }
+UINT16 *
+BdsFillDevOrderBuf (
+ IN BBS_TABLE *BbsTable,
+ IN BBS_TYPE BbsType,
+ IN UINTN BbsCount,
+ OUT UINT16 *Buf
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < BbsCount; Index++) {
+ if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
+ continue;
+ }
+
+ if (BbsTable[Index].DeviceType != BbsType) {
+ continue;
+ }
+
+ *Buf = (UINT16) (Index & 0xFF);
+ Buf++;
+ }
+
+ return Buf;
+}
+
+/**
+ Create the device order buffer.
+
+ @param BbsTable The BBS table.
+ @param BbsCount The BBS Count.
+
+ @retval EFI_SUCCES The buffer is created and the EFI variable named
+ VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid is
+ set correctly.
+ @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough.
+ @retval EFI_DEVICE_ERROR Fail to add the device order into EFI variable fail
+ because of hardware error.
+**/
+EFI_STATUS
+BdsCreateDevOrder (
+ IN BBS_TABLE *BbsTable,
+ IN UINT16 BbsCount
+ )
+{
+ UINTN Index;
+ UINTN FDCount;
+ UINTN HDCount;
+ UINTN CDCount;
+ UINTN NETCount;
+ UINTN BEVCount;
+ UINTN TotalSize;
+ UINTN HeaderSize;
+ LEGACY_DEV_ORDER_ENTRY *DevOrder;
+ LEGACY_DEV_ORDER_ENTRY *DevOrderPtr;
+ EFI_STATUS Status;
+
+ FDCount = 0;
+ HDCount = 0;
+ CDCount = 0;
+ NETCount = 0;
+ BEVCount = 0;
+ TotalSize = 0;
+ HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16);
+ DevOrder = NULL;
+ Status = EFI_SUCCESS;
+
+ //
+ // Count all boot devices
+ //
+ for (Index = 0; Index < BbsCount; Index++) {
+ if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
+ continue;
+ }
+
+ switch (BbsTable[Index].DeviceType) {
+ case BBS_FLOPPY:
+ FDCount++;
+ break;
+
+ case BBS_HARDDISK:
+ HDCount++;
+ break;
+
+ case BBS_CDROM:
+ CDCount++;
+ break;
+
+ case BBS_EMBED_NETWORK:
+ NETCount++;
+ break;
+
+ case BBS_BEV_DEVICE:
+ BEVCount++;
+ break;
+ default:
+ break;
+ }
+ }
+
+ TotalSize += (HeaderSize + sizeof (UINT16) * FDCount);
+ TotalSize += (HeaderSize + sizeof (UINT16) * HDCount);
+ TotalSize += (HeaderSize + sizeof (UINT16) * CDCount);
+ TotalSize += (HeaderSize + sizeof (UINT16) * NETCount);
+ TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount);
+
+ //
+ // Create buffer to hold all boot device order
+ //
+ DevOrder = AllocateZeroPool (TotalSize);
+ if (NULL == DevOrder) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ DevOrderPtr = DevOrder;
+
+ DevOrderPtr->BbsType = BBS_FLOPPY;
+ DevOrderPtr->Length = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16));
+ DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data);
+
+ DevOrderPtr->BbsType = BBS_HARDDISK;
+ DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16));
+ DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data);
+
+ DevOrderPtr->BbsType = BBS_CDROM;
+ DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16));
+ DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data);
+
+ DevOrderPtr->BbsType = BBS_EMBED_NETWORK;
+ DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16));
+ DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data);
+
+ DevOrderPtr->BbsType = BBS_BEV_DEVICE;
+ DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16));
+ DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data);
+
+ ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *) DevOrder));
+
+ //
+ // Save device order for legacy boot device to variable.
+ //
+ Status = gRT->SetVariable (
+ VAR_LEGACY_DEV_ORDER,
+ &gEfiLegacyDevOrderVariableGuid,
+ VAR_FLAG,
+ TotalSize,
+ DevOrder
+ );
+ FreePool (DevOrder);
+
+ return Status;
+}