Remove the references to DuetPkg.  Copy the files from revision
ffea0a2ce2 of DuetPkg into
CorebootModulePkg.  The components include:
* PciBusNoEnumerationDxe
* PciRootBridgeNoEnumerationDxe
* SataControllerDxe
TEST=Build and run on Galileo Gen2
Change-Id: Id07185f7e226749e5f7c6b6cb427bcef7eac8496
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-by: Maurice Ma <maurice.ma@intel.com>
Reviewed-by: Prince Agyeman <prince.agyeman@intel.com>
		
	
		
			
				
	
	
		
			1037 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1037 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*++
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 |