pciio.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,868 行 · 第 1/4 页
C
1,868 行
/*++
Copyright (c) 2005 - 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"
//
// PCI I/O Support Function Prototypes
//
//
BOOLEAN
PciDevicesOnTheSamePath (
IN PCI_IO_DEVICE *PciDevice1,
IN PCI_IO_DEVICE *PciDevice2
);
EFI_STATUS
UpStreamBridgesAttributes (
IN PCI_IO_DEVICE *PciIoDevice,
IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
IN UINT64 Attributes
);
BOOLEAN
CheckBarType (
IN PCI_IO_DEVICE *PciIoDevice,
UINT8 BarIndex,
PCI_BAR_TYPE BarType
);
EFI_STATUS
SetBootVGA (
IN PCI_IO_DEVICE *PciIoDevice
);
EFI_STATUS
DisableBootVGA (
IN PCI_IO_DEVICE *PciIoDevice
);
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
);
EFI_STATUS
PciIoVerifyConfigAccess (
PCI_IO_DEVICE *PciIoDevice,
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
IN UINTN Count,
IN UINT64 *Offset
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
EFI_STATUS
EFIAPI
PciIoUnmap (
IN EFI_PCI_IO_PROTOCOL *This,
IN VOID *Mapping
);
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
);
EFI_STATUS
EFIAPI
PciIoFreeBuffer (
IN EFI_PCI_IO_PROTOCOL *This,
IN UINTN Pages,
IN VOID *HostAddress
);
EFI_STATUS
EFIAPI
PciIoFlush (
IN EFI_PCI_IO_PROTOCOL *This
);
EFI_STATUS
EFIAPI
PciIoGetLocation (
IN EFI_PCI_IO_PROTOCOL *This,
OUT UINTN *Segment,
OUT UINTN *Bus,
OUT UINTN *Device,
OUT UINTN *Function
);
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
);
EFI_STATUS
EFIAPI
PciIoGetBarAttributes(
IN EFI_PCI_IO_PROTOCOL *This,
IN UINT8 BarIndex,
OUT UINT64 *Supports, OPTIONAL
OUT VOID **Resources OPTIONAL
);
EFI_STATUS
EFIAPI
PciIoSetBarAttributes(
IN EFI_PCI_IO_PROTOCOL *This,
IN UINT64 Attributes,
IN UINT8 BarIndex,
IN OUT UINT64 *Offset,
IN OUT UINT64 *Length
);
//
// 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
};
EFI_STATUS
InitializePciIoInstance (
PCI_IO_DEVICE *PciIoDevice
)
/*++
Routine Description:
Initializes a PCI I/O Instance
Arguments:
Returns:
None
--*/
{
EfiCopyMem (&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
--*/
{
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 * (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
--*/
{
UINT64 ExtendOffset;
if (Width < 0 || Width >= EfiPciIoWidthMaximum) {
return EFI_INVALID_PARAMETER;
}
//
// If Width is EfiPciIoWidthFifoUintX then convert to EfiPciIoWidthUintX
// If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX
//
Width &= 0x03;
if (PciIoDevice->IsPciExp) {
if ((*Offset + Count * (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 * (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
--*/
{
EFI_STATUS Status;
PCI_IO_DEVICE *PciIoDevice;
PciIoDevice = PCI_IO_DEVICE_FROM_PCI_IO_THIS (This);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?