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