pcienumeratorsupport.c

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

C
2,267
字号
  PciIoDevice = CreatePciIoDevice (
                  PciRootBridgeIo,
                  Pci,
                  Bus,
                  Device,
                  Func
                  );

  if (!PciIoDevice) {
    return NULL;
  }

  //
  // Create a device path for this PCI device and store it into its private data
  //
  CreatePciDevicePath (
    Bridge->DevicePath,
    PciIoDevice
    );

  if (gFullEnumeration) {
    PciDisableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);

    //
    // Initalize the bridge control register
    //
    PciDisableBridgeControlRegister (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED);

  }
  //
  // P2C only has one bar that is in 0x10
  //
  PciParseBar (PciIoDevice, 0x10, P2C_BAR_0);

  //
  // Read PciBar information from the bar register
  //
  GetBackPcCardBar (PciIoDevice);
  PciIoDevice->Decodes = EFI_BRIDGE_MEM32_DECODE_SUPPORTED  |
                         EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |
                         EFI_BRIDGE_IO32_DECODE_SUPPORTED;

  return PciIoDevice;
}

EFI_DEVICE_PATH_PROTOCOL *
CreatePciDevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
  IN  PCI_IO_DEVICE            *PciIoDevice
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    ParentDevicePath - add argument and description to function comment
// TODO:    PciIoDevice - add argument and description to function comment
{

  PCI_DEVICE_PATH PciNode;

  //
  // Create PCI device path
  //
  PciNode.Header.Type     = HARDWARE_DEVICE_PATH;
  PciNode.Header.SubType  = HW_PCI_DP;
  SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));

  PciNode.Device          = PciIoDevice->DeviceNumber;
  PciNode.Function        = PciIoDevice->FunctionNumber;
  PciIoDevice->DevicePath = EfiAppendDevicePathNode (ParentDevicePath, &PciNode.Header);

  return PciIoDevice->DevicePath;
}

EFI_STATUS
BarExisted (
  IN PCI_IO_DEVICE *PciIoDevice,
  IN UINTN         Offset,
  OUT UINT32       *BarLengthValue,
  OUT UINT32       *OriginalBarValue
  )
/*++

Routine Description:

  Check the bar is existed or not.

Arguments:

  PciIoDevice       - A pointer to the PCI_IO_DEVICE.
  Offset            - The offset.
  BarLengthValue    - The bar length value.
  OriginalBarValue  - The original bar value.

Returns:

  EFI_NOT_FOUND     - The bar don't exist.
  EFI_SUCCESS       - The bar exist.

--*/
{
  EFI_PCI_IO_PROTOCOL *PciIo;
  UINT32              OriginalValue;
  UINT32              Value;
  EFI_TPL             OldTpl;

  PciIo = &PciIoDevice->PciIo;

  //
  // Preserve the original value
  //

  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);

  //
  // Raise TPL to high level to disable timer interrupt while the BAR is probed
  //
  OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);
  PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);

  //
  // Write back the original value
  //
  PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);

  //
  // Restore TPL to its original level
  //
  gBS->RestoreTPL (OldTpl);

  if (BarLengthValue != NULL) {
    *BarLengthValue = Value;
  }

  if (OriginalBarValue != NULL) {
    *OriginalBarValue = OriginalValue;
  }

  if (Value == 0) {
    return EFI_NOT_FOUND;
  } else {
    return EFI_SUCCESS;
  }
}

EFI_STATUS
PciTestSupportedAttribute (
  IN PCI_IO_DEVICE                      *PciIoDevice,
  IN UINT16                             *Command,
  IN UINT16                             *BridgeControl,
  IN UINT16                             *OldCommand,
  IN UINT16                             *OldBridgeControl
  )
