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