pcatpcirootbridgeio.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,024 行 · 第 1/2 页
C
1,024 行
/*++
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:
PcatPciRootBridgeIo.c
Abstract:
EFI PC AT PCI Root Bridge Io Protocol
Revision History
--*/
#include "PcatPciRootBridge.h"
#include "pci22.h"
//
// Protocol Member Function Prototypes
//
EFI_STATUS
PcatRootBridgeIoPollMem (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINT64 Mask,
IN UINT64 Value,
IN UINT64 Delay,
OUT UINT64 *Result
);
EFI_STATUS
PcatRootBridgeIoPollIo (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINT64 Mask,
IN UINT64 Value,
IN UINT64 Delay,
OUT UINT64 *Result
);
EFI_STATUS
PcatRootBridgeIoMemRead (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
);
EFI_STATUS
PcatRootBridgeIoMemWrite (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
);
EFI_STATUS
PcatRootBridgeIoIoRead (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
);
EFI_STATUS
PcatRootBridgeIoIoWrite (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 UserAddress,
IN UINTN Count,
IN OUT VOID *UserBuffer
);
EFI_STATUS
PcatRootBridgeIoCopyMem (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 DestAddress,
IN UINT64 SrcAddress,
IN UINTN Count
);
EFI_STATUS
PcatRootBridgeIoPciRead (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
);
EFI_STATUS
PcatRootBridgeIoPciWrite (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
);
EFI_STATUS
PcatRootBridgeIoMap (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
IN VOID *HostAddress,
IN OUT UINTN *NumberOfBytes,
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
OUT VOID **Mapping
);
EFI_STATUS
PcatRootBridgeIoUnmap (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN VOID *Mapping
);
EFI_STATUS
PcatRootBridgeIoAllocateBuffer (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN Pages,
OUT VOID **HostAddress,
IN UINT64 Attributes
);
EFI_STATUS
PcatRootBridgeIoFreeBuffer (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN UINTN Pages,
OUT VOID *HostAddress
);
EFI_STATUS
PcatRootBridgeIoFlush (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
);
EFI_STATUS
PcatRootBridgeIoGetAttributes (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
OUT UINT64 *Supported,
OUT UINT64 *Attributes
);
EFI_STATUS
PcatRootBridgeIoSetAttributes (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN UINT64 Attributes,
IN OUT UINT64 *ResourceBase,
IN OUT UINT64 *ResourceLength
);
EFI_STATUS
PcatRootBridgeIoConfiguration (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
OUT VOID **Resources
);
//
// Private Function Prototypes
//
STATIC
EFI_STATUS
EFIAPI
PcatRootBridgeIoMemRW (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINTN Count,
IN BOOLEAN InStrideFlag,
IN PTR In,
IN BOOLEAN OutStrideFlag,
OUT PTR Out
);
EFI_STATUS
PcatRootBridgeIoConstructor (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Protocol,
IN UINTN SegmentNumber
)
/*++
Routine Description:
Contruct the Pci Root Bridge Io protocol
Arguments:
Protocol - protocol to initialize
Returns:
None
--*/
{
Protocol->ParentHandle = NULL;
Protocol->PollMem = PcatRootBridgeIoPollMem;
Protocol->PollIo = PcatRootBridgeIoPollIo;
Protocol->Mem.Read = PcatRootBridgeIoMemRead;
Protocol->Mem.Write = PcatRootBridgeIoMemWrite;
Protocol->Io.Read = PcatRootBridgeIoIoRead;
Protocol->Io.Write = PcatRootBridgeIoIoWrite;
Protocol->CopyMem = PcatRootBridgeIoCopyMem;
Protocol->Pci.Read = PcatRootBridgeIoPciRead;
Protocol->Pci.Write = PcatRootBridgeIoPciWrite;
Protocol->Map = PcatRootBridgeIoMap;
Protocol->Unmap = PcatRootBridgeIoUnmap;
Protocol->AllocateBuffer = PcatRootBridgeIoAllocateBuffer;
Protocol->FreeBuffer = PcatRootBridgeIoFreeBuffer;
Protocol->Flush = PcatRootBridgeIoFlush;
Protocol->GetAttributes = PcatRootBridgeIoGetAttributes;
Protocol->SetAttributes = PcatRootBridgeIoSetAttributes;
Protocol->Configuration = PcatRootBridgeIoConfiguration;
Protocol->SegmentNumber = (UINT32)SegmentNumber;
return EFI_SUCCESS;
}
EFI_STATUS
PcatRootBridgeIoPollMem (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINT64 Mask,
IN UINT64 Value,
IN UINT64 Delay,
OUT UINT64 *Result
)
{
EFI_STATUS Status;
UINT64 NumberOfTicks;
UINTN Remainder;
if (Result == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Width < 0 || Width > EfiPciWidthUint64) {
return EFI_INVALID_PARAMETER;
}
//
// No matter what, always do a single poll.
//
Status = This->Mem.Read (This, Width, Address, 1, Result);
if ( EFI_ERROR(Status) ) {
return Status;
}
if ( (*Result & Mask) == Value ) {
return EFI_SUCCESS;
}
if ( Delay != 0 ) {
NumberOfTicks = DivU64x32 (Delay, 100, &Remainder);
if ( Remainder !=0 ) {
NumberOfTicks += 1;
}
NumberOfTicks += 1;
while ( NumberOfTicks ) {
gBS->Stall (10);
Status = This->Mem.Read (This, Width, Address, 1, Result);
if ( EFI_ERROR(Status) ) {
return Status;
}
if ( (*Result & Mask) == Value ) {
return EFI_SUCCESS;
}
NumberOfTicks -= 1;
}
}
return EFI_TIMEOUT;
}
EFI_STATUS
PcatRootBridgeIoPollIo (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINT64 Mask,
IN UINT64 Value,
IN UINT64 Delay,
OUT UINT64 *Result
)
{
EFI_STATUS Status;
UINT64 NumberOfTicks;
UINTN Remainder;
if (Result == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Width < 0 || Width > EfiPciWidthUint64) {
return EFI_INVALID_PARAMETER;
}
//
// No matter what, always do a single poll.
//
Status = This->Io.Read (This, Width, Address, 1, Result);
if ( EFI_ERROR(Status) ) {
return Status;
}
if ( (*Result & Mask) == Value ) {
return EFI_SUCCESS;
}
if (Delay != 0) {
NumberOfTicks = DivU64x32 (Delay, 100, &Remainder);
if ( Remainder !=0 ) {
NumberOfTicks += 1;
}
NumberOfTicks += 1;
while ( NumberOfTicks ) {
gBS->Stall(10);
Status = This->Io.Read (This, Width, Address, 1, Result);
if ( EFI_ERROR(Status) ) {
return Status;
}
if ( (*Result & Mask) == Value ) {
return EFI_SUCCESS;
}
NumberOfTicks -= 1;
}
}
return EFI_TIMEOUT;
}
BOOLEAN
PcatRootBridgeMemAddressValid (
IN PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData,
IN UINT64 Address
)
{
if ((Address >= PrivateData->PciExpressBaseAddress) && (Address < PrivateData->PciExpressBaseAddress + 0x10000000)) {
return TRUE;
}
if ((Address >= PrivateData->MemBase) && (Address < PrivateData->MemLimit)) {
return TRUE;
}
return FALSE;
}
EFI_STATUS
PcatRootBridgeIoMemRead (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
{
PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
UINTN AlignMask;
PTR In;
PTR Out;
if ( Buffer == NULL ) {
return EFI_INVALID_PARAMETER;
}
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
if (!PcatRootBridgeMemAddressValid (PrivateData, Address)) {
return EFI_INVALID_PARAMETER;
}
AlignMask = (1 << (Width & 0x03)) - 1;
if (Address & AlignMask) {
return EFI_INVALID_PARAMETER;
}
Address += PrivateData->PhysicalMemoryBase;
In.buf = Buffer;
Out.buf = (VOID *)(UINTN) Address;
if (Width >= EfiPciWidthUint8 && Width <= EfiPciWidthUint64) {
return PcatRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
}
if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
return PcatRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
}
if (Width >= EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
return PcatRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
}
return EFI_INVALID_PARAMETER;
}
EFI_STATUS
PcatRootBridgeIoMemWrite (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINTN Count,
IN OUT VOID *Buffer
)
{
PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
UINTN AlignMask;
PTR In;
PTR Out;
if ( Buffer == NULL ) {
return EFI_INVALID_PARAMETER;
}
PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
if (!PcatRootBridgeMemAddressValid (PrivateData, Address)) {
return EFI_INVALID_PARAMETER;
}
AlignMask = (1 << (Width & 0x03)) - 1;
if (Address & AlignMask) {
return EFI_INVALID_PARAMETER;
}
Address += PrivateData->PhysicalMemoryBase;
In.buf = (VOID *)(UINTN) Address;
Out.buf = Buffer;
if (Width >= EfiPciWidthUint8 && Width <= EfiPciWidthUint64) {
return PcatRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
}
if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
return PcatRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
}
if (Width >= EfiPciWidthFillUint8 && Width <= EfiPciWidthFillUint64) {
return PcatRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
}
return EFI_INVALID_PARAMETER;
}
EFI_STATUS
PcatRootBridgeIoCopyMem (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 DestAddress,
IN UINT64 SrcAddress,
IN UINTN Count
)
{
EFI_STATUS Status;
BOOLEAN Direction;
UINTN Stride;
UINTN Index;
UINT64 Result;
if (Width < 0 || Width > EfiPciWidthUint64) {
return EFI_INVALID_PARAMETER;
}
if (DestAddress == SrcAddress) {
return EFI_SUCCESS;
}
Stride = 1 << Width;
Direction = TRUE;
if ((DestAddress > SrcAddress) && (DestAddress < (SrcAddress + Count * Stride))) {
Direction = FALSE;
SrcAddress = SrcAddress + (Count-1) * Stride;
DestAddress = DestAddress + (Count-1) * Stride;
}
for (Index = 0;Index < Count;Index++) {
Status = PcatRootBridgeIoMemRead (
This,
Width,
SrcAddress,
1,
&Result
);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?