1)PciCommand.h: Add some macro constants definitions that will be used by other changes. 2)PciDeviceSupport.c: a)Fix the bug that programs Non-Bridge Devices' Interrupt Line Register to 0x00. Although this register is rarely used in modern OS (actually, only Dos still uses it), it is good practice to modify it so it will align the spec. Please refer to PCI 3.0 Spec for the chapter on Interrupt line register. b) Change the way used to detect VGA device. The old method will fail. 3)PciEnumeratorSupport.c: Make changes so Pci Driver will preserve those bits in Command & Bridge Control Register that were set by Customer's Chipset initialization code. Pci Driver is supposed to only touch those bits that are generic. Problems will arise if we destroy some initializations already done. 4)PciIo.c: PollIo() is not conformant to EFI spec so fix it. Also, some fixes are introduced to better support VGA card. These modifications are supposed to work with fixes in PciDeviceSupport.c. 5) PciOptionromSupport.c:Add the fix to enhance the logic working with OptionRom. Some legacy cards do not report correct imagelength so we add double check. And add EFI_MIN and EFI_MAX macro definition since they are not currently defined in global files. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1738 6f19259b-4bc3-4df7-8a09-765794883524
1980 lines
56 KiB
C
1980 lines
56 KiB
C
/*++
|
|
|
|
Copyright (c) 2006, Intel Corporation
|
|
All rights reserved. This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
Module Name:
|
|
|
|
PciIo.c
|
|
|
|
Abstract:
|
|
|
|
PCI I/O Abstraction Driver
|
|
|
|
Revision History
|
|
|
|
--*/
|
|
|
|
#include "pcibus.h"
|
|
|
|
//
|
|
// Internal use only
|
|
//
|
|
STATIC
|
|
EFI_STATUS
|
|
ReportErrorStatusCode (
|
|
IN PCI_IO_DEVICE *PciIoDevice,
|
|
IN EFI_STATUS_CODE_VALUE Code
|
|
);
|
|
|
|
//
|
|
// PCI I/O Support Function Prototypes
|
|
//
|
|
//
|
|
//
|
|
// Pci Io Protocol Interface
|
|
//
|
|
static EFI_PCI_IO_PROTOCOL PciIoInterface = {
|
|
PciIoPollMem,
|
|
PciIoPollIo,
|
|
{
|
|
PciIoMemRead,
|
|
PciIoMemWrite
|
|
},
|
|
{
|
|
PciIoIoRead,
|
|
PciIoIoWrite
|
|
},
|
|
{
|
|
PciIoConfigRead,
|
|
PciIoConfigWrite
|
|
},
|
|
PciIoCopyMem,
|
|
PciIoMap,
|
|
PciIoUnmap,
|
|
PciIoAllocateBuffer,
|
|
PciIoFreeBuffer,
|
|
PciIoFlush,
|
|
PciIoGetLocation,
|
|
PciIoAttributes,
|
|
PciIoGetBarAttributes,
|
|
PciIoSetBarAttributes,
|
|
0,
|
|
NULL
|
|
};
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
ReportErrorStatusCode (
|
|
IN PCI_IO_DEVICE *PciIoDevice,
|
|
IN EFI_STATUS_CODE_VALUE Code
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
report a error Status code of PCI bus driver controller
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: PciIoDevice - add argument and description to function comment
|
|
// TODO: Code - add argument and description to function comment
|
|
{
|
|
return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
|
|
EFI_ERROR_CODE | EFI_ERROR_MINOR,
|
|
Code,
|
|
PciIoDevice->DevicePath
|
|
);
|
|
}
|
|
|
|
EFI_STATUS
|
|
InitializePciIoInstance (
|
|
PCI_IO_DEVICE *PciIoDevice
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initializes a PCI I/O Instance
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: PciIoDevice - add argument and description to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
{
|
|
CopyMem (&PciIoDevice->PciIo, &PciIoInterface, sizeof (EFI_PCI_IO_PROTOCOL));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
PciIoVerifyBarAccess (
|
|
PCI_IO_DEVICE *PciIoDevice,
|
|
UINT8 BarIndex,
|
|
PCI_BAR_TYPE Type,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINTN Count,
|
|
UINT64 *Offset
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Verifies access to a PCI Base Address Register (BAR)
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: PciIoDevice - add argument and description to function comment
|
|
// TODO: BarIndex - add argument and description to function comment
|
|
// TODO: Type - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: Count - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
{
|
|
if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// BarIndex 0-5 is legal
|
|
//
|
|
if (BarIndex >= PCI_MAX_BAR) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!CheckBarType (PciIoDevice, BarIndex, Type)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX
|
|
// If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX
|
|
//
|
|
if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
|
|
Count = 1;
|
|
}
|
|
|
|
Width &= 0x03;
|
|
|
|
if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
*Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
PciIoVerifyConfigAccess (
|
|
PCI_IO_DEVICE *PciIoDevice,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINTN Count,
|
|
IN UINT64 *Offset
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Verifies access to a PCI Config Header
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: PciIoDevice - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: Count - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
{
|
|
UINT64 ExtendOffset;
|
|
|
|
if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX
|
|
//
|
|
Width &= 0x03;
|
|
|
|
if (PciIoDevice->IsPciExp) {
|
|
if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_EXP_MAX_CONFIG_OFFSET) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
ExtendOffset = LShiftU64 (*Offset, 32);
|
|
*Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, 0);
|
|
*Offset = (*Offset) | ExtendOffset;
|
|
|
|
} else {
|
|
if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PCI_MAX_CONFIG_OFFSET) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
*Offset = EFI_PCI_ADDRESS (PciIoDevice->BusNumber, PciIoDevice->DeviceNumber, PciIoDevice->FunctionNumber, *Offset);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoPollMem (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINT8 BarIndex,
|
|
IN UINT64 Offset,
|
|
IN UINT64 Mask,
|
|
IN UINT64 Value,
|
|
IN UINT64 Delay,
|
|
OUT UINT64 *Result
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Poll PCI Memmory
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: BarIndex - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: Mask - add argument and description to function comment
|
|
// TODO: Value - add argument and description to function comment
|
|
// TODO: Delay - add argument and description to function comment
|
|
// TODO: Result - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, 1, &Offset);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (Width > EfiPciIoWidthUint64) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->PollMem (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
|
Offset,
|
|
Mask,
|
|
Value,
|
|
Delay,
|
|
Result
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoPollIo (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINT8 BarIndex,
|
|
IN UINT64 Offset,
|
|
IN UINT64 Mask,
|
|
IN UINT64 Value,
|
|
IN UINT64 Delay,
|
|
OUT UINT64 *Result
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Poll PCI IO
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: BarIndex - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: Mask - add argument and description to function comment
|
|
// TODO: Value - add argument and description to function comment
|
|
// TODO: Delay - add argument and description to function comment
|
|
// TODO: Result - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
if (Width < 0 || Width > EfiPciIoWidthUint64) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, 1, &Offset);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->PollIo (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
|
Offset,
|
|
Mask,
|
|
Value,
|
|
Delay,
|
|
Result
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoMemRead (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINT8 BarIndex,
|
|
IN UINT64 Offset,
|
|
IN UINTN Count,
|
|
IN OUT VOID *Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Performs a PCI Memory Read Cycle
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: BarIndex - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: Count - add argument and description to function comment
|
|
// TODO: Buffer - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->Mem.Read (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
|
Offset,
|
|
Count,
|
|
Buffer
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoMemWrite (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINT8 BarIndex,
|
|
IN UINT64 Offset,
|
|
IN UINTN Count,
|
|
IN OUT VOID *Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Performs a PCI Memory Write Cycle
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: BarIndex - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: Count - add argument and description to function comment
|
|
// TODO: Buffer - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeMem, Width, Count, &Offset);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->Mem.Write (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
|
Offset,
|
|
Count,
|
|
Buffer
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoIoRead (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINT8 BarIndex,
|
|
IN UINT64 Offset,
|
|
IN UINTN Count,
|
|
IN OUT VOID *Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Performs a PCI I/O Read Cycle
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: BarIndex - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: Count - add argument and description to function comment
|
|
// TODO: Buffer - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->Io.Read (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
|
Offset,
|
|
Count,
|
|
Buffer
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoIoWrite (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINT8 BarIndex,
|
|
IN UINT64 Offset,
|
|
IN UINTN Count,
|
|
IN OUT VOID *Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Performs a PCI I/O Write Cycle
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: BarIndex - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: Count - add argument and description to function comment
|
|
// TODO: Buffer - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = PciIoVerifyBarAccess (PciIoDevice, BarIndex, PciBarTypeIo, Width, Count, &Offset);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->Io.Write (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
|
Offset,
|
|
Count,
|
|
Buffer
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoConfigRead (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINT32 Offset,
|
|
IN UINTN Count,
|
|
IN OUT VOID *Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Performs a PCI Configuration Read Cycle
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: Count - add argument and description to function comment
|
|
// TODO: Buffer - add argument and description to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
UINT64 Address;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
Address = Offset;
|
|
Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->Pci.Read (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
|
Address,
|
|
Count,
|
|
Buffer
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_READ_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoConfigWrite (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINT32 Offset,
|
|
IN UINTN Count,
|
|
IN OUT VOID *Buffer
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Performs a PCI Configuration Write Cycle
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: Count - add argument and description to function comment
|
|
// TODO: Buffer - add argument and description to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
UINT64 Address;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
Address = Offset;
|
|
Status = PciIoVerifyConfigAccess (PciIoDevice, Width, Count, &Address);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->Pci.Write (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
|
Address,
|
|
Count,
|
|
Buffer
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_WRITE_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoCopyMem (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
|
|
IN UINT8 DestBarIndex,
|
|
IN UINT64 DestOffset,
|
|
IN UINT8 SrcBarIndex,
|
|
IN UINT64 SrcOffset,
|
|
IN UINTN Count
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Copy PCI Memory
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Width - add argument and description to function comment
|
|
// TODO: DestBarIndex - add argument and description to function comment
|
|
// TODO: DestOffset - add argument and description to function comment
|
|
// TODO: SrcBarIndex - add argument and description to function comment
|
|
// TODO: SrcOffset - add argument and description to function comment
|
|
// TODO: Count - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (Width == EfiPciIoWidthFifoUint8 ||
|
|
Width == EfiPciIoWidthFifoUint16 ||
|
|
Width == EfiPciIoWidthFifoUint32 ||
|
|
Width == EfiPciIoWidthFifoUint64 ||
|
|
Width == EfiPciIoWidthFillUint8 ||
|
|
Width == EfiPciIoWidthFillUint16 ||
|
|
Width == EfiPciIoWidthFillUint32 ||
|
|
Width == EfiPciIoWidthFillUint64) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = PciIoVerifyBarAccess (PciIoDevice, DestBarIndex, PciBarTypeMem, Width, Count, &DestOffset);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = PciIoVerifyBarAccess (PciIoDevice, SrcBarIndex, PciBarTypeMem, Width, Count, &SrcOffset);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->CopyMem (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
|
|
DestOffset,
|
|
SrcOffset,
|
|
Count
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoMap (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,
|
|
IN VOID *HostAddress,
|
|
IN OUT UINTN *NumberOfBytes,
|
|
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
|
|
OUT VOID **Mapping
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Maps a memory region for DMA
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Operation - add argument and description to function comment
|
|
// TODO: HostAddress - add argument and description to function comment
|
|
// TODO: NumberOfBytes - add argument and description to function comment
|
|
// TODO: DeviceAddress - add argument and description to function comment
|
|
// TODO: Mapping - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
if (Operation < 0 || Operation >= EfiPciIoOperationMaximum) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {
|
|
Operation = Operation + EfiPciOperationBusMasterRead64;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->Map (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation,
|
|
HostAddress,
|
|
NumberOfBytes,
|
|
DeviceAddress,
|
|
Mapping
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoUnmap (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN VOID *Mapping
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unmaps a memory region for DMA
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Mapping - add argument and description to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->Unmap (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
Mapping
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoAllocateBuffer (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN EFI_ALLOCATE_TYPE Type,
|
|
IN EFI_MEMORY_TYPE MemoryType,
|
|
IN UINTN Pages,
|
|
OUT VOID **HostAddress,
|
|
IN UINT64 Attributes
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Allocates a common buffer for DMA
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Type - add argument and description to function comment
|
|
// TODO: MemoryType - add argument and description to function comment
|
|
// TODO: Pages - add argument and description to function comment
|
|
// TODO: HostAddress - add argument and description to function comment
|
|
// TODO: Attributes - add argument and description to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
if (Attributes &
|
|
(~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
if (PciIoDevice->Attributes & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE) {
|
|
Attributes |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
|
|
}
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->AllocateBuffer (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
Type,
|
|
MemoryType,
|
|
Pages,
|
|
HostAddress,
|
|
Attributes
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoFreeBuffer (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
IN UINTN Pages,
|
|
IN VOID *HostAddress
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Frees a common buffer
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Pages - add argument and description to function comment
|
|
// TODO: HostAddress - add argument and description to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->FreeBuffer (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
Pages,
|
|
HostAddress
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoFlush (
|
|
IN EFI_PCI_IO_PROTOCOL *This
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Flushes a DMA buffer
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->Flush (
|
|
PciIoDevice->PciRootBridgeIo
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoGetLocation (
|
|
IN EFI_PCI_IO_PROTOCOL *This,
|
|
OUT UINTN *Segment,
|
|
OUT UINTN *Bus,
|
|
OUT UINTN *Device,
|
|
OUT UINTN *Function
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets a PCI device's current bus number, device number, and function number.
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Segment - 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: Function - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
{
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
if (Segment == NULL || Bus == NULL || Device == NULL || Function == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
*Segment = PciIoDevice->PciRootBridgeIo->SegmentNumber;
|
|
*Bus = PciIoDevice->BusNumber;
|
|
*Device = PciIoDevice->DeviceNumber;
|
|
*Function = PciIoDevice->FunctionNumber;
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
BOOLEAN
|
|
CheckBarType (
|
|
IN PCI_IO_DEVICE *PciIoDevice,
|
|
UINT8 BarIndex,
|
|
PCI_BAR_TYPE BarType
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets a PCI controllers attributes on a resource range
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: PciIoDevice - add argument and description to function comment
|
|
// TODO: BarIndex - add argument and description to function comment
|
|
// TODO: BarType - add argument and description to function comment
|
|
{
|
|
switch (BarType) {
|
|
|
|
case PciBarTypeMem:
|
|
|
|
if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem32 &&
|
|
PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem32 &&
|
|
PciIoDevice->PciBar[BarIndex].BarType != PciBarTypePMem64 &&
|
|
PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeMem64 ) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
case PciBarTypeIo:
|
|
if (PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo32 &&
|
|
PciIoDevice->PciBar[BarIndex].BarType != PciBarTypeIo16){
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
EFI_STATUS
|
|
ModifyRootBridgeAttributes (
|
|
IN PCI_IO_DEVICE *PciIoDevice,
|
|
IN UINT64 Attributes,
|
|
IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Set new attributes to a Root Bridge
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: PciIoDevice - add argument and description to function comment
|
|
// TODO: Attributes - add argument and description to function comment
|
|
// TODO: Operation - add argument and description to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
{
|
|
UINT64 PciRootBridgeSupports;
|
|
UINT64 PciRootBridgeAttributes;
|
|
UINT64 NewPciRootBridgeAttributes;
|
|
EFI_STATUS Status;
|
|
|
|
//
|
|
// Get the current attributes of this PCI device's PCI Root Bridge
|
|
//
|
|
Status = PciIoDevice->PciRootBridgeIo->GetAttributes (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
&PciRootBridgeSupports,
|
|
&PciRootBridgeAttributes
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// Record the new attribute of the Root Bridge
|
|
//
|
|
if (Operation == EfiPciIoAttributeOperationEnable) {
|
|
NewPciRootBridgeAttributes = PciRootBridgeAttributes | Attributes;
|
|
} else {
|
|
NewPciRootBridgeAttributes = PciRootBridgeAttributes & (~Attributes);
|
|
}
|
|
|
|
//
|
|
// Call the PCI Root Bridge to attempt to modify the attributes
|
|
//
|
|
if (NewPciRootBridgeAttributes ^ PciRootBridgeAttributes) {
|
|
|
|
Status = PciIoDevice->PciRootBridgeIo->SetAttributes (
|
|
PciIoDevice->PciRootBridgeIo,
|
|
NewPciRootBridgeAttributes,
|
|
NULL,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// The PCI Root Bridge could not modify the attributes, so return the error.
|
|
//
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Also update the attributes for this Root Bridge structure
|
|
//
|
|
PciIoDevice->Attributes = NewPciRootBridgeAttributes;
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
EFI_STATUS
|
|
SupportPaletteSnoopAttributes (
|
|
IN PCI_IO_DEVICE *PciIoDevice,
|
|
IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Check whether this device can be enable/disable to snoop
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: PciIoDevice - add argument and description to function comment
|
|
// TODO: Operation - 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_SUCCESS - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value 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
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
{
|
|
PCI_IO_DEVICE *Temp;
|
|
UINT16 VGACommand;
|
|
|
|
//
|
|
// Snoop attribute can be only modified by GFX
|
|
//
|
|
if (!IS_PCI_GFX (&PciIoDevice->Pci)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// 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
|
|
//
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Check these two agents are on the same path
|
|
//
|
|
if (!PciDevicesOnTheSamePath (Temp, PciIoDevice)) {
|
|
//
|
|
// they are not on the same path, so snoop can be enabled or disabled
|
|
//
|
|
return EFI_SUCCESS;
|
|
}
|
|
//
|
|
// Check if they are on the same bus
|
|
//
|
|
if (Temp->Parent == PciIoDevice->Parent) {
|
|
|
|
PciReadCommandRegister (Temp, &VGACommand);
|
|
|
|
//
|
|
// If they are on the same bus, either one can
|
|
// be set to snoop, the other set to decode
|
|
//
|
|
if (VGACommand & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) {
|
|
//
|
|
// VGA has set to snoop, so GFX can be only set to disable snoop
|
|
//
|
|
if (Operation == EfiPciIoAttributeOperationEnable) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
} else {
|
|
//
|
|
// VGA has disabled to snoop, so GFX can be only enabled
|
|
//
|
|
if (Operation == EfiPciIoAttributeOperationDisable) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// 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) {
|
|
//
|
|
// GFX should be set to decode
|
|
//
|
|
if (Operation == EfiPciIoAttributeOperationDisable) {
|
|
PciEnableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);
|
|
Temp->Attributes |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
|
|
} else {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// GFX should be set to snoop
|
|
//
|
|
if (Operation == EfiPciIoAttributeOperationEnable) {
|
|
PciDisableCommandRegister (Temp, EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);
|
|
Temp->Attributes &= (~EFI_PCI_COMMAND_VGA_PALETTE_SNOOP);
|
|
} else {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciIoAttributes (
|
|
IN EFI_PCI_IO_PROTOCOL * This,
|
|
IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
|
|
IN UINT64 Attributes,
|
|
OUT UINT64 *Result OPTIONAL
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Operation - add argument and description to function comment
|
|
// TODO: Attributes - add argument and description to function comment
|
|
// TODO: Result - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
PCI_IO_DEVICE *PciIoDevice;
|
|
PCI_IO_DEVICE *UpStreamBridge;
|
|
PCI_IO_DEVICE *Temp;
|
|
|
|
UINT64 Supports;
|
|
UINT64 UpStreamAttributes;
|
|
UINT16 BridgeControl;
|
|
UINT16 Command;
|
|
|
|
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
|
|
|
|
switch (Operation) {
|
|
case EfiPciIoAttributeOperationGet:
|
|
if (Result == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
*Result = PciIoDevice->Attributes;
|
|
return EFI_SUCCESS;
|
|
|
|
case EfiPciIoAttributeOperationSupported:
|
|
if (Result == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
*Result = PciIoDevice->Supports;
|
|
return EFI_SUCCESS;
|
|
|
|
case EfiPciIoAttributeOperationSet:
|
|
Status = PciIoDevice->PciIo.Attributes (
|
|
&(PciIoDevice->PciIo),
|
|
EfiPciIoAttributeOperationEnable,
|
|
Attributes,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = PciIoDevice->PciIo.Attributes (
|
|
&(PciIoDevice->PciIo),
|
|
EfiPciIoAttributeOperationDisable,
|
|
(~Attributes) & (PciIoDevice->Supports),
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
case EfiPciIoAttributeOperationEnable:
|
|
case EfiPciIoAttributeOperationDisable:
|
|
break;
|
|
|
|
default:
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
//
|
|
// Just a trick for ENABLE attribute
|
|
//
|
|
if ((Attributes & EFI_PCI_DEVICE_ENABLE) == EFI_PCI_DEVICE_ENABLE) {
|
|
Attributes &= (PciIoDevice->Supports);
|
|
|
|
//
|
|
// Raise the EFI_P_PC_ENABLE Status code
|
|
//
|
|
REPORT_STATUS_CODE_WITH_DEVICE_PATH (
|
|
EFI_PROGRESS_CODE,
|
|
EFI_IO_BUS_PCI | EFI_P_PC_ENABLE,
|
|
PciIoDevice->DevicePath
|
|
);
|
|
}
|
|
|
|
//
|
|
// If no attributes can be supported, then return.
|
|
// Otherwise, set the attributes that it can support.
|
|
//
|
|
Supports = (PciIoDevice->Supports) & Attributes;
|
|
if (Supports != Attributes) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// For Root Bridge, just call RootBridgeIo to set attributes;
|
|
//
|
|
if (!PciIoDevice->Parent) {
|
|
Status = ModifyRootBridgeAttributes (PciIoDevice, Attributes, Operation);
|
|
return Status;
|
|
}
|
|
|
|
Command = 0;
|
|
BridgeControl = 0;
|
|
|
|
//
|
|
// Check VGA and VGA16, they can not be set at the same time
|
|
//
|
|
if (((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) &&
|
|
(Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) ||
|
|
((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO) &&
|
|
(Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ||
|
|
((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) &&
|
|
(Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) ||
|
|
((Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO) &&
|
|
(Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) ) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
//
|
|
// For PPB & P2C, set relevant attribute bits
|
|
//
|
|
if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {
|
|
|
|
if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {
|
|
BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA;
|
|
}
|
|
|
|
if (Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) {
|
|
BridgeControl |= EFI_PCI_BRIDGE_CONTROL_ISA;
|
|
}
|
|
|
|
if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) {
|
|
Command |= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
|
|
}
|
|
|
|
if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {
|
|
BridgeControl |= EFI_PCI_BRIDGE_CONTROL_VGA_16;
|
|
}
|
|
|
|
} else {
|
|
//
|
|
// Do with the attributes on VGA
|
|
// Only for VGA's legacy resource, we just can enable once.
|
|
//
|
|
if (Attributes &
|
|
(EFI_PCI_IO_ATTRIBUTE_VGA_IO |
|
|
EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 |
|
|
EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY)) {
|
|
//
|
|
// Check if a VGA has been enabled before enabling a new one
|
|
//
|
|
if (Operation == EfiPciIoAttributeOperationEnable) {
|
|
//
|
|
// Check if there have been an active VGA device on the same segment
|
|
//
|
|
Temp = ActiveVGADeviceOnTheSameSegment (PciIoDevice);
|
|
if (Temp && Temp != PciIoDevice) {
|
|
//
|
|
// An active VGA has been detected, so can not enable another
|
|
//
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Do with the attributes on GFX
|
|
//
|
|
if (Attributes & (EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16)) {
|
|
|
|
if (Operation == EfiPciIoAttributeOperationEnable) {
|
|
//
|
|
// Check if snoop can be enabled in current configuration
|
|
//
|
|
Status = SupportPaletteSnoopAttributes (PciIoDevice, Operation);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
//
|
|
// Enable operation is forbidden, so mask the bit in attributes
|
|
// so as to keep consistent with the actual Status
|
|
//
|
|
// Attributes &= (~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);
|
|
//
|
|
//
|
|
//
|
|
return EFI_UNSUPPORTED;
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// It can be supported, so get ready to set the bit
|
|
//
|
|
Command |= EFI_PCI_COMMAND_VGA_PALETTE_SNOOP;
|
|
}
|
|
}
|
|
|
|
if (Attributes & EFI_PCI_IO_ATTRIBUTE_IO) {
|
|
Command |= EFI_PCI_COMMAND_IO_SPACE;
|
|
}
|
|
|
|
if (Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) {
|
|
Command |= EFI_PCI_COMMAND_MEMORY_SPACE;
|
|
}
|
|
|
|
if (Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) {
|
|
Command |= EFI_PCI_COMMAND_BUS_MASTER;
|
|
}
|
|
//
|
|
// The upstream bridge should be also set to revelant attribute
|
|
// expect for IO, Mem and BusMaster
|
|
//
|
|
UpStreamAttributes = Attributes &
|
|
(~(EFI_PCI_IO_ATTRIBUTE_IO |
|
|
EFI_PCI_IO_ATTRIBUTE_MEMORY |
|
|
EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
|
|
)
|
|
);
|
|
UpStreamBridge = PciIoDevice->Parent;
|
|
|
|
if (Operation == EfiPciIoAttributeOperationEnable) {
|
|
//
|
|
// Enable relevant attributes to command register and bridge control register
|
|
//
|
|
Status = PciEnableCommandRegister (PciIoDevice, Command);
|
|
if (BridgeControl) {
|
|
Status = PciEnableBridgeControlRegister (PciIoDevice, BridgeControl);
|
|
}
|
|
|
|
PciIoDevice->Attributes |= Attributes;
|
|
|
|
//
|
|
// Enable attributes of the upstream bridge
|
|
//
|
|
Status = UpStreamBridge->PciIo.Attributes (
|
|
&(UpStreamBridge->PciIo),
|
|
EfiPciIoAttributeOperationEnable,
|
|
UpStreamAttributes,
|
|
NULL
|
|
);
|
|
} else {
|
|
|
|
//
|
|
// Disable relevant attributes to command register and bridge control register
|
|
//
|
|
Status = PciDisableCommandRegister (PciIoDevice, Command);
|
|
if (BridgeControl) {
|
|
Status = PciDisableBridgeControlRegister (PciIoDevice, BridgeControl);
|
|
}
|
|
|
|
PciIoDevice->Attributes &= (~Attributes);
|
|
Status = EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
ReportErrorStatusCode (PciIoDevice, EFI_IO_BUS_PCI | EFI_IOB_EC_CONTROLLER_ERROR);
|
|
}
|
|
|
|
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
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: BarIndex - add argument and description to function comment
|
|
// TODO: Supports - add argument and description to function comment
|
|
// TODO: Resources - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - 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 *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 = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) * NumConfig + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
|
|
if (Configuration == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
ZeroMem (
|
|
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;
|
|
|
|
default:
|
|
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
|
|
|
|
--*/
|
|
// TODO: This - add argument and description to function comment
|
|
// TODO: Attributes - add argument and description to function comment
|
|
// TODO: BarIndex - add argument and description to function comment
|
|
// TODO: Offset - add argument and description to function comment
|
|
// TODO: Length - add argument and description to function comment
|
|
// TODO: EFI_INVALID_PARAMETER - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_UNSUPPORTED - add return value to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
{
|
|
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
|
|
|
|
--*/
|
|
// TODO: PciIoDevice - add argument and description to function comment
|
|
// TODO: Operation - add argument and description to function comment
|
|
// TODO: Attributes - add argument and description to function comment
|
|
// TODO: EFI_SUCCESS - add return value to function comment
|
|
{
|
|
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:
|
|
|
|
Returns:
|
|
|
|
None
|
|
|
|
--*/
|
|
// TODO: PciDevice1 - add argument and description to function comment
|
|
// TODO: PciDevice2 - add argument and description to function comment
|
|
{
|
|
|
|
if (PciDevice1->Parent == PciDevice2->Parent) {
|
|
return TRUE;
|
|
}
|
|
|
|
if (PciDevice1->BusNumber > PciDevice2->BusNumber) {
|
|
return PciDeviceExisted (PciDevice1->Parent, PciDevice2);
|
|
}
|
|
|
|
return PciDeviceExisted (PciDevice2->Parent, PciDevice1);
|
|
}
|