+++ /dev/null
-/*++
-
-Copyright (c) 2005 - 2012, Intel Corporation. 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.
-
-Module Name:
- PcatPciRootBridgeIo.c
-
-Abstract:
-
- EFI PC AT PCI Root Bridge Io Protocol
-
-Revision History
-
---*/
-
-#include "PcatPciRootBridge.h"
-
-//
-// Protocol Member Function Prototypes
-//
-EFI_STATUS
-EFIAPI
-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
-EFIAPI
-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
-EFIAPI
-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
-EFIAPI
-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
-EFIAPI
-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
-EFIAPI
-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
-EFIAPI
-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
-EFIAPI
-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
-EFIAPI
-PcatRootBridgeIoUnmap (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN VOID *Mapping
- );
-
-EFI_STATUS
-EFIAPI
-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
-EFIAPI
-PcatRootBridgeIoFreeBuffer (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN UINTN Pages,
- OUT VOID *HostAddress
- );
-
-EFI_STATUS
-EFIAPI
-PcatRootBridgeIoFlush (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
- );
-
-EFI_STATUS
-EFIAPI
-PcatRootBridgeIoGetAttributes (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- OUT UINT64 *Supported,
- OUT UINT64 *Attributes
- );
-
-EFI_STATUS
-EFIAPI
-PcatRootBridgeIoSetAttributes (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN UINT64 Attributes,
- IN OUT UINT64 *ResourceBase,
- IN OUT UINT64 *ResourceLength
- );
-
-EFI_STATUS
-EFIAPI
-PcatRootBridgeIoConfiguration (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- OUT VOID **Resources
- );
-
-//
-// Private Function Prototypes
-//
-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
-EFIAPI
-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;
- UINT32 Remainder;
-
- if (Result == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
-
- if ((UINT32)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) {
- return EFI_SUCCESS;
- } else {
-
- NumberOfTicks = DivU64x32Remainder (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
-EFIAPI
-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;
- UINT32 Remainder;
-
- if (Result == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if ((UINT32)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) {
- return EFI_SUCCESS;
- } else {
-
- NumberOfTicks = DivU64x32Remainder (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
-EFIAPI
-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 ((UINT32)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
-EFIAPI
-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 ((UINT32)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
-EFIAPI
-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 ((UINT32)Width > EfiPciWidthUint64) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (DestAddress == SrcAddress) {
- return EFI_SUCCESS;
- }
-
- Stride = (UINTN)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
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = PcatRootBridgeIoMemWrite (
- This,
- Width,
- DestAddress,
- 1,
- &Result
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (Direction) {
- SrcAddress += Stride;
- DestAddress += Stride;
- } else {
- SrcAddress -= Stride;
- DestAddress -= Stride;
- }
- }
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-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
- )
-{
- if (Buffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- return PcatRootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
-}
-
-EFI_STATUS
-EFIAPI
-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
- )
-{
- if (Buffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- return PcatRootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
-}
-
-EFI_STATUS
-EFIAPI
-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 Status;
- EFI_PHYSICAL_ADDRESS PhysicalAddress;
- MAP_INFO *MapInfo;
- MAP_INFO_INSTANCE *MapInstance;
- PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
-
- if ( HostAddress == NULL || NumberOfBytes == NULL ||
- DeviceAddress == NULL || Mapping == NULL ) {
-
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Perform a fence operation to make sure all memory operations are flushed
- //
- MemoryFence();
-
- //
- // Initialize the return values to their defaults
- //
- *Mapping = NULL;
-
- //
- // Make sure that Operation is valid
- //
- if ((UINT32)Operation >= EfiPciOperationMaximum) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Most PCAT like chipsets can not handle performing DMA above 4GB.
- // If any part of the DMA transfer being mapped is above 4GB, then
- // map the DMA transfer to a buffer below 4GB.
- //
- PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;
- if ((PhysicalAddress + *NumberOfBytes) > 0x100000000ULL) {
-
- //
- // Common Buffer operations can not be remapped. If the common buffer
- // if above 4GB, then it is not possible to generate a mapping, so return
- // an error.
- //
- if (Operation == EfiPciOperationBusMasterCommonBuffer || Operation == EfiPciOperationBusMasterCommonBuffer64) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Allocate a MAP_INFO structure to remember the mapping when Unmap() is
- // called later.
- //
- Status = gBS->AllocatePool (
- EfiBootServicesData,
- sizeof(MAP_INFO),
- (VOID **)&MapInfo
- );
- if (EFI_ERROR (Status)) {
- *NumberOfBytes = 0;
- return Status;
- }
-
- //
- // Return a pointer to the MAP_INFO structure in Mapping
- //
- *Mapping = MapInfo;
-
- //
- // Initialize the MAP_INFO structure
- //
- MapInfo->Operation = Operation;
- MapInfo->NumberOfBytes = *NumberOfBytes;
- MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES(*NumberOfBytes);
- MapInfo->HostAddress = PhysicalAddress;
- MapInfo->MappedHostAddress = 0x00000000ffffffff;
-
- //
- // Allocate a buffer below 4GB to map the transfer to.
- //
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiBootServicesData,
- MapInfo->NumberOfPages,
- &MapInfo->MappedHostAddress
- );
- if (EFI_ERROR(Status)) {
- gBS->FreePool (MapInfo);
- *NumberOfBytes = 0;
- return Status;
- }
-
- //
- // If this is a read operation from the Bus Master's point of view,
- // then copy the contents of the real buffer into the mapped buffer
- // so the Bus Master can read the contents of the real buffer.
- //
- if (Operation == EfiPciOperationBusMasterRead || Operation == EfiPciOperationBusMasterRead64) {
- CopyMem (
- (VOID *)(UINTN)MapInfo->MappedHostAddress,
- (VOID *)(UINTN)MapInfo->HostAddress,
- MapInfo->NumberOfBytes
- );
- }
-
-
- Status =gBS->AllocatePool (
- EfiBootServicesData,
- sizeof(MAP_INFO_INSTANCE),
- (VOID **)&MapInstance
- );
- if (EFI_ERROR(Status)) {
- gBS->FreePages (MapInfo->MappedHostAddress,MapInfo->NumberOfPages);
- gBS->FreePool (MapInfo);
- *NumberOfBytes = 0;
- return Status;
- }
-
- MapInstance->Map=MapInfo;
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
- InsertTailList(&PrivateData->MapInfo,&MapInstance->Link);
-
- //
- // The DeviceAddress is the address of the maped buffer below 4GB
- //
- *DeviceAddress = MapInfo->MappedHostAddress;
- } else {
- //
- // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress
- //
- *DeviceAddress = PhysicalAddress;
- }
-
- //
- // Perform a fence operation to make sure all memory operations are flushed
- //
- MemoryFence();
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-PcatRootBridgeIoUnmap (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN VOID *Mapping
- )
-
-{
- MAP_INFO *MapInfo;
- PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
- LIST_ENTRY *Link;
-
- //
- // Perform a fence operation to make sure all memory operations are flushed
- //
- MemoryFence();
-
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
- //
- // See if the Map() operation associated with this Unmap() required a mapping buffer.
- // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
- //
- if (Mapping != NULL) {
- //
- // Get the MAP_INFO structure from Mapping
- //
- MapInfo = (MAP_INFO *)Mapping;
-
- for (Link = PrivateData->MapInfo.ForwardLink; Link != &PrivateData->MapInfo; Link = Link->ForwardLink) {
- if (((MAP_INFO_INSTANCE*)Link)->Map == MapInfo)
- break;
- }
-
- if (Link == &PrivateData->MapInfo) {
- return EFI_INVALID_PARAMETER;
- }
-
- RemoveEntryList(Link);
- ((MAP_INFO_INSTANCE*)Link)->Map = NULL;
- gBS->FreePool((MAP_INFO_INSTANCE*)Link);
-
- //
- // If this is a write operation from the Bus Master's point of view,
- // then copy the contents of the mapped buffer into the real buffer
- // so the processor can read the contents of the real buffer.
- //
- if (MapInfo->Operation == EfiPciOperationBusMasterWrite || MapInfo->Operation == EfiPciOperationBusMasterWrite64) {
- CopyMem (
- (VOID *)(UINTN)MapInfo->HostAddress,
- (VOID *)(UINTN)MapInfo->MappedHostAddress,
- MapInfo->NumberOfBytes
- );
- }
-
- //
- // Free the mapped buffer and the MAP_INFO structure.
- //
- gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
- gBS->FreePool (Mapping);
- }
-
- //
- // Perform a fence operation to make sure all memory operations are flushed
- //
- MemoryFence();
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-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 Status;
- EFI_PHYSICAL_ADDRESS PhysicalAddress;
-
- //
- // Validate Attributes
- //
- if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Check for invalid inputs
- //
- if (HostAddress == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
- //
- if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Limit allocations to memory below 4GB
- //
- PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xffffffff);
-
- Status = gBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &PhysicalAddress);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- *HostAddress = (VOID *)(UINTN)PhysicalAddress;
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-PcatRootBridgeIoFreeBuffer (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN UINTN Pages,
- OUT VOID *HostAddress
- )
-
-{
-
- if( HostAddress == NULL ){
- return EFI_INVALID_PARAMETER;
- }
- return gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, Pages);
-}
-
-EFI_STATUS
-EFIAPI
-PcatRootBridgeIoFlush (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
- )
-
-{
- //
- // Perform a fence operation to make sure all memory operations are flushed
- //
- MemoryFence();
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-PcatRootBridgeIoGetAttributes (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- OUT UINT64 *Supported, OPTIONAL
- OUT UINT64 *Attributes
- )
-
-{
- PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
-
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
-
- if (Attributes == NULL && Supported == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Supported is an OPTIONAL parameter. See if it is NULL
- //
- if (Supported) {
- //
- // This is a generic driver for a PC-AT class system. It does not have any
- // chipset specific knowlegde, so none of the attributes can be set or
- // cleared. Any attempt to set attribute that are already set will succeed,
- // and any attempt to set an attribute that is not supported will fail.
- //
- *Supported = PrivateData->Attributes;
- }
-
- //
- // Set Attrbutes to the attributes detected when the PCI Root Bridge was initialized
- //
-
- if (Attributes) {
- *Attributes = PrivateData->Attributes;
- }
-
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-PcatRootBridgeIoSetAttributes (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN UINT64 Attributes,
- IN OUT UINT64 *ResourceBase,
- IN OUT UINT64 *ResourceLength
- )
-
-{
- PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
-
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
-
- //
- // This is a generic driver for a PC-AT class system. It does not have any
- // chipset specific knowlegde, so none of the attributes can be set or
- // cleared. Any attempt to set attribute that are already set will succeed,
- // and any attempt to set an attribute that is not supported will fail.
- //
- if (Attributes & (~PrivateData->Attributes)) {
- return EFI_UNSUPPORTED;
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-PcatRootBridgeIoConfiguration (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- OUT VOID **Resources
- )
-
-{
- PCAT_PCI_ROOT_BRIDGE_INSTANCE *PrivateData;
-
- PrivateData = DRIVER_INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(This);
-
- *Resources = PrivateData->Configuration;
-
- return EFI_SUCCESS;
-}
-
-//
-// Internal function
-//
-
-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
- )
-/*++
-
-Routine Description:
-
- Private service to provide the memory read/write
-
-Arguments:
-
- Width of the Memory Access
- Count of the number of accesses to perform
-
-Returns:
-
- Status
-
- EFI_SUCCESS - Successful transaction
- EFI_INVALID_PARAMETER - Unsupported width and address combination
-
---*/
-{
- 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.buf += InStride, Out.buf += OutStride) {
- MemoryFence();
- *In.ui8 = *Out.ui8;
- MemoryFence();
- }
- break;
- case EfiPciWidthUint16:
- for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
- MemoryFence();
- *In.ui16 = *Out.ui16;
- MemoryFence();
- }
- break;
- case EfiPciWidthUint32:
- for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
- MemoryFence();
- *In.ui32 = *Out.ui32;
- MemoryFence();
- }
- break;
- default:
- return EFI_INVALID_PARAMETER;
- }
-
- return EFI_SUCCESS;
-}
-