/** @file

  Internal definitions for the VirtIo PCI Device driver

  Copyright (C) 2013, ARM Ltd
  Copyright (c) 2017, AMD Inc, All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef _VIRTIO_PCI_DEVICE_DXE_H_
#define _VIRTIO_PCI_DEVICE_DXE_H_

#include <Protocol/ComponentName.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/PciIo.h>
#include <Protocol/VirtioDevice.h>

#include <IndustryStandard/Virtio.h>

#define VIRTIO_PCI_DEVICE_SIGNATURE  SIGNATURE_32 ('V', 'P', 'C', 'I')

typedef struct {
  UINT32                    Signature;
  VIRTIO_DEVICE_PROTOCOL    VirtioDevice;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  UINT64                    OriginalPciAttributes;
  UINT32                    DeviceSpecificConfigurationOffset;
} VIRTIO_PCI_DEVICE;

#define VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE(Device) \
    CR (Device, VIRTIO_PCI_DEVICE, VirtioDevice, VIRTIO_PCI_DEVICE_SIGNATURE)

EFI_STATUS
EFIAPI
VirtioPciIoRead (
  IN  VIRTIO_PCI_DEVICE  *Dev,
  IN  UINTN              FieldOffset,
  IN  UINTN              FieldSize,
  IN  UINTN              BufferSize,
  OUT VOID               *Buffer
  );

EFI_STATUS
EFIAPI
VirtioPciIoWrite (
  IN  VIRTIO_PCI_DEVICE  *Dev,
  IN UINTN               FieldOffset,
  IN UINTN               FieldSize,
  IN UINT64              Value
  );

/********************************************
 * PCI Functions for VIRTIO_DEVICE_PROTOCOL
 *******************************************/
EFI_STATUS
EFIAPI
VirtioPciDeviceRead (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  UINTN                   FieldOffset,
  IN  UINTN                   FieldSize,
  IN  UINTN                   BufferSize,
  OUT VOID                    *Buffer
  );

EFI_STATUS
EFIAPI
VirtioPciDeviceWrite (
  IN VIRTIO_DEVICE_PROTOCOL  *This,
  IN UINTN                   FieldOffset,
  IN UINTN                   FieldSize,
  IN UINT64                  Value
  );

EFI_STATUS
EFIAPI
VirtioPciGetDeviceFeatures (
  IN VIRTIO_DEVICE_PROTOCOL  *This,
  OUT UINT64                 *DeviceFeatures
  );

EFI_STATUS
EFIAPI
VirtioPciGetQueueSize (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  OUT UINT16                  *QueueNumMax
  );

EFI_STATUS
EFIAPI
VirtioPciSetQueueAlignment (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  UINT32                  Alignment
  );

EFI_STATUS
EFIAPI
VirtioPciSetPageSize (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  UINT32                  PageSize
  );

EFI_STATUS
EFIAPI
VirtioPciGetDeviceStatus (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  OUT UINT8                   *DeviceStatus
  );

EFI_STATUS
EFIAPI
VirtioPciSetGuestFeatures (
  IN VIRTIO_DEVICE_PROTOCOL  *This,
  IN UINT64                  Features
  );

EFI_STATUS
EFIAPI
VirtioPciSetQueueAddress (
  IN VIRTIO_DEVICE_PROTOCOL  *This,
  IN VRING                   *Ring,
  IN UINT64                  RingBaseShift
  );

EFI_STATUS
EFIAPI
VirtioPciSetQueueSel (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  UINT16                  Sel
  );

EFI_STATUS
EFIAPI
VirtioPciSetQueueNotify (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  UINT16                  Index
  );

EFI_STATUS
EFIAPI
VirtioPciSetQueueSize (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  UINT16                  Size
  );

EFI_STATUS
EFIAPI
VirtioPciSetDeviceStatus (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  UINT8                   DeviceStatus
  );

EFI_STATUS
EFIAPI
VirtioPciAllocateSharedPages (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  UINTN                   NumPages,
  OUT VOID                    **HostAddress
  );

VOID
EFIAPI
VirtioPciFreeSharedPages (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  UINTN                   NumPages,
  IN  VOID                    *HostAddress
  );

EFI_STATUS
EFIAPI
VirtioPciMapSharedBuffer (
  IN      VIRTIO_DEVICE_PROTOCOL  *This,
  IN      VIRTIO_MAP_OPERATION    Operation,
  IN      VOID                    *HostAddress,
  IN OUT  UINTN                   *NumberOfBytes,
  OUT     EFI_PHYSICAL_ADDRESS    *DeviceAddress,
  OUT     VOID                    **Mapping
  );

EFI_STATUS
EFIAPI
VirtioPciUnmapSharedBuffer (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  VOID                    *Mapping
  );

#endif // _VIRTIO_PCI_DEVICE_DXE_H_
