x86defs/msi.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! x86 definitions of non-translated MSI address and data.
5
6use crate::apic::APIC_BASE_ADDRESS;
7use bitfield_struct::bitfield;
8
9/// The layout of the MSI address element.
10#[bitfield(u32)]
11pub struct MsiAddress {
12 #[bits(2)]
13 _reserved: u32,
14 pub destination_mode_logical: bool,
15 pub redirection_hint: bool,
16 pub extended_destination: u8,
17 pub destination: u8,
18 #[bits(12)]
19 pub address: u16,
20}
21
22/// The expected value for MsiAddress::address.
23pub const MSI_ADDRESS: u16 = (APIC_BASE_ADDRESS >> 20) as u16;
24
25impl MsiAddress {
26 /// Returns a 15-bit destination encoded in the MSI address. This is not
27 /// architectural--normally only an 8-bit destination is supported unless
28 /// interrupt redirection is enabled--but this is supported by some
29 /// virtualization platforms (including Hyper-V and KVM).
30 ///
31 /// The high 7 bits are encoded as the high 7 bits of the extended
32 /// destination field. The low bit of that field is ignored and presumed to
33 /// be zero in this configuration.
34 pub fn virt_destination(&self) -> u16 {
35 self.destination() as u16 | ((self.extended_destination() as u16 & !1) << 7)
36 }
37
38 /// Returns a value with a 15-bit destination encoded as guests expect when
39 /// running with Hyper-V or KVM virtualization extensions.
40 ///
41 /// This updates the destination and extended destination fields.
42 pub fn with_virt_destination(self, destination: u16) -> Self {
43 self.with_destination(destination as u8)
44 .with_extended_destination((destination >> 7) as u8 & !1)
45 }
46
47 /// Updates the value with a 15-bit destination encoded as guests expect
48 /// when running with Hyper-V or KVM virtualization extensions.
49 ///
50 /// This updates the destination and extended destination fields.
51 pub fn set_virt_destination(&mut self, destination: u16) {
52 *self = self.with_virt_destination(destination);
53 }
54}
55
56/// The layout of the MSI data element.
57///
58/// Note that the significant bits correspond to low bits of
59/// [`Icr`](super::apic::Icr).
60#[bitfield(u32)]
61pub struct MsiData {
62 pub vector: u8,
63 #[bits(3)]
64 pub delivery_mode: u8,
65 pub destination_mode_logical: bool,
66 #[bits(2)]
67 _reserved: u8,
68 pub assert: bool,
69 pub trigger_mode_level: bool,
70 _reserved: u16,
71}