pcienumerator.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,178 行 · 第 1/4 页

C
2,178
字号

  //
  // Program Mem32 resources
  //
  ProgramResource (
    Mem32Base,
    Mem32Bridge
    );

  //
  // Program PMem32 resources
  //
  ProgramResource (
    PMem32Base,
    PMem32Bridge
    );

  //
  // Program Mem64 resources
  //
  ProgramResource (
    Mem64Base,
    Mem64Bridge
    );

  //
  // Program PMem64 resources
  //
  ProgramResource (
    PMem64Base,
    PMem64Bridge
    );

  DestroyResourceTree (IoBridge);
  DestroyResourceTree (Mem32Bridge);
  DestroyResourceTree (PMem32Bridge);
  DestroyResourceTree (PMem64Bridge);
  DestroyResourceTree (Mem64Bridge);

  gBS->FreePool (IoBridge);
  gBS->FreePool (Mem32Bridge);
  gBS->FreePool (PMem32Bridge);
  gBS->FreePool (PMem64Bridge);
  gBS->FreePool (Mem64Bridge);

  return EFI_SUCCESS;
}

EFI_STATUS
GetResourceBaseFromBridge (
  IN  PCI_IO_DEVICE *Bridge,
  OUT UINT64        *IoBase,
  OUT UINT64        *Mem32Base,
  OUT UINT64        *PMem32Base,
  OUT UINT64        *Mem64Base,
  OUT UINT64        *PMem64Base
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    Bridge - add argument and description to function comment
// TODO:    IoBase - add argument and description to function comment
// TODO:    Mem32Base - add argument and description to function comment
// TODO:    PMem32Base - add argument and description to function comment
// TODO:    Mem64Base - add argument and description to function comment
// TODO:    PMem64Base - add argument and description to function comment
// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  if (!Bridge->Allocated) {
    return EFI_OUT_OF_RESOURCES;
  }

  *IoBase     = gAllOne;
  *Mem32Base  = gAllOne;
  *PMem32Base = gAllOne;
  *Mem64Base  = gAllOne;
  *PMem64Base = gAllOne;

  if (IS_PCI_BRIDGE (&Bridge->Pci)) {

    if (Bridge->PciBar[PPB_IO_RANGE].Length) {
      *IoBase = Bridge->PciBar[PPB_IO_RANGE].BaseAddress;
    }

    if (Bridge->PciBar[PPB_MEM32_RANGE].Length) {
      *Mem32Base = Bridge->PciBar[PPB_MEM32_RANGE].BaseAddress;
    }

    if (Bridge->PciBar[PPB_PMEM32_RANGE].Length) {
      *PMem32Base = Bridge->PciBar[PPB_PMEM32_RANGE].BaseAddress;
    }

    if (Bridge->PciBar[PPB_PMEM64_RANGE].Length) {
      *PMem64Base = Bridge->PciBar[PPB_PMEM64_RANGE].BaseAddress;
    } else {
      *PMem64Base = gAllOne;
    }

  }

  if (IS_CARDBUS_BRIDGE (&Bridge->Pci)) {
    if (Bridge->PciBar[P2C_IO_1].Length) {
      *IoBase = Bridge->PciBar[P2C_IO_1].BaseAddress;
    } else {
      if (Bridge->PciBar[P2C_IO_2].Length) {
        *IoBase = Bridge->PciBar[P2C_IO_2].BaseAddress;
      }
    }

    if (Bridge->PciBar[P2C_MEM_1].Length) {
      if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypePMem32) {
        *PMem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;
      }

      if (Bridge->PciBar[P2C_MEM_1].BarType == PciBarTypeMem32) {
        *Mem32Base = Bridge->PciBar[P2C_MEM_1].BaseAddress;
      }
    }

    if (Bridge->PciBar[P2C_MEM_2].Length) {
      if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypePMem32) {
        *PMem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;
      }

      if (Bridge->PciBar[P2C_MEM_2].BarType == PciBarTypeMem32) {
        *Mem32Base = Bridge->PciBar[P2C_MEM_2].BaseAddress;
      }
    }
  }

  return EFI_SUCCESS;
}

