mirror of https://github.com/acidanthera/audk.git
300 lines
9.7 KiB
C
300 lines
9.7 KiB
C
/** @file
|
|
|
|
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
|
|
|
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.
|
|
|
|
**/
|
|
|
|
#include "PciEmulation.h"
|
|
|
|
BOOLEAN
|
|
PciRootBridgeMemAddressValid (
|
|
IN PCI_ROOT_BRIDGE *Private,
|
|
IN UINT64 Address
|
|
)
|
|
{
|
|
if ((Address >= Private->MemoryStart) && (Address < (Private->MemoryStart + Private->MemorySize))) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
EFI_STATUS
|
|
PciRootBridgeIoMemRW (
|
|
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
|
IN UINTN Count,
|
|
IN BOOLEAN InStrideFlag,
|
|
IN PTR In,
|
|
IN BOOLEAN OutStrideFlag,
|
|
OUT PTR Out
|
|
)
|
|
{
|
|
UINTN Stride;
|
|
UINTN InStride;
|
|
UINTN OutStride;
|
|
|
|
Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
|
|
Stride = (UINTN)1 << Width;
|
|
InStride = InStrideFlag ? Stride : 0;
|
|
OutStride = OutStrideFlag ? Stride : 0;
|
|
|
|
//
|
|
// Loop for each iteration and move the data
|
|
//
|
|
switch (Width) {
|
|
case EfiPciWidthUint8:
|
|
for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
|
|
*In.Ui8 = *Out.Ui8;
|
|
}
|
|
break;
|
|
case EfiPciWidthUint16:
|
|
for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
|
|
*In.Ui16 = *Out.Ui16;
|
|
}
|
|
break;
|
|
case EfiPciWidthUint32:
|
|
for (;Count > 0; Count--, In.Buffer += InStride, Out.Buffer += OutStride) {
|
|
*In.Ui32 = *Out.Ui32;
|
|
}
|
|
break;
|
|
default:
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
PciRootBridgeIoPciRW (
|
|
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
|
|
IN BOOLEAN Write,
|
|
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
|
|
IN UINT64 UserAddress,
|
|
IN UINTN Count,
|
|
IN OUT VOID *UserBuffer
|
|
)
|
|
{
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
|
|
|
|
@param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
|
|
@param Width Signifies the width of the memory operations.
|
|
@param Address The base address of the memory operations.
|
|
@param Count The number of memory operations to perform.
|
|
@param Buffer For read operations, the destination buffer to store the results. For write
|
|
operations, the source buffer to write data from.
|
|
|
|
@retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
|
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciRootBridgeIoMemRead (
|
|
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
|
|
)
|
|
{
|
|
PCI_ROOT_BRIDGE *Private;
|
|
UINTN AlignMask;
|
|
PTR In;
|
|
PTR Out;
|
|
|
|
if ( Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
|
|
|
|
if (!PciRootBridgeMemAddressValid (Private, Address)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
AlignMask = (1 << (Width & 0x03)) - 1;
|
|
if (Address & AlignMask) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
In.Buffer = Buffer;
|
|
Out.Buffer = (VOID *)(UINTN) Address;
|
|
|
|
switch (Width) {
|
|
case EfiPciWidthUint8:
|
|
case EfiPciWidthUint16:
|
|
case EfiPciWidthUint32:
|
|
case EfiPciWidthUint64:
|
|
return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
|
|
|
|
case EfiPciWidthFifoUint8:
|
|
case EfiPciWidthFifoUint16:
|
|
case EfiPciWidthFifoUint32:
|
|
case EfiPciWidthFifoUint64:
|
|
return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
|
|
|
|
case EfiPciWidthFillUint8:
|
|
case EfiPciWidthFillUint16:
|
|
case EfiPciWidthFillUint32:
|
|
case EfiPciWidthFillUint64:
|
|
return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
/**
|
|
Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
|
|
|
|
@param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
|
|
@param Width Signifies the width of the memory operations.
|
|
@param Address The base address of the memory operations.
|
|
@param Count The number of memory operations to perform.
|
|
@param Buffer For read operations, the destination buffer to store the results. For write
|
|
operations, the source buffer to write data from.
|
|
|
|
@retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
|
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciRootBridgeIoMemWrite (
|
|
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
|
|
)
|
|
{
|
|
PCI_ROOT_BRIDGE *Private;
|
|
UINTN AlignMask;
|
|
PTR In;
|
|
PTR Out;
|
|
|
|
if ( Buffer == NULL ) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
|
|
|
|
if (!PciRootBridgeMemAddressValid (Private, Address)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
AlignMask = (1 << (Width & 0x03)) - 1;
|
|
if (Address & AlignMask) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
In.Buffer = (VOID *)(UINTN) Address;
|
|
Out.Buffer = Buffer;
|
|
|
|
switch (Width) {
|
|
case EfiPciWidthUint8:
|
|
case EfiPciWidthUint16:
|
|
case EfiPciWidthUint32:
|
|
case EfiPciWidthUint64:
|
|
return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
|
|
|
|
case EfiPciWidthFifoUint8:
|
|
case EfiPciWidthFifoUint16:
|
|
case EfiPciWidthFifoUint32:
|
|
case EfiPciWidthFifoUint64:
|
|
return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
|
|
|
|
case EfiPciWidthFillUint8:
|
|
case EfiPciWidthFillUint16:
|
|
case EfiPciWidthFillUint32:
|
|
case EfiPciWidthFillUint64:
|
|
return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
/**
|
|
Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
|
|
|
|
@param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
|
|
@param Width Signifies the width of the memory operations.
|
|
@param Address The base address of the memory operations.
|
|
@param Count The number of memory operations to perform.
|
|
@param Buffer For read operations, the destination buffer to store the results. For write
|
|
operations, the source buffer to write data from.
|
|
|
|
@retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
|
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciRootBridgeIoPciRead (
|
|
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
|
|
)
|
|
{
|
|
if (Buffer == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
return PciRootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
|
|
}
|
|
|
|
/**
|
|
Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
|
|
|
|
@param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
|
|
@param Width Signifies the width of the memory operations.
|
|
@param Address The base address of the memory operations.
|
|
@param Count The number of memory operations to perform.
|
|
@param Buffer For read operations, the destination buffer to store the results. For write
|
|
operations, the source buffer to write data from.
|
|
|
|
@retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
|
|
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
|
|
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PciRootBridgeIoPciWrite (
|
|
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
|
|
)
|
|
{
|
|
if (Buffer == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
return PciRootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
|
|
}
|