Esempio n. 1
0
/**
  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;
}
Esempio n. 2
0
/**
  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;

}