REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the OvmfPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Andrew Fish <afish@apple.com>
		
			
				
	
	
		
			227 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			227 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Plug a PciSegmentLib backend into PciCapLib, for config space access.
 | 
						|
 | 
						|
  Copyright (C) 2018, Red Hat, Inc.
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
**/
 | 
						|
 | 
						|
#include <IndustryStandard/Pci23.h>
 | 
						|
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
#include <Library/PciSegmentLib.h>
 | 
						|
 | 
						|
#include "BasePciCapPciSegmentLib.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Read the config space of a given PCI device (both normal and extended).
 | 
						|
 | 
						|
  SegmentDevReadConfig() performs as few config space accesses as possible
 | 
						|
  (without attempting 64-bit wide accesses).
 | 
						|
 | 
						|
  @param[in] PciDevice           Implementation-specific unique representation
 | 
						|
                                 of the PCI device in the PCI hierarchy.
 | 
						|
 | 
						|
  @param[in] SourceOffset        Source offset in the config space of the PCI
 | 
						|
                                 device to start reading from.
 | 
						|
 | 
						|
  @param[out] DestinationBuffer  Buffer to store the read data to.
 | 
						|
 | 
						|
  @param[in] Size                The number of bytes to transfer.
 | 
						|
 | 
						|
  @retval RETURN_SUCCESS      Size bytes have been transferred from config
 | 
						|
                              space to DestinationBuffer.
 | 
						|
 | 
						|
  @retval RETURN_UNSUPPORTED  Accessing Size bytes from SourceOffset exceeds
 | 
						|
                              the config space limit of the PCI device.
 | 
						|
                              Although PCI_CAP_DEV_READ_CONFIG allows reading
 | 
						|
                              fewer than Size bytes in this case,
 | 
						|
                              SegmentDevReadConfig() will read none.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
