pcienumerator.c

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

C
2,178
字号
        EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT,
        0,
        &gEfiCallerIdGuid,
        (EFI_STATUS_CODE_DATA *) &AllocFailExtendedData
        );

      //
      // Add it to the array and indicate at least a device has been rejected
      //
      RemovedPciDev[RemovedPciDevNum++] = PciResNode->PciDev;
      AllocationAjusted                 = TRUE;
    }
  }
  //
  // End for
  //

  if (AllocationAjusted) {
    return EFI_SUCCESS;
  } else {
    return EFI_ABORTED;
  }
}

EFI_STATUS
ConstructAcpiResourceRequestor (
  IN PCI_IO_DEVICE      *Bridge,
  IN PCI_RESOURCE_NODE  *IoNode,
  IN PCI_RESOURCE_NODE  *Mem32Node,
  IN PCI_RESOURCE_NODE  *PMem32Node,
  IN PCI_RESOURCE_NODE  *Mem64Node,
  IN PCI_RESOURCE_NODE  *PMem64Node,
  OUT VOID              **pConfig
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    Bridge - add argument and description to function comment
// TODO:    IoNode - add argument and description to function comment
// TODO:    Mem32Node - add argument and description to function comment
// TODO:    PMem32Node - add argument and description to function comment
// TODO:    Mem64Node - add argument and description to function comment
// TODO:    PMem64Node - add argument and description to function comment
// TODO:    pConfig - add argument and description to function comment
// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  UINT8                             NumConfig;
  UINT8                             Aperture;
  UINT8                             *Configuration;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
  EFI_ACPI_END_TAG_DESCRIPTOR       *PtrEnd;

  NumConfig = 0;
  Aperture  = 0;

  *pConfig  = NULL;

  //
  // if there is io request, add to the io aperture
  //
  if (ResourceRequestExisted (IoNode)) {
    NumConfig++;
    Aperture |= 0x01;
  }

  //
  // if there is mem32 request, add to the mem32 aperture
  //
  if (ResourceRequestExisted (Mem32Node)) {
    NumConfig++;
    Aperture |= 0x02;
  }

  //
  // if there is pmem32 request, add to the pmem32 aperture
  //
  if (ResourceRequestExisted (PMem32Node)) {
    NumConfig++;
    Aperture |= 0x04;
  }

  //
  // if there is mem64 request, add to the mem64 aperture
  //
  if (ResourceRequestExisted (Mem64Node)) {
    NumConfig++;
    Aperture |= 0x08;
  }

  //
  // if there is pmem64 request, add to the pmem64 aperture
  //
  if (ResourceRequestExisted (PMem64Node)) {
    NumConfig++;
    Aperture |= 0x10;
  }

  if (NumConfig != 0) {

    //
    // If there is at least one type of resource request,
    // allocate a acpi resource node
    //
    Configuration = EfiLibAllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
    if (Configuration == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    EfiZeroMem (
      Configuration,
      sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
      );

    Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;

    //
    // Deal with io aperture
    //
    if (Aperture & 0x01) {
      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;
      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
      //
      // Io
      //
      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_IO;
      //
      // non ISA range
      //
      Ptr->SpecificFlag = 1;
      Ptr->AddrLen      = IoNode->Length;
      Ptr->AddrRangeMax = IoNode->Alignment;

      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
    }
    //
    // Deal with mem32 aperture
    //
    if (Aperture & 0x02) {
      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;
      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
      //
      // Mem
      //
      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;
      //
      // Nonprefechable
      //
      Ptr->SpecificFlag = 0;
      //
      // 32 bit
      //
      Ptr->AddrSpaceGranularity = 32;
      Ptr->AddrLen      = Mem32Node->Length;
      Ptr->AddrRangeMax = Mem32Node->Alignment;

      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
    }

    //
    // Deal with Pmem32 aperture
    //
    if (Aperture & 0x04) {
      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;
      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
      //
      // Mem
      //
      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;
      //
      // prefechable
      //
      Ptr->SpecificFlag = 0x6;
      //
      // 32 bit
      //
      Ptr->AddrSpaceGranularity = 32;
      Ptr->AddrLen      = PMem32Node->Length;
      Ptr->AddrRangeMax = PMem32Node->Alignment;

      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
    }
    //
    // Deal with mem64 aperture
    //
    if (Aperture & 0x08) {
      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;
      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
      //
      // Mem
      //
      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;
      //
      // nonprefechable
      //
      Ptr->SpecificFlag = 0;
      //
      // 64 bit
      //
      Ptr->AddrSpaceGranularity = 64;
      Ptr->AddrLen      = Mem64Node->Length;
      Ptr->AddrRangeMax = Mem64Node->Alignment;

      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
    }
    //
    // Deal with Pmem64 aperture
    //
    if (Aperture & 0x10) {
      Ptr->Desc     = ACPI_ADDRESS_SPACE_DESCRIPTOR;
      Ptr->Len      = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
      //
      // Mem
      //
      Ptr->ResType  = ACPI_ADDRESS_SPACE_TYPE_MEM;
      //
      // prefechable
      //
      Ptr->SpecificFlag = 0x06;
      //
      // 64 bit
      //
      Ptr->AddrSpaceGranularity = 64;
      Ptr->AddrLen      = PMem64Node->Length;
      Ptr->AddrRangeMax = PMem64Node->Alignment;

      Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
    }

    //
    // put the checksum
    //
    PtrEnd            = (EFI_ACPI_END_TAG_DESCRIPTOR *) ((UINT8 *) Ptr);

    PtrEnd->Desc      = ACPI_END_TAG_DESCRIPTOR;
    PtrEnd->Checksum  = 0;

  } else {

    //
    // If there is no resource request
    //
    Configuration = EfiLibAllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
    if (Configuration == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    EfiZeroMem (Configuration, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));

    Ptr               = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) (Configuration);
    Ptr->Desc         = ACPI_ADDRESS_SPACE_DESCRIPTOR;

    PtrEnd            = (EFI_ACPI_END_TAG_DESCRIPTOR *) (Configuration + sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR));
    PtrEnd->Desc      = ACPI_END_TAG_DESCRIPTOR;
    PtrEnd->Checksum  = 0;
  }

  *pConfig = Configuration;

  return EFI_SUCCESS;
}

