/** Internal helper function. Update the BBS Table so that devices of DeviceType have their boot priority updated to a high/bootable value. See "DeviceType values" in http://www.intel.com/content/dam/doc/reference-guide/efi-compatibility-support-module-specification-v097.pdf NOTE: This function should probably be refactored! Currently, all devices of type are enabled. This should be updated so that only a specific device is enabled. The wrong device could boot if there are multiple targets of the same type. @param DeviceType The device type that we wish to enable **/ VOID UpdateBbsTable (BDS_COMMON_OPTION *Option) { UINT16 Idx; EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; EFI_STATUS Status; UINT16 HddCount = 0; HDD_INFO *HddInfo = NULL; UINT16 BbsCount = 0; BBS_TABLE *LocalBbsTable = NULL; BBS_BBS_DEVICE_PATH *OptionBBS; CHAR16 Desc[100]; Status = refit_call3_wrapper(gBS->LocateProtocol, &gEfiLegacyBootProtocolGuid, NULL, (VOID **) &LegacyBios); if (EFI_ERROR (Status) || (Option == NULL)) { return; } OptionBBS = (BBS_BBS_DEVICE_PATH *) Option->DevicePath; Status = refit_call5_wrapper(LegacyBios->GetBbsInfo, LegacyBios, &HddCount, &HddInfo, &BbsCount, &LocalBbsTable); // Print (L"\n"); // Print (L" NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n"); // Print (L"=============================================\n"); for (Idx = 0; Idx < BbsCount; Idx++) { if(LocalBbsTable[Idx].DeviceType == 0) { continue; } BdsBuildLegacyDevNameString (&LocalBbsTable[Idx], Idx, sizeof (Desc), Desc); // Set devices of a particular type to BootPriority of 0 or 1. 0 is the highest priority. if (LocalBbsTable[Idx].DeviceType == OptionBBS->DeviceType) { if (StriCmp(Desc, Option->Description) == 0) { // This entry exactly matches what we're looking for; make it highest priority LocalBbsTable[Idx].BootPriority = 0; } else { // This entry doesn't exactly match, but is the right disk type; make it a bit lower // in priority. Done mainly as a fallback in case of string-matching weirdness. LocalBbsTable[Idx].BootPriority = 1; } // if/else } else if (LocalBbsTable[Idx].BootPriority <= 1) { // Something's got a high enough boot priority to interfere with booting // our chosen entry, so bump it down a bit.... LocalBbsTable[Idx].BootPriority = 2; } // if/else if // Print ( // L" %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n", // (UINTN) Idx, // (UINTN) LocalBbsTable[Idx].BootPriority, // (UINTN) LocalBbsTable[Idx].Bus, // (UINTN) LocalBbsTable[Idx].Device, // (UINTN) LocalBbsTable[Idx].Function, // (UINTN) LocalBbsTable[Idx].Class, // (UINTN) LocalBbsTable[Idx].SubClass, // (UINTN) LocalBbsTable[Idx].DeviceType, // (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags, // (UINTN) LocalBbsTable[Idx].BootHandlerSegment, // (UINTN) LocalBbsTable[Idx].BootHandlerOffset, // (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset), // (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset) // ); // Print(L"%s\n", Desc); } // for // PauseForKey(); }
EFI_STATUS BOpt_GetLegacyOptions ( VOID ) /*++ Routine Description: Build the LegacyFDMenu LegacyHDMenu LegacyCDMenu according to LegacyBios.GetBbsInfo(). Arguments: None Returns: The device info of legacy device. --*/ { BM_MENU_ENTRY *NewMenuEntry; BM_LEGACY_DEVICE_CONTEXT *NewLegacyDevContext; EFI_STATUS Status; EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; UINT16 HddCount; HDD_INFO *HddInfo; UINT16 BbsCount; BBS_TABLE *BbsTable; UINTN Index; CHAR16 DescString[100]; UINTN FDNum; UINTN HDNum; UINTN CDNum; UINTN NETNum; UINTN BEVNum; NewMenuEntry = NULL; HddInfo = NULL; BbsTable = NULL; BbsCount = 0; // // Initialize Bbs Table Context from BBS info data // InitializeListHead (&LegacyFDMenu.Head); InitializeListHead (&LegacyHDMenu.Head); InitializeListHead (&LegacyCDMenu.Head); InitializeListHead (&LegacyNETMenu.Head); InitializeListHead (&LegacyBEVMenu.Head); Status = gBS->LocateProtocol ( &gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios ); if (!EFI_ERROR (Status)) { Status = LegacyBios->GetBbsInfo ( LegacyBios, &HddCount, &HddInfo, &BbsCount, &BbsTable ); if (EFI_ERROR (Status)) { return Status; } } FDNum = 0; HDNum = 0; CDNum = 0; NETNum = 0; BEVNum = 0; for (Index = 0; Index < BbsCount; Index++) { if ((BBS_IGNORE_ENTRY == BbsTable[Index].BootPriority) || (BBS_DO_NOT_BOOT_FROM == BbsTable[Index].BootPriority) ) { continue; } NewMenuEntry = BOpt_CreateMenuEntry (BM_LEGACY_DEV_CONTEXT_SELECT); if (NULL == NewMenuEntry) { break; } NewLegacyDevContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext; NewLegacyDevContext->BbsTable = &BbsTable[Index]; NewLegacyDevContext->Index = Index; NewLegacyDevContext->BbsCount = BbsCount; BdsBuildLegacyDevNameString ( &BbsTable[Index], Index, sizeof (DescString), DescString ); NewLegacyDevContext->Description = EfiAllocateZeroPool (EfiStrSize (DescString)); if (NULL == NewLegacyDevContext->Description) { break; } EfiCopyMem (NewLegacyDevContext->Description, DescString, EfiStrSize (DescString)); NewMenuEntry->DisplayString = NewLegacyDevContext->Description; NewMenuEntry->HelpString = NULL; switch (BbsTable[Index].DeviceType) { case BBS_FLOPPY: InsertTailList (&LegacyFDMenu.Head, &NewMenuEntry->Link); FDNum++; break; case BBS_HARDDISK: InsertTailList (&LegacyHDMenu.Head, &NewMenuEntry->Link); HDNum++; break; case BBS_CDROM: InsertTailList (&LegacyCDMenu.Head, &NewMenuEntry->Link); CDNum++; break; case BBS_EMBED_NETWORK: InsertTailList (&LegacyNETMenu.Head, &NewMenuEntry->Link); NETNum++; break; case BBS_BEV_DEVICE: InsertTailList (&LegacyBEVMenu.Head, &NewMenuEntry->Link); BEVNum++; break; } } if (Index != BbsCount) { BOpt_FreeLegacyOptions (); return EFI_OUT_OF_RESOURCES; } LegacyFDMenu.MenuNumber = FDNum; LegacyHDMenu.MenuNumber = HDNum; LegacyCDMenu.MenuNumber = CDNum; LegacyNETMenu.MenuNumber = NETNum; LegacyBEVMenu.MenuNumber = BEVNum; return EFI_SUCCESS; }