1#![expect(missing_docs)]
8#![forbid(unsafe_code)]
9
10use bitfield_struct::bitfield;
11use guid::Guid;
12use open_enum::open_enum;
13use static_assertions::const_assert;
14use static_assertions::const_assert_eq;
15use std::fmt::Debug;
16use zerocopy::FromBytes;
17use zerocopy::Immutable;
18use zerocopy::IntoBytes;
19use zerocopy::KnownLayout;
20use zerocopy::LittleEndian;
21use zerocopy::U16;
22
23pub mod crash;
24pub mod dps_json; pub const MAX_MESSAGE_SIZE: usize = 12288;
28
29pub const MAX_HEADER_SIZE: usize = 256;
30
31pub const MAX_PAYLOAD_SIZE: usize = 8192;
34
35const_assert!(MAX_MESSAGE_SIZE >= MAX_HEADER_SIZE + MAX_PAYLOAD_SIZE);
36
37pub const GUEST_EMULATION_DEVICE_ID: Guid = guid::guid!("455c0f1b-d51b-40b1-beac-87377fe6e041");
39
40pub const GUEST_EMULATION_INTERFACE_TYPE: Guid =
42 guid::guid!("8dedd1aa-9056-49e4-bfd6-1bf90dc38ef0");
43
44pub const GUEST_EMULATION_INTERFACE_INSTANCE: Guid =
46 guid::guid!("d3e4454d-62af-44ec-b851-3170915e5f56");
47
48const fn make_version(major: u16, minor: u16) -> u32 {
50 (minor as u32) | ((major as u32) << 16)
51}
52
53open_enum! {
54 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
55 pub enum ProtocolVersion: u32 {
56 INVALID = 0,
57 RS5 = make_version(1, 0),
58 IRON = make_version(3, 0),
59 NICKEL_REV2 = make_version(4, 2),
60 }
61}
62
63open_enum! {
64 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
65 pub enum MessageVersions: u8 {
66 INVALID = 0,
67 HEADER_VERSION_1 = 1,
68 }
69}
70
71open_enum! {
72 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
73 pub enum MessageTypes: u8 {
74 INVALID = 0,
75 HOST_NOTIFICATION = 1,
76 HOST_REQUEST = 2,
77 HOST_RESPONSE = 3,
78 GUEST_NOTIFICATION = 4,
79 }
80}
81
82open_enum! {
83 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
88 pub enum GuestNotifications: u16 {
89 INVALID = 0,
90 UPDATE_GENERATION_ID = 1,
91 SAVE_GUEST_VTL2_STATE = 2,
93 _RESERVED_DO_NOT_USE_3 = 3,
94 VPCI_DEVICE_NOTIFICATION = 4,
95 MODIFY_VTL2_SETTINGS = 5,
96 MODIFY_VTL2_SETTINGS_REV1 = 6,
97 BATTERY_STATUS = 7,
99 INJECT_DEBUG_INTERRUPT = 8,
100 NOTIFY_POST_LIVE_MIGRATION = 9,
101 }
102}
103
104open_enum! {
105 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
110 pub enum HostNotifications: u16 {
111 INVALID = 0,
112 POWER_OFF = 1,
113 RESET = 2,
114 EVENT_LOG = 3,
115 LOG_TRACE = 4,
116 RESTORE_GUEST_VTL2_STATE_COMPLETED = 5,
118 MODIFY_VTL2_SETTINGS_COMPLETED = 6,
119 START_VTL0_COMPLETED = 7,
120 VTL_CRASH = 8,
121 TRIPLE_FAULT = 9,
122 IPMI_SEL = 13,
123 }
124}
125
126open_enum! {
127 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
129 pub enum HostRequests: u16 {
130 INVALID = 0,
131 VERSION = 1,
132 TIME = 2,
133 BIOS_BOOT_FINALIZE = 3,
134 VMGS_GET_DEVICE_INFO = 4,
135 VMGS_READ = 5,
136 VMGS_WRITE = 6,
137 VMGS_FLUSH = 7,
138 IGVM_ATTEST = 8,
139 GUEST_STATE_PROTECTION_BY_ID = 9,
141 VMGS_KEYS_READ = 10,
142 LOG_TRACE = 11, ACTIVITY_TRACE_START = 12,
144 ACTIVITY_TRACE_OP = 13,
145 EVENT_TRACE = 14,
146 DEVICE_PLATFORM_SETTINGS = 15, ADVISORY_PLATFORM_SETTINGS = 16, GUEST_STATE_PROTECTION = 17,
151 DEVICE_PLATFORM_SETTINGS_V2 = 18, VPCI_DEVICE_CONTROL = 19,
154 SAVE_GUEST_VTL2_STATE = 20,
155 RESTORE_GUEST_VTL2_STATE = 21,
156 VPCI_DEVICE_BINDING_CHANGE = 22,
157 VGA_PROXY_PCI_READ = 23,
158 VGA_PROXY_PCI_WRITE = 24,
159 _RESERVED_DO_NOT_USE_25 = 25,
160 _RESERVED_DO_NOT_USE_26 = 26,
161 DEVICE_PLATFORM_SETTINGS_V2_REV1 = 27, CREATE_RAM_GPA_RANGE = 28,
163 RESET_RAM_GPA_RANGE = 29,
164 LOAD_FIRMWARE = 30,
165
166 MAP_FRAMEBUFFER = 0xFFFF,
168 UNMAP_FRAMEBUFFER = 0xFFFE,
169 }
170}
171
172pub use header::*;
173pub mod header {
174 use super::MessageTypes;
175 use super::MessageVersions;
176 use static_assertions::const_assert_eq;
177 use zerocopy::FromBytes;
178 use zerocopy::Immutable;
179 use zerocopy::IntoBytes;
180 use zerocopy::KnownLayout;
181
182 use super::GuestNotifications;
183 use super::HostNotifications;
184 use super::HostRequests;
185
186 #[repr(C)]
188 #[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
189 pub struct HeaderRaw {
190 pub message_version: MessageVersions,
191 pub message_type: MessageTypes,
192 pub message_id: u16,
193 }
194
195 pub trait HeaderMeta: private::Sealed {
199 const MESSAGE_TYPE: MessageTypes;
200 type MessageId: Copy + IntoBytes + FromBytes + Immutable + KnownLayout + Sized;
201 }
202
203 macro_rules! defn_header_meta {
204 (
205 $(($header_alias:ident => $name:ident, $message_type:ident, $message_id:ident)$(,)*)*
206 ) => {
207 mod private {
208 pub trait Sealed {}
209 $(
210 impl Sealed for super::$name {}
211 )*
212 }
213
214 $(
215 #[derive(Copy, Clone, Debug)]
216 pub enum $name {}
217
218 impl HeaderMeta for $name {
219 const MESSAGE_TYPE: MessageTypes = MessageTypes::$message_type;
220 type MessageId = $message_id;
221 }
222
223 const_assert_eq!(size_of::<u16>(), size_of::<$message_id>());
225 const_assert_eq!(4, size_of::<HeaderGeneric<$name>>());
227
228 impl TryFrom<HeaderRaw> for HeaderGeneric<$name> {
229 type Error = ();
230
231 fn try_from(raw: HeaderRaw) -> Result<HeaderGeneric<$name>, ()> {
232 if raw.message_type != MessageTypes::$message_type {
233 return Err(());
234 }
235
236 Ok(HeaderGeneric {
237 message_version: raw.message_version,
238 message_type: raw.message_type,
239 message_id: $message_id(raw.message_id),
240 })
241 }
242 }
243
244 pub type $header_alias = HeaderGeneric<$name>;
245 )*
246
247 };
248 }
249
250 defn_header_meta! {
251 (HeaderGuestNotification => GuestNotification, GUEST_NOTIFICATION, GuestNotifications),
252 (HeaderHostNotification => HostNotification, HOST_NOTIFICATION, HostNotifications),
253 (HeaderHostResponse => HostResponse, HOST_RESPONSE, HostRequests),
254 (HeaderHostRequest => HostRequest, HOST_REQUEST, HostRequests),
255 }
256
257 #[repr(C, packed)]
262 #[derive(Copy, Clone, Debug, FromBytes, Immutable, KnownLayout, PartialEq, IntoBytes)]
263 pub struct HeaderGeneric<Meta: HeaderMeta> {
264 pub message_version: MessageVersions,
265 pub message_type: MessageTypes,
266 message_id: Meta::MessageId,
267 }
268
269 impl<Meta: HeaderMeta> HeaderGeneric<Meta> {
270 pub fn new(message_id: Meta::MessageId) -> Self {
271 Self {
272 message_version: MessageVersions::HEADER_VERSION_1,
273 message_type: Meta::MESSAGE_TYPE,
274 message_id,
275 }
276 }
277
278 pub fn message_id(&self) -> Meta::MessageId {
284 self.message_id
285 }
286 }
287}
288
289open_enum! {
290 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
291 pub enum LargePayloadState : u32 {
292 END = 0,
293 MORE = 1,
294 }
295}
296
297#[repr(C)]
298#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
299pub struct PowerOffNotification {
300 pub message_header: HeaderHostNotification,
301 pub hibernate: ProtocolBool,
302 pub _pad: u8,
303}
304
305const_assert_eq!(6, size_of::<PowerOffNotification>());
306
307impl PowerOffNotification {
308 pub fn new(hibernate: bool) -> Self {
309 Self {
310 message_header: HeaderGeneric::new(HostNotifications::POWER_OFF),
311
312 hibernate: hibernate.into(),
313 _pad: 0,
314 }
315 }
316}
317
318#[repr(C)]
319#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
320pub struct ResetNotification {
321 pub message_header: HeaderHostNotification,
322}
323
324const_assert_eq!(4, size_of::<ResetNotification>());
325
326impl ResetNotification {
327 pub fn new() -> Self {
328 Self {
329 message_header: HeaderGeneric::new(HostNotifications::RESET),
330 }
331 }
332}
333
334open_enum! {
335 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
336 pub enum EventLogId: u32 {
337 INVALID_ID = 0,
338 BOOT_SUCCESS = 1,
339 BOOT_SUCCESS_SECURE_BOOT_FAILED = 2,
340 BOOT_FAILURE = 3,
341 BOOT_FAILURE_SECURE_BOOT_FAILED = 4,
342 NO_BOOT_DEVICE = 5,
343 ATTESTATION_FAILED = 6,
344 VMGS_FILE_CLEAR = 7,
345 VMGS_INIT_FAILED = 8,
346 VMGS_INVALID_FORMAT = 9,
347 VMGS_CORRUPT_FORMAT = 10,
348 KEY_NOT_RELEASED = 11,
349 DEK_DECRYPTION_FAILED = 12,
350 WATCHDOG_TIMEOUT_RESET = 13,
351 BOOT_ATTEMPT = 14,
352 VMGS_ACCESS_FAILED = 15,
353 CERTIFICATE_RENEWAL_FAILED = 16,
354 TPM_INVALID_STATE = 17,
355 TPM_IDENTITY_CHANGE_FAILED = 18,
356 WRAPPED_KEY_REQUIRED_BUT_INVALID = 19,
357 DEK_HARDWARE_SEALING_INVALID_KEY = 20,
358 DEK_HARDWARE_SEALING_FAILED = 21,
359 DEK_HARDWARE_UNSEALING_SKIPPED = 23,
360 }
361}
362
363#[repr(C)]
364#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
365pub struct EventLogNotification {
366 pub message_header: HeaderHostNotification,
367 pub event_log_id: EventLogId,
368}
369
370const_assert_eq!(8, size_of::<EventLogNotification>());
371
372impl EventLogNotification {
373 pub fn new(event_log_id: EventLogId) -> Self {
374 Self {
375 message_header: HeaderGeneric::new(HostNotifications::EVENT_LOG),
376 event_log_id,
377 }
378 }
379}
380
381pub use ipmi_protocol::SEL_RECORD_SIZE as IPMI_SEL_RECORD_SIZE;
382
383#[repr(C)]
384#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
385pub struct IpmiSelNotification {
386 pub message_header: HeaderHostNotification,
387 pub record_id: U16<LittleEndian>,
388 pub record: [u8; IPMI_SEL_RECORD_SIZE],
389}
390
391const_assert_eq!(22, size_of::<IpmiSelNotification>());
392const_assert_eq!(0, std::mem::offset_of!(IpmiSelNotification, message_header));
393const_assert_eq!(4, std::mem::offset_of!(IpmiSelNotification, record_id));
394const_assert_eq!(6, std::mem::offset_of!(IpmiSelNotification, record));
395
396impl IpmiSelNotification {
397 pub fn new(record_id: u16, record: [u8; IPMI_SEL_RECORD_SIZE]) -> Self {
398 Self {
399 message_header: HeaderGeneric::new(HostNotifications::IPMI_SEL),
400 record_id: U16::new(record_id),
401 record,
402 }
403 }
404}
405
406pub const TRACE_MSG_MAX_SIZE: usize = 256;
407open_enum! {
408 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
409 pub enum LogLevel: u32 {
410 INVALID = 0,
411 CRITICAL = 1,
412 ERROR = 2,
413 WARNING = 3,
414 INFORMATION = 4,
415 VERBOSE = 5,
416 }
417}
418
419impl From<LogLevel> for u8 {
420 fn from(level: LogLevel) -> Self {
421 match level {
422 LogLevel::INVALID => 0,
423 LogLevel::CRITICAL => 1,
424 LogLevel::ERROR => 2,
425 LogLevel::WARNING => 3,
426 LogLevel::INFORMATION => 4,
427 LogLevel::VERBOSE => 5,
428 _ => {
429 unreachable!();
430 }
431 }
432 }
433}
434
435open_enum! {
436 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
437 pub enum GuestVtl2SaveRestoreStatus : u16 {
438 SUCCESS = 0,
439 FAILURE = 1,
440 MORE_DATA = 2,
441 REQUEST_DATA = 3,
442 }
443}
444
445#[repr(C)]
446#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
447pub struct LogTraceNotification {
448 pub message_header: HeaderHostNotification,
449 pub level: LogLevel,
450 pub message: [u16; TRACE_MSG_MAX_SIZE],
451}
452
453const_assert_eq!(520, size_of::<LogTraceNotification>());
454
455pub const VTL_CRASH_PARAMETERS: usize = 5;
456
457#[repr(C)]
459#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
460pub struct VtlCrashNotification {
461 pub message_header: HeaderHostNotification,
462 pub vp_index: u32,
463 pub last_vtl: u8,
464 pub reserved0: u8,
465 pub reserved1: u16,
466 pub reserved2: u32,
467 pub control: u64,
468 pub parameters: [u64; VTL_CRASH_PARAMETERS],
469}
470
471const_assert_eq!(64, size_of::<VtlCrashNotification>());
472
473impl VtlCrashNotification {
474 pub fn new(
475 vp_index: u32,
476 last_vtl: u8,
477 control: u64,
478 parameters: [u64; VTL_CRASH_PARAMETERS],
479 ) -> Self {
480 Self {
481 message_header: HeaderGeneric::new(HostNotifications::VTL_CRASH),
482 vp_index,
483 last_vtl,
484 reserved0: 0,
485 reserved1: 0,
486 reserved2: 0,
487 control,
488 parameters,
489 }
490 }
491}
492
493open_enum! {
494 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
495 pub enum TripleFaultType: u32 {
496 UNRECOVERABLE_EXCEPTION = 1,
497 }
498}
499
500#[repr(C)]
501#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
502pub struct RegisterState {
503 pub name: u32,
504 pub value: [u8; 16],
505}
506const_assert_eq!(20, size_of::<RegisterState>());
507
508#[repr(C)]
510#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
511pub struct TripleFaultNotification {
512 pub message_header: HeaderHostNotification,
513 pub vp_index: u32,
514 pub fault_type: TripleFaultType,
515 pub register_count: u32,
516}
517const_assert_eq!(16, size_of::<TripleFaultNotification>());
518
519impl TripleFaultNotification {
520 pub fn new(vp_index: u32, fault_type: TripleFaultType, register_count: u32) -> Self {
521 Self {
522 message_header: HeaderGeneric::new(HostNotifications::TRIPLE_FAULT),
523 vp_index,
524 fault_type,
525 register_count,
526 }
527 }
528}
529
530#[repr(C)]
531#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
532pub struct VersionRequest {
533 pub message_header: HeaderHostRequest,
534 pub version: ProtocolVersion,
535}
536
537impl VersionRequest {
538 pub fn new(version: ProtocolVersion) -> Self {
540 Self {
541 message_header: HeaderGeneric::new(HostRequests::VERSION),
542 version,
543 }
544 }
545}
546
547const_assert_eq!(8, size_of::<VersionRequest>());
548
549#[repr(C)]
550#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
551pub struct VersionResponse {
552 pub message_header: HeaderHostResponse,
553 pub version_accepted: ProtocolBool,
554 pub _pad: u8,
555}
556
557impl VersionResponse {
558 pub fn new(version_accepted: bool) -> Self {
559 Self {
560 message_header: HeaderGeneric::new(HostRequests::VERSION),
561 version_accepted: version_accepted.into(),
562 _pad: 0,
563 }
564 }
565}
566
567const_assert_eq!(6, size_of::<VersionResponse>());
568
569#[repr(C)]
570#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
571pub struct TimeRequest {
572 pub message_header: HeaderHostRequest,
573}
574
575const_assert_eq!(4, size_of::<TimeRequest>());
576
577impl TimeRequest {
578 pub fn new() -> Self {
579 Self {
580 message_header: HeaderGeneric::new(HostRequests::TIME),
581 }
582 }
583}
584
585#[repr(C)]
586#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
587pub struct TimeResponse {
588 pub message_header: HeaderHostResponse,
589 pub _pad: u32,
590
591 pub vm_reference_time: u64,
592 pub utc: i64,
593 pub time_zone: i16,
594 pub daylight_savings: ProtocolBool,
595 pub _pad1: [u8; 5],
596}
597
598impl TimeResponse {
599 pub fn new(vm_reference_time: u64, utc: i64, time_zone: i16, daylight_savings: bool) -> Self {
600 Self {
601 message_header: HeaderGeneric::new(HostRequests::TIME),
602 _pad: 0,
603
604 vm_reference_time,
605 utc,
606 time_zone,
607 daylight_savings: daylight_savings.into(),
608 _pad1: [0; 5],
609 }
610 }
611}
612
613const_assert_eq!(32, size_of::<TimeResponse>());
614
615pub const IGVM_ATTEST_MSG_REQ_AGENT_DATA_MAX_SIZE: usize = 2048;
617pub const IGVM_ATTEST_MSG_REQ_REPORT_MAX_SIZE: usize = 4096;
619
620pub const IGVM_ATTEST_MSG_MAX_SHARED_GPA: usize = 16;
622
623pub const IGVM_ATTEST_VMWP_GENERIC_ERROR_CODE: usize = 0xFFFFFFFF;
626
627#[repr(C)]
631#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
632pub struct IgvmAttestRequest {
633 pub message_header: HeaderHostRequest,
634 pub number_gpa: u32,
636 pub shared_gpa: [u64; IGVM_ATTEST_MSG_MAX_SHARED_GPA],
638 pub agent_data_length: u32,
640 pub report_length: u32,
642 pub agent_data: [u8; IGVM_ATTEST_MSG_REQ_AGENT_DATA_MAX_SIZE],
644 pub report: [u8; IGVM_ATTEST_MSG_REQ_REPORT_MAX_SIZE],
646}
647
648const_assert_eq!(6288, size_of::<IgvmAttestRequest>());
649
650impl IgvmAttestRequest {
651 pub fn new(
652 shared_gpa: [u64; IGVM_ATTEST_MSG_MAX_SHARED_GPA],
653 number_gpa: u32,
654 agent_data: [u8; IGVM_ATTEST_MSG_REQ_AGENT_DATA_MAX_SIZE],
655 agent_data_length: u32,
656 report: [u8; IGVM_ATTEST_MSG_REQ_REPORT_MAX_SIZE],
657 report_length: u32,
658 ) -> Self {
659 Self {
660 message_header: HeaderGeneric::new(HostRequests::IGVM_ATTEST),
661 number_gpa,
662 shared_gpa,
663 agent_data_length,
664 report_length,
665 agent_data,
666 report,
667 }
668 }
669}
670
671#[repr(C)]
672#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
673pub struct IgvmAttestResponse {
674 pub message_header: HeaderHostResponse,
675 pub length: u32,
676}
677
678const_assert_eq!(8, size_of::<IgvmAttestResponse>());
679
680#[repr(C)]
682#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
683pub struct BiosBootFinalizeRequest {
684 pub message_header: HeaderHostRequest,
685 pub value: u8,
686 pub _pad: u8,
687}
688
689const_assert_eq!(6, size_of::<BiosBootFinalizeRequest>());
690
691#[repr(C)]
692#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
693pub struct BiosBootFinalizeResponse {
694 pub message_header: HeaderHostResponse,
695}
696
697impl BiosBootFinalizeResponse {
698 pub fn new() -> BiosBootFinalizeResponse {
699 BiosBootFinalizeResponse {
700 message_header: HeaderGeneric::new(HostRequests::BIOS_BOOT_FINALIZE),
701 }
702 }
703}
704
705const_assert_eq!(4, size_of::<BiosBootFinalizeResponse>());
706
707#[repr(C)]
708#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
709pub struct VmgsGetDeviceInfoRequest {
710 pub message_header: HeaderHostRequest,
711}
712
713impl VmgsGetDeviceInfoRequest {
714 pub fn new() -> Self {
715 Self {
716 message_header: HeaderGeneric::new(HostRequests::VMGS_GET_DEVICE_INFO),
717 }
718 }
719}
720
721const_assert_eq!(4, size_of::<VmgsGetDeviceInfoRequest>());
722
723open_enum! {
724 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
725 pub enum VmgsIoStatus: u32 {
726 SUCCESS = 0,
727 INVALID_COMMAND = 1,
728 DEVICE_ERROR = 2,
729 RETRY = 3,
730 }
731}
732
733open_enum! {
734 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
735 pub enum VmgsWriteFlags: u32 {
736 NONE = 0,
737 WRITE_THROUGH = 0x00000001,
738 }
739}
740
741open_enum! {
742 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
743 pub enum VmgsReadFlags: u32 {
744 NONE = 0,
745 }
746}
747
748#[repr(C)]
749#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
750pub struct VmgsGetDeviceInfoResponse {
751 pub message_header: HeaderHostResponse,
752 pub status: VmgsIoStatus,
753 pub capacity: u64, pub bytes_per_logical_sector: u16,
755 pub bytes_per_physical_sector: u16,
756 pub maximum_transfer_size_bytes: u32,
757}
758
759impl VmgsGetDeviceInfoResponse {
760 pub fn new(
761 status: VmgsIoStatus,
762 capacity: u64,
763 bytes_per_logical_sector: u16,
764 bytes_per_physical_sector: u16,
765 maximum_transfer_size_bytes: u32,
766 ) -> VmgsGetDeviceInfoResponse {
767 VmgsGetDeviceInfoResponse {
768 message_header: HeaderGeneric::new(HostRequests::VMGS_GET_DEVICE_INFO),
769
770 status,
771 capacity,
772 bytes_per_logical_sector,
773 bytes_per_physical_sector,
774 maximum_transfer_size_bytes,
775 }
776 }
777}
778
779const_assert_eq!(24, size_of::<VmgsGetDeviceInfoResponse>());
780
781#[repr(C)]
782#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
783pub struct VmgsWriteRequest {
784 pub message_header: HeaderHostRequest,
785 pub flags: VmgsWriteFlags,
786 pub sector_offset: u64, pub sector_count: u32, pub _pad: u32,
789 }
791
792const_assert_eq!(24, size_of::<VmgsWriteRequest>());
793
794impl VmgsWriteRequest {
795 pub fn new(flags: VmgsWriteFlags, sector_offset: u64, sector_count: u32) -> Self {
796 Self {
797 message_header: HeaderGeneric::new(HostRequests::VMGS_WRITE),
798 flags,
799 sector_offset,
800 sector_count,
801 _pad: 0,
802 }
803 }
804}
805
806#[repr(C)]
807#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
808pub struct VmgsWriteResponse {
809 pub message_header: HeaderHostResponse,
810 pub status: VmgsIoStatus,
811}
812
813impl VmgsWriteResponse {
814 pub fn new(status: VmgsIoStatus) -> VmgsWriteResponse {
815 VmgsWriteResponse {
816 message_header: HeaderGeneric::new(HostRequests::VMGS_WRITE),
817 status,
818 }
819 }
820}
821
822const_assert_eq!(8, size_of::<VmgsWriteResponse>());
823
824#[repr(C)]
825#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
826pub struct VmgsReadRequest {
827 pub message_header: HeaderHostRequest,
828 pub flags: VmgsReadFlags,
829 pub sector_offset: u64, pub sector_count: u32, pub _pad: u32,
832}
833
834const_assert_eq!(24, size_of::<VmgsReadRequest>());
835
836impl VmgsReadRequest {
837 pub fn new(flags: VmgsReadFlags, sector_offset: u64, sector_count: u32) -> Self {
838 Self {
839 message_header: HeaderGeneric::new(HostRequests::VMGS_READ),
840 flags,
841 sector_offset,
842 sector_count,
843 _pad: 0,
844 }
845 }
846}
847
848#[repr(C)]
849#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
850pub struct VmgsReadResponse {
851 pub message_header: HeaderHostResponse,
852 pub status: VmgsIoStatus,
853 }
855
856impl VmgsReadResponse {
857 pub fn new(status: VmgsIoStatus) -> VmgsReadResponse {
858 VmgsReadResponse {
859 message_header: HeaderGeneric::new(HostRequests::VMGS_READ),
860 status,
861 }
862 }
863}
864
865const_assert_eq!(8, size_of::<VmgsReadResponse>());
866
867#[repr(C)]
868#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
869pub struct VmgsFlushRequest {
870 pub message_header: HeaderHostRequest,
871}
872
873impl VmgsFlushRequest {
874 pub fn new() -> Self {
875 Self {
876 message_header: HeaderGeneric::new(HostRequests::VMGS_FLUSH),
877 }
878 }
879}
880
881const_assert_eq!(4, size_of::<VmgsFlushRequest>());
882
883#[repr(C)]
884#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
885pub struct VmgsFlushResponse {
886 pub message_header: HeaderHostResponse,
887 pub status: VmgsIoStatus,
888}
889
890impl VmgsFlushResponse {
891 pub fn new(status: VmgsIoStatus) -> VmgsFlushResponse {
892 VmgsFlushResponse {
893 message_header: HeaderGeneric::new(HostRequests::VMGS_FLUSH),
894 status,
895 }
896 }
897}
898
899const_assert_eq!(8, size_of::<VmgsFlushResponse>());
900
901const VMGS_MAX_IO_MSG_HEADER_SIZE: usize = size_of::<VmgsReadRequest>();
902const_assert!(VMGS_MAX_IO_MSG_HEADER_SIZE >= size_of::<VmgsReadResponse>());
903const_assert!(VMGS_MAX_IO_MSG_HEADER_SIZE >= size_of::<VmgsWriteRequest>());
904const_assert!(VMGS_MAX_IO_MSG_HEADER_SIZE >= size_of::<VmgsWriteResponse>());
905const_assert!(VMGS_MAX_IO_MSG_HEADER_SIZE <= MAX_HEADER_SIZE);
906
907pub const MAX_TRANSFER_SIZE: usize = u32::MAX as usize - VMGS_MAX_IO_MSG_HEADER_SIZE;
908
909open_enum! {
910 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
911 pub enum ActivityClassId: u32 {
912 INVALID = 0,
913 VMGS_INITIALIZE_DEVICE = 1,
914 VMGS_INITIALIZE_STORE = 2,
915 VMGS_OPEN_STORE = 3,
916 VMGS_FORMAT = 4,
917 VMGS_SEND_RECEIVE = 5,
918 VMGS_DEVICE_READ = 6,
919 VMGS_DEVICE_WRITE = 7,
920 VMGS_DEVICE_FLUSH = 8,
921 }
922}
923
924open_enum! {
925 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
926 pub enum ActivityOpCode: u32 {
927 INFO = 0,
928 START = 1,
929 STOP = 2,
930 }
931}
932
933open_enum! {
934 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
935 pub enum EventId: u32 {
936 INVALID = 0,
937 VMGS_INFO = 1,
938 VMGS_WARNING = 2,
939 VMGS_ERROR = 3,
940 VMGS_CRITICAL = 4,
941 }
942}
943
944#[repr(C)]
945#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
946pub struct LogTraceRequest {
947 pub message_header: HeaderHostRequest,
948 pub level: LogLevel,
949 pub message: [u16; TRACE_MSG_MAX_SIZE],
950}
951
952const_assert_eq!(520, size_of::<LogTraceRequest>());
953
954#[repr(C)]
955#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
956pub struct LogTraceResponse {
957 pub message_header: HeaderHostResponse,
958}
959
960const_assert_eq!(4, size_of::<LogTraceResponse>());
961
962#[repr(C)]
963#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
964pub struct ActivityTraceStartRequest {
965 pub message_header: HeaderHostRequest,
966 pub activity_class: ActivityClassId,
967 pub related_activity_id: Guid,
968 pub size: u32, }
971
972const_assert_eq!(28, size_of::<ActivityTraceStartRequest>());
973
974#[repr(C)]
975#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
976pub struct ActivityTraceStartResponse {
977 pub message_header: HeaderHostResponse,
978 pub activity_id: Guid,
979}
980
981const_assert_eq!(20, size_of::<ActivityTraceStartResponse>());
982
983#[repr(C)]
984#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
985pub struct ActivityTraceOpRequest {
986 pub message_header: HeaderHostRequest,
987 pub activity_class: ActivityClassId,
988 pub activity_id: Guid,
989 pub related_activity_id: Guid,
990 pub op_code: ActivityOpCode,
991 pub size: u32, }
994
995const_assert_eq!(48, size_of::<ActivityTraceOpRequest>());
996
997#[repr(C)]
998#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
999pub struct ActivityTraceOpResponse {
1000 pub message_header: HeaderHostResponse,
1001}
1002
1003const_assert_eq!(4, size_of::<ActivityTraceOpResponse>());
1004
1005#[repr(C)]
1006#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1007pub struct EventTraceRequest {
1008 pub message_header: HeaderHostRequest,
1009 pub event: EventId,
1010 pub size: u32, }
1013
1014const_assert_eq!(12, size_of::<EventTraceRequest>());
1015
1016#[repr(C)]
1017#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1018pub struct EventTraceResponse {
1019 pub message_header: HeaderHostResponse,
1020}
1021
1022const_assert_eq!(4, size_of::<EventTraceResponse>());
1023
1024open_enum! {
1025 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1026 pub enum SecureBootTemplateType: u32 {
1027 SECURE_BOOT_DISABLED = 0,
1028 MICROSOFT_WINDOWS = 1,
1029 MICROSOFT_UEFI_CERTIFICATE_AUTHORITY = 2,
1030 OPEN_SOURCE_SHIELDED_VM = 3,
1031 }
1032}
1033
1034open_enum! {
1035 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1036 pub enum UefiConsoleMode: u8 {
1037 DEFAULT = 0,
1038 COM1 = 1,
1039 COM2 = 2,
1040 NONE = 3,
1041 }
1042}
1043
1044pub const HCL_DEVICE_PLATFORM_MAX_SMBIOS_LENGTH: usize = 64;
1045
1046#[repr(C)]
1047#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1048pub struct DevicePlatformSettingsRequestV2 {
1049 pub message_header: HeaderHostRequest,
1050}
1051
1052impl DevicePlatformSettingsRequestV2 {
1053 pub fn new() -> Self {
1054 Self {
1055 message_header: HeaderGeneric::new(HostRequests::DEVICE_PLATFORM_SETTINGS_V2),
1056 }
1057 }
1058}
1059
1060const_assert_eq!(4, size_of::<DevicePlatformSettingsRequestV2>());
1061
1062#[repr(transparent)]
1065#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1066pub struct ProtocolBool(pub u8);
1067
1068impl From<bool> for ProtocolBool {
1069 fn from(value: bool) -> Self {
1070 ProtocolBool(if value { 1 } else { 0 })
1071 }
1072}
1073
1074#[repr(C)]
1075#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1076pub struct DevicePlatformSettingsResponseV2 {
1077 pub message_header: HeaderHostResponse,
1078
1079 pub size: u32,
1080 }
1082
1083#[repr(C)]
1084#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1085pub struct DevicePlatformSettingsResponseV2Rev1 {
1086 pub message_header: HeaderHostResponse,
1087
1088 pub size: u32,
1089
1090 pub payload_state: LargePayloadState,
1091 }
1093
1094pub const GSP_CLEARTEXT_MAX: u32 = 32;
1095pub const GSP_CIPHERTEXT_MAX: u32 = 512;
1096pub const NUMBER_GSP: u32 = 2;
1097
1098#[bitfield(u32)]
1099#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq)]
1100pub struct GspExtendedStatusFlags {
1101 pub state_refresh_request: bool,
1102 pub no_registry_file: bool,
1103 pub no_rpc_server: bool,
1104 pub allow_ak_cert_renewal: bool,
1105 pub requires_rpc_server: bool,
1106
1107 #[bits(27)]
1108 _reserved: u32,
1109}
1110
1111#[repr(C)]
1112#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1113pub struct GspCleartextContent {
1114 pub length: u32,
1115 pub buffer: [u8; GSP_CLEARTEXT_MAX as usize * 2],
1116}
1117
1118const_assert_eq!(68, size_of::<GspCleartextContent>());
1119
1120#[repr(C)]
1121#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1122pub struct GspCiphertextContent {
1123 pub length: u32,
1124 pub buffer: [u8; GSP_CIPHERTEXT_MAX as usize],
1125}
1126
1127const_assert_eq!(516, size_of::<GspCiphertextContent>());
1128
1129#[repr(C)]
1131#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1132pub struct GuestStateProtectionByIdRequest {
1133 pub message_header: HeaderHostRequest,
1134}
1135
1136const_assert_eq!(4, size_of::<GuestStateProtectionByIdRequest>());
1137
1138impl GuestStateProtectionByIdRequest {
1139 pub fn new() -> Self {
1140 Self {
1141 message_header: HeaderGeneric::new(HostRequests::GUEST_STATE_PROTECTION_BY_ID),
1142 }
1143 }
1144}
1145
1146#[repr(C)]
1147#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1148pub struct GuestStateProtectionByIdResponse {
1149 pub message_header: HeaderHostResponse,
1150 pub seed: GspCleartextContent,
1151 pub extended_status_flags: GspExtendedStatusFlags,
1152}
1153
1154const_assert_eq!(76, size_of::<GuestStateProtectionByIdResponse>());
1155
1156#[repr(C)]
1157#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1158pub struct GuestStateProtectionRequest {
1159 pub message_header: HeaderHostRequest,
1160 pub new_gsp: GspCleartextContent,
1161 pub encrypted_gsp: [GspCiphertextContent; NUMBER_GSP as usize],
1162 pub extended_status_support_flags: GspExtendedStatusFlags,
1163}
1164
1165const_assert_eq!(1108, size_of::<GuestStateProtectionRequest>());
1166
1167impl GuestStateProtectionRequest {
1168 pub fn new(
1169 buffer: [u8; GSP_CLEARTEXT_MAX as usize * 2],
1170 encrypted_gsp: [GspCiphertextContent; NUMBER_GSP as usize],
1171 extended_status_support_flags: GspExtendedStatusFlags,
1172 ) -> Self {
1173 Self {
1174 message_header: HeaderGeneric::new(HostRequests::GUEST_STATE_PROTECTION),
1175 new_gsp: GspCleartextContent {
1176 length: GSP_CLEARTEXT_MAX,
1177 buffer,
1178 },
1179 encrypted_gsp,
1180 extended_status_support_flags,
1181 }
1182 }
1183}
1184
1185#[repr(C)]
1186#[derive(Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1187pub struct GuestStateProtectionResponse {
1188 pub message_header: HeaderHostResponse,
1189 pub encrypted_gsp: GspCiphertextContent,
1190 pub decrypted_gsp: [GspCleartextContent; NUMBER_GSP as usize],
1191 pub extended_status_flags: GspExtendedStatusFlags,
1192}
1193
1194const_assert_eq!(660, size_of::<GuestStateProtectionResponse>());
1195
1196#[repr(C)]
1197#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1198pub struct UpdateGenerationId {
1199 pub message_header: HeaderGuestNotification,
1200 pub _pad: u32,
1201 pub generation_id: [u8; 16],
1202}
1203
1204const_assert_eq!(24, size_of::<UpdateGenerationId>());
1205
1206impl UpdateGenerationId {
1207 pub fn new(generation_id: [u8; 16]) -> Self {
1208 Self {
1209 message_header: HeaderGeneric::new(GuestNotifications::UPDATE_GENERATION_ID),
1210 _pad: 0,
1211 generation_id,
1212 }
1213 }
1214}
1215
1216#[bitfield(u64)]
1218#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1219pub struct SaveGuestVtl2StateFlags {
1220 #[bits(1)]
1222 pub enable_nvme_keepalive: bool,
1223
1224 #[bits(1)]
1226 pub enable_mana_keepalive: bool,
1227
1228 #[bits(62)]
1230 _rsvd1: u64,
1231}
1232
1233#[repr(C, packed)]
1234#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1235pub struct SaveGuestVtl2StateNotification {
1236 pub message_header: HeaderGuestNotification,
1237 pub correlation_id: Guid,
1238 pub capabilities_flags: SaveGuestVtl2StateFlags,
1239 pub timeout_hint_secs: u16,
1240}
1241
1242const_assert_eq!(30, size_of::<SaveGuestVtl2StateNotification>());
1243
1244#[repr(C)]
1245#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1246pub struct SaveGuestVtl2StateRequest {
1247 pub message_header: HeaderHostRequest,
1248 pub save_status: GuestVtl2SaveRestoreStatus,
1249 }
1251
1252const_assert_eq!(6, size_of::<SaveGuestVtl2StateRequest>());
1253
1254impl SaveGuestVtl2StateRequest {
1255 pub fn new(status: GuestVtl2SaveRestoreStatus) -> Self {
1256 Self {
1257 message_header: HeaderGeneric::new(HostRequests::SAVE_GUEST_VTL2_STATE),
1258 save_status: status,
1259 }
1260 }
1261}
1262
1263#[repr(C)]
1264#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1265pub struct SaveGuestVtl2StateResponse {
1266 pub message_header: HeaderHostResponse,
1267 pub save_status: GuestVtl2SaveRestoreStatus,
1268}
1269
1270const_assert_eq!(6, size_of::<SaveGuestVtl2StateResponse>());
1271
1272impl SaveGuestVtl2StateResponse {
1273 pub fn new(status: GuestVtl2SaveRestoreStatus) -> Self {
1274 Self {
1275 message_header: HeaderGeneric::new(HostRequests::SAVE_GUEST_VTL2_STATE),
1276 save_status: status,
1277 }
1278 }
1279}
1280
1281#[repr(C)]
1282#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1283pub struct RestoreGuestVtl2StateHostNotification {
1284 pub message_header: HeaderHostNotification,
1285 pub status: GuestVtl2SaveRestoreStatus,
1286}
1287
1288const_assert_eq!(6, size_of::<RestoreGuestVtl2StateHostNotification>());
1289
1290impl RestoreGuestVtl2StateHostNotification {
1291 pub fn new(stat: GuestVtl2SaveRestoreStatus) -> Self {
1292 Self {
1293 message_header: HeaderGeneric::new(
1294 HostNotifications::RESTORE_GUEST_VTL2_STATE_COMPLETED,
1295 ),
1296 status: stat,
1297 }
1298 }
1299}
1300
1301#[repr(C)]
1302#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1303pub struct RestoreGuestVtl2StateRequest {
1304 pub message_header: HeaderHostRequest,
1305 pub restore_status: GuestVtl2SaveRestoreStatus,
1306}
1307
1308const_assert_eq!(6, size_of::<RestoreGuestVtl2StateRequest>());
1309
1310impl RestoreGuestVtl2StateRequest {
1311 pub fn new(status: GuestVtl2SaveRestoreStatus) -> Self {
1312 Self {
1313 message_header: HeaderGeneric::new(HostRequests::RESTORE_GUEST_VTL2_STATE),
1314 restore_status: status,
1315 }
1316 }
1317}
1318
1319#[repr(C, packed)]
1320#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1321pub struct RestoreGuestVtl2StateResponse {
1322 pub message_header: HeaderHostResponse,
1323 pub data_length: u32,
1324 pub restore_status: GuestVtl2SaveRestoreStatus,
1325 }
1327
1328const_assert_eq!(10, size_of::<RestoreGuestVtl2StateResponse>());
1329
1330impl RestoreGuestVtl2StateResponse {
1331 pub fn new(length: u32, status: GuestVtl2SaveRestoreStatus) -> Self {
1332 Self {
1333 message_header: HeaderGeneric::new(HostRequests::RESTORE_GUEST_VTL2_STATE),
1334 data_length: length,
1335 restore_status: status,
1336 }
1337 }
1338}
1339
1340open_enum! {
1341 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1342 pub enum VpciDeviceControlCode: u32 {
1343 UNDEFINED = 0,
1344 OFFER = 1,
1345 REVOKE = 2,
1346 RESET = 3,
1347 }
1348}
1349
1350open_enum! {
1351 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1352 pub enum VpciDeviceControlStatus: u32 {
1353 SUCCESS = 0,
1354 INVALID_REQUEST = 1,
1355 DEVICE_NOT_FOUND = 2,
1356 INVALID_DEVICE_STATE = 3,
1357 GENERIC_FAILURE = 4,
1358 }
1359}
1360
1361#[repr(C)]
1362#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1363pub struct VpciDeviceControlRequest {
1364 pub message_header: HeaderHostRequest,
1365 pub code: VpciDeviceControlCode,
1366 pub bus_instance_id: Guid,
1367}
1368
1369const_assert_eq!(24, size_of::<VpciDeviceControlRequest>());
1370
1371impl VpciDeviceControlRequest {
1372 pub fn new(code: VpciDeviceControlCode, bus_instance_id: Guid) -> Self {
1373 Self {
1374 message_header: HeaderGeneric::new(HostRequests::VPCI_DEVICE_CONTROL),
1375 code,
1376 bus_instance_id,
1377 }
1378 }
1379}
1380
1381#[repr(C)]
1382#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1383pub struct VpciDeviceControlResponse {
1384 pub message_header: HeaderHostResponse,
1385 pub status: VpciDeviceControlStatus,
1386}
1387
1388const_assert_eq!(8, size_of::<VpciDeviceControlResponse>());
1389
1390impl VpciDeviceControlResponse {
1391 pub fn new(status: VpciDeviceControlStatus) -> Self {
1392 Self {
1393 message_header: HeaderGeneric::new(HostRequests::VPCI_DEVICE_CONTROL),
1394 status,
1395 }
1396 }
1397}
1398
1399open_enum! {
1400 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1401 pub enum VpciDeviceNotificationCode : u32 {
1402 UNDEFINED = 0,
1403 ENUMERATED = 1,
1404 PREPARE_FOR_REMOVAL = 2,
1405 }
1406}
1407
1408#[repr(C)]
1409#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1410pub struct VpciDeviceNotification {
1411 pub message_header: HeaderGuestNotification,
1412 pub bus_instance_id: Guid,
1413 pub code: VpciDeviceNotificationCode,
1414}
1415
1416const_assert_eq!(24, size_of::<VpciDeviceNotification>());
1417
1418#[repr(C, packed)]
1419#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1420pub struct VpciDeviceBindingChangeRequest {
1421 pub message_header: HeaderHostRequest,
1422 pub bus_instance_id: [u8; 16], pub binding_state: u8,
1424}
1425
1426const_assert_eq!(21, size_of::<VpciDeviceBindingChangeRequest>());
1427
1428impl VpciDeviceBindingChangeRequest {
1429 pub fn new(bus_instance_id: Guid, binding_state: bool) -> Self {
1430 let mut guid: [u8; 16] = [0; 16];
1431 guid.copy_from_slice(bus_instance_id.as_bytes());
1432 Self {
1433 message_header: HeaderGeneric::new(HostRequests::VPCI_DEVICE_BINDING_CHANGE),
1434 bus_instance_id: guid,
1435 binding_state: binding_state as u8,
1436 }
1437 }
1438}
1439
1440#[repr(C)]
1441#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1442pub struct VpciDeviceBindingChangeResponse {
1443 pub message_header: HeaderHostResponse,
1444 pub bus_instance_id: Guid,
1445 pub status: VpciDeviceControlStatus,
1446}
1447
1448const_assert_eq!(24, size_of::<VpciDeviceBindingChangeResponse>());
1449
1450impl VpciDeviceBindingChangeResponse {
1451 pub fn new(bus_instance_id: Guid, status: VpciDeviceControlStatus) -> Self {
1452 Self {
1453 message_header: HeaderGeneric::new(HostRequests::VPCI_DEVICE_BINDING_CHANGE),
1454 bus_instance_id,
1455 status,
1456 }
1457 }
1458}
1459
1460#[repr(C, packed)]
1461#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1462pub struct VgaProxyPciReadRequest {
1463 pub message_header: HeaderHostRequest,
1464 pub offset: u16,
1465}
1466
1467const_assert_eq!(6, size_of::<VgaProxyPciReadRequest>());
1468
1469impl VgaProxyPciReadRequest {
1470 pub fn new(offset: u16) -> Self {
1471 Self {
1472 message_header: HeaderGeneric::new(HostRequests::VGA_PROXY_PCI_READ),
1473 offset,
1474 }
1475 }
1476}
1477
1478#[repr(C)]
1479#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1480pub struct VgaProxyPciReadResponse {
1481 pub message_header: HeaderHostResponse,
1482 pub value: u32,
1483}
1484
1485const_assert_eq!(8, size_of::<VgaProxyPciReadResponse>());
1486
1487impl VgaProxyPciReadResponse {
1488 pub fn new(value: u32) -> Self {
1489 Self {
1490 message_header: HeaderGeneric::new(HostRequests::VGA_PROXY_PCI_READ),
1491 value,
1492 }
1493 }
1494}
1495
1496#[repr(C, packed)]
1497#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1498pub struct VgaProxyPciWriteRequest {
1499 pub message_header: HeaderHostRequest,
1500 pub value: u32,
1501 pub offset: u16,
1502}
1503
1504const_assert_eq!(10, size_of::<VgaProxyPciWriteRequest>());
1505
1506impl VgaProxyPciWriteRequest {
1507 pub fn new(offset: u16, value: u32) -> Self {
1508 Self {
1509 message_header: HeaderGeneric::new(HostRequests::VGA_PROXY_PCI_WRITE),
1510 offset,
1511 value,
1512 }
1513 }
1514}
1515
1516#[repr(C)]
1517#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1518pub struct VgaProxyPciWriteResponse {
1519 pub message_header: HeaderHostResponse,
1520}
1521
1522const_assert_eq!(4, size_of::<VgaProxyPciWriteResponse>());
1523
1524impl VgaProxyPciWriteResponse {
1525 pub fn new() -> Self {
1526 Self {
1527 message_header: HeaderGeneric::new(HostRequests::VGA_PROXY_PCI_WRITE),
1528 }
1529 }
1530}
1531
1532open_enum! {
1533 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1534 pub enum ModifyVtl2SettingsStatus : u32 {
1535 SUCCESS = 0,
1536 FAILURE = 1,
1537 }
1538}
1539
1540#[repr(C)]
1541#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1542pub struct ModifyVtl2SettingsNotification {
1543 pub message_header: HeaderGuestNotification,
1544
1545 pub size: u32,
1546 }
1548
1549const_assert_eq!(8, size_of::<ModifyVtl2SettingsNotification>());
1550
1551#[repr(C)]
1552#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1553pub struct ModifyVtl2SettingsRev1Notification {
1554 pub message_header: HeaderGuestNotification,
1555
1556 pub size: u32,
1557
1558 pub payload_state: LargePayloadState,
1559 }
1561
1562const_assert_eq!(12, size_of::<ModifyVtl2SettingsRev1Notification>());
1563
1564#[repr(C, packed)]
1565#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1566pub struct ModifyVtl2SettingsCompleteNotification {
1567 pub message_header: HeaderHostNotification,
1568 pub modify_status: ModifyVtl2SettingsStatus,
1569 pub result_document_size: u32,
1570}
1571
1572const_assert_eq!(12, size_of::<ModifyVtl2SettingsCompleteNotification>());
1573
1574impl ModifyVtl2SettingsCompleteNotification {
1575 pub fn new(status: ModifyVtl2SettingsStatus, result_document_size: u32) -> Self {
1576 Self {
1577 message_header: HeaderGeneric::new(HostNotifications::MODIFY_VTL2_SETTINGS_COMPLETED),
1578 modify_status: status,
1579 result_document_size,
1580 }
1581 }
1582}
1583
1584pub const GET_LOG_INTERFACE_GUID: Guid = guid::guid!("AA5DE534-D149-487A-9053-05972BA20A7C");
1585
1586open_enum! {
1587 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1588 pub enum LogType: u8 {
1589 EVENT = 0,
1590 SPAN_ENTER = 1,
1591 SPAN_EXIT = 2,
1592 }
1593}
1594
1595#[bitfield(u16)]
1596#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1597pub struct LogFlags {
1598 pub kmsg: bool,
1599 #[bits(15)]
1600 pub mbz0: u16,
1601}
1602
1603pub const TRACE_LOGGING_NAME_MAX_SIZE: usize = 128;
1604pub const TRACE_LOGGING_TARGET_MAX_SIZE: usize = 128;
1605pub const TRACE_LOGGING_FIELDS_MAX_SIZE: usize = 256;
1606pub const TRACE_LOGGING_MESSAGE_MAX_SIZE: usize = 4096;
1607pub const TRACE_LOGGING_NOTIFICATION_MAX_SIZE: usize = TRACE_LOGGING_NAME_MAX_SIZE
1608 + TRACE_LOGGING_TARGET_MAX_SIZE
1609 + TRACE_LOGGING_FIELDS_MAX_SIZE
1610 + TRACE_LOGGING_MESSAGE_MAX_SIZE
1611 + size_of::<TraceLoggingNotificationHeader>();
1612
1613#[repr(C)]
1614#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1615pub struct TraceLoggingBufferOffset {
1616 pub size: u16,
1617 pub offset: u16,
1618}
1619
1620#[repr(C)]
1626#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1627pub struct TraceLoggingNotificationHeader {
1628 pub log_type: LogType,
1629 pub level: u8,
1630 pub flags: LogFlags,
1631 pub name: TraceLoggingBufferOffset,
1632 pub target: TraceLoggingBufferOffset,
1633 pub fields: TraceLoggingBufferOffset,
1634 pub message: TraceLoggingBufferOffset,
1635 pub mbz0: u32,
1636 pub activity_id: Guid,
1637 pub related_activity_id: Guid,
1638 pub correlation_id: Guid,
1639 pub timestamp: u64,
1640}
1641const_assert_eq!(80, size_of::<TraceLoggingNotificationHeader>());
1642
1643#[repr(C, packed)]
1645#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1646pub struct MapFramebufferRequest {
1647 pub message_header: HeaderHostRequest,
1648 pub gpa: u64,
1649}
1650
1651const_assert_eq!(12, size_of::<MapFramebufferRequest>());
1652
1653impl MapFramebufferRequest {
1654 pub fn new(gpa: u64) -> Self {
1655 Self {
1656 message_header: HeaderGeneric::new(HostRequests::MAP_FRAMEBUFFER),
1657 gpa,
1658 }
1659 }
1660}
1661
1662open_enum! {
1663 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1664 pub enum MapFramebufferStatus : u32 {
1665 SUCCESS = 0,
1666 FAILURE = 1,
1667 }
1668}
1669
1670#[repr(C, packed)]
1672#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1673pub struct MapFramebufferResponse {
1674 pub message_header: HeaderHostResponse,
1675 pub status: MapFramebufferStatus,
1676}
1677
1678const_assert_eq!(8, size_of::<MapFramebufferResponse>());
1679
1680impl MapFramebufferResponse {
1681 pub fn new(status: MapFramebufferStatus) -> Self {
1682 Self {
1683 message_header: HeaderGeneric::new(HostRequests::MAP_FRAMEBUFFER),
1684 status,
1685 }
1686 }
1687}
1688
1689#[repr(C, packed)]
1691#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1692pub struct UnmapFramebufferRequest {
1693 pub message_header: HeaderHostRequest,
1694}
1695
1696const_assert_eq!(4, size_of::<UnmapFramebufferRequest>());
1697
1698impl UnmapFramebufferRequest {
1699 pub fn new() -> Self {
1700 Self {
1701 message_header: HeaderGeneric::new(HostRequests::UNMAP_FRAMEBUFFER),
1702 }
1703 }
1704}
1705
1706open_enum! {
1707 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1708 pub enum UnmapFramebufferStatus : u32 {
1709 SUCCESS = 0,
1710 FAILURE = 1,
1711 }
1712}
1713
1714#[repr(C, packed)]
1716#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1717pub struct UnmapFramebufferResponse {
1718 pub message_header: HeaderHostResponse,
1719 pub status: UnmapFramebufferStatus,
1720}
1721
1722const_assert_eq!(8, size_of::<UnmapFramebufferResponse>());
1723
1724impl UnmapFramebufferResponse {
1725 pub fn new(status: UnmapFramebufferStatus) -> Self {
1726 Self {
1727 message_header: HeaderGeneric::new(HostRequests::UNMAP_FRAMEBUFFER),
1728 status,
1729 }
1730 }
1731}
1732
1733open_enum! {
1734 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1735 pub enum StartVtl0Status : u32 {
1736 SUCCESS = 0,
1737 FAILURE = 1,
1738 }
1739}
1740
1741#[repr(C, packed)]
1742#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1743pub struct StartVtl0CompleteNotification {
1744 pub message_header: HeaderHostNotification,
1745 pub status: StartVtl0Status,
1746 pub result_document_size: u32,
1747 }
1750
1751const_assert_eq!(12, size_of::<StartVtl0CompleteNotification>());
1752
1753impl StartVtl0CompleteNotification {
1754 pub fn new(status: StartVtl0Status, result_document_size: u32) -> Self {
1755 Self {
1756 message_header: HeaderGeneric::new(HostNotifications::START_VTL0_COMPLETED),
1757 status,
1758 result_document_size,
1759 }
1760 }
1761}
1762
1763#[repr(C)]
1764#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1765pub struct BatteryStatusNotification {
1766 pub message_header: HeaderGuestNotification,
1767 pub flags: BatteryStatusFlags,
1768 pub max_capacity: u32,
1769 pub remaining_capacity: u32,
1770 pub rate: u32,
1771}
1772
1773#[bitfield(u32)]
1774#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1775pub struct BatteryStatusFlags {
1776 pub ac_online: bool,
1777 pub battery_present: bool,
1778 pub charging: bool,
1779 pub discharging: bool,
1780 #[bits(28)]
1781 pub reserved: u32,
1782}
1783
1784impl BatteryStatusNotification {
1785 pub fn new(
1786 flags: BatteryStatusFlags,
1787 max_capacity: u32,
1788 remaining_capacity: u32,
1789 rate: u32,
1790 ) -> Self {
1791 Self {
1792 message_header: HeaderGeneric::new(GuestNotifications::BATTERY_STATUS),
1793 flags,
1794 max_capacity,
1795 remaining_capacity,
1796 rate,
1797 }
1798 }
1799}
1800
1801#[repr(C)]
1802#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1803pub struct InjectDebugInterruptNotification {
1804 pub message_header: HeaderGuestNotification,
1805 pub vtl: u8,
1806 pub _pad: u8,
1807}
1808const_assert_eq!(6, size_of::<InjectDebugInterruptNotification>());
1809
1810#[repr(C)]
1811#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1812pub struct PostLiveMigrationNotification {
1813 pub message_header: HeaderGuestNotification,
1814}
1815const_assert_eq!(4, size_of::<PostLiveMigrationNotification>());
1816
1817#[bitfield(u64)]
1818#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1819pub struct CreateRamGpaRangeFlags {
1820 _reserved1: bool,
1821
1822 pub rom_mb: bool,
1824
1825 #[bits(62)]
1826 _reserved: u64,
1827}
1828
1829#[repr(C, packed)]
1830#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1831pub struct CreateRamGpaRangeRequest {
1832 pub message_header: HeaderHostRequest,
1833 pub slot: u32,
1834 pub gpa_start: u64,
1835 pub gpa_count: u64,
1836 pub gpa_offset: u64,
1837 pub flags: CreateRamGpaRangeFlags,
1838}
1839
1840const_assert_eq!(40, size_of::<CreateRamGpaRangeRequest>());
1841
1842impl CreateRamGpaRangeRequest {
1843 pub fn new(
1844 slot: u32,
1845 gpa_start: u64,
1846 gpa_count: u64,
1847 gpa_offset: u64,
1848 flags: CreateRamGpaRangeFlags,
1849 ) -> Self {
1850 Self {
1851 message_header: HeaderGeneric::new(HostRequests::CREATE_RAM_GPA_RANGE),
1852 slot,
1853 gpa_start,
1854 gpa_count,
1855 gpa_offset,
1856 flags,
1857 }
1858 }
1859}
1860
1861open_enum! {
1862 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1863 pub enum CreateRamGpaRangeStatus : u32 {
1864 SUCCESS = 0,
1865 SLOT_OUT_OF_BOUNDS = 1,
1867 SLOT_OCCUPIED = 2,
1869 INVALID_FLAG = 3,
1871 INVALID_GPA = 4,
1873 FAILED = 5,
1875 }
1876}
1877
1878#[repr(C)]
1879#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1880pub struct CreateRamGpaRangeResponse {
1881 pub message_header: HeaderHostResponse,
1882 pub status: CreateRamGpaRangeStatus,
1883}
1884
1885const_assert_eq!(8, size_of::<CreateRamGpaRangeResponse>());
1886
1887impl CreateRamGpaRangeResponse {
1888 pub fn new(status: CreateRamGpaRangeStatus) -> Self {
1889 Self {
1890 message_header: HeaderGeneric::new(HostRequests::CREATE_RAM_GPA_RANGE),
1891 status,
1892 }
1893 }
1894}
1895
1896#[repr(C)]
1897#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1898pub struct ResetRamGpaRangeRequest {
1899 pub message_header: HeaderHostRequest,
1900 pub slot: u32,
1901}
1902
1903const_assert_eq!(8, size_of::<ResetRamGpaRangeRequest>());
1904
1905impl ResetRamGpaRangeRequest {
1906 pub fn new(slot: u32) -> Self {
1907 Self {
1908 message_header: HeaderGeneric::new(HostRequests::RESET_RAM_GPA_RANGE),
1909 slot,
1910 }
1911 }
1912}
1913
1914#[repr(C)]
1915#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1916pub struct ResetRamGpaRangeResponse {
1917 pub message_header: HeaderHostResponse,
1918}
1919
1920const_assert_eq!(4, size_of::<ResetRamGpaRangeResponse>());
1921
1922impl ResetRamGpaRangeResponse {
1923 pub fn new() -> Self {
1924 Self {
1925 message_header: HeaderGeneric::new(HostRequests::RESET_RAM_GPA_RANGE),
1926 }
1927 }
1928}
1929
1930#[repr(C, packed)]
1935#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1936pub struct LoadFirmwareRequest {
1937 pub message_header: HeaderHostRequest,
1938 pub firmware_token: u64,
1940}
1941
1942const_assert_eq!(12, size_of::<LoadFirmwareRequest>());
1943
1944impl LoadFirmwareRequest {
1945 pub fn new(firmware_token: u64) -> Self {
1946 Self {
1947 message_header: HeaderGeneric::new(HostRequests::LOAD_FIRMWARE),
1948 firmware_token,
1949 }
1950 }
1951}
1952
1953open_enum! {
1954 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1955 pub enum LoadFirmwareStatus: u32 {
1956 SUCCESS = 0,
1957 INVALID_TOKEN = 1,
1959 FAILED = 2,
1961 }
1962}
1963
1964#[repr(C)]
1965#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1966pub struct LoadFirmwareResponse {
1967 pub message_header: HeaderHostResponse,
1968 pub status: LoadFirmwareStatus,
1969 pub entry_point_image_offset: u64,
1974}
1975
1976const_assert_eq!(16, size_of::<LoadFirmwareResponse>());
1977
1978impl LoadFirmwareResponse {
1979 pub fn new(status: LoadFirmwareStatus, entry_point_image_offset: u64) -> Self {
1980 Self {
1981 message_header: HeaderGeneric::new(HostRequests::LOAD_FIRMWARE),
1982 status,
1983 entry_point_image_offset,
1984 }
1985 }
1986}
1987
1988pub mod test_utilities {
1989 pub const TEST_VMGS_SECTOR_SIZE: u32 = 512;
1991 pub const TEST_VMGS_CAPACITY: usize = 4194816; }