mirror of https://github.com/acidanthera/audk.git
1981 lines
56 KiB
C
1981 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 = (EFI_PCI_IO_PROTOCOL_WIDTH) (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 = (EFI_PCI_IO_PROTOCOL_WIDTH) (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 = (EFI_PCI_IO_PROTOCOL_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
|
||
|
{
|
||
|
BOOLEAN Existed1;
|
||
|
BOOLEAN Existed2;
|
||
|
|
||
|
if (PciDevice1->Parent == PciDevice2->Parent) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
Existed1 = PciDeviceExisted (PciDevice1->Parent, PciDevice2);
|
||
|
Existed2 = PciDeviceExisted (PciDevice2->Parent, PciDevice1);
|
||
|
|
||
|
return (BOOLEAN) (Existed1 || Existed2);
|
||
|
}
|