SegmentDevReadConfig (
 | 
						|
  IN  PCI_CAP_DEV  *PciDevice,
 | 
						|
  IN  UINT16       SourceOffset,
 | 
						|
  OUT VOID         *DestinationBuffer,
 | 
						|
  IN  UINT16       Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  SEGMENT_DEV  *SegmentDev;
 | 
						|
  UINT16       ConfigSpaceSize;
 | 
						|
  UINT64       SourceAddress;
 | 
						|
 | 
						|
  SegmentDev      = SEGMENT_DEV_FROM_PCI_CAP_DEV (PciDevice);
 | 
						|
  ConfigSpaceSize = (SegmentDev->MaxDomain == PciCapNormal ?
 | 
						|
                     PCI_MAX_CONFIG_OFFSET : PCI_EXP_MAX_CONFIG_OFFSET);
 | 
						|
  //
 | 
						|
  // Note that all UINT16 variables below are promoted to INT32, and the
 | 
						|
  // addition and the comparison is carried out in INT32.
 | 
						|
  //
 | 
						|
  if (SourceOffset + Size > ConfigSpaceSize) {
 | 
						|
    return RETURN_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  SourceAddress = PCI_SEGMENT_LIB_ADDRESS (
 | 
						|
                    SegmentDev->SegmentNr,
 | 
						|
                    SegmentDev->BusNr,
 | 
						|
                    SegmentDev->DeviceNr,
 | 
						|
                    SegmentDev->FunctionNr,
 | 
						|
                    SourceOffset
 | 
						|
                    );
 | 
						|
  PciSegmentReadBuffer (SourceAddress, Size, DestinationBuffer);
 | 
						|
  return RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Write the config space of a given PCI device (both normal and extended).
 | 
						|
 | 
						|
  SegmentDevWriteConfig() performs as few config space accesses as possible
 | 
						|
  (without attempting 64-bit wide accesses).
 | 
						|
 | 
						|
  @param[in] PciDevice          Implementation-specific unique representation
 | 
						|
                                of the PCI device in the PCI hierarchy.
 | 
						|
 | 
						|
  @param[in] DestinationOffset  Destination offset in the config space of the
 | 
						|
                                PCI device to start writing at.
 | 
						|
 | 
						|
  @param[in] SourceBuffer       Buffer to read the data to be stored from.
 | 
						|
 | 
						|
  @param[in] Size               The number of bytes to transfer.
 | 
						|
 | 
						|
  @retval RETURN_SUCCESS      Size bytes have been transferred from
 | 
						|
                              SourceBuffer to config space.
 | 
						|
 | 
						|
  @retval RETURN_UNSUPPORTED  Accessing Size bytes at DestinationOffset exceeds
 | 
						|
                              the config space limit of the PCI device.
 | 
						|
                              Although PCI_CAP_DEV_WRITE_CONFIG allows writing
 | 
						|
                              fewer than Size bytes in this case,
 | 
						|
                              SegmentDevWriteConfig() will write none.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
SegmentDevWriteConfig (
 | 
						|
  IN PCI_CAP_DEV  *PciDevice,
 | 
						|
  IN UINT16       DestinationOffset,
 | 
						|
  IN VOID         *SourceBuffer,
 | 
						|
  IN UINT16       Size
 | 
						|
  )
 | 
						|
{
 | 
						|
  SEGMENT_DEV  *SegmentDev;
 | 
						|
  UINT16       ConfigSpaceSize;
 | 
						|
  UINT64       DestinationAddress;
 | 
						|
 | 
						|
  SegmentDev      = SEGMENT_DEV_FROM_PCI_CAP_DEV (PciDevice);
 | 
						|
  ConfigSpaceSize = (SegmentDev->MaxDomain == PciCapNormal ?
 | 
						|
                     PCI_MAX_CONFIG_OFFSET : PCI_EXP_MAX_CONFIG_OFFSET);
 | 
						|
  //
 | 
						|
  // Note that all UINT16 variables below are promoted to INT32, and the
 | 
						|
  // addition and the comparison is carried out in INT32.
 | 
						|
  //
 | 
						|
  if (DestinationOffset + Size > ConfigSpaceSize) {
 | 
						|
    return RETURN_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  DestinationAddress = PCI_SEGMENT_LIB_ADDRESS (
 | 
						|
                         SegmentDev->SegmentNr,
 | 
						|
                         SegmentDev->BusNr,
 | 
						|
                         SegmentDev->DeviceNr,
 | 
						|
                         SegmentDev->FunctionNr,
 | 
						|
                         DestinationOffset
 | 
						|
                         );
 | 
						|
  PciSegmentWriteBuffer (DestinationAddress, Size, SourceBuffer);
 | 
						|
  return RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Create a PCI_CAP_DEV object from the PCI Segment:Bus:Device.Function
 | 
						|
  quadruplet. The config space accessors are based upon PciSegmentLib.
 | 
						|
 | 
						|
  @param[in] MaxDomain   If MaxDomain is PciCapExtended, then
 | 
						|
                         PciDevice->ReadConfig() and PciDevice->WriteConfig()
 | 
						|
                         will delegate extended config space accesses too to
 | 
						|
                         PciSegmentReadBuffer() and PciSegmentWriteBuffer(),
 | 
						|
                         respectively. Otherwise, PciDevice->ReadConfig() and
 | 
						|
                         PciDevice->WriteConfig() will reject accesses to
 | 
						|
                         extended config space with RETURN_UNSUPPORTED, without
 | 
						|
                         calling PciSegmentReadBuffer() or
 | 
						|
                         PciSegmentWriteBuffer(). By setting MaxDomain to
 | 
						|
                         PciCapNormal, the platform can prevent undefined
 | 
						|
                         PciSegmentLib behavior when the PCI root bridge under
 | 
						|
                         the PCI device at Segment:Bus:Device.Function doesn't
 | 
						|
                         support extended config space.
 | 
						|
 | 
						|
  @param[in] Segment     16-bit wide segment number.
 | 
						|
 | 
						|
  @param[in] Bus         8-bit wide bus number.
 | 
						|
 | 
						|
  @param[in] Device      5-bit wide device number.
 | 
						|
 | 
						|
  @param[in] Function    3-bit wide function number.
 | 
						|
 | 
						|
  @param[out] PciDevice  The PCI_CAP_DEV object constructed as described above.
 | 
						|
                         PciDevice can be passed to the PciCapLib APIs.
 | 
						|
 | 
						|
  @retval RETURN_SUCCESS            PciDevice has been constructed and output.
 | 
						|
 | 
						|
  @retval RETURN_INVALID_PARAMETER  Device or Function does not fit in the
 | 
						|
                                    permitted number of bits.
 | 
						|
 | 
						|
  @retval RETURN_OUT_OF_RESOURCES   Memory allocation failed.
 | 
						|
**/
 | 
						|
RETURN_STATUS
 | 
						|
EFIAPI
 | 
						|
PciCapPciSegmentDeviceInit (
 | 
						|
  IN  PCI_CAP_DOMAIN  MaxDomain,
 | 
						|
  IN  UINT16          Segment,
 | 
						|
  IN  UINT8           Bus,
 | 
						|
  IN  UINT8           Device,
 | 
						|
  IN  UINT8           Function,
 | 
						|
  OUT PCI_CAP_DEV     **PciDevice
 | 
						|
  )
 | 
						|
{
 | 
						|
  SEGMENT_DEV  *SegmentDev;
 | 
						|
 | 
						|
  if ((Device > PCI_MAX_DEVICE) || (Function > PCI_MAX_FUNC)) {
 | 
						|
    return RETURN_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  SegmentDev = AllocatePool (sizeof *SegmentDev);
 | 
						|
  if (SegmentDev == NULL) {
 | 
						|
    return RETURN_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  SegmentDev->Signature              = SEGMENT_DEV_SIG;
 | 
						|
  SegmentDev->MaxDomain              = MaxDomain;
 | 
						|
  SegmentDev->SegmentNr              = Segment;
 | 
						|
  SegmentDev->BusNr                  = Bus;
 | 
						|
  SegmentDev->DeviceNr               = Device;
 | 
						|
  SegmentDev->FunctionNr             = Function;
 | 
						|
  SegmentDev->BaseDevice.ReadConfig  = SegmentDevReadConfig;
 | 
						|
  SegmentDev->BaseDevice.WriteConfig = SegmentDevWriteConfig;
 | 
						|
 | 
						|
  *PciDevice = &SegmentDev->BaseDevice;
 | 
						|
  return RETURN_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Free the resources used by PciDevice.
 | 
						|
 | 
						|
  @param[in] PciDevice  The PCI_CAP_DEV object to free, originally produced by
 | 
						|
                        PciCapPciSegmentDeviceInit().
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
PciCapPciSegmentDeviceUninit (
 | 
						|
  IN PCI_CAP_DEV  *PciDevice
 | 
						|
  )
 | 
						|
{
 | 
						|
  SEGMENT_DEV  *SegmentDev;
 | 
						|
 | 
						|
  SegmentDev = SEGMENT_DEV_FROM_PCI_CAP_DEV (PciDevice);
 | 
						|
  FreePool (SegmentDev);
 | 
						|
}
 |