#ifndef VIRTIO_ACCEL_H
#define VIRTIO_ACCEL_H
#include <stddef.h>
#include <stdint.h>
#define VIRTIO_ACCEL_PROTOCOL_MAJOR UINT16_C(1)
#define VIRTIO_ACCEL_PROTOCOL_MINOR UINT16_C(0)
#define VIRTIO_ACCEL_COMMAND_QUEUE UINT16_C(0)
#define VIRTIO_ACCEL_BASELINE_COMMAND_QUEUES UINT16_C(1)
#define VIRTIO_ACCEL_HARD_MAX_CHAIN_DESCRIPTORS UINT16_C(256)
#define VIRTIO_ACCEL_MIN_MAX_REQUEST_BYTES UINT32_C(97)
#define VIRTIO_ACCEL_MIN_MAX_RESPONSE_BYTES UINT32_C(92)
#define VIRTIO_ACCEL_HARD_MAX_REQUEST_BYTES UINT32_C(16777216)
#define VIRTIO_ACCEL_HARD_MAX_RESPONSE_BYTES UINT32_C(16777216)
#define VIRTIO_ACCEL_HARD_MAX_BINDINGS UINT32_C(4096)
#define VIRTIO_ACCEL_F_MULTI_QUEUE 0
#define VIRTIO_ACCEL_F_EVENT_QUEUE 1
#define VIRTIO_ACCEL_F_EXTERNAL_MEMORY 2
#define VIRTIO_ACCEL_F_TIMELINE_FENCES 3
#define VIRTIO_ACCEL_F_SECURE_CONTEXTS 4
#define VIRTIO_ACCEL_BASELINE_FEATURES UINT64_C(0)
#define VIRTIO_ACCEL_RESERVED_FEATURES UINT64_C(0x1f)
#define VIRTIO_ACCEL_CAP_HOST_VISIBLE_MEMORY (UINT64_C(1) << 0)
#define VIRTIO_ACCEL_CAP_DEVICE_LOCAL_MEMORY (UINT64_C(1) << 1)
#define VIRTIO_ACCEL_CAP_EVENT_CANCELLATION (UINT64_C(1) << 2)
#define VIRTIO_ACCEL_CAP_EXTERNAL_MEMORY (UINT64_C(1) << 3)
#define VIRTIO_ACCEL_CAP_SECURE_CONTEXTS (UINT64_C(1) << 4)
#define VIRTIO_ACCEL_CAP_SHARED_MEMORY (UINT64_C(1) << 5)
#define VIRTIO_ACCEL_CLASS_OTHER UINT16_C(0)
#define VIRTIO_ACCEL_CLASS_NPU UINT16_C(1)
#define VIRTIO_ACCEL_CLASS_GPU UINT16_C(2)
#define VIRTIO_ACCEL_CLASS_DSP UINT16_C(3)
#define VIRTIO_ACCEL_MEMORY_HOST UINT8_C(1)
#define VIRTIO_ACCEL_MEMORY_DEVICE UINT8_C(2)
#define VIRTIO_ACCEL_MEMORY_SHARED UINT8_C(3)
#define VIRTIO_ACCEL_BUFFER_TRANSFER_SOURCE (UINT32_C(1) << 0)
#define VIRTIO_ACCEL_BUFFER_TRANSFER_DESTINATION (UINT32_C(1) << 1)
#define VIRTIO_ACCEL_BUFFER_PROGRAM_INPUT (UINT32_C(1) << 2)
#define VIRTIO_ACCEL_BUFFER_PROGRAM_OUTPUT (UINT32_C(1) << 3)
#define VIRTIO_ACCEL_BUFFER_MUTABLE_STATE (UINT32_C(1) << 4)
#define VIRTIO_ACCEL_KNOWN_BUFFER_USAGE_BITS UINT32_C(0x1f)
#define VIRTIO_ACCEL_ACCESS_READ UINT8_C(1)
#define VIRTIO_ACCEL_ACCESS_WRITE UINT8_C(2)
#define VIRTIO_ACCEL_ACCESS_READ_WRITE UINT8_C(3)
#define VIRTIO_ACCEL_OP_GET_DEVICE_INFO UINT16_C(0x0001)
#define VIRTIO_ACCEL_OP_CREATE_CONTEXT UINT16_C(0x0100)
#define VIRTIO_ACCEL_OP_DESTROY_CONTEXT UINT16_C(0x0101)
#define VIRTIO_ACCEL_OP_ALLOCATE_BUFFER UINT16_C(0x0200)
#define VIRTIO_ACCEL_OP_FREE_BUFFER UINT16_C(0x0201)
#define VIRTIO_ACCEL_OP_WRITE_BUFFER UINT16_C(0x0202)
#define VIRTIO_ACCEL_OP_READ_BUFFER UINT16_C(0x0203)
#define VIRTIO_ACCEL_OP_LOAD_PROGRAM UINT16_C(0x0300)
#define VIRTIO_ACCEL_OP_UNLOAD_PROGRAM UINT16_C(0x0301)
#define VIRTIO_ACCEL_OP_CREATE_QUEUE UINT16_C(0x0400)
#define VIRTIO_ACCEL_OP_DESTROY_QUEUE UINT16_C(0x0401)
#define VIRTIO_ACCEL_OP_SUBMIT UINT16_C(0x0500)
#define VIRTIO_ACCEL_OP_POLL_EVENT UINT16_C(0x0501)
#define VIRTIO_ACCEL_OP_CANCEL_EVENT UINT16_C(0x0502)
#define VIRTIO_ACCEL_OP_DESTROY_EVENT UINT16_C(0x0503)
#define VIRTIO_ACCEL_STATUS_OK UINT16_C(0)
#define VIRTIO_ACCEL_STATUS_UNSUPPORTED UINT16_C(1)
#define VIRTIO_ACCEL_STATUS_INCOMPATIBLE UINT16_C(2)
#define VIRTIO_ACCEL_STATUS_INVALID_ARGUMENT UINT16_C(3)
#define VIRTIO_ACCEL_STATUS_OUT_OF_BOUNDS UINT16_C(4)
#define VIRTIO_ACCEL_STATUS_BUSY UINT16_C(5)
#define VIRTIO_ACCEL_STATUS_OUT_OF_MEMORY UINT16_C(6)
#define VIRTIO_ACCEL_STATUS_RESOURCE_LIMIT UINT16_C(7)
#define VIRTIO_ACCEL_STATUS_DEADLINE_EXPIRED UINT16_C(8)
#define VIRTIO_ACCEL_STATUS_DEVICE_LOST UINT16_C(9)
#define VIRTIO_ACCEL_STATUS_PERMISSION_DENIED UINT16_C(10)
#define VIRTIO_ACCEL_STATUS_STALE_OBJECT UINT16_C(11)
#define VIRTIO_ACCEL_STATUS_INTERNAL_ERROR UINT16_C(0xffff)
#define VIRTIO_ACCEL_EVENT_PENDING UINT16_C(0)
#define VIRTIO_ACCEL_EVENT_COMPLETE UINT16_C(1)
#define VIRTIO_ACCEL_EVENT_FAILED UINT16_C(2)
#define VIRTIO_ACCEL_EVENT_CANCELLED UINT16_C(3)
#define VIRTIO_ACCEL_KNOWN_REQUEST_FLAGS UINT16_C(0)
#define VIRTIO_ACCEL_KNOWN_CONTEXT_FLAGS UINT32_C(0)
#define VIRTIO_ACCEL_KNOWN_PROGRAM_FLAGS UINT32_C(0)
#define VIRTIO_ACCEL_KNOWN_QUEUE_FLAGS UINT32_C(0)
#define VIRTIO_ACCEL_KNOWN_SUBMIT_FLAGS UINT32_C(0)
#pragma pack(push, 1)
struct virtio_accel_config {
uint16_t protocol_major;
uint16_t protocol_minor;
uint16_t command_queue_count;
uint16_t max_chain_descriptors;
uint32_t max_request_bytes;
uint32_t max_response_bytes;
};
struct virtio_accel_request_header {
uint16_t opcode;
uint16_t flags;
uint32_t payload_bytes;
uint64_t request_id;
};
struct virtio_accel_response_header {
uint16_t status;
uint16_t flags;
uint32_t payload_bytes;
uint64_t request_id;
};
struct virtio_accel_device_info {
uint8_t uuid[16];
uint16_t accelerator_class;
uint16_t reserved;
uint32_t vendor_id;
uint32_t device_id;
uint64_t capabilities;
uint32_t max_contexts;
uint32_t max_buffers_per_context;
uint32_t max_programs_per_context;
uint32_t max_queues_per_context;
uint32_t max_events_per_context;
uint32_t max_bindings_per_submission;
uint64_t max_buffer_bytes;
uint64_t max_artifact_bytes;
};
struct virtio_accel_create_context_request {
uint32_t flags;
uint32_t reserved;
};
struct virtio_accel_object_payload {
uint64_t object_id;
};
struct virtio_accel_allocate_buffer_request {
uint64_t context_id;
uint64_t bytes;
uint64_t alignment;
uint8_t memory_domain;
uint8_t reserved0[7];
uint32_t usage;
uint32_t reserved1;
};
struct virtio_accel_transfer_buffer_request {
uint64_t buffer_id;
uint64_t offset;
uint64_t bytes;
};
struct virtio_accel_load_program_request {
uint64_t context_id;
uint32_t format;
uint32_t flags;
uint32_t target[12];
uint64_t payload_bytes;
uint64_t resident_bytes;
};
struct virtio_accel_create_queue_request {
uint64_t context_id;
uint32_t flags;
uint32_t reserved;
};
struct virtio_accel_submit_request {
uint64_t queue_id;
uint64_t program_id;
uint32_t binding_count;
uint32_t flags;
uint64_t timeout_ns;
};
struct virtio_accel_binding {
uint64_t buffer_id;
uint64_t offset;
uint64_t bytes;
uint32_t slot;
uint8_t access;
uint8_t reserved[3];
};
struct virtio_accel_submit_response {
uint64_t event_id;
};
struct virtio_accel_event_state {
uint16_t state;
uint16_t error;
uint32_t reserved;
};
#pragma pack(pop)
#if defined(__cplusplus)
#define VIRTIO_ACCEL_STATIC_ASSERT(condition, message) static_assert(condition, message)
#define VIRTIO_ACCEL_ALIGNOF(type) alignof(type)
#else
#define VIRTIO_ACCEL_STATIC_ASSERT(condition, message) _Static_assert(condition, message)
#define VIRTIO_ACCEL_ALIGNOF(type) _Alignof(type)
#endif
#define VIRTIO_ACCEL_ASSERT_LAYOUT(type, bytes) \
VIRTIO_ACCEL_STATIC_ASSERT(sizeof(struct type) == (bytes), #type " size"); \
VIRTIO_ACCEL_STATIC_ASSERT(VIRTIO_ACCEL_ALIGNOF(struct type) == 1, #type " align")
#define VIRTIO_ACCEL_ASSERT_OFFSET(type, field, offset) \
VIRTIO_ACCEL_STATIC_ASSERT(offsetof(struct type, field) == (offset), \
#type "." #field " offset")
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_config, 16);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_config, protocol_major, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_config, protocol_minor, 2);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_config, command_queue_count, 4);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_config, max_chain_descriptors, 6);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_config, max_request_bytes, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_config, max_response_bytes, 12);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_request_header, 16);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_request_header, opcode, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_request_header, flags, 2);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_request_header, payload_bytes, 4);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_request_header, request_id, 8);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_response_header, 16);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_response_header, status, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_response_header, flags, 2);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_response_header, payload_bytes, 4);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_response_header, request_id, 8);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_device_info, 76);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, uuid, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, accelerator_class, 16);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, reserved, 18);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, vendor_id, 20);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, device_id, 24);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, capabilities, 28);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, max_contexts, 36);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, max_buffers_per_context, 40);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, max_programs_per_context, 44);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, max_queues_per_context, 48);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, max_events_per_context, 52);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, max_bindings_per_submission, 56);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, max_buffer_bytes, 60);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_device_info, max_artifact_bytes, 68);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_create_context_request, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_create_context_request, flags, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_create_context_request, reserved, 4);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_object_payload, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_object_payload, object_id, 0);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_allocate_buffer_request, 40);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_allocate_buffer_request, context_id, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_allocate_buffer_request, bytes, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_allocate_buffer_request, alignment, 16);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_allocate_buffer_request, memory_domain, 24);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_allocate_buffer_request, reserved0, 25);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_allocate_buffer_request, usage, 32);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_allocate_buffer_request, reserved1, 36);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_transfer_buffer_request, 24);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_transfer_buffer_request, buffer_id, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_transfer_buffer_request, offset, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_transfer_buffer_request, bytes, 16);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_load_program_request, 80);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_load_program_request, context_id, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_load_program_request, format, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_load_program_request, flags, 12);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_load_program_request, target, 16);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_load_program_request, payload_bytes, 64);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_load_program_request, resident_bytes, 72);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_create_queue_request, 16);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_create_queue_request, context_id, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_create_queue_request, flags, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_create_queue_request, reserved, 12);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_submit_request, 32);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_submit_request, queue_id, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_submit_request, program_id, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_submit_request, binding_count, 16);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_submit_request, flags, 20);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_submit_request, timeout_ns, 24);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_binding, 32);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_binding, buffer_id, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_binding, offset, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_binding, bytes, 16);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_binding, slot, 24);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_binding, access, 28);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_binding, reserved, 29);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_submit_response, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_submit_response, event_id, 0);
VIRTIO_ACCEL_ASSERT_LAYOUT(virtio_accel_event_state, 8);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_event_state, state, 0);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_event_state, error, 2);
VIRTIO_ACCEL_ASSERT_OFFSET(virtio_accel_event_state, reserved, 4);
#undef VIRTIO_ACCEL_ASSERT_OFFSET
#undef VIRTIO_ACCEL_ASSERT_LAYOUT
#undef VIRTIO_ACCEL_ALIGNOF
#undef VIRTIO_ACCEL_STATIC_ASSERT
#endif