use crate::sys::ioctl::ioctl_io;
use crate::{
bitflags, consts, ioctl_none, ioctl_write_buf, ioctl_write_ptr, ioctl_write_val,
ioctl_writeread,
};
pub const VFIO_TYPE: u8 = b';';
pub const IOMMUFD_TYPE: u8 = b';';
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct VfioInfoCapHeader {
pub id: u16,
pub version: u16,
pub next: u32,
}
bitflags! {
#[derive(Default)]
pub struct VfioDeviceInfoFlag(u32) {
RESET = 1 << 0;
PCI = 1 << 1;
PLATFORM = 1 << 2;
AMBA = 1 << 3;
CCW = 1 << 4;
AP = 1 << 5;
FSL_MC = 1 << 6;
CAPS = 1 << 7;
CDX = 1 << 8;
}
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct VfioDeviceInfo {
pub argsz: u32,
pub flags: VfioDeviceInfoFlag,
pub num_regions: u32,
pub num_irqs: u32,
pub cap_offset: u32,
pub pad: u32,
}
bitflags! {
#[derive(Default)]
pub struct VfioRegionInfoFlag(u32) {
READ = 1 << 0;
WRITE = 1 << 1;
MMAP = 1 << 2;
CAPS = 1 << 3;
}
}
consts! {
pub struct VfioPciRegion(u32) {
BAR0 = 0;
BAR1 = 1;
BAR2 = 2;
BAR3 = 3;
BAR4 = 4;
BAR5 = 5;
ROM = 6;
CONFIG = 7;
VGA = 8;
}
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct VfioRegionInfo {
pub argsz: u32,
pub flags: VfioRegionInfoFlag,
pub index: u32,
pub cap_offset: u32,
pub size: u64,
pub offset: u64,
}
consts! {
#[derive(Default)]
pub struct VfioRegionInfoCap(u16) {
MSIX_MAPPABLE = 3;
}
}
bitflags! {
#[derive(Default)]
pub struct VfioIrqInfoFlag(u32) {
EVENTFD = 1 << 0;
MASKABLE = 1 << 1;
AUTOMASKED = 1 << 2;
NORESIZE = 1 << 3;
}
}
consts! {
#[derive(Default)]
pub struct VfioPciIrq(u32) {
INTX = 0;
MSI = 1;
MSIX = 2;
ERR = 3;
REQ = 4;
}
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct VfioIrqInfo {
pub argsz: u32,
pub flags: VfioIrqInfoFlag,
pub index: u32,
pub count: u32,
}
bitflags! {
pub struct VfioIrqSetFlag(u32) {
DATA_NONE = 1 << 0;
DATA_BOOL = 1 << 1;
DATA_EVENTFD = 1 << 2;
ACTION_MASK = 1 << 3;
ACTION_UNMASK = 1 << 4;
ACTION_TRIGGER = 1 << 5;
}
}
#[repr(C)]
#[derive(Clone, Copy)]
pub union VfioIrqSetData<const N: usize> {
pub eventfds: [i32; N],
pub bools: [bool; N],
}
#[repr(C)]
#[derive(Clone)]
pub struct VfioIrqSet<const N: usize> {
pub argsz: u32,
pub flags: VfioIrqSetFlag,
pub index: u32,
pub start: u32,
pub count: u32,
pub data: VfioIrqSetData<N>,
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct VfioDeviceBindIommufd {
pub argsz: u32,
pub flags: u32,
pub iommufd: i32,
pub out_devid: u32,
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct VfioDeviceAttachIommufdPt {
pub argsz: u32,
pub flags: u32,
pub pt_id: u32,
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct VfioDeviceDetachIommufdPt {
pub argsz: u32,
pub flags: u32,
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct IommuDestroy {
pub size: u32,
pub id: u32,
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct IommuIoasAlloc {
pub size: u32,
pub flags: u32,
pub out_ioas_id: u32,
}
bitflags! {
#[derive(Default)]
pub struct IommuIoasMapFlag(u32) {
FIXED_IOVA = 1 << 0;
WRITEABLE = 1 << 1;
READABLE = 1 << 2;
}
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct IommuIoasMap {
pub size: u32,
pub flags: IommuIoasMapFlag,
pub ioas_id: u32,
pub _reserved: u32,
pub user_va: u64,
pub length: u64,
pub iova: u64,
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct IommuIoasUnmap {
pub size: u32,
pub ioas_id: u32,
pub iova: u64,
pub length: u64,
}
bitflags! {
#[derive(Default)]
pub struct VfioDmaMapFlag(u32) {
READ = 1 << 0;
WRITE = 1 << 1;
VADDR = 1 << 2;
}
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct VfioIommuType1DmaMap {
pub argsz: u32,
pub flags: VfioDmaMapFlag,
pub vaddr: u64,
pub iova: u64,
pub size: u64,
}
bitflags! {
#[derive(Default)]
pub struct VfioDmaUnmapFlag(u32) {
GET_DIRTY_BITMAP = 1 << 0;
ALL = 1 << 1;
VADDR = 1 << 2;
}
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct VfioIommuType1DmaUnmap {
pub argsz: u32,
pub flags: VfioDmaUnmapFlag,
pub iova: u64,
pub size: u64,
}
consts! {
pub struct VfioIommu(i32) {
TYPE1 = 1;
SPAR_TCE= 2;
TYPE1_V2 = 3;
}
}
ioctl_writeread!(
vfio_device_get_info,
ioctl_io(VFIO_TYPE, 107),
VfioDeviceInfo
);
ioctl_writeread!(
vfio_device_get_region_info,
ioctl_io(VFIO_TYPE, 108),
VfioRegionInfo
);
ioctl_writeread!(
vfio_device_get_irq_info,
ioctl_io(VFIO_TYPE, 109),
VfioIrqInfo
);
ioctl_write_buf!(vfio_device_set_irqs, ioctl_io(VFIO_TYPE, 110), VfioIrqSet);
ioctl_none!(vfio_device_reset, VFIO_TYPE, 111);
ioctl_write_ptr!(
vfio_device_bind_iommufd,
ioctl_io(VFIO_TYPE, 118),
VfioDeviceBindIommufd
);
ioctl_write_ptr!(
vfio_device_attach_iommufd_pt,
ioctl_io(VFIO_TYPE, 119),
VfioDeviceAttachIommufdPt
);
ioctl_write_ptr!(
vfio_device_detach_iommufd_pt,
ioctl_io(VFIO_TYPE, 120),
VfioDeviceDetachIommufdPt
);
ioctl_write_ptr!(iommu_destroy, ioctl_io(IOMMUFD_TYPE, 0x80), IommuDestroy);
ioctl_writeread!(
iommu_ioas_alloc,
ioctl_io(IOMMUFD_TYPE, 0x81),
IommuIoasAlloc
);
ioctl_write_ptr!(iommu_ioas_map, ioctl_io(IOMMUFD_TYPE, 0x85), IommuIoasMap);
ioctl_write_ptr!(
iommu_ioas_unmap,
ioctl_io(IOMMUFD_TYPE, 0x86),
IommuIoasUnmap
);
ioctl_write_ptr!(
vfio_iommu_map_dma,
ioctl_io(VFIO_TYPE, 113),
VfioIommuType1DmaMap
);
ioctl_writeread!(
vfio_iommu_unmap_dma,
ioctl_io(VFIO_TYPE, 114),
VfioIommuType1DmaUnmap
);
ioctl_write_val!(
vfio_group_get_device_fd,
ioctl_io(VFIO_TYPE, 106),
*const libc::c_char
);
ioctl_write_ptr!(vfio_group_set_container, ioctl_io(VFIO_TYPE, 104), i32);
ioctl_none!(vfio_group_unset_container, VFIO_TYPE, 105);
ioctl_write_val!(vfio_set_iommu, ioctl_io(VFIO_TYPE, 102), VfioIommu);