/* Verifies access to a PCI Base Address Register (BAR). */
EFI_STATUS PciIoVerifyBarAccess(IN PCI_IO_DEVICE *PciIoDevice, IN UINT8 BarIndex, IN PCI_BAR_TYPE Type, IN IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN IN UINTN Count, IN UINT64 *Offset)
/* Verifies access to a PCI Base Address Register (BAR). */
EFI_STATUS PciIoVerifyBarAccess(IN PCI_IO_DEVICE *PciIoDevice, IN UINT8 BarIndex, IN PCI_BAR_TYPE Type, IN IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN IN UINTN Count, IN UINT64 *Offset)
{
  if ((UINT32)Width >= EfiPciIoWidthMaximum) {
    return EFI_INVALID_PARAMETER;
  }
  if (BarIndex == EFI_PCI_IO_PASS_THROUGH_BAR) {
    return EFI_SUCCESS;
  }
  if (BarIndex >= PCI_MAX_BAR) {
    return EFI_INVALID_PARAMETER;
  }
  if (!CheckBarType (PciIoDevice, BarIndex, Type)) {
    return EFI_INVALID_PARAMETER;
  }
  if ((Width >= EfiPciIoWidthFifoUint8) && (Width <= EfiPciIoWidthFifoUint64)) {
    Count = 1;
  }
  Width = (EFI_PCI_IO_PROTOCOL_WIDTH)(Width & 0x03);
  if ((*Offset + Count * (UINTN)(1 << Width)) - 1 >= PciIoDevice->PciBar[BarIndex].Length) {
    return EFI_INVALID_PARAMETER;
  }
  *Offset = *Offset + PciIoDevice->PciBar[BarIndex].BaseAddress;
  return EFI_SUCCESS;
}