/*++

Routine Description:

Arguments:

Returns:

  None

--*/
// TODO:    PciIoDevice - add argument and description to function comment
// TODO:    Command - add argument and description to function comment
// TODO:    BridgeControl - add argument and description to function comment
// TODO:    OldCommand - add argument and description to function comment
// TODO:    OldBridgeControl - add argument and description to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  EFI_TPL OldTpl;

  //
  // Preserve the original value
  //
  PciReadCommandRegister (PciIoDevice, OldCommand);

  //
  // Raise TPL to high level to disable timer interrupt while the BAR is probed
  //
  OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

  PciSetCommandRegister (PciIoDevice, *Command);
  PciReadCommandRegister (PciIoDevice, Command);

  //
  // Write back the original value
  //
  PciSetCommandRegister (PciIoDevice, *OldCommand);

  //
  // Restore TPL to its original level
  //
  gBS->RestoreTPL (OldTpl);

  if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
    
    //
    // Preserve the original value
    //
    PciReadBridgeControlRegister (PciIoDevice, OldBridgeControl);

    //
    // Raise TPL to high level to disable timer interrupt while the BAR is probed
    //
    OldTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL);

    PciSetBridgeControlRegister (PciIoDevice, *BridgeControl);
    PciReadBridgeControlRegister (PciIoDevice, BridgeControl);

    //
    // Write back the original value
    //
    PciSetBridgeControlRegister (PciIoDevice, *OldBridgeControl);

    //
    // Restore TPL to its original level
    //
    gBS->RestoreTPL (OldTpl);

  } else {
    *OldBridgeControl = 0;
    *BridgeControl    = 0;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
PciSetDeviceAttribute (
  IN PCI_IO_DEVICE                      *PciIoDevice,
  IN UINT16                             Command,
  IN UINT16                             BridgeControl,
  IN UINTN                              Option
  )
/*++

  Routine Description:
    Set the supported or current attributes of a PCI device    

  Arguments:
    PciIoDevice   - Structure pointer for PCI device.
    Command       - Command register value.
    BridgeControl - Bridge control value for PPB or P2C.
    Option        - Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES.

  Returns:    

--*/

/*++

Routine Description:

  

Arguments:
 
  
Returns:
  
  EFI_SUCCESS   Always success
  

--*/
{
  UINT64  Attributes;

  Attributes = 0;

  if (Command & EFI_PCI_COMMAND_IO_SPACE) {
    Attributes |= EFI_PCI_IO_ATTRIBUTE_IO;
  }

  if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {
    Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY;
  }

  if (Command & EFI_PCI_COMMAND_BUS_MASTER) {
    Attributes |= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;
  }

  if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {
    Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
  }

  if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA) {
    Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;
  }

  if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA) {
    Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;
    Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;
    Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
  }

  if (BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16) {
    Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO_16;
    Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16;
  }

  if (Option == EFI_SET_SUPPORTS) {

    Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | 
                  EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED        |
                  EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE       |
                  EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE      |
                  EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM         |
                  EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;

    if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {
      Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;
      Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_IO;
    }

    if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
      //
      // For bridge, it should support IDE attributes
      //
      Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;
      Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;
    } else {

      if (IS_PCI_IDE (&PciIoDevice->Pci)) {
        Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;
        Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;
      }

      if (IS_PCI_VGA (&PciIoDevice->Pci)) {
        Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;
        Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_IO;
      }
    }

    PciIoDevice->Supports = Attributes;
    PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \
                               EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \
                               EFI_PCI_IO_ATTRIBUTE_BUS_MASTER );

  } else {
    PciIoDevice->Attributes = Attributes;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
GetFastBackToBackSupport (
  IN PCI_IO_DEVICE                      *PciIoDevice,
  IN UINT8                              StatusIndex
  )
/*++

Routine Description:
 
  Determine if the device can support Fast Back to Back attribute

Arguments:

Returns:

  None

--*/
// TODO:    PciIoDevice - add argument and description to function comment
// TODO:    StatusIndex - 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
// TODO:    EFI_UNSUPPORTED - add return value to function comment
{
  EFI_PCI_IO_PROTOCOL *PciIo;
  EFI_STATUS          Status;
  UINT32              StatusRegister;

  //
  // Read the status register
  //
  PciIo   = &PciIoDevice->PciIo;
  Status  = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister);
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }
  
  //
  // Check the Fast B2B bit
  //
  if (StatusRegister & EFI_PCI_FAST_BACK_TO_BACK_CAPABLE) {
    return EFI_SUCCESS;
  } else {
    return EFI_UNSUPPORTED;
  }

}

