Ejemplo n.º 1
0
EFI_STATUS
PciRomLoadEfiDriversFromOptionRomTable (
  IN EFI_DRIVER_BINDING_PROTOCOL      *This,
  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL  *PciRootBridgeIo
  )
/*++

Routine Description:

Arguments:

Returns:

--*/
{
  EFI_STATUS                        Status;
  EFI_PCI_OPTION_ROM_TABLE          *PciOptionRomTable;
  EFI_PCI_OPTION_ROM_DESCRIPTOR     *PciOptionRomDescriptor;
  UINTN                             Index;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;
  UINT16                            MinBus;
  UINT16                            MaxBus;

  Status = EfiGetSystemConfigurationTable (&gEfiPciOptionRomTableGuid, (VOID **) &PciOptionRomTable);
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  Status = EFI_NOT_FOUND;

  for (Index = 0; Index < PciOptionRomTable->PciOptionRomCount; Index++) {
    PciOptionRomDescriptor = &PciOptionRomTable->PciOptionRomDescriptors[Index];
    if (!PciOptionRomDescriptor->DontLoadEfiRom) {
      if (PciOptionRomDescriptor->Seg == PciRootBridgeIo->SegmentNumber) {
        Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);
        if (EFI_ERROR (Status)) {
          return Status;
        }

        PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL);
        if ((MinBus <= PciOptionRomDescriptor->Bus) && (PciOptionRomDescriptor->Bus <= MaxBus)) {
          Status = PciRomLoadEfiDriversFromRomImage (This, PciOptionRomDescriptor);
          PciOptionRomDescriptor->DontLoadEfiRom |= 2;
        }
      }
    }
  }

  return Status;
}
EFI_STATUS
PciEnumeratorLight (
  IN EFI_HANDLE                    Controller
  )
/*++

Routine Description:

  This routine is used to enumerate entire pci bus system 
  in a given platform

Arguments:

Returns:

  None

--*/
{

  EFI_STATUS                        Status;
  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *PciRootBridgeIo;
  PCI_IO_DEVICE                     *RootBridgeDev;
  UINT16                            MinBus;
  UINT16                            MaxBus;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;

  MinBus      = 0;
  MaxBus      = PCI_MAX_BUS;
  Descriptors = NULL;

  //
  // If this host bridge has been already enumerated, then return successfully
  //
  if (RootBridgeExisted (Controller)) {
    return EFI_SUCCESS;
  }

  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  Controller      ,   
                  &gEfiDevicePathProtocolGuid,  
                  (VOID **)&ParentDevicePath,
                  gPciBusDriverBinding.DriverBindingHandle,     
                  Controller,   
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  //
  // Open pci root bridge io protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciRootBridgeIoProtocolGuid,
                  (VOID **) &PciRootBridgeIo,
                  gPciBusDriverBinding.DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  //
  // Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge 
  //
  /*Status = */PciRomLoadEfiDriversFromOptionRomTable (&gPciBusDriverBinding, PciRootBridgeIo);

  Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {

    //
    // Create a device node for root bridge device with a NULL host bridge controller handle
    //
    RootBridgeDev = CreateRootBridge (Controller);

    //
    // Record the root bridge device path
    //
    RootBridgeDev->DevicePath = ParentDevicePath;

    //
    // Record the root bridge io protocol
    //
    RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;

    Status = PciPciDeviceInfoCollector (
              RootBridgeDev,
              (UINT8) MinBus
              );

    if (!EFI_ERROR (Status)) {

      //
      // If successfully, insert the node into device pool
      //
      InsertRootBridge (RootBridgeDev);
    } else {

      //
      // If unsuccessly, destroy the entire node
      //
      DestroyRootBridge (RootBridgeDev);
    }

    Descriptors++;
  }

  return EFI_SUCCESS;
}