use bitfield::bitfield;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{bitflags, consts};
bitflags! {
pub struct VuFeature(u64) {
MQ = 1 << 0;
LOG_SHMFD = 1 << 1;
RARP = 1 << 2;
REPLY_ACK = 1 << 3;
MTU = 1 << 4;
BACKEND_REQ = 1 << 5;
CROSS_ENDIAN = 1 << 6;
CRYPTO_SESSION = 1 << 7;
PAGEFAULT = 1 << 8;
CONFIG = 1 << 9;
BACKEND_SEND_FD = 1 << 10;
HOST_NOTIFIER = 1 << 11;
INFLIGHT_SHMFD = 1 << 12;
RESET_DEVICE = 1 << 13;
INBAND_NOTIFICATIONS = 1 << 14;
CONFIGURE_MEM_SLOTS = 1 << 15;
STATUS = 1 << 16;
XEN_MMAP = 1 << 17;
SHARED_OBJECT = 1 << 18;
DEVICE_STATE = 1 << 19;
}
}
consts! {
pub struct VuFrontMsg(u32) {
GET_FEATURES = 1;
SET_FEATURES = 2;
SET_OWNER = 3;
RESET_OWNER = 4;
SET_MEM_TABLE = 5;
SET_LOG_BASE = 6;
SET_LOG_FD = 7;
SET_VIRTQ_NUM = 8;
SET_VIRTQ_ADDR = 9;
SET_VIRTQ_BASE = 10;
GET_VIRTQ_BASE = 11;
SET_VIRTQ_KICK = 12;
SET_VIRTQ_CALL = 13;
SET_VIRTQ_ERR = 14;
GET_PROTOCOL_FEATURES = 15;
SET_PROTOCOL_FEATURES = 16;
GET_QUEUE_NUM = 17;
SET_VIRTQ_ENABLE = 18;
SEND_RARP = 19;
NET_SET_MTU = 20;
SET_BACKEND_REQ_FD = 21;
IOTLB_MSG = 22;
SET_VIRTQ_ENDIAN = 23;
GET_CONFIG = 24;
SET_CONFIG = 25;
CREATE_CRYPTO_SESSION = 26;
CLOSE_CRYPTO_SESSION = 27;
POSTCOPY_ADVISE = 28;
POSTCOPY_LISTEN = 29;
POSTCOPY_END = 30;
GET_INFLIGHT_FD = 31;
SET_INFLIGHT_FD = 32;
GPU_SET_SOCKET = 33;
RESET_DEVICE = 34;
GET_MAX_MEM_SLOTS = 36;
ADD_MEM_REG = 37;
REM_MEM_REG = 38;
SET_STATUS = 39;
GET_STATUS = 40;
GET_SHARED_OBJECT = 41;
SET_DEVICE_STATE_FD = 42;
CHECK_DEVICE_STATE = 43;
}
}
consts! {
pub struct VuFrontMsgSize((u32, usize)) {
GET_FEATURES = (0, size_of::<u64>());
}
}
consts! {
pub struct VuBackMsg(u32) {
IOTLB_MSG = 1;
CONFIG_CHANGE_MSG = 2;
VIRTQ_HOST_NOTIFIER_MSG = 3;
VIRTQ_CALL = 4;
VIRTQ_ERR = 5;
SHARED_OBJECT_ADD = 6;
SHARED_OBJECT_REMOVE = 7;
SHARED_OBJECT_LOOKUP = 8;
}
}
bitfield! {
#[derive(Copy, Clone, Default, IntoBytes, FromBytes, Immutable)]
#[repr(transparent)]
pub struct MessageFlag(u32);
impl Debug;
pub need_reply, set_need_reply: 3;
pub reply, set_reply: 2;
pub version, set_version: 1, 0;
}
impl MessageFlag {
pub const NEED_REPLY: u32 = 1 << 3;
pub const REPLY: u32 = 1 << 2;
pub const VERSION_1: u32 = 0x1;
pub const fn sender() -> Self {
MessageFlag(MessageFlag::VERSION_1 | MessageFlag::NEED_REPLY)
}
pub const fn receiver() -> Self {
MessageFlag(MessageFlag::VERSION_1 | MessageFlag::REPLY)
}
}
#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct VirtqState {
pub index: u32,
pub val: u32,
}
#[derive(Debug, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct VirtqAddr {
pub index: u32,
pub flags: u32,
pub desc_hva: u64,
pub used_hva: u64,
pub avail_hva: u64,
pub log_guest_addr: u64,
}
#[derive(Debug, Clone, IntoBytes, FromBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct MemoryRegion {
pub gpa: u64,
pub size: u64,
pub hva: u64,
pub mmap_offset: u64,
}
#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct MemorySingleRegion {
pub _padding: u64,
pub region: MemoryRegion,
}
#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct MemoryMultipleRegion {
pub num: u32,
pub _padding: u32,
pub regions: [MemoryRegion; 8],
}
pub const MAX_CONFIG_SIZE: usize = 256;
#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct DeviceConfig {
pub offset: u32,
pub size: u32,
pub flags: u32,
}
#[derive(Debug, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
#[repr(C)]
pub struct FsMap {
pub fd_offset: [u64; 8],
pub cache_offset: [u64; 8],
pub len: [u64; 8],
pub flags: [u64; 8],
}
#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct Message {
pub request: u32,
pub flag: MessageFlag,
pub size: u32,
}