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