EFI_STATUS
GetResourceBase (
  IN VOID     *pConfig,
  OUT UINT64  *IoBase,
  OUT UINT64  *Mem32Base,
  OUT UINT64  *PMem32Base,
  OUT UINT64  *Mem64Base,
  OUT UINT64  *PMem64Base
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    pConfig - 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_SUCCESS - add return value to function comment
{
  UINT8                             *Temp;
  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
  UINT64                            ResStatus;

  *IoBase     = 0xFFFFFFFFFFFFFFFF;
  *Mem32Base  = 0xFFFFFFFFFFFFFFFF;
  *PMem32Base = 0xFFFFFFFFFFFFFFFF;
  *Mem64Base  = 0xFFFFFFFFFFFFFFFF;
  *PMem64Base = 0xFFFFFFFFFFFFFFFF;

  Temp        = (UINT8 *) pConfig;

  while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {

    Ptr       = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Temp;
    ResStatus = Ptr->AddrTranslationOffset;

    if (ResStatus == EFI_RESOURCE_SATISFIED) {

      switch (Ptr->ResType) {

      //
      // Memory type aperture
      //
      case 0:
  
        //
        // Check to see the granularity
        //
        if (Ptr->AddrSpaceGranularity == 32) {
          if (Ptr->SpecificFlag & 0x06) {
            *PMem32Base = Ptr->AddrRangeMin;
          } else {
            *Mem32Base = Ptr->AddrRangeMin;
          }
        }

        if (Ptr->AddrSpaceGranularity == 64) {
          if (Ptr->SpecificFlag & 0x06) {
            *PMem64Base = Ptr->AddrRangeMin;
          } else {
            *Mem64Base = Ptr->AddrRangeMin;
          }
        }
        break;

      case 1:

        //
        // Io type aperture
        //
        *IoBase = Ptr->AddrRangeMin;
        break;

      default:
        break;

      }
      //
      // End switch
      //
    }
    //
    // End for
    //
    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
  }

  return EFI_SUCCESS;
}

EFI_STATUS
PciBridgeEnumerator (
  IN PCI_IO_DEVICE                                     *BridgeDev
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    BridgeDev - add argument and description to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  UINT8               SubBusNumber;
  UINT8               StartBusNumber;
  EFI_PCI_IO_PROTOCOL *PciIo;
  EFI_STATUS          Status;

  SubBusNumber    = 0;
  StartBusNumber  = 0;
  PciIo           = &(BridgeDev->PciIo);
  Status          = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x19, 1, &StartBusNumber);

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

  Status = PciAssignBusNumber (
            BridgeDev,
            StartBusNumber,
            &SubBusNumber
            );

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

  Status = PciPciDeviceInfoCollector (BridgeDev, StartBusNumber);

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

  Status = PciBridgeResourceAllocator (BridgeDev);

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

  Status = DetermineDeviceAttribute (BridgeDev);

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

  return EFI_SUCCESS;

}

EFI_STATUS
PciBridgeResourceAllocator (
  IN PCI_IO_DEVICE  *Bridge
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    Bridge - add argument and description to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  PCI_RESOURCE_NODE *IoBridge;
  PCI_RESOURCE_NODE *Mem32Bridge;
  PCI_RESOURCE_NODE *PMem32Bridge;
  PCI_RESOURCE_NODE *Mem64Bridge;
  PCI_RESOURCE_NODE *PMem64Bridge;
  UINT64            IoBase;
  UINT64            Mem32Base;
  UINT64            PMem32Base;
  UINT64            Mem64Base;
  UINT64            PMem64Base;
  EFI_STATUS        Status;

  IoBridge = CreateResourceNode (
              Bridge,
              0,
              0xFFF,
              0,
              PciBarTypeIo16,
              PciResUsageTypical
              );

  Mem32Bridge = CreateResourceNode (
                  Bridge,
                  0,
                  0xFFFFF,
                  0,
                  PciBarTypeMem32,
                  PciResUsageTypical
                  );

  PMem32Bridge = CreateResourceNode (
                  Bridge,
                  0,
                  0xFFFFF,
                  0,
                  PciBarTypePMem32,
                  PciResUsageTypical
                  );

  Mem64Bridge = CreateResourceNode (
                  Bridge,
                  0,
                  0xFFFFF,
                  0,
                  PciBarTypeMem64,
                  PciResUsageTypical
                  );

  PMem64Bridge = CreateResourceNode (
                  Bridge,
                  0,
                  0xFFFFF,
                  0,
                  PciBarTypePMem64,
                  PciResUsageTypical
                  );

  //
  // Create resourcemap by going through all the devices subject to this root bridge
  //
  Status = CreateResourceMap (
            Bridge,
            IoBridge,
            Mem32Bridge,
            PMem32Bridge,
            Mem64Bridge,
            PMem64Bridge
            );

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

  Status = GetResourceBaseFromBridge (
            Bridge,
            &IoBase,
            &Mem32Base,
            &PMem32Base,
            &Mem64Base,
            &PMem64Base
            );

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

  //
  // Program IO resources
  //
  ProgramResource (
    IoBase,
    IoBridge
    );

⌨️ 快捷键说明

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