/** Complete build of BBS TABLE. @param Private Legacy BIOS Instance data @param BbsTable BBS Table passed to 16-bit code @retval EFI_SUCCESS Removable media not present **/ EFI_STATUS LegacyBiosBuildBbs ( IN LEGACY_BIOS_INSTANCE *Private, IN BBS_TABLE *BbsTable ) { UINTN BbsIndex; HDD_INFO *HddInfo; UINTN HddIndex; UINTN Index; // // First entry is floppy. // Next 2*MAX_IDE_CONTROLLER entries are for onboard IDE. // Next n entries are filled in after each ROM is dispatched. // Entry filled in if follow BBS spec. See LegacyPci.c // Next entries are for non-BBS compliant ROMS. They are filled in by // 16-bit code during Legacy16UpdateBbs invocation. Final BootPriority // occurs after that invocation. // // Floppy // Set default state. // IsHaveMediaInFloppy = HasMediaInFloppy (); if (IsHaveMediaInFloppy == FLOPPY_PRESENT_WITH_MEDIA) { BbsTable[0].BootPriority = BBS_UNPRIORITIZED_ENTRY; } else { if (IsHaveMediaInFloppy == FLOPPY_PRESENT_NO_MEDIA) { BbsTable[0].BootPriority = BBS_LOWEST_PRIORITY; } else { BbsTable[0].BootPriority = BBS_IGNORE_ENTRY; } } BbsTable[0].Bus = 0xff; BbsTable[0].Device = 0xff; BbsTable[0].Function = 0xff; BbsTable[0].DeviceType = BBS_FLOPPY; BbsTable[0].Class = 01; BbsTable[0].SubClass = 02; BbsTable[0].StatusFlags.OldPosition = 0; BbsTable[0].StatusFlags.Reserved1 = 0; BbsTable[0].StatusFlags.Enabled = 0; BbsTable[0].StatusFlags.Failed = 0; BbsTable[0].StatusFlags.MediaPresent = 0; BbsTable[0].StatusFlags.Reserved2 = 0; // // Onboard HDD - Note Each HDD controller controls 2 drives // Master & Slave // HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0]; // // Get IDE Drive Info // LegacyBiosBuildIdeData (Private, &HddInfo, 0); for (HddIndex = 0; HddIndex < MAX_IDE_CONTROLLER; HddIndex++) { BbsIndex = HddIndex * 2 + 1; for (Index = 0; Index < 2; ++Index) { BbsTable[BbsIndex + Index].Bus = HddInfo[HddIndex].Bus; BbsTable[BbsIndex + Index].Device = HddInfo[HddIndex].Device; BbsTable[BbsIndex + Index].Function = HddInfo[HddIndex].Function; BbsTable[BbsIndex + Index].Class = 01; BbsTable[BbsIndex + Index].SubClass = 01; BbsTable[BbsIndex + Index].StatusFlags.OldPosition = 0; BbsTable[BbsIndex + Index].StatusFlags.Reserved1 = 0; BbsTable[BbsIndex + Index].StatusFlags.Enabled = 0; BbsTable[BbsIndex + Index].StatusFlags.Failed = 0; BbsTable[BbsIndex + Index].StatusFlags.MediaPresent = 0; BbsTable[BbsIndex + Index].StatusFlags.Reserved2 = 0; // // If no controller found or no device found set to ignore // else set to unprioritized and set device type // if (HddInfo[HddIndex].CommandBaseAddress == 0) { BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; } else { if (Index == 0) { if ((HddInfo[HddIndex].Status & (HDD_MASTER_IDE | HDD_MASTER_ATAPI_CDROM | HDD_MASTER_ATAPI_ZIPDISK)) != 0) { BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY; if ((HddInfo[HddIndex].Status & HDD_MASTER_IDE) != 0) { BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; } else if ((HddInfo[HddIndex].Status & HDD_MASTER_ATAPI_CDROM) != 0) { BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM; } else { // // for ZIPDISK // BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; } } else { BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; } } else { if ((HddInfo[HddIndex].Status & (HDD_SLAVE_IDE | HDD_SLAVE_ATAPI_CDROM | HDD_SLAVE_ATAPI_ZIPDISK)) != 0) { BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY; if ((HddInfo[HddIndex].Status & HDD_SLAVE_IDE) != 0) { BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; } else if ((HddInfo[HddIndex].Status & HDD_SLAVE_ATAPI_CDROM) != 0) { BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM; } else { // // for ZIPDISK // BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; } } else { BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; } } } } } // // add virtio-blk devices // { EFI_STATUS Status; UINTN NumPciIoHandles; EFI_HANDLE *PciIoHandles; BbsIndex = HddIndex * 2 + 1; // // scan all handles supporting the PCI IO protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiPciIoProtocolGuid, NULL, &NumPciIoHandles, &PciIoHandles ); if (Status == EFI_SUCCESS) { UINTN CurPciIo; for (CurPciIo = 0; CurPciIo < NumPciIoHandles; ++CurPciIo) { EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *References; UINTN NumReferences; UINTN CurRef; // // on each handle supporting the PCI IO protocol, see which drivers // (agents) have a PCI IO protocol interface actually opened // Status = gBS->OpenProtocolInformation ( PciIoHandles[CurPciIo], &gEfiPciIoProtocolGuid, &References, &NumReferences ); if (EFI_ERROR (Status)) { continue; } for (CurRef = 0; CurRef < NumReferences; ++CurRef) { if (References[CurRef].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) { EFI_COMPONENT_NAME2_PROTOCOL *ComponentName; CHAR16 *DriverName; // // OpenProtocol() enforced non-NULL AgentHandle for this case // ASSERT (References[CurRef].AgentHandle != NULL); // // Check if the agent owning the open protocol interface can // provide its name, and if so, whether it's VirtioBlkDxe. For this // check we don't want a persistent reference to the agent's // EFI_COMPONENT_NAME2_PROTOCOL instance, therefore we use // HandleProtocol() instead of OpenProtocol(). // Status = gBS->HandleProtocol ( References[CurRef].AgentHandle, &gEfiComponentName2ProtocolGuid, (VOID **) &ComponentName ); if (EFI_ERROR (Status)) { continue; } Status = ComponentName->GetDriverName ( ComponentName, "en", &DriverName ); if (Status == EFI_SUCCESS && StrCmp (DriverName, L"Virtio Block Driver") == 0) { break; } } } if (CurRef < NumReferences) { EFI_PCI_IO_PROTOCOL *PciIo; UINTN Segment; UINTN Bus; UINTN Device; UINTN Function; // // reference by VirtioBlkDxe found, produce boot entry for device // Status = gBS->HandleProtocol ( PciIoHandles[CurPciIo], &gEfiPciIoProtocolGuid, (VOID **) &PciIo ); ASSERT (Status == EFI_SUCCESS); Status = PciIo->GetLocation ( PciIo, &Segment, &Bus, &Device, &Function ); ASSERT (Status == EFI_SUCCESS); if (Segment == 0) { BbsTable[BbsIndex].Bus = (UINT32) Bus; BbsTable[BbsIndex].Device = (UINT32) Device; BbsTable[BbsIndex].Function = (UINT32) Function; BbsTable[BbsIndex].Class = 1; BbsTable[BbsIndex].SubClass = 0x80; BbsTable[BbsIndex].StatusFlags.OldPosition = 0; BbsTable[BbsIndex].StatusFlags.Reserved1 = 0; BbsTable[BbsIndex].StatusFlags.Enabled = 0; BbsTable[BbsIndex].StatusFlags.Failed = 0; BbsTable[BbsIndex].StatusFlags.MediaPresent = 0; BbsTable[BbsIndex].StatusFlags.Reserved2 = 0; BbsTable[BbsIndex].DeviceType = BBS_HARDDISK; BbsTable[BbsIndex].BootPriority = BBS_UNPRIORITIZED_ENTRY; ++BbsIndex; } } FreePool (References); } FreePool (PciIoHandles); } } return EFI_SUCCESS; }
/** Complete build of BBS TABLE. @param Private Legacy BIOS Instance data @param BbsTable BBS Table passed to 16-bit code @retval EFI_SUCCESS Removable media not present **/ EFI_STATUS LegacyBiosBuildBbs ( IN LEGACY_BIOS_INSTANCE *Private, IN BBS_TABLE *BbsTable ) { UINTN BbsIndex; HDD_INFO *HddInfo; UINTN HddIndex; UINTN Index; // // First entry is floppy. // Next 2*MAX_IDE_CONTROLLER entries are for onboard IDE. // Next n entries are filled in after each ROM is dispatched. // Entry filled in if follow BBS spec. See LegacyPci.c // Next entries are for non-BBS compliant ROMS. They are filled in by // 16-bit code during Legacy16UpdateBbs invocation. Final BootPriority // occurs after that invocation. // // Floppy // Set default state. // IsHaveMediaInFloppy = HasMediaInFloppy (); if (IsHaveMediaInFloppy == FLOPPY_PRESENT_WITH_MEDIA) { BbsTable[0].BootPriority = BBS_UNPRIORITIZED_ENTRY; } else { if (IsHaveMediaInFloppy == FLOPPY_PRESENT_NO_MEDIA) { BbsTable[0].BootPriority = BBS_LOWEST_PRIORITY; } else { BbsTable[0].BootPriority = BBS_IGNORE_ENTRY; } } BbsTable[0].Bus = 0xff; BbsTable[0].Device = 0xff; BbsTable[0].Function = 0xff; BbsTable[0].DeviceType = BBS_FLOPPY; BbsTable[0].Class = 01; BbsTable[0].SubClass = 02; BbsTable[0].StatusFlags.OldPosition = 0; BbsTable[0].StatusFlags.Reserved1 = 0; BbsTable[0].StatusFlags.Enabled = 0; BbsTable[0].StatusFlags.Failed = 0; BbsTable[0].StatusFlags.MediaPresent = 0; BbsTable[0].StatusFlags.Reserved2 = 0; // // Onboard HDD - Note Each HDD controller controls 2 drives // Master & Slave // HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0]; // // Get IDE Drive Info // LegacyBiosBuildIdeData (Private, &HddInfo, 0); for (HddIndex = 0; HddIndex < MAX_IDE_CONTROLLER; HddIndex++) { BbsIndex = HddIndex * 2 + 1; for (Index = 0; Index < 2; ++Index) { BbsTable[BbsIndex + Index].Bus = HddInfo[HddIndex].Bus; BbsTable[BbsIndex + Index].Device = HddInfo[HddIndex].Device; BbsTable[BbsIndex + Index].Function = HddInfo[HddIndex].Function; BbsTable[BbsIndex + Index].Class = 01; BbsTable[BbsIndex + Index].SubClass = 01; BbsTable[BbsIndex + Index].StatusFlags.OldPosition = 0; BbsTable[BbsIndex + Index].StatusFlags.Reserved1 = 0; BbsTable[BbsIndex + Index].StatusFlags.Enabled = 0; BbsTable[BbsIndex + Index].StatusFlags.Failed = 0; BbsTable[BbsIndex + Index].StatusFlags.MediaPresent = 0; BbsTable[BbsIndex + Index].StatusFlags.Reserved2 = 0; // // If no controller found or no device found set to ignore // else set to unprioritized and set device type // if (HddInfo[HddIndex].CommandBaseAddress == 0) { BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; } else { if (Index == 0) { if ((HddInfo[HddIndex].Status & (HDD_MASTER_IDE | HDD_MASTER_ATAPI_CDROM | HDD_MASTER_ATAPI_ZIPDISK)) != 0) { BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY; if ((HddInfo[HddIndex].Status & HDD_MASTER_IDE) != 0) { BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; } else if ((HddInfo[HddIndex].Status & HDD_MASTER_ATAPI_CDROM) != 0) { BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM; } else { // // for ZIPDISK // BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; } } else { BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; } } else { if ((HddInfo[HddIndex].Status & (HDD_SLAVE_IDE | HDD_SLAVE_ATAPI_CDROM | HDD_SLAVE_ATAPI_ZIPDISK)) != 0) { BbsTable[BbsIndex + Index].BootPriority = BBS_UNPRIORITIZED_ENTRY; if ((HddInfo[HddIndex].Status & HDD_SLAVE_IDE) != 0) { BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; } else if ((HddInfo[HddIndex].Status & HDD_SLAVE_ATAPI_CDROM) != 0) { BbsTable[BbsIndex + Index].DeviceType = BBS_CDROM; } else { // // for ZIPDISK // BbsTable[BbsIndex + Index].DeviceType = BBS_HARDDISK; } } else { BbsTable[BbsIndex + Index].BootPriority = BBS_IGNORE_ENTRY; } } } } } return EFI_SUCCESS; }