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