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 #[bits(63)]
1192 _rsvd1: u64,
1193}
1194
1195#[repr(C, packed)]
1196#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1197pub struct SaveGuestVtl2StateNotification {
1198 pub message_header: HeaderGuestNotification,
1199 pub correlation_id: Guid,
1200 pub capabilities_flags: SaveGuestVtl2StateFlags,
1201 pub timeout_hint_secs: u16,
1202}
1203
1204const_assert_eq!(30, size_of::<SaveGuestVtl2StateNotification>());
1205
1206#[repr(C)]
1207#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1208pub struct SaveGuestVtl2StateRequest {
1209 pub message_header: HeaderHostRequest,
1210 pub save_status: GuestVtl2SaveRestoreStatus,
1211 }
1213
1214const_assert_eq!(6, size_of::<SaveGuestVtl2StateRequest>());
1215
1216impl SaveGuestVtl2StateRequest {
1217 pub fn new(status: GuestVtl2SaveRestoreStatus) -> Self {
1218 Self {
1219 message_header: HeaderGeneric::new(HostRequests::SAVE_GUEST_VTL2_STATE),
1220 save_status: status,
1221 }
1222 }
1223}
1224
1225#[repr(C)]
1226#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1227pub struct SaveGuestVtl2StateResponse {
1228 pub message_header: HeaderHostResponse,
1229 pub save_status: GuestVtl2SaveRestoreStatus,
1230}
1231
1232const_assert_eq!(6, size_of::<SaveGuestVtl2StateResponse>());
1233
1234impl SaveGuestVtl2StateResponse {
1235 pub fn new(status: GuestVtl2SaveRestoreStatus) -> Self {
1236 Self {
1237 message_header: HeaderGeneric::new(HostRequests::SAVE_GUEST_VTL2_STATE),
1238 save_status: status,
1239 }
1240 }
1241}
1242
1243#[repr(C)]
1244#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1245pub struct RestoreGuestVtl2StateHostNotification {
1246 pub message_header: HeaderHostNotification,
1247 pub status: GuestVtl2SaveRestoreStatus,
1248}
1249
1250const_assert_eq!(6, size_of::<RestoreGuestVtl2StateHostNotification>());
1251
1252impl RestoreGuestVtl2StateHostNotification {
1253 pub fn new(stat: GuestVtl2SaveRestoreStatus) -> Self {
1254 Self {
1255 message_header: HeaderGeneric::new(
1256 HostNotifications::RESTORE_GUEST_VTL2_STATE_COMPLETED,
1257 ),
1258 status: stat,
1259 }
1260 }
1261}
1262
1263#[repr(C)]
1264#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1265pub struct RestoreGuestVtl2StateRequest {
1266 pub message_header: HeaderHostRequest,
1267 pub restore_status: GuestVtl2SaveRestoreStatus,
1268}
1269
1270const_assert_eq!(6, size_of::<RestoreGuestVtl2StateRequest>());
1271
1272impl RestoreGuestVtl2StateRequest {
1273 pub fn new(status: GuestVtl2SaveRestoreStatus) -> Self {
1274 Self {
1275 message_header: HeaderGeneric::new(HostRequests::RESTORE_GUEST_VTL2_STATE),
1276 restore_status: status,
1277 }
1278 }
1279}
1280
1281#[repr(C, packed)]
1282#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1283pub struct RestoreGuestVtl2StateResponse {
1284 pub message_header: HeaderHostResponse,
1285 pub data_length: u32,
1286 pub restore_status: GuestVtl2SaveRestoreStatus,
1287 }
1289
1290const_assert_eq!(10, size_of::<RestoreGuestVtl2StateResponse>());
1291
1292impl RestoreGuestVtl2StateResponse {
1293 pub fn new(length: u32, status: GuestVtl2SaveRestoreStatus) -> Self {
1294 Self {
1295 message_header: HeaderGeneric::new(HostRequests::RESTORE_GUEST_VTL2_STATE),
1296 data_length: length,
1297 restore_status: status,
1298 }
1299 }
1300}
1301
1302open_enum! {
1303 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1304 pub enum VpciDeviceControlCode: u32 {
1305 UNDEFINED = 0,
1306 OFFER = 1,
1307 REVOKE = 2,
1308 RESET = 3,
1309 }
1310}
1311
1312open_enum! {
1313 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1314 pub enum VpciDeviceControlStatus: u32 {
1315 SUCCESS = 0,
1316 INVALID_REQUEST = 1,
1317 DEVICE_NOT_FOUND = 2,
1318 INVALID_DEVICE_STATE = 3,
1319 GENERIC_FAILURE = 4,
1320 }
1321}
1322
1323#[repr(C)]
1324#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1325pub struct VpciDeviceControlRequest {
1326 pub message_header: HeaderHostRequest,
1327 pub code: VpciDeviceControlCode,
1328 pub bus_instance_id: Guid,
1329}
1330
1331const_assert_eq!(24, size_of::<VpciDeviceControlRequest>());
1332
1333impl VpciDeviceControlRequest {
1334 pub fn new(code: VpciDeviceControlCode, bus_instance_id: Guid) -> Self {
1335 Self {
1336 message_header: HeaderGeneric::new(HostRequests::VPCI_DEVICE_CONTROL),
1337 code,
1338 bus_instance_id,
1339 }
1340 }
1341}
1342
1343#[repr(C)]
1344#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1345pub struct VpciDeviceControlResponse {
1346 pub message_header: HeaderHostResponse,
1347 pub status: VpciDeviceControlStatus,
1348}
1349
1350const_assert_eq!(8, size_of::<VpciDeviceControlResponse>());
1351
1352impl VpciDeviceControlResponse {
1353 pub fn new(status: VpciDeviceControlStatus) -> Self {
1354 Self {
1355 message_header: HeaderGeneric::new(HostRequests::VPCI_DEVICE_CONTROL),
1356 status,
1357 }
1358 }
1359}
1360
1361open_enum! {
1362 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1363 pub enum VpciDeviceNotificationCode : u32 {
1364 UNDEFINED = 0,
1365 ENUMERATED = 1,
1366 PREPARE_FOR_REMOVAL = 2,
1367 }
1368}
1369
1370#[repr(C)]
1371#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1372pub struct VpciDeviceNotification {
1373 pub message_header: HeaderGuestNotification,
1374 pub bus_instance_id: Guid,
1375 pub code: VpciDeviceNotificationCode,
1376}
1377
1378const_assert_eq!(24, size_of::<VpciDeviceNotification>());
1379
1380#[repr(C, packed)]
1381#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1382pub struct VpciDeviceBindingChangeRequest {
1383 pub message_header: HeaderHostRequest,
1384 pub bus_instance_id: [u8; 16], pub binding_state: u8,
1386}
1387
1388const_assert_eq!(21, size_of::<VpciDeviceBindingChangeRequest>());
1389
1390impl VpciDeviceBindingChangeRequest {
1391 pub fn new(bus_instance_id: Guid, binding_state: bool) -> Self {
1392 let mut guid: [u8; 16] = [0; 16];
1393 guid.copy_from_slice(bus_instance_id.as_bytes());
1394 Self {
1395 message_header: HeaderGeneric::new(HostRequests::VPCI_DEVICE_BINDING_CHANGE),
1396 bus_instance_id: guid,
1397 binding_state: binding_state as u8,
1398 }
1399 }
1400}
1401
1402#[repr(C)]
1403#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1404pub struct VpciDeviceBindingChangeResponse {
1405 pub message_header: HeaderHostResponse,
1406 pub bus_instance_id: Guid,
1407 pub status: VpciDeviceControlStatus,
1408}
1409
1410const_assert_eq!(24, size_of::<VpciDeviceBindingChangeResponse>());
1411
1412impl VpciDeviceBindingChangeResponse {
1413 pub fn new(bus_instance_id: Guid, status: VpciDeviceControlStatus) -> Self {
1414 Self {
1415 message_header: HeaderGeneric::new(HostRequests::VPCI_DEVICE_BINDING_CHANGE),
1416 bus_instance_id,
1417 status,
1418 }
1419 }
1420}
1421
1422#[repr(C, packed)]
1423#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1424pub struct VgaProxyPciReadRequest {
1425 pub message_header: HeaderHostRequest,
1426 pub offset: u16,
1427}
1428
1429const_assert_eq!(6, size_of::<VgaProxyPciReadRequest>());
1430
1431impl VgaProxyPciReadRequest {
1432 pub fn new(offset: u16) -> Self {
1433 Self {
1434 message_header: HeaderGeneric::new(HostRequests::VGA_PROXY_PCI_READ),
1435 offset,
1436 }
1437 }
1438}
1439
1440#[repr(C)]
1441#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1442pub struct VgaProxyPciReadResponse {
1443 pub message_header: HeaderHostResponse,
1444 pub value: u32,
1445}
1446
1447const_assert_eq!(8, size_of::<VgaProxyPciReadResponse>());
1448
1449impl VgaProxyPciReadResponse {
1450 pub fn new(value: u32) -> Self {
1451 Self {
1452 message_header: HeaderGeneric::new(HostRequests::VGA_PROXY_PCI_READ),
1453 value,
1454 }
1455 }
1456}
1457
1458#[repr(C, packed)]
1459#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1460pub struct VgaProxyPciWriteRequest {
1461 pub message_header: HeaderHostRequest,
1462 pub value: u32,
1463 pub offset: u16,
1464}
1465
1466const_assert_eq!(10, size_of::<VgaProxyPciWriteRequest>());
1467
1468impl VgaProxyPciWriteRequest {
1469 pub fn new(offset: u16, value: u32) -> Self {
1470 Self {
1471 message_header: HeaderGeneric::new(HostRequests::VGA_PROXY_PCI_WRITE),
1472 offset,
1473 value,
1474 }
1475 }
1476}
1477
1478#[repr(C)]
1479#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1480pub struct VgaProxyPciWriteResponse {
1481 pub message_header: HeaderHostResponse,
1482}
1483
1484const_assert_eq!(4, size_of::<VgaProxyPciWriteResponse>());
1485
1486impl VgaProxyPciWriteResponse {
1487 pub fn new() -> Self {
1488 Self {
1489 message_header: HeaderGeneric::new(HostRequests::VGA_PROXY_PCI_WRITE),
1490 }
1491 }
1492}
1493
1494open_enum! {
1495 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1496 pub enum ModifyVtl2SettingsStatus : u32 {
1497 SUCCESS = 0,
1498 FAILURE = 1,
1499 }
1500}
1501
1502#[repr(C)]
1503#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1504pub struct ModifyVtl2SettingsNotification {
1505 pub message_header: HeaderGuestNotification,
1506
1507 pub size: u32,
1508 }
1510
1511const_assert_eq!(8, size_of::<ModifyVtl2SettingsNotification>());
1512
1513#[repr(C)]
1514#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1515pub struct ModifyVtl2SettingsRev1Notification {
1516 pub message_header: HeaderGuestNotification,
1517
1518 pub size: u32,
1519
1520 pub payload_state: LargePayloadState,
1521 }
1523
1524const_assert_eq!(12, size_of::<ModifyVtl2SettingsRev1Notification>());
1525
1526#[repr(C, packed)]
1527#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1528pub struct ModifyVtl2SettingsCompleteNotification {
1529 pub message_header: HeaderHostNotification,
1530 pub modify_status: ModifyVtl2SettingsStatus,
1531 pub result_document_size: u32,
1532}
1533
1534const_assert_eq!(12, size_of::<ModifyVtl2SettingsCompleteNotification>());
1535
1536impl ModifyVtl2SettingsCompleteNotification {
1537 pub fn new(status: ModifyVtl2SettingsStatus, result_document_size: u32) -> Self {
1538 Self {
1539 message_header: HeaderGeneric::new(HostNotifications::MODIFY_VTL2_SETTINGS_COMPLETED),
1540 modify_status: status,
1541 result_document_size,
1542 }
1543 }
1544}
1545
1546pub const GET_LOG_INTERFACE_GUID: Guid = guid::guid!("AA5DE534-D149-487A-9053-05972BA20A7C");
1547
1548open_enum! {
1549 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1550 pub enum LogType: u8 {
1551 EVENT = 0,
1552 SPAN_ENTER = 1,
1553 SPAN_EXIT = 2,
1554 }
1555}
1556
1557#[bitfield(u16)]
1558#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1559pub struct LogFlags {
1560 pub kmsg: bool,
1561 #[bits(15)]
1562 pub mbz0: u16,
1563}
1564
1565pub const TRACE_LOGGING_NAME_MAX_SIZE: usize = 128;
1566pub const TRACE_LOGGING_TARGET_MAX_SIZE: usize = 128;
1567pub const TRACE_LOGGING_FIELDS_MAX_SIZE: usize = 256;
1568pub const TRACE_LOGGING_MESSAGE_MAX_SIZE: usize = 4096;
1569pub const TRACE_LOGGING_NOTIFICATION_MAX_SIZE: usize = TRACE_LOGGING_NAME_MAX_SIZE
1570 + TRACE_LOGGING_TARGET_MAX_SIZE
1571 + TRACE_LOGGING_FIELDS_MAX_SIZE
1572 + TRACE_LOGGING_MESSAGE_MAX_SIZE
1573 + size_of::<TraceLoggingNotificationHeader>();
1574
1575#[repr(C)]
1576#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1577pub struct TraceLoggingBufferOffset {
1578 pub size: u16,
1579 pub offset: u16,
1580}
1581
1582#[repr(C)]
1588#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1589pub struct TraceLoggingNotificationHeader {
1590 pub log_type: LogType,
1591 pub level: u8,
1592 pub flags: LogFlags,
1593 pub name: TraceLoggingBufferOffset,
1594 pub target: TraceLoggingBufferOffset,
1595 pub fields: TraceLoggingBufferOffset,
1596 pub message: TraceLoggingBufferOffset,
1597 pub mbz0: u32,
1598 pub activity_id: Guid,
1599 pub related_activity_id: Guid,
1600 pub correlation_id: Guid,
1601 pub timestamp: u64,
1602}
1603const_assert_eq!(80, size_of::<TraceLoggingNotificationHeader>());
1604
1605#[repr(C, packed)]
1607#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1608pub struct MapFramebufferRequest {
1609 pub message_header: HeaderHostRequest,
1610 pub gpa: u64,
1611}
1612
1613const_assert_eq!(12, size_of::<MapFramebufferRequest>());
1614
1615impl MapFramebufferRequest {
1616 pub fn new(gpa: u64) -> Self {
1617 Self {
1618 message_header: HeaderGeneric::new(HostRequests::MAP_FRAMEBUFFER),
1619 gpa,
1620 }
1621 }
1622}
1623
1624open_enum! {
1625 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1626 pub enum MapFramebufferStatus : u32 {
1627 SUCCESS = 0,
1628 FAILURE = 1,
1629 }
1630}
1631
1632#[repr(C, packed)]
1634#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1635pub struct MapFramebufferResponse {
1636 pub message_header: HeaderHostResponse,
1637 pub status: MapFramebufferStatus,
1638}
1639
1640const_assert_eq!(8, size_of::<MapFramebufferResponse>());
1641
1642impl MapFramebufferResponse {
1643 pub fn new(status: MapFramebufferStatus) -> Self {
1644 Self {
1645 message_header: HeaderGeneric::new(HostRequests::MAP_FRAMEBUFFER),
1646 status,
1647 }
1648 }
1649}
1650
1651#[repr(C, packed)]
1653#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1654pub struct UnmapFramebufferRequest {
1655 pub message_header: HeaderHostRequest,
1656}
1657
1658const_assert_eq!(4, size_of::<UnmapFramebufferRequest>());
1659
1660impl UnmapFramebufferRequest {
1661 pub fn new() -> Self {
1662 Self {
1663 message_header: HeaderGeneric::new(HostRequests::UNMAP_FRAMEBUFFER),
1664 }
1665 }
1666}
1667
1668open_enum! {
1669 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1670 pub enum UnmapFramebufferStatus : u32 {
1671 SUCCESS = 0,
1672 FAILURE = 1,
1673 }
1674}
1675
1676#[repr(C, packed)]
1678#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1679pub struct UnmapFramebufferResponse {
1680 pub message_header: HeaderHostResponse,
1681 pub status: UnmapFramebufferStatus,
1682}
1683
1684const_assert_eq!(8, size_of::<UnmapFramebufferResponse>());
1685
1686impl UnmapFramebufferResponse {
1687 pub fn new(status: UnmapFramebufferStatus) -> Self {
1688 Self {
1689 message_header: HeaderGeneric::new(HostRequests::UNMAP_FRAMEBUFFER),
1690 status,
1691 }
1692 }
1693}
1694
1695open_enum! {
1696 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1697 pub enum StartVtl0Status : u32 {
1698 SUCCESS = 0,
1699 FAILURE = 1,
1700 }
1701}
1702
1703#[repr(C, packed)]
1704#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1705pub struct StartVtl0CompleteNotification {
1706 pub message_header: HeaderHostNotification,
1707 pub status: StartVtl0Status,
1708 pub result_document_size: u32,
1709 }
1712
1713const_assert_eq!(12, size_of::<StartVtl0CompleteNotification>());
1714
1715impl StartVtl0CompleteNotification {
1716 pub fn new(status: StartVtl0Status, result_document_size: u32) -> Self {
1717 Self {
1718 message_header: HeaderGeneric::new(HostNotifications::START_VTL0_COMPLETED),
1719 status,
1720 result_document_size,
1721 }
1722 }
1723}
1724
1725#[repr(C)]
1726#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1727pub struct BatteryStatusNotification {
1728 pub message_header: HeaderGuestNotification,
1729 pub flags: BatteryStatusFlags,
1730 pub max_capacity: u32,
1731 pub remaining_capacity: u32,
1732 pub rate: u32,
1733}
1734
1735#[bitfield(u32)]
1736#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1737pub struct BatteryStatusFlags {
1738 pub ac_online: bool,
1739 pub battery_present: bool,
1740 pub charging: bool,
1741 pub discharging: bool,
1742 #[bits(28)]
1743 pub reserved: u32,
1744}
1745
1746impl BatteryStatusNotification {
1747 pub fn new(
1748 flags: BatteryStatusFlags,
1749 max_capacity: u32,
1750 remaining_capacity: u32,
1751 rate: u32,
1752 ) -> Self {
1753 Self {
1754 message_header: HeaderGeneric::new(GuestNotifications::BATTERY_STATUS),
1755 flags,
1756 max_capacity,
1757 remaining_capacity,
1758 rate,
1759 }
1760 }
1761}
1762
1763#[repr(C)]
1764#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1765pub struct InjectDebugInterruptNotification {
1766 pub message_header: HeaderGuestNotification,
1767 pub vtl: u8,
1768 pub _pad: u8,
1769}
1770
1771const_assert_eq!(6, size_of::<InjectDebugInterruptNotification>());
1772
1773#[bitfield(u64)]
1774#[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1775pub struct CreateRamGpaRangeFlags {
1776 _reserved1: bool,
1777
1778 pub rom_mb: bool,
1780
1781 #[bits(62)]
1782 _reserved: u64,
1783}
1784
1785#[repr(C, packed)]
1786#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1787pub struct CreateRamGpaRangeRequest {
1788 pub message_header: HeaderHostRequest,
1789 pub slot: u32,
1790 pub gpa_start: u64,
1791 pub gpa_count: u64,
1792 pub gpa_offset: u64,
1793 pub flags: CreateRamGpaRangeFlags,
1794}
1795
1796const_assert_eq!(40, size_of::<CreateRamGpaRangeRequest>());
1797
1798impl CreateRamGpaRangeRequest {
1799 pub fn new(
1800 slot: u32,
1801 gpa_start: u64,
1802 gpa_count: u64,
1803 gpa_offset: u64,
1804 flags: CreateRamGpaRangeFlags,
1805 ) -> Self {
1806 Self {
1807 message_header: HeaderGeneric::new(HostRequests::CREATE_RAM_GPA_RANGE),
1808 slot,
1809 gpa_start,
1810 gpa_count,
1811 gpa_offset,
1812 flags,
1813 }
1814 }
1815}
1816
1817open_enum! {
1818 #[derive(IntoBytes, FromBytes, Immutable, KnownLayout)]
1819 pub enum CreateRamGpaRangeStatus : u32 {
1820 SUCCESS = 0,
1821 SLOT_OUT_OF_BOUNDS = 1,
1823 SLOT_OCCUPIED = 2,
1825 INVALID_FLAG = 3,
1827 INVALID_GPA = 4,
1829 FAILED = 5,
1831 }
1832}
1833
1834#[repr(C)]
1835#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1836pub struct CreateRamGpaRangeResponse {
1837 pub message_header: HeaderHostResponse,
1838 pub status: CreateRamGpaRangeStatus,
1839}
1840
1841const_assert_eq!(8, size_of::<CreateRamGpaRangeResponse>());
1842
1843impl CreateRamGpaRangeResponse {
1844 pub fn new(status: CreateRamGpaRangeStatus) -> Self {
1845 Self {
1846 message_header: HeaderGeneric::new(HostRequests::CREATE_RAM_GPA_RANGE),
1847 status,
1848 }
1849 }
1850}
1851
1852#[repr(C)]
1853#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1854pub struct ResetRamGpaRangeRequest {
1855 pub message_header: HeaderHostRequest,
1856 pub slot: u32,
1857}
1858
1859const_assert_eq!(8, size_of::<ResetRamGpaRangeRequest>());
1860
1861impl ResetRamGpaRangeRequest {
1862 pub fn new(slot: u32) -> Self {
1863 Self {
1864 message_header: HeaderGeneric::new(HostRequests::RESET_RAM_GPA_RANGE),
1865 slot,
1866 }
1867 }
1868}
1869
1870#[repr(C)]
1871#[derive(Copy, Clone, Debug, IntoBytes, FromBytes, Immutable, KnownLayout)]
1872pub struct ResetRamGpaRangeResponse {
1873 pub message_header: HeaderHostResponse,
1874}
1875
1876const_assert_eq!(4, size_of::<ResetRamGpaRangeResponse>());
1877
1878impl ResetRamGpaRangeResponse {
1879 pub fn new() -> Self {
1880 Self {
1881 message_header: HeaderGeneric::new(HostRequests::RESET_RAM_GPA_RANGE),
1882 }
1883 }
1884}
1885
1886pub mod test_utilities {
1887 pub const TEST_VMGS_SECTOR_SIZE: u32 = 512;
1889 pub const TEST_VMGS_CAPACITY: usize = 4194816; }