EFI_STATUS
NotifyPhase (
  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *PciResAlloc,
  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE       Phase
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    PciResAlloc - add argument and description to function comment
// TODO:    Phase - add argument and description to function comment
// TODO:    EFI_NOT_FOUND - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  EFI_HANDLE                      HostBridgeHandle;
  EFI_HANDLE                      RootBridgeHandle;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
  EFI_STATUS                      Status;

  HostBridgeHandle  = NULL;
  RootBridgeHandle  = NULL;
  if (gPciPlatformProtocol != NULL) {
    //
    // Get Host Bridge Handle.
    //
    PciResAlloc->GetNextRootBridge (PciResAlloc, &RootBridgeHandle);

    //
    // Get the rootbridge Io protocol to find the host bridge handle
    //
    Status = gBS->HandleProtocol (
                    RootBridgeHandle,
                    &gEfiPciRootBridgeIoProtocolGuid,
                    (VOID **) &PciRootBridgeIo
                    );

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

    HostBridgeHandle = PciRootBridgeIo->ParentHandle;

    //
    // Call PlatformPci::PhaseNotify() if the protocol is present.
    //
    gPciPlatformProtocol->PhaseNotify (
                            gPciPlatformProtocol,
                            HostBridgeHandle,
                            Phase,
                            ChipsetEntry
                            );
  }

  Status = PciResAlloc->NotifyPhase (
                          PciResAlloc,
                          Phase
                          );

  if (gPciPlatformProtocol != NULL) {
    //
    // Call PlatformPci::PhaseNotify() if the protocol is present.
    //
    gPciPlatformProtocol->PhaseNotify (
                            gPciPlatformProtocol,
                            HostBridgeHandle,
                            Phase,
                            ChipsetExit
                            );

  }

  return EFI_SUCCESS;
}

EFI_STATUS
PreprocessController (
  IN PCI_IO_DEVICE                                    *Bridge,
  IN UINT8                                            Bus,
  IN UINT8                                            Device,
  IN UINT8                                            Func,
  IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE     Phase
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    Bridge - add argument and description to function comment
// TODO:    Bus - add argument and description to function comment
// TODO:    Device - add argument and description to function comment
// TODO:    Func - add argument and description to function comment
// TODO:    Phase - add argument and description to function comment
// TODO:    EFI_UNSUPPORTED - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS       RootBridgePciAddress;
  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL  *PciResAlloc;
  EFI_HANDLE                                        RootBridgeHandle;
  EFI_HANDLE                                        HostBridgeHandle;
  EFI_STATUS                                        Status;

  //
  // Get the host bridge handle
  //
  HostBridgeHandle = Bridge->PciRootBridgeIo->ParentHandle;

  //
  // Get the pci host bridge resource allocation protocol
  //
  Status = gBS->OpenProtocol (
                  HostBridgeHandle,
                  &gEfiPciHostBridgeResourceAllocationProtocolGuid,
                  (VOID **) &PciResAlloc,
                  NULL,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }
  
  //
  // Get Root Brige Handle
  //
  while (Bridge->Parent) {
    Bridge = Bridge->Parent;
  }

  RootBridgeHandle                      = Bridge->Handle;

  RootBridgePciAddress.Register         = 0;
  RootBridgePciAddress.Function         = Func;
  RootBridgePciAddress.Device           = Device;
  RootBridgePciAddress.Bus              = Bus;
  RootBridgePciAddress.ExtendedRegister = 0;

  if (gPciPlatformProtocol != NULL) {
    //
    // Call PlatformPci::PrepController() if the protocol is present.
    //
    gPciPlatformProtocol->PlatformPrepController (
                            gPciPlatformProtocol,
                            HostBridgeHandle,
                            RootBridgeHandle,
                            RootBridgePciAddress,
                            Phase,
                            ChipsetEntry
                            );
  }

  Status = PciResAlloc->PreprocessController (
                          PciResAlloc,
                          RootBridgeHandle,
                          RootBridgePciAddress,
                          Phase
                          );

  if (gPciPlatformProtocol != NULL) {
    //
    // Call PlatformPci::PrepController() if the protocol is present.
    //
    gPciPlatformProtocol->PlatformPrepController (
                            gPciPlatformProtocol,
                            HostBridgeHandle,
                            RootBridgeHandle,
                            RootBridgePciAddress,
                            Phase,
                            ChipsetExit
                            );
  }

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
PciHotPlugRequestNotify (
  IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL * This,
  IN EFI_PCI_HOTPLUG_OPERATION        Operation,
  IN EFI_HANDLE                       Controller,
  IN EFI_DEVICE_PATH_PROTOCOL         * RemainingDevicePath OPTIONAL,
  IN OUT UINT8                        *NumberOfChildren,
  IN OUT EFI_HANDLE                   * ChildHandleBuffer
  )
/*++

Routine Description:

  Hot plug request notify.
  
Arguments:

  This                 - A pointer to the hot plug request protocol.
  Operation            - The operation.
  Controller           - A pointer to the controller.
  RemainningDevicePath - A pointer to the device path.
  NumberOfChildren     - A the number of child handle in the ChildHandleBuffer.
  ChildHandleBuffer    - A pointer to the array contain the child handle.

Returns:

  Status code.

--*/
// TODO:    RemainingDevicePath - add argument and description to function comment
// TODO:    EFI_NOT_FOUND - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  PCI_IO_DEVICE       *Bridge;
  PCI_IO_DEVICE       *Temp;
  EFI_PCI_IO_PROTOCOL *PciIo;
  UINTN               Index;
  EFI_HANDLE          RootBridgeHandle;
  EFI_STATUS          Status;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **) &PciIo,
                  gPciBusDriverBinding.DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

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

  Bridge = PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo);

  //
  // Get root bridge handle
  //
  Temp = Bridge;
  while (Temp->Parent) {
    Temp = Temp->Parent;
  }

  RootBridgeHandle = Temp->Handle;

  if (Operation == EfiPciHotPlugRequestAdd) {

    if (NumberOfChildren != NULL) {
      *NumberOfChildren = 0;
    }

    if (IsListEmpty (&Bridge->ChildList)) {

      Status = PciBridgeEnumerator (Bridge);

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

    Status = StartPciDevicesOnBridge (
              RootBridgeHandle,
              Bridge,
              RemainingDevicePath,
              NumberOfChildren,
              ChildHandleBuffer
              );

    return EFI_SUCCESS;
  }

  if (Operation == EfiPciHotplugRequestRemove) {

    if (*NumberOfChildren == 0) {
      //
      // Remove all devices on the bridge
      //
      Status = RemoveAllPciDeviceOnBridge (RootBridgeHandle, Bridge);
      return Status;

    }

    for (Index = 0; Index < *NumberOfChildren; Index++) {
      //
      // De register all the pci device
      //
      Status = DeRegisterPciDevice (RootBridgeHandle, ChildHandleBuffer[Index]);

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

    }
    //
    // End for
    //
    return EFI_SUCCESS;
  }

  return EFI_SUCCESS;
}

