/** @file

  Internal definitions for the VirtIo MMIO 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_MMIO_DEVICE_INTERNAL_H_
#define _VIRTIO_MMIO_DEVICE_INTERNAL_H_

#include <Protocol/VirtioDevice.h>

#include <IndustryStandard/Virtio.h>

#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/UefiLib.h>
#include <Library/VirtioMmioDeviceLib.h>
#include <Library/MemoryAllocationLib.h>

#define VIRTIO_MMIO_DEVICE_SIGNATURE     SIGNATURE_32 ('V', 'M', 'I', 'O')
#define VIRTIO_MMIO_DEVICE_VERSION_0_95  1
#define VIRTIO_MMIO_DEVICE_VERSION_1_00  2

typedef struct {
  UINT32                    Signature;
  UINT32                    Version;
  UINT16                    QueueNum;
  VIRTIO_DEVICE_PROTOCOL    VirtioDevice;
  PHYSICAL_ADDRESS          BaseAddress;
} VIRTIO_MMIO_DEVICE;

#define VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE(Device) \
    CR (Device, VIRTIO_MMIO_DEVICE, VirtioDevice, VIRTIO_MMIO_DEVICE_SIGNATURE)

#define VIRTIO_CFG_WRITE(Device, Offset, Val) \
    (MmioWrite32 (Device->BaseAddress + (Offset), Val))
#define VIRTIO_CFG_READ(Device, Offset)       \
    (MmioRead32  (Device->BaseAddress + (Offset)))

EFI_STATUS
EFIAPI
VirtioMmioDeviceRead (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  UINTN                   FieldOFfset,
  IN  UINTN                   FieldSize,
  IN  UINTN                   BufferSize,
  OUT VOID                    *Buffer
  );

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

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

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

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

EFI_STATUS
EFIAPI
VirtioMmioSetQueueSize (
  IN VIRTIO_DEVICE_PROTOCOL  *This,
  IN UINT16                  QueueSize
  );

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

EFI_STATUS
EFIAPI
VirtioMmioSetQueueNotify (
  IN VIRTIO_DEVICE_PROTOCOL  *This,
  IN UINT16                  QueueNotify
  );

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

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

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

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

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

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

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

EFI_STATUS
EFIAPI
VirtioMmioMapSharedBuffer (
  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
VirtioMmioUnmapSharedBuffer (
  IN  VIRTIO_DEVICE_PROTOCOL  *This,
  IN  VOID                    *Mapping
  );

#endif // _VIRTIO_MMIO_DEVICE_INTERNAL_H_
