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 + -
显示快捷键?