1 // Copyright 2022 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #![cfg_attr(windows, allow(dead_code))] 6 7 use base::error; 8 use base::AsRawDescriptor; 9 use base::Event; 10 use base::RawDescriptor; 11 use base::Tube; 12 use bit_field::*; 13 use vm_control::VmIrqRequest; 14 use vm_control::VmIrqResponse; 15 use zerocopy::AsBytes; 16 use zerocopy::FromBytes; 17 18 use crate::pci::PciCapability; 19 use crate::pci::PciCapabilityID; 20 // MSI registers 21 pub const PCI_MSI_NEXT_POINTER: u32 = 0x1; // Next cap pointer 22 pub const PCI_MSI_FLAGS: u32 = 0x2; // Message Control 23 const PCI_MSI_FLAGS_ENABLE: u16 = 0x0001; // MSI feature enabled 24 pub const PCI_MSI_FLAGS_64BIT: u16 = 0x0080; // 64-bit addresses allowed 25 pub const PCI_MSI_FLAGS_MASKBIT: u16 = 0x0100; // Per-vector masking capable 26 const PCI_MSI_ADDRESS_LO: u32 = 0x4; // MSI address lower 32 bits 27 const PCI_MSI_ADDRESS_HI: u32 = 0x8; // MSI address upper 32 bits (if 64 bit allowed) 28 const PCI_MSI_DATA_32: u32 = 0x8; // 16 bits of data for 32-bit message address 29 const PCI_MSI_DATA_64: u32 = 0xC; // 16 bits of date for 64-bit message address 30 31 // MSI length 32 const MSI_LENGTH_32BIT_WITHOUT_MASK: u32 = 0xA; 33 const MSI_LENGTH_32BIT_WITH_MASK: u32 = 0x14; 34 const MSI_LENGTH_64BIT_WITHOUT_MASK: u32 = 0xE; 35 const MSI_LENGTH_64BIT_WITH_MASK: u32 = 0x18; 36 37 pub enum MsiStatus { 38 Enabled, 39 Disabled, 40 NothingToDo, 41 } 42 43 /// Wrapper over MSI Capability Structure 44 pub struct MsiConfig { 45 is_64bit: bool, 46 mask_cap: bool, 47 ctrl: u16, 48 address: u64, 49 data: u16, 50 vm_socket_irq: Tube, 51 irqfd: Option<Event>, 52 gsi: Option<u32>, 53 device_id: u32, 54 device_name: String, 55 } 56 57 impl MsiConfig { new( is_64bit: bool, mask_cap: bool, vm_socket_irq: Tube, device_id: u32, device_name: String, ) -> Self58 pub fn new( 59 is_64bit: bool, 60 mask_cap: bool, 61 vm_socket_irq: Tube, 62 device_id: u32, 63 device_name: String, 64 ) -> Self { 65 let mut ctrl: u16 = 0; 66 if is_64bit { 67 ctrl |= PCI_MSI_FLAGS_64BIT; 68 } 69 if mask_cap { 70 ctrl |= PCI_MSI_FLAGS_MASKBIT; 71 } 72 MsiConfig { 73 is_64bit, 74 mask_cap, 75 ctrl, 76 address: 0, 77 data: 0, 78 vm_socket_irq, 79 irqfd: None, 80 gsi: None, 81 device_id, 82 device_name, 83 } 84 } 85 is_msi_reg(&self, offset: u32, index: u64, len: usize) -> bool86 pub fn is_msi_reg(&self, offset: u32, index: u64, len: usize) -> bool { 87 let msi_len = match (self.is_64bit, self.mask_cap) { 88 (true, true) => MSI_LENGTH_64BIT_WITH_MASK, 89 (true, false) => MSI_LENGTH_64BIT_WITHOUT_MASK, 90 (false, true) => MSI_LENGTH_32BIT_WITH_MASK, 91 (false, false) => MSI_LENGTH_32BIT_WITHOUT_MASK, 92 }; 93 94 index >= offset as u64 95 && index + len as u64 <= (offset + msi_len) as u64 96 && len as u32 <= msi_len 97 } 98 read_msi_capability(&self, offset: u32, data: u32) -> u3299 pub fn read_msi_capability(&self, offset: u32, data: u32) -> u32 { 100 if offset == 0 { 101 (self.ctrl as u32) << 16 | (data & u16::max_value() as u32) 102 } else { 103 data 104 } 105 } 106 write_msi_capability(&mut self, offset: u32, data: &[u8]) -> MsiStatus107 pub fn write_msi_capability(&mut self, offset: u32, data: &[u8]) -> MsiStatus { 108 let len = data.len(); 109 let mut ret = MsiStatus::NothingToDo; 110 let old_address = self.address; 111 let old_data = self.data; 112 113 // write msi ctl 114 if len == 2 && offset == PCI_MSI_FLAGS { 115 let was_enabled = self.is_msi_enabled(); 116 let value: [u8; 2] = [data[0], data[1]]; 117 self.ctrl = u16::from_le_bytes(value); 118 let is_enabled = self.is_msi_enabled(); 119 if !was_enabled && is_enabled { 120 self.enable(); 121 ret = MsiStatus::Enabled; 122 } else if was_enabled && !is_enabled { 123 ret = MsiStatus::Disabled; 124 } 125 } else if len == 4 && offset == PCI_MSI_ADDRESS_LO && !self.is_64bit { 126 //write 32 bit message address 127 let value: [u8; 8] = [data[0], data[1], data[2], data[3], 0, 0, 0, 0]; 128 self.address = u64::from_le_bytes(value); 129 } else if len == 4 && offset == PCI_MSI_ADDRESS_LO && self.is_64bit { 130 // write 64 bit message address low part 131 let value: [u8; 8] = [data[0], data[1], data[2], data[3], 0, 0, 0, 0]; 132 self.address &= !0xffffffff; 133 self.address |= u64::from_le_bytes(value); 134 } else if len == 4 && offset == PCI_MSI_ADDRESS_HI && self.is_64bit { 135 //write 64 bit message address high part 136 let value: [u8; 8] = [0, 0, 0, 0, data[0], data[1], data[2], data[3]]; 137 self.address &= 0xffffffff; 138 self.address |= u64::from_le_bytes(value); 139 } else if len == 8 && offset == PCI_MSI_ADDRESS_LO && self.is_64bit { 140 // write 64 bit message address 141 let value: [u8; 8] = [ 142 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], 143 ]; 144 self.address = u64::from_le_bytes(value); 145 } else if len == 2 146 && ((offset == PCI_MSI_DATA_32 && !self.is_64bit) 147 || (offset == PCI_MSI_DATA_64 && self.is_64bit)) 148 { 149 // write message data 150 let value: [u8; 2] = [data[0], data[1]]; 151 self.data = u16::from_le_bytes(value); 152 } 153 154 if self.is_msi_enabled() && (old_address != self.address || old_data != self.data) { 155 self.add_msi_route(); 156 } 157 158 ret 159 } 160 is_msi_enabled(&self) -> bool161 pub fn is_msi_enabled(&self) -> bool { 162 self.ctrl & PCI_MSI_FLAGS_ENABLE == PCI_MSI_FLAGS_ENABLE 163 } 164 add_msi_route(&self)165 fn add_msi_route(&self) { 166 let gsi = match self.gsi { 167 Some(g) => g, 168 None => { 169 error!("Add msi route but gsi is none"); 170 return; 171 } 172 }; 173 if let Err(e) = self.vm_socket_irq.send(&VmIrqRequest::AddMsiRoute { 174 gsi, 175 msi_address: self.address, 176 msi_data: self.data.into(), 177 }) { 178 error!("failed to send AddMsiRoute request at {:?}", e); 179 return; 180 } 181 match self.vm_socket_irq.recv() { 182 Ok(VmIrqResponse::Err(e)) => error!("failed to call AddMsiRoute request {:?}", e), 183 Ok(_) => {} 184 Err(e) => error!("failed to receive AddMsiRoute response {:?}", e), 185 } 186 } 187 allocate_one_msi(&mut self)188 fn allocate_one_msi(&mut self) { 189 let irqfd = match self.irqfd.take() { 190 Some(e) => e, 191 None => match Event::new() { 192 Ok(e) => e, 193 Err(e) => { 194 error!("failed to create event: {:?}", e); 195 return; 196 } 197 }, 198 }; 199 200 let request = VmIrqRequest::AllocateOneMsi { 201 irqfd, 202 device_id: self.device_id, 203 queue_id: 0, 204 device_name: self.device_name.clone(), 205 }; 206 let request_result = self.vm_socket_irq.send(&request); 207 208 // Stash the irqfd in self immediately because we used take above. 209 self.irqfd = match request { 210 VmIrqRequest::AllocateOneMsi { irqfd, .. } => Some(irqfd), 211 _ => unreachable!(), 212 }; 213 214 if let Err(e) = request_result { 215 error!("failed to send AllocateOneMsi request: {:?}", e); 216 return; 217 } 218 219 match self.vm_socket_irq.recv() { 220 Ok(VmIrqResponse::AllocateOneMsi { gsi }) => self.gsi = Some(gsi), 221 _ => error!("failed to receive AllocateOneMsi Response"), 222 } 223 } 224 enable(&mut self)225 fn enable(&mut self) { 226 if self.gsi.is_none() || self.irqfd.is_none() { 227 self.allocate_one_msi(); 228 } 229 230 self.add_msi_route(); 231 } 232 get_irqfd(&self) -> Option<&Event>233 pub fn get_irqfd(&self) -> Option<&Event> { 234 self.irqfd.as_ref() 235 } 236 destroy(&mut self)237 pub fn destroy(&mut self) { 238 if let Some(gsi) = self.gsi { 239 if let Some(irqfd) = self.irqfd.take() { 240 let request = VmIrqRequest::ReleaseOneIrq { gsi, irqfd }; 241 if self.vm_socket_irq.send(&request).is_ok() { 242 let _ = self.vm_socket_irq.recv::<VmIrqResponse>(); 243 } 244 } 245 } 246 } 247 248 /// Return the raw descriptor of the MSI device socket get_msi_socket(&self) -> RawDescriptor249 pub fn get_msi_socket(&self) -> RawDescriptor { 250 self.vm_socket_irq.as_raw_descriptor() 251 } 252 trigger(&self)253 pub fn trigger(&self) { 254 if let Some(irqfd) = self.irqfd.as_ref() { 255 irqfd.signal().unwrap(); 256 } 257 } 258 } 259 260 #[bitfield] 261 #[derive(Copy, Clone, AsBytes, FromBytes)] 262 pub struct MsiCtrl { 263 enable: B1, 264 multi_msg_capable: B3, 265 multi_msg_enable: B3, 266 is_64bit: B1, 267 per_vector_masking: B1, 268 extended_msg_data_capable: B1, 269 extended_msg_data_enable: B1, 270 reserved: B5, 271 } 272 273 #[allow(dead_code)] 274 #[repr(C, align(4))] 275 #[derive(Clone, Copy, Default, AsBytes, FromBytes)] 276 struct Msi32BitWithoutMask { 277 msg_data: u16, 278 msg_extended_data: u16, 279 _padding: [u8; 12], 280 } 281 282 #[allow(dead_code)] 283 #[repr(C, align(4))] 284 #[derive(Clone, Copy, Default, AsBytes, FromBytes)] 285 struct Msi32BitWithMask { 286 msg_data: u16, 287 msg_extended_data: u16, 288 mask_bits: u32, 289 pending_bits: u32, 290 _padding: [u8; 4], 291 } 292 293 #[allow(dead_code)] 294 #[repr(C, align(4))] 295 #[derive(Clone, Copy, Default, AsBytes, FromBytes)] 296 struct Msi64BitWithoutMask { 297 msg_upper: u32, 298 msg_data: u16, 299 msg_extended_data: u16, 300 _padding: [u8; 8], 301 } 302 303 #[allow(dead_code)] 304 #[repr(C)] 305 #[derive(Clone, Copy, Default, AsBytes, FromBytes)] 306 struct Msi64BitWithMask { 307 msg_upper: u32, 308 msg_data: u16, 309 msg_extended_data: u16, 310 mask_bits: u32, 311 pending_bits: u32, 312 } 313 314 #[allow(dead_code)] 315 #[repr(C)] 316 #[derive(Clone, Copy, AsBytes, FromBytes)] 317 union MsiVary { 318 msi_32bit_without_mask: Msi32BitWithoutMask, 319 msi_32bit_with_mask: Msi32BitWithMask, 320 msi_64bit_without_mask: Msi64BitWithoutMask, 321 msi_64bit_with_mask: Msi64BitWithMask, 322 } 323 324 #[allow(dead_code)] 325 #[repr(C)] 326 #[derive(Clone, Copy, AsBytes, FromBytes)] 327 /// MSI Capability Structure 328 pub struct MsiCap { 329 // To make add_capability() happy 330 _cap_vndr: u8, 331 _cap_next: u8, 332 // Message Control Register 333 msg_ctl: MsiCtrl, 334 // Message Address 335 msg_addr: u32, 336 // Msi Vary structure 337 msi_vary: MsiVary, 338 } 339 340 impl PciCapability for MsiCap { bytes(&self) -> &[u8]341 fn bytes(&self) -> &[u8] { 342 self.as_bytes() 343 } 344 id(&self) -> PciCapabilityID345 fn id(&self) -> PciCapabilityID { 346 PciCapabilityID::MessageSignalledInterrupts 347 } 348 writable_bits(&self) -> Vec<u32>349 fn writable_bits(&self) -> Vec<u32> { 350 // Check spec for detail 351 match ( 352 self.msg_ctl.get_is_64bit(), 353 self.msg_ctl.get_per_vector_masking(), 354 ) { 355 (0, 0) => vec![0x0471_0000, 0xffff_fffc, 0xffff_ffff], 356 (0, 1) => vec![0x0471_0000, 0xffff_fffc, 0xffff_ffff, 0xffff_ffff], 357 (1, 0) => vec![ 358 0x0471_0000, 359 0xffff_fffc, 360 0xffff_ffff, 361 0xffff_ffff, 362 0x0000_0000, 363 ], 364 (1, 1) => vec![ 365 0x0471_0000, 366 0xffff_fffc, 367 0xffff_ffff, 368 0xffff_ffff, 369 0xffff_ffff, 370 0x0000_0000, 371 ], 372 (_, _) => Vec::new(), 373 } 374 } 375 } 376 377 impl MsiCap { new(is_64bit: bool, mask_cap: bool) -> Self378 pub fn new(is_64bit: bool, mask_cap: bool) -> Self { 379 let mut msg_ctl = MsiCtrl::new(); 380 if is_64bit { 381 msg_ctl.set_is_64bit(1); 382 } 383 if mask_cap { 384 msg_ctl.set_per_vector_masking(1); 385 } 386 let msi_vary = match (is_64bit, mask_cap) { 387 (false, false) => MsiVary { 388 msi_32bit_without_mask: Msi32BitWithoutMask::default(), 389 }, 390 (false, true) => MsiVary { 391 msi_32bit_with_mask: Msi32BitWithMask::default(), 392 }, 393 (true, false) => MsiVary { 394 msi_64bit_without_mask: Msi64BitWithoutMask::default(), 395 }, 396 (true, true) => MsiVary { 397 msi_64bit_with_mask: Msi64BitWithMask::default(), 398 }, 399 }; 400 MsiCap { 401 _cap_vndr: 0, 402 _cap_next: 0, 403 msg_ctl, 404 msg_addr: 0, 405 msi_vary, 406 } 407 } 408 } 409