pciio.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,868 行 · 第 1/4 页
C
1,868 行
}
}
//
// Check to see if an VGA related attributes are being set.
//
if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO)) {
if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) {
EnableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
} else {
DisableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
}
}
} else {
if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO)) {
if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) {
//
//Check if there have been an active VGA device on the same segment
//
Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);
if (Temp && Temp != PciIoDevice) {
return EFI_UNSUPPORTED;
}
}
}
if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO)) {
if (IS_PCI_GFX(&PciIoDevice->Pci)) {
//
//Get the boot VGA on the same segement
//
Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);
if (!Temp) {
//
// If there is no VGA device on the segement, set
// this graphics card to decode the palette range
//
DisableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
} else {
//
// Check these two agents are on the same path
//
if (PciDevicesOnTheSamePath(Temp, PciIoDevice)) {
//
// Check if they are on the same bus
//
if (Temp->Parent == PciIoDevice->Parent) {
PciReadCommandRegister (Temp, &Command);
//
// If they are on the same bus, either one can
// be set to snoop, the other set to decode
//
if (Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {
DisableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
} else {
EnableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
}
} else {
//
// If they are on the same path but on the different bus
// The first agent is set to snoop, the second one set to
// decode
//
if (Temp->BusNumber > PciIoDevice->BusNumber) {
PciEnableCommandRegister(Temp,EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);
DisableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
} else {
PciDisableCommandRegister(Temp,EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);
EnableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
}
}
} else {
EnableCommand |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
}
}
}
}
}
//
// Check to see of the I/O enable is being modified
//
if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_IO) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_IO)) {
if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_IO) {
EnableCommand |= EFI_PCI_COMMAND_IO_SPACE;
} else {
DisableCommand |= EFI_PCI_COMMAND_IO_SPACE;
}
}
//
// Check to see of the Memory enable is being modified
//
if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY)) {
if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) {
EnableCommand |= EFI_PCI_COMMAND_MEMORY_SPACE;
} else {
DisableCommand |= EFI_PCI_COMMAND_MEMORY_SPACE;
}
}
//
// Check to see of the Bus Master enable is being modified
//
if ((NewAttributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) ^ (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER)) {
if (NewAttributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) {
EnableCommand |= EFI_PCI_COMMAND_BUS_MASTER;
} else {
DisableCommand |= EFI_PCI_COMMAND_BUS_MASTER;
}
}
Status = EFI_SUCCESS;
if (EnableCommand) {
Status = PciEnableCommandRegister(PciIoDevice, EnableCommand);
}
if (DisableCommand) {
Status = PciDisableCommandRegister(PciIoDevice, DisableCommand);
}
if (EFI_ERROR(Status)) {
return EFI_UNSUPPORTED;
}
if (EnableBridge) {
Status = PciEnableBridgeControlRegister(PciIoDevice, EnableBridge);
}
if (DisableBridge) {
Status = PciDisableBridgeControlRegister(PciIoDevice, DisableBridge);
}
if (EFI_ERROR(Status)) {
return EFI_UNSUPPORTED;
}
//
// Set the upstream bridge attributes
//
if (Operation != EfiPciIoAttributeOperationGet && Operation != EfiPciIoAttributeOperationSupported) {
//
// EFI_PCI_IO_ATTRIBUTE_MEMORY, EFI_PCI_IO_ATTRIBUTE_IO, EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
// EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED
// EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE will not effect to upstream bridge
//
NewUpStreamBridgeAttributes = Attributes & \
(~(EFI_PCI_IO_ATTRIBUTE_IO | \
EFI_PCI_IO_ATTRIBUTE_MEMORY | \
EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | \
EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE | \
EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | \
EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE));
if (NewUpStreamBridgeAttributes){
UpStreamBridgesAttributes(PciIoDevice, Operation, NewUpStreamBridgeAttributes);
}
}
PciIoDevice->Attributes = NewAttributes;
return Status;
}
EFI_STATUS
EFIAPI
PciIoGetBarAttributes (
IN EFI_PCI_IO_PROTOCOL * This,
IN UINT8 BarIndex,
OUT UINT64 *Supports, OPTIONAL
OUT VOID **Resources OPTIONAL
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
UINT8 *Configuration;
UINT8 NumConfig;
PCI_IO_DEVICE *PciIoDevice;
EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
EFI_ACPI_END_TAG_DESCRIPTOR *PtrEnd;
NumConfig = 0;
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
if (Supports == NULL && Resources == NULL) {
return EFI_INVALID_PARAMETER;
}
if (BarIndex >= PCI_MAX_BAR) {
return EFI_UNSUPPORTED;
}
//
// This driver does not support modifications to the WRITE_COMBINE or
// CACHED attributes for BAR ranges.
//
if (Supports != NULL) {
*Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;
}
if (Resources != NULL) {
if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeUnknown) {
NumConfig = 1;
}
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;
if (NumConfig == 1) {
Ptr->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
Ptr->Len = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
Ptr->AddrRangeMin = PciIoDevice->PciBar[BarIndex].BaseAddress;
Ptr->AddrLen = PciIoDevice->PciBar[BarIndex].Length;
Ptr->AddrRangeMax = PciIoDevice->PciBar[BarIndex].Alignment;
switch (PciIoDevice->PciBar[BarIndex].BarType) {
case PciBarTypeIo16:
case PciBarTypeIo32:
//
// Io
//
Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
break;
case PciBarTypeMem32:
//
// Mem
//
Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
//
// 32 bit
//
Ptr->AddrSpaceGranularity = 32;
break;
case PciBarTypePMem32:
//
// Mem
//
Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
//
// prefechable
//
Ptr->SpecificFlag = 0x6;
//
// 32 bit
//
Ptr->AddrSpaceGranularity = 32;
break;
case PciBarTypeMem64:
//
// Mem
//
Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
//
// 64 bit
//
Ptr->AddrSpaceGranularity = 64;
break;
case PciBarTypePMem64:
//
// Mem
//
Ptr->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
//
// prefechable
//
Ptr->SpecificFlag = 0x6;
//
// 64 bit
//
Ptr->AddrSpaceGranularity = 64;
break;
}
Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) ((UINT8 *) Ptr + 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;
*Resources = Configuration;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
PciIoSetBarAttributes (
IN EFI_PCI_IO_PROTOCOL *This,
IN UINT64 Attributes,
IN UINT8 BarIndex,
IN OUT UINT64 *Offset,
IN OUT UINT64 *Length
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
EFI_STATUS Status;
PCI_IO_DEVICE *PciIoDevice;
UINT64 NonRelativeOffset;
UINT64 Supports;
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
//
// Make sure Offset and Length are not NULL
//
if (Offset == NULL || Length == NULL) {
return EFI_INVALID_PARAMETER;
}
if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeUnknown) {
return EFI_UNSUPPORTED;
}
//
// This driver does not support setting the WRITE_COMBINE or the CACHED attributes.
// If Attributes is not 0, then return EFI_UNSUPPORTED.
//
Supports = PciIoDevice->Supports & EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED & EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;
if (Attributes != (Attributes & Supports)) {
return EFI_UNSUPPORTED;
}
//
// Attributes must be supported. Make sure the BAR range describd by BarIndex, Offset, and
// Length are valid for this PCI device.
//
NonRelativeOffset = *Offset;
Status = PciIoVerifyBarAccess (
PciIoDevice,
BarIndex,
PciBarTypeMem,
EfiPciIoWidthUint8,
(UINT32) *Length,
&NonRelativeOffset
);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
}
EFI_STATUS
UpStreamBridgesAttributes (
IN PCI_IO_DEVICE *PciIoDevice,
IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
IN UINT64 Attributes
)
/*++
Routine Description:
Arguments:
Returns:
None
--*/
{
PCI_IO_DEVICE *Parent;
EFI_PCI_IO_PROTOCOL *PciIo;
Parent = PciIoDevice->Parent;
while (Parent && IS_PCI_BRIDGE (&Parent->Pci)) {
//
// Get the PciIo Protocol
//
PciIo = &Parent->PciIo;
PciIo->Attributes (PciIo, Operation, Attributes, NULL);
Parent = Parent->Parent;
}
return EFI_SUCCESS;
}
BOOLEAN
PciDevicesOnTheSamePath (
IN PCI_IO_DEVICE *PciDevice1,
IN PCI_IO_DEVICE *PciDevice2
)
/*++
Routine Description:
Arguments:
PciDevice1 - The pointer to the first PCI_IO_DEVICE.
PciDevice2 - The pointer to the second PCI_IO_DEVICE.
Returns:
TRUE - The two Pci devices are on the same path.
FALSE - The two Pci devices are not on the same path.
--*/
{
if (PciDevice1->Parent == PciDevice2->Parent) {
return TRUE;
}
return (PciDeviceExisted (PciDevice1->Parent, PciDevice2)|| PciDeviceExisted (PciDevice2->Parent, PciDevice1));
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?