hyperv_ic_protocol/
timesync.rs1use crate::Version;
7use bitfield_struct::bitfield;
8use zerocopy::FromBytes;
9use zerocopy::Immutable;
10use zerocopy::IntoBytes;
11use zerocopy::KnownLayout;
12use zerocopy::little_endian::U64 as U64LE;
13
14pub const INTERFACE_ID: guid::Guid = guid::guid!("9527e630-d0ae-497b-adce-e80ab0175caf");
16pub const INSTANCE_ID: guid::Guid = guid::guid!("2dd1ce17-079e-403c-b352-a1921ee207ee");
18
19pub const TIMESYNC_VERSION_1: Version = Version::new(1, 0);
21pub const TIMESYNC_VERSION_3: Version = Version::new(3, 0);
23pub const TIMESYNC_VERSION_4: Version = Version::new(4, 0);
25
26pub const EPOCH: jiff::Timestamp = jiff::Timestamp::constant(-11644473600, 0);
29
30#[repr(C)]
32#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
33pub struct TimesyncMessage {
34 pub parent_time: U64LE,
37 pub child_time: U64LE,
39 pub round_trip_time: U64LE,
41 pub flags: TimesyncFlags,
43 pub reserved: [u8; 3],
45}
46
47#[repr(C)]
49#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
50pub struct TimesyncMessageV4 {
51 pub parent_time: U64LE,
54 pub vm_reference_time: u64,
57 pub flags: TimesyncFlags,
59 pub leap_indicator: u8,
61 pub stratum: u8,
63 pub reserved: [u8; 5],
65}
66
67#[bitfield(u8)]
69#[derive(IntoBytes, Immutable, KnownLayout, FromBytes)]
70pub struct TimesyncFlags {
71 pub sync: bool,
73 pub sample: bool,
75 #[bits(6)]
76 _rsvd: u8,
77}
78
79#[cfg(test)]
80mod tests {
81 #[test]
82 fn verify_epoch() {
83 let epoch = jiff::civil::date(1601, 1, 1)
84 .at(0, 0, 0, 0)
85 .to_zoned(jiff::tz::TimeZone::UTC)
86 .unwrap()
87 .timestamp();
88
89 assert_eq!(
90 epoch,
91 super::EPOCH,
92 "{} {}",
93 epoch.as_second(),
94 epoch.subsec_nanosecond()
95 );
96 }
97}