BOOLEAN
SearchHostBridgeHandle (
  IN EFI_HANDLE RootBridgeHandle
  )
/*++

Routine Description:
  
Arguments:

Returns:

  None

--*/
// TODO:    RootBridgeHandle - add argument and description to function comment
{
  EFI_HANDLE                      HostBridgeHandle;
  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
  UINTN                           Index;
  EFI_STATUS                      Status;

  //
  // Get the rootbridge Io protocol to find the host bridge handle
  //
  Status = gBS->OpenProtocol (
                  RootBridgeHandle,
                  &gEfiPciRootBridgeIoProtocolGuid,
                  (VOID **) &PciRootBridgeIo,
                  gPciBusDriverBinding.DriverBindingHandle,
                  RootBridgeHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

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

  HostBridgeHandle = PciRootBridgeIo->ParentHandle;
  for (Index = 0; Index < gPciHostBridgeNumber; Index++) {
    if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {
      return TRUE;
    }
  }

  return FALSE;
}

EFI_STATUS
AddHostBridgeEnumerator (
  IN EFI_HANDLE HostBridgeHandle
  )
/*++

Routine Description:
  
Arguments:

Returns:

  None

--*/
// TODO:    HostBridgeHandle - add argument and description to function comment
// TODO:    EFI_ABORTED - add return value to function comment
// TODO:    EFI_ABORTED - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  UINTN Index;

  if (!HostBridgeHandle) {
    return EFI_ABORTED;
  }

  for (Index = 0; Index < gPciHostBridgeNumber; Index++) {
    if (HostBridgeHandle == gPciHostBrigeHandles[Index]) {
      return EFI_ABORTED;
    }
  }

  if (Index < PCI_MAX_HOST_BRIDGE_NUM) {
    gPciHostBrigeHandles[Index] = HostBridgeHandle;
    gPciHostBridgeNumber++;
  }

  return EFI_SUCCESS;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?