MCPcopy Index your code
hub / github.com/cloud-hypervisor/cloud-hypervisor / update

Method update

pci/src/msi.rs:117–175  ·  view source on GitHub ↗
(&mut self, offset: u64, data: &[u8])

Source from the content-addressed store, hash-verified

115 }
116
117 fn update(&mut self, offset: u64, data: &[u8]) {
118 // Calculate message data offset depending on the address being 32 or
119 // 64 bits.
120 // Calculate upper address offset if the address is 64 bits.
121 // Calculate mask bits offset based on the address being 32 or 64 bits
122 // and based on the per vector masking being enabled or not.
123 let (msg_data_offset, addr_hi_offset, mask_bits_offset): (u64, Option<u64>, Option<u64>) =
124 if self.addr_64_bits() {
125 let mask_bits = if self.per_vector_mask() {
126 Some(0x10)
127 } else {
128 None
129 };
130 (0xc, Some(0x8), mask_bits)
131 } else {
132 let mask_bits = if self.per_vector_mask() {
133 Some(0xc)
134 } else {
135 None
136 };
137 (0x8, None, mask_bits)
138 };
139
140 // Update cache without overriding the read-only bits.
141 match data.len() {
142 2 => {
143 let value = LittleEndian::read_u16(data);
144 match offset {
145 MSI_MSG_CTL_OFFSET => {
146 self.msg_ctl = (self.msg_ctl
147 & !(MSI_CTL_ENABLE | MSI_CTL_MULTI_MSG_ENABLE))
148 | (value & (MSI_CTL_ENABLE | MSI_CTL_MULTI_MSG_ENABLE));
149 }
150 x if x == msg_data_offset => self.msg_data = value,
151 _ => error!("invalid offset"),
152 }
153 }
154 4 => {
155 let value = LittleEndian::read_u32(data);
156 match offset {
157 0x0 => {
158 self.msg_ctl = (self.msg_ctl
159 & !(MSI_CTL_ENABLE | MSI_CTL_MULTI_MSG_ENABLE))
160 | ((value >> 16) as u16 & (MSI_CTL_ENABLE | MSI_CTL_MULTI_MSG_ENABLE));
161 }
162 MSI_MSG_ADDR_LO_OFFSET => self.msg_addr_lo = value & MSI_MSG_ADDR_LO_MASK,
163 x if x == msg_data_offset => self.msg_data = value as u16,
164 x if addr_hi_offset.is_some() && x == addr_hi_offset.unwrap() => {
165 self.msg_addr_hi = value;
166 }
167 x if mask_bits_offset.is_some() && x == mask_bits_offset.unwrap() => {
168 self.mask_bits = value;
169 }
170 _ => error!("invalid offset"),
171 }
172 }
173 _ => error!("invalid data length"),
174 }

Callers 4

newMethod · 0.45
set_msg_ctlMethod · 0.45
write_tableMethod · 0.45
newMethod · 0.45

Calls 8

addr_64_bitsMethod · 0.80
per_vector_maskMethod · 0.80
num_enabled_vectorsMethod · 0.80
vector_maskedMethod · 0.80
lenMethod · 0.45
enabledMethod · 0.45
enableMethod · 0.45
disableMethod · 0.45

Tested by

no test coverage detected