1 #![allow(dead_code)] 2 3 use core::mem::size_of; 4 use core::ptr::NonNull; 5 6 use alloc::ffi::CString; 7 use alloc::vec::Vec; 8 9 use super::pci::{PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError}; 10 use crate::arch::msi::{ia64_pci_get_arch_msi_message_address, ia64_pci_get_arch_msi_message_data}; 11 use crate::arch::{PciArch, TraitPciArch}; 12 use crate::include::bindings::bindings::{ 13 c_irq_install, c_irq_uninstall, pt_regs, ul, EAGAIN, EINVAL, 14 }; 15 use crate::libs::volatile::{volread, volwrite, Volatile, VolatileReadable, VolatileWritable}; 16 17 /// MSIX表的一项 18 #[repr(C)] 19 struct MsixEntry { 20 vector_control: Volatile<u32>, 21 msg_data: Volatile<u32>, 22 msg_upper_addr: Volatile<u32>, 23 msg_addr: Volatile<u32>, 24 } 25 /// Pending表的一项 26 #[repr(C)] 27 struct PendingEntry { 28 entry: Volatile<u64>, 29 } 30 /// PCI设备中断错误 31 #[derive(Copy, Clone, Debug, Eq, PartialEq)] 32 pub enum PciIrqError { 33 IrqTypeNotSupported, 34 PciDeviceNotSupportIrq, 35 IrqTypeUnmatch, 36 InvalidIrqIndex(u16), 37 InvalidIrqNum(u16), 38 IrqNumOccupied(u16), 39 DeviceIrqOverflow, 40 MxiIrqNumWrong, 41 PciBarNotInited, 42 BarGetVaddrFailed, 43 MaskNotSupported, 44 IrqNotInited, 45 } 46 /// PCI设备的中断类型 47 #[derive(Copy, Clone, Debug)] 48 pub enum IrqType { 49 Msi { 50 address_64: bool, 51 maskable: bool, 52 irq_max_num: u16, 53 cap_offset: u8, 54 }, 55 Msix { 56 msix_table_bar: u8, 57 msix_table_offset: u32, 58 pending_table_bar: u8, 59 pending_table_offset: u32, 60 irq_max_num: u16, 61 cap_offset: u8, 62 }, 63 Legacy, 64 Unused, 65 } 66 // PCI设备install中断时需要传递的参数 67 #[derive(Clone, Debug)] 68 pub struct IrqMsg { 69 irq_common_message: IrqCommonMsg, 70 irq_specific_message: IrqSpecificMsg, 71 } 72 // PCI设备install中断时需要传递的共同参数 73 #[derive(Clone, Debug)] 74 pub struct IrqCommonMsg { 75 irq_index: u16, //要install的中断号在PCI设备中的irq_vector的index 76 irq_name: CString, //中断名字 77 irq_parameter: u16, //中断额外参数,可传入中断处理函数 78 irq_hander: unsafe extern "C" fn(irq_num: ul, parameter: ul, regs: *mut pt_regs), // 中断处理函数 79 irq_ack: Option<unsafe extern "C" fn(irq_num: ul)>, // 中断的ack,可为None,若为None则中断处理中会正常通知中断结束,不为None则调用传入的函数进行回复 80 } 81 // PCI设备install中断时需要传递的特有参数,Msi代表MSI与MSIX 82 #[derive(Clone, Debug)] 83 pub enum IrqSpecificMsg { 84 Legacy, 85 Msi { 86 processor: u16, 87 trigger_mode: TriggerMode, 88 }, 89 } 90 impl IrqSpecificMsg { 91 fn msi_default() -> Self { 92 IrqSpecificMsg::Msi { 93 processor: 0, 94 trigger_mode: TriggerMode::EdgeTrigger, 95 } 96 } 97 } 98 // 申请中断的触发模式,MSI默认为边沿触发 99 #[derive(Copy, Clone, Debug)] 100 pub enum TriggerMode { 101 EdgeTrigger, 102 AssertHigh, 103 AssertLow, 104 } 105 bitflags! { 106 /// 设备中断类型,使用bitflag使得中断类型的选择更多元化 107 pub struct IRQ: u8{ 108 const PCI_IRQ_LEGACY = 1 << 0; 109 const PCI_IRQ_MSI = 1 << 1; 110 const PCI_IRQ_MSIX = 1 << 2; 111 const PCI_IRQ_ALL_TYPES=IRQ::PCI_IRQ_LEGACY.bits|IRQ::PCI_IRQ_MSI.bits|IRQ::PCI_IRQ_MSIX.bits; 112 } 113 } 114 /// PciDeviceStructure的子trait,使用继承以直接使用PciDeviceStructure里的接口 115 pub trait PciInterrupt: PciDeviceStructure { 116 /// @brief PCI设备调用该函数选择中断类型 117 /// @param self PCI设备的可变引用 118 /// @param flag 选择的中断类型(支持多个选择),如PCI_IRQ_ALL_TYPES表示所有中断类型均可,让系统按顺序进行选择 119 /// @return Option<IrqType> 失败返回None,成功则返回对应中断类型 120 fn irq_init(&mut self, flag: IRQ) -> Option<IrqType> { 121 // MSIX中断优先 122 if flag.contains(IRQ::PCI_IRQ_MSIX) { 123 if let Some(cap_offset) = self.msix_capability_offset() { 124 let data = 125 PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 4); 126 let irq_max_num = ((data >> 16) & 0x07ff) as u16; 127 let data = 128 PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 4); 129 let msix_table_bar = (data & 0x01) as u8; 130 let msix_table_offset = data & 0xfffe; 131 let data = 132 PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 8); 133 let pending_table_bar = (data & 0x01) as u8; 134 let pending_table_offset = data & 0xfffe; 135 *self.irq_type_mut()? = IrqType::Msix { 136 msix_table_bar, 137 msix_table_offset, 138 pending_table_bar, 139 pending_table_offset, 140 irq_max_num, 141 cap_offset, 142 }; 143 return Some(IrqType::Msix { 144 msix_table_bar, 145 msix_table_offset, 146 pending_table_bar, 147 pending_table_offset, 148 irq_max_num, 149 cap_offset, 150 }); 151 } 152 } 153 // 其次MSI 154 if flag.contains(IRQ::PCI_IRQ_MSI) { 155 if let Some(cap_offset) = self.msi_capability_offset() { 156 let data = 157 PciArch::read_config(&self.common_header().bus_device_function, cap_offset); 158 let message_control = (data >> 16) as u16; 159 let maskable = (message_control & 0x0100) != 0; 160 let address_64 = (message_control & 0x0080) != 0; 161 let irq_max_num = (1 << (((message_control & 0x000e) >> 1) + 1)) as u16; 162 *self.irq_type_mut()? = IrqType::Msi { 163 address_64, 164 maskable, 165 irq_max_num, 166 cap_offset, 167 }; 168 return Some(IrqType::Msi { 169 address_64, 170 maskable, 171 irq_max_num, 172 cap_offset, 173 }); 174 } 175 } 176 // 最后选择legacy# 177 if flag.contains(IRQ::PCI_IRQ_LEGACY) { 178 *self.irq_type_mut()? = IrqType::Legacy; 179 return Some(IrqType::Legacy); 180 } 181 None 182 } 183 184 /// @brief 启动/关闭设备中断 185 /// @param self PCI设备的可变引用 186 /// @param enable 开启/关闭 187 fn irq_enable(&mut self, enable: bool) -> Result<u8, PciError> { 188 if let Some(irq_type) = self.irq_type_mut() { 189 match *irq_type { 190 IrqType::Msix { .. } => { 191 return self.msix_enable(enable); 192 } 193 IrqType::Msi { .. } => { 194 return self.msi_enable(enable); 195 } 196 IrqType::Legacy => { 197 return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported)); 198 } 199 IrqType::Unused => { 200 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 201 } 202 } 203 } 204 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 205 } 206 /// @brief 启动/关闭设备MSIX中断 207 /// @param self PCI设备的可变引用 208 /// @param enable 开启/关闭 209 fn msix_enable(&mut self, enable: bool) -> Result<u8, PciError> { 210 if let Some(irq_type) = self.irq_type_mut() { 211 match *irq_type { 212 IrqType::Msix { cap_offset, .. } => { 213 let mut message = 214 PciArch::read_config(&self.common_header().bus_device_function, cap_offset); 215 if enable { 216 message |= 1 << 31; 217 } else { 218 message &= !(1 << 31); 219 } 220 PciArch::write_config( 221 &self.common_header().bus_device_function, 222 cap_offset, 223 message, 224 ); 225 return Ok(0); 226 } 227 IrqType::Unused => { 228 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 229 } 230 _ => { 231 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 232 } 233 } 234 } 235 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 236 } 237 /// @brief 启动/关闭设备MSI中断 238 /// @param self PCI设备的可变引用 239 /// @param enable 开启/关闭 240 fn msi_enable(&mut self, enable: bool) -> Result<u8, PciError> { 241 if let Some(irq_type) = self.irq_type_mut() { 242 match *irq_type { 243 IrqType::Msi { cap_offset, .. } => { 244 let mut message = 245 PciArch::read_config(&self.common_header().bus_device_function, cap_offset); 246 if enable { 247 message |= 1 << 16; 248 } else { 249 message &= !(1 << 16); 250 } 251 PciArch::write_config( 252 &self.common_header().bus_device_function, 253 cap_offset, 254 message, 255 ); 256 return Ok(0); 257 } 258 IrqType::Unused => { 259 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 260 } 261 _ => { 262 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 263 } 264 } 265 } 266 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 267 } 268 /// @brief 获取指定数量的中断号 todo 需要中断重构支持 269 fn irq_alloc(_num: u16) -> Option<Vec<u16>> { 270 None 271 } 272 /// @brief 进行PCI设备中断的安装 273 /// @param self PCI设备的可变引用 274 /// @param msg PCI设备install中断时需要传递的共同参数 275 /// @return 一切正常返回Ok(0),有错误返回对应错误原因 276 fn irq_install(&mut self, msg: IrqMsg) -> Result<u8, PciError> { 277 if let Some(irq_vector) = self.irq_vector_mut() { 278 if msg.irq_common_message.irq_index as usize > irq_vector.len() { 279 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 280 msg.irq_common_message.irq_index, 281 ))); 282 } 283 } 284 self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断 285 if let Some(irq_type) = self.irq_type_mut() { 286 match *irq_type { 287 IrqType::Msix { .. } => { 288 return self.msix_install(msg); 289 } 290 IrqType::Msi { .. } => { 291 return self.msi_install(msg); 292 } 293 IrqType::Unused => { 294 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 295 } 296 _ => { 297 return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported)); 298 } 299 } 300 } 301 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 302 } 303 /// @brief 进行PCI设备中断的安装(MSI) 304 /// @param self PCI设备的可变引用 305 /// @param msg PCI设备install中断时需要传递的共同参数 306 /// @return 一切正常返回Ok(0),有错误返回对应错误原因 307 fn msi_install(&mut self, msg: IrqMsg) -> Result<u8, PciError> { 308 if let Some(irq_type) = self.irq_type_mut() { 309 match *irq_type { 310 IrqType::Msi { 311 address_64, 312 irq_max_num, 313 cap_offset, 314 .. 315 } => { 316 // 注意:MSI中断分配的中断号必须连续且大小为2的倍数 317 if self.irq_vector_mut().unwrap().len() > irq_max_num as usize { 318 return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow)); 319 } 320 let irq_num = 321 self.irq_vector_mut().unwrap()[msg.irq_common_message.irq_index as usize]; 322 let common_msg = &msg.irq_common_message; 323 let result = unsafe { 324 c_irq_install( 325 irq_num as u64, 326 Some(common_msg.irq_hander), 327 common_msg.irq_parameter as u64, 328 common_msg.irq_name.as_ptr(), 329 common_msg.irq_ack, 330 ) 331 }; 332 match result as u32 { 333 EINVAL => { 334 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqNum(irq_num))); 335 } 336 EAGAIN => { 337 return Err(PciError::PciIrqError(PciIrqError::IrqNumOccupied( 338 irq_num, 339 ))); 340 } 341 _ => {} 342 } 343 //MSI中断只需配置一次PCI寄存器 344 if common_msg.irq_index == 0 { 345 let msg_address = ia64_pci_get_arch_msi_message_address(0); 346 let trigger = match msg.irq_specific_message { 347 IrqSpecificMsg::Legacy => { 348 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 349 } 350 IrqSpecificMsg::Msi { trigger_mode, .. } => trigger_mode, 351 }; 352 let msg_data = ia64_pci_get_arch_msi_message_data(irq_num, 0, trigger); 353 //写入Message Data和Message Address 354 if address_64 { 355 PciArch::write_config( 356 &self.common_header().bus_device_function, 357 cap_offset + 4, 358 msg_address, 359 ); 360 PciArch::write_config( 361 &self.common_header().bus_device_function, 362 cap_offset + 8, 363 0, 364 ); 365 PciArch::write_config( 366 &self.common_header().bus_device_function, 367 cap_offset + 12, 368 msg_data, 369 ); 370 } else { 371 PciArch::write_config( 372 &self.common_header().bus_device_function, 373 cap_offset + 4, 374 msg_address, 375 ); 376 PciArch::write_config( 377 &self.common_header().bus_device_function, 378 cap_offset + 8, 379 msg_data, 380 ); 381 } 382 let data = PciArch::read_config( 383 &self.common_header().bus_device_function, 384 cap_offset, 385 ); 386 let message_control = (data >> 16) as u16; 387 match self.irq_vector_mut().unwrap().len() { 388 1 => { 389 let temp = message_control & (!0x0070); 390 PciArch::write_config( 391 &self.common_header().bus_device_function, 392 cap_offset, 393 (temp as u32) << 16, 394 ); 395 } 396 2 => { 397 let temp = message_control & (!0x0070); 398 PciArch::write_config( 399 &self.common_header().bus_device_function, 400 cap_offset, 401 ((temp | (0x0001 << 4)) as u32) << 16, 402 ); 403 } 404 4 => { 405 let temp = message_control & (!0x0070); 406 PciArch::write_config( 407 &self.common_header().bus_device_function, 408 cap_offset, 409 ((temp | (0x0002 << 4)) as u32) << 16, 410 ); 411 } 412 8 => { 413 let temp = message_control & (!0x0070); 414 PciArch::write_config( 415 &self.common_header().bus_device_function, 416 cap_offset, 417 ((temp | (0x0003 << 4)) as u32) << 16, 418 ); 419 } 420 16 => { 421 let temp = message_control & (!0x0070); 422 PciArch::write_config( 423 &self.common_header().bus_device_function, 424 cap_offset, 425 ((temp | (0x0004 << 4)) as u32) << 16, 426 ); 427 } 428 32 => { 429 let temp = message_control & (!0x0070); 430 PciArch::write_config( 431 &self.common_header().bus_device_function, 432 cap_offset, 433 ((temp | (0x0005 << 4)) as u32) << 16, 434 ); 435 } 436 _ => { 437 return Err(PciError::PciIrqError(PciIrqError::MxiIrqNumWrong)); 438 } 439 } 440 } 441 return Ok(0); 442 } 443 IrqType::Unused => { 444 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 445 } 446 _ => { 447 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 448 } 449 } 450 } 451 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 452 } 453 /// @brief 进行PCI设备中断的安装(MSIX) 454 /// @param self PCI设备的可变引用 455 /// @param msg PCI设备install中断时需要传递的共同参数 456 /// @return 一切正常返回Ok(0),有错误返回对应错误原因 457 fn msix_install(&mut self, msg: IrqMsg) -> Result<u8, PciError> { 458 if let Some(irq_type) = self.irq_type_mut() { 459 match *irq_type { 460 IrqType::Msix { 461 irq_max_num, 462 msix_table_bar, 463 msix_table_offset, 464 .. 465 } => { 466 if self.irq_vector_mut().unwrap().len() > irq_max_num as usize { 467 return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow)); 468 } 469 let irq_num = 470 self.irq_vector_mut().unwrap()[msg.irq_common_message.irq_index as usize]; 471 let common_msg = &msg.irq_common_message; 472 let result = unsafe { 473 c_irq_install( 474 irq_num as u64, 475 Some(common_msg.irq_hander), 476 common_msg.irq_parameter as u64, 477 common_msg.irq_name.as_ptr(), 478 common_msg.irq_ack, 479 ) 480 }; 481 match result as u32 { 482 EINVAL => { 483 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqNum(irq_num))); 484 } 485 EAGAIN => { 486 return Err(PciError::PciIrqError(PciIrqError::IrqNumOccupied( 487 irq_num, 488 ))); 489 } 490 _ => {} 491 } 492 493 let msg_address = ia64_pci_get_arch_msi_message_address(0); 494 let trigger = match msg.irq_specific_message { 495 IrqSpecificMsg::Legacy => { 496 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 497 } 498 IrqSpecificMsg::Msi { trigger_mode, .. } => trigger_mode, 499 }; 500 let msg_data = ia64_pci_get_arch_msi_message_data(irq_num, 0, trigger); 501 //写入Message Data和Message Address 502 let pcistandardbar = self 503 .bar() 504 .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))?; 505 let msix_bar = pcistandardbar.get_bar(msix_table_bar)?; 506 let vaddr = msix_bar 507 .virtual_address() 508 .ok_or(PciError::PciIrqError(PciIrqError::BarGetVaddrFailed))? 509 + msix_table_offset as usize 510 + msg.irq_common_message.irq_index as usize * size_of::<MsixEntry>(); 511 let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap(); 512 unsafe { 513 volwrite!(msix_entry, vector_control, 0); 514 volwrite!(msix_entry, msg_data, msg_data); 515 volwrite!(msix_entry, msg_upper_addr, 0); 516 volwrite!(msix_entry, msg_addr, msg_address); 517 } 518 return Ok(0); 519 } 520 IrqType::Unused => { 521 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 522 } 523 _ => { 524 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 525 } 526 } 527 } 528 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 529 } 530 /// @brief 进行PCI设备中断的卸载 531 /// @param self PCI设备的可变引用 532 fn irq_uninstall(&mut self) -> Result<u8, PciError> { 533 self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断 534 if let Some(irq_type) = self.irq_type_mut() { 535 match *irq_type { 536 IrqType::Msix { .. } => { 537 return self.msix_uninstall(); 538 } 539 IrqType::Msi { .. } => { 540 return self.msi_uninstall(); 541 } 542 IrqType::Unused => { 543 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 544 } 545 _ => { 546 return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported)); 547 } 548 } 549 } 550 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 551 } 552 /// @brief 进行PCI设备中断的卸载(MSI) 553 /// @param self PCI设备的可变引用 554 fn msi_uninstall(&mut self) -> Result<u8, PciError> { 555 if let Some(irq_type) = self.irq_type_mut() { 556 match *irq_type { 557 IrqType::Msi { 558 address_64, 559 cap_offset, 560 .. 561 } => { 562 for vector in self.irq_vector_mut().unwrap() { 563 unsafe { 564 c_irq_uninstall(vector.clone() as u64); 565 } 566 } 567 PciArch::write_config(&self.common_header().bus_device_function, cap_offset, 0); 568 PciArch::write_config( 569 &self.common_header().bus_device_function, 570 cap_offset + 4, 571 0, 572 ); 573 PciArch::write_config( 574 &self.common_header().bus_device_function, 575 cap_offset + 8, 576 0, 577 ); 578 if address_64 { 579 PciArch::write_config( 580 &self.common_header().bus_device_function, 581 cap_offset + 12, 582 0, 583 ); 584 } 585 return Ok(0); 586 } 587 IrqType::Unused => { 588 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 589 } 590 _ => { 591 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 592 } 593 } 594 } 595 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 596 } 597 /// @brief 进行PCI设备中断的卸载(MSIX) 598 /// @param self PCI设备的可变引用 599 fn msix_uninstall(&mut self) -> Result<u8, PciError> { 600 if let Some(irq_type) = self.irq_type_mut() { 601 match *irq_type { 602 IrqType::Msix { 603 irq_max_num, 604 cap_offset, 605 msix_table_bar, 606 msix_table_offset, 607 .. 608 } => { 609 for vector in self.irq_vector_mut().unwrap() { 610 unsafe { 611 c_irq_uninstall(vector.clone() as u64); 612 } 613 } 614 PciArch::write_config(&self.common_header().bus_device_function, cap_offset, 0); 615 let pcistandardbar = self 616 .bar() 617 .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited)) 618 .unwrap(); 619 let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap(); 620 for index in 0..irq_max_num { 621 let vaddr = msix_bar 622 .virtual_address() 623 .ok_or(PciError::PciIrqError(PciIrqError::BarGetVaddrFailed)) 624 .unwrap() 625 + msix_table_offset as usize 626 + index as usize * size_of::<MsixEntry>(); 627 let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap(); 628 unsafe { 629 volwrite!(msix_entry, vector_control, 0); 630 volwrite!(msix_entry, msg_data, 0); 631 volwrite!(msix_entry, msg_upper_addr, 0); 632 volwrite!(msix_entry, msg_addr, 0); 633 } 634 } 635 return Ok(0); 636 } 637 IrqType::Unused => { 638 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 639 } 640 _ => { 641 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 642 } 643 } 644 } 645 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 646 } 647 /// @brief 屏蔽相应位置的中断 648 /// @param self PCI设备的可变引用 649 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 650 fn irq_mask(&mut self, irq_index: u16) -> Result<u8, PciError> { 651 if let Some(irq_type) = self.irq_type_mut() { 652 match *irq_type { 653 IrqType::Msix { .. } => { 654 return self.msix_mask(irq_index); 655 } 656 IrqType::Msi { .. } => { 657 return self.msi_mask(irq_index); 658 } 659 IrqType::Unused => { 660 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 661 } 662 _ => { 663 return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported)); 664 } 665 } 666 } 667 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 668 } 669 /// @brief 屏蔽相应位置的中断(MSI) 670 /// @param self PCI设备的可变引用 671 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 672 fn msi_mask(&mut self, irq_index: u16) -> Result<u8, PciError> { 673 if let Some(irq_type) = self.irq_type_mut() { 674 match *irq_type { 675 IrqType::Msi { 676 maskable, 677 address_64, 678 cap_offset, 679 irq_max_num, 680 } => { 681 if irq_index >= irq_max_num { 682 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 683 irq_index, 684 ))); 685 } 686 if maskable { 687 match address_64 { 688 true => { 689 let mut mask = PciArch::read_config( 690 &self.common_header().bus_device_function, 691 cap_offset + 16, 692 ); 693 mask |= 1 << irq_index; 694 PciArch::write_config( 695 &self.common_header().bus_device_function, 696 cap_offset, 697 mask, 698 ); 699 } 700 false => { 701 let mut mask = PciArch::read_config( 702 &self.common_header().bus_device_function, 703 cap_offset + 12, 704 ); 705 mask |= 1 << irq_index; 706 PciArch::write_config( 707 &self.common_header().bus_device_function, 708 cap_offset, 709 mask, 710 ); 711 } 712 } 713 return Ok(0); 714 } 715 return Err(PciError::PciIrqError(PciIrqError::MaskNotSupported)); 716 } 717 IrqType::Unused => { 718 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 719 } 720 _ => { 721 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 722 } 723 } 724 } 725 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 726 } 727 /// @brief 屏蔽相应位置的中断(MSIX) 728 /// @param self PCI设备的可变引用 729 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 730 fn msix_mask(&mut self, irq_index: u16) -> Result<u8, PciError> { 731 if let Some(irq_type) = self.irq_type_mut() { 732 match *irq_type { 733 IrqType::Msix { 734 irq_max_num, 735 msix_table_bar, 736 msix_table_offset, 737 .. 738 } => { 739 if irq_index >= irq_max_num { 740 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 741 irq_index, 742 ))); 743 } 744 let pcistandardbar = self 745 .bar() 746 .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited)) 747 .unwrap(); 748 let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap(); 749 let vaddr = msix_bar.virtual_address().unwrap() 750 + msix_table_offset as usize 751 + irq_index as usize * size_of::<MsixEntry>(); 752 let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap(); 753 unsafe { 754 volwrite!(msix_entry, vector_control, 1); 755 } 756 return Ok(0); 757 } 758 IrqType::Unused => { 759 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 760 } 761 _ => { 762 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 763 } 764 } 765 } 766 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 767 } 768 /// @brief 解除屏蔽相应位置的中断 769 /// @param self PCI设备的可变引用 770 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 771 fn irq_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> { 772 if let Some(irq_type) = self.irq_type_mut() { 773 match *irq_type { 774 IrqType::Msix { .. } => { 775 return self.msix_unmask(irq_index); 776 } 777 IrqType::Msi { .. } => { 778 return self.msi_unmask(irq_index); 779 } 780 IrqType::Unused => { 781 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 782 } 783 _ => { 784 return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported)); 785 } 786 } 787 } 788 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 789 } 790 /// @brief 解除屏蔽相应位置的中断(MSI) 791 /// @param self PCI设备的可变引用 792 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 793 fn msi_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> { 794 if let Some(irq_type) = self.irq_type_mut() { 795 match *irq_type { 796 IrqType::Msi { 797 maskable, 798 address_64, 799 cap_offset, 800 irq_max_num, 801 } => { 802 if irq_index >= irq_max_num { 803 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 804 irq_index, 805 ))); 806 } 807 if maskable { 808 match address_64 { 809 true => { 810 let mut mask = PciArch::read_config( 811 &self.common_header().bus_device_function, 812 cap_offset + 16, 813 ); 814 mask &= !(1 << irq_index); 815 PciArch::write_config( 816 &self.common_header().bus_device_function, 817 cap_offset, 818 mask, 819 ); 820 } 821 false => { 822 let mut mask = PciArch::read_config( 823 &self.common_header().bus_device_function, 824 cap_offset + 12, 825 ); 826 mask &= !(1 << irq_index); 827 PciArch::write_config( 828 &self.common_header().bus_device_function, 829 cap_offset, 830 mask, 831 ); 832 } 833 } 834 } 835 return Err(PciError::PciIrqError(PciIrqError::MaskNotSupported)); 836 } 837 IrqType::Unused => { 838 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 839 } 840 _ => { 841 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 842 } 843 } 844 } 845 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 846 } 847 /// @brief 解除屏蔽相应位置的中断(MSIX) 848 /// @param self PCI设备的可变引用 849 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 850 fn msix_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> { 851 if let Some(irq_type) = self.irq_type_mut() { 852 match *irq_type { 853 IrqType::Msix { 854 irq_max_num, 855 msix_table_bar, 856 msix_table_offset, 857 .. 858 } => { 859 if irq_index >= irq_max_num { 860 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 861 irq_index, 862 ))); 863 } 864 let pcistandardbar = self 865 .bar() 866 .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited)) 867 .unwrap(); 868 let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap(); 869 let vaddr = msix_bar.virtual_address().unwrap() 870 + msix_table_offset as usize 871 + irq_index as usize * size_of::<MsixEntry>(); 872 let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap(); 873 unsafe { 874 volwrite!(msix_entry, vector_control, 0); 875 } 876 return Ok(0); 877 } 878 IrqType::Unused => { 879 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 880 } 881 _ => { 882 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 883 } 884 } 885 } 886 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 887 } 888 /// @brief 检查被挂起的中断是否在挂起的时候产生了 889 /// @param self PCI设备的可变引用 890 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 891 /// @return 是否在挂起过程中产生中断(异常情况也返回false) 892 fn irq_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> { 893 if let Some(irq_type) = self.irq_type_mut() { 894 match *irq_type { 895 IrqType::Msix { .. } => { 896 return self.msix_check_pending(irq_index); 897 } 898 IrqType::Msi { .. } => { 899 return self.msi_check_pending(irq_index); 900 } 901 IrqType::Unused => { 902 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 903 } 904 _ => { 905 return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported)); 906 } 907 } 908 } 909 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 910 } 911 /// @brief 检查被挂起的中断是否在挂起的时候产生了(MSI) 912 /// @param self PCI设备的可变引用 913 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 914 /// @return 是否在挂起过程中产生中断(异常情况也返回false) 915 fn msi_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> { 916 if let Some(irq_type) = self.irq_type_mut() { 917 match *irq_type { 918 IrqType::Msi { 919 maskable, 920 address_64, 921 cap_offset, 922 irq_max_num, 923 } => { 924 if irq_index >= irq_max_num { 925 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 926 irq_index, 927 ))); 928 } 929 if maskable { 930 match address_64 { 931 true => { 932 let mut pend = PciArch::read_config( 933 &self.common_header().bus_device_function, 934 cap_offset + 20, 935 ); 936 pend &= 1 << irq_index; 937 return Ok(pend != 0); 938 } 939 false => { 940 let mut pend = PciArch::read_config( 941 &self.common_header().bus_device_function, 942 cap_offset + 16, 943 ); 944 pend &= 1 << irq_index; 945 return Ok(pend != 0); 946 } 947 } 948 } 949 } 950 IrqType::Unused => { 951 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 952 } 953 _ => { 954 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 955 } 956 } 957 } 958 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 959 } 960 /// @brief 检查被挂起的中断是否在挂起的时候产生了(MSIX) 961 /// @param self PCI设备的可变引用 962 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 963 /// @return 是否在挂起过程中产生中断(异常情况也返回false) 964 fn msix_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> { 965 if let Some(irq_type) = self.irq_type_mut() { 966 match *irq_type { 967 IrqType::Msix { 968 irq_max_num, 969 pending_table_bar, 970 pending_table_offset, 971 .. 972 } => { 973 if irq_index >= irq_max_num { 974 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 975 irq_index, 976 ))); 977 } 978 let pcistandardbar = self 979 .bar() 980 .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited)) 981 .unwrap(); 982 let pending_bar = pcistandardbar.get_bar(pending_table_bar).unwrap(); 983 let vaddr = pending_bar.virtual_address().unwrap() 984 + pending_table_offset as usize 985 + (irq_index as usize / 64) * size_of::<PendingEntry>(); 986 let pending_entry = NonNull::new(vaddr.data() as *mut PendingEntry).unwrap(); 987 let pending_entry = unsafe { volread!(pending_entry, entry) }; 988 return Ok(pending_entry & (1 << (irq_index as u64 % 64)) != 0); 989 } 990 IrqType::Unused => { 991 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 992 } 993 _ => { 994 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 995 } 996 } 997 } 998 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 999 } 1000 } 1001 /// PCI标准设备的msi/msix中断相关函数块 1002 impl PciInterrupt for PciDeviceStructureGeneralDevice {} 1003