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