EFI_STATUS
ProcessOptionRomLight (
  IN PCI_IO_DEVICE                      *PciIoDevice
  )
/*++

Routine Description:
 
  Process the option ROM for all the children of the specified parent PCI device.
  It can only be used after the first full Option ROM process.

Arguments:

Returns:

  None

--*/
// TODO:    PciIoDevice - add argument and description to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  PCI_IO_DEVICE   *Temp;
  EFI_LIST_ENTRY  *CurrentLink;

  //
  // For RootBridge, PPB , P2C, go recursively to traverse all its children
  //
  CurrentLink = PciIoDevice->ChildList.ForwardLink;
  while (CurrentLink && CurrentLink != &PciIoDevice->ChildList) {

    Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);

    if (!IsListEmpty (&Temp->ChildList)) {
      ProcessOptionRomLight (Temp);
    }

    PciRomGetImageMapping (Temp);
    CurrentLink = CurrentLink->ForwardLink;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
DetermineDeviceAttribute (
  IN PCI_IO_DEVICE                      *PciIoDevice
  )
/*++

Routine Description:
 
  Determine the related attributes of all devices under a Root Bridge

Arguments:

Returns:

  None

--*/
// TODO:    PciIoDevice - add argument and description to function comment
// TODO:    EFI_SUCCESS - add return value to function comment
{
  UINT16          Command;
  UINT16          BridgeControl;
  UINT16          OldCommand;
  UINT16          OldBridgeControl;
  BOOLEAN         FastB2BSupport;

  /*
  UINT8  IdePI;
  EFI_PCI_IO_PROTOCOL   *PciIo;
  */
  PCI_IO_DEVICE   *Temp;
  EFI_LIST_ENTRY  *CurrentLink;
  EFI_STATUS      Status;

  //
  // For Root Bridge, just copy it by RootBridgeIo proctocol
  // so as to keep consistent with the actual attribute
  //
  if (!PciIoDevice->Parent) {
    Status = PciIoDevice->PciRootBridgeIo->GetAttributes (
                                            PciIoDevice->PciRootBridgeIo,
                                            &PciIoDevice->Supports,
                                            &PciIoDevice->Attributes
                                            );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  } else {
  
    //
    // Set the attributes to be checked for common PCI devices and PPB or P2C
    // Since some devices only support part of them, it is better to set the
    // attribute according to its command or bridge control register
    //
    Command = EFI_PCI_COMMAND_IO_SPACE     |
              EFI_PCI_COMMAND_MEMORY_SPACE |
              EFI_PCI_COMMAND_BUS_MASTER   |
              EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;

    BridgeControl = EFI_PCI_BRIDGE_CONTROL_ISA | EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16;

    //
    // Test whether the device can support attributes above
    //
    PciTestSupportedAttribute (PciIoDevice, &Command, &BridgeControl, &OldCommand, &OldBridgeControl);

    //
    // Set the supported attributes for specified PCI device
    //
    PciSetDeviceAttribute (PciIoDevice, Command, BridgeControl, EFI_SET_SUPPORTS);

    //
    // Set the current attributes for specified PCI device
    //
    PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES);

    //
    // Enable other supported attributes but not defined in PCI_IO_PROTOCOL
    //
    PciEnableCommandRegister (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);

    //
    // Enable IDE native mode
    //
    /*
    if (IS_PCI_IDE(&PciIoDevice->Pci)) {

      PciIo = &PciIoDevice->PciIo;  

      PciIo->Pci.Read (
                              PciIo, 
                              EfiPciIoWidthUint8, 
                              0x09, 
                              1, 
                              &IdePI
                              );
      
      //
      // Set native mode if it can be supported
      //      
      IdePI |= (((IdePI & 0x0F) >> 1) & 0x05);

      PciIo->Pci.Write (
                              PciIo, 
                              EfiPciIoWidthUint8, 
                              0x09, 
                              1, 
                              &IdePI
                              );  
    
    }  
    */
  }

  FastB2BSupport = TRUE;

  //
  // P2C can not support FB2B on the secondary side
  //
  if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {

⌨️ 快捷键说明

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