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(&mut 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()? = 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()? = 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()? = 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(&mut self, enable: bool) -> Result<u8, PciError> { 230 if let Some(irq_type) = self.irq_type_mut() { 231 match *irq_type { 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(&mut self, enable: bool) -> Result<u8, PciError> { 252 if let Some(irq_type) = self.irq_type_mut() { 253 match *irq_type { 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(&mut self, enable: bool) -> Result<u8, PciError> { 283 if let Some(irq_type) = self.irq_type_mut() { 284 match *irq_type { 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(&mut 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.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 { 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(&mut self, msg: PciIrqMsg) -> Result<u8, PciError> { 350 if let Some(irq_type) = self.irq_type_mut() { 351 match *irq_type { 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().len() > irq_max_num as usize { 360 return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow)); 361 } 362 let irq_num = 363 self.irq_vector_mut().unwrap()[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::empty(), 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().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(&mut self, msg: PciIrqMsg) -> Result<u8, PciError> { 515 if let Some(irq_type) = self.irq_type_mut() { 516 match *irq_type { 517 IrqType::Msix { 518 irq_max_num, 519 msix_table_bar, 520 msix_table_offset, 521 .. 522 } => { 523 if self.irq_vector_mut().unwrap().len() > irq_max_num as usize { 524 return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow)); 525 } 526 let irq_num = 527 self.irq_vector_mut().unwrap()[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::empty(), 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 let msix_bar = pcistandardbar.get_bar(msix_table_bar)?; 576 let vaddr: crate::mm::VirtAddr = msix_bar 577 .virtual_address() 578 .ok_or(PciError::PciIrqError(PciIrqError::BarGetVaddrFailed))? 579 + msix_table_offset as usize 580 + msg.irq_common_message.irq_index as usize * size_of::<MsixEntry>(); 581 let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap(); 582 // 这里的操作并不适用于所有架构,需要再优化,msg_upper_data并不一定为0 583 unsafe { 584 volwrite!(msix_entry, vector_control, 0); 585 volwrite!(msix_entry, msg_data, msg_data); 586 volwrite!(msix_entry, msg_upper_addr, 0); 587 volwrite!(msix_entry, msg_addr, msg_address); 588 } 589 return Ok(0); 590 } 591 IrqType::Unused => { 592 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 593 } 594 _ => { 595 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 596 } 597 } 598 } 599 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 600 } 601 /// @brief 进行PCI设备中断的卸载 602 /// @param self PCI设备的可变引用 603 fn irq_uninstall(&mut self) -> Result<u8, PciError> { 604 self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断 605 if let Some(irq_type) = self.irq_type_mut() { 606 match *irq_type { 607 IrqType::Msix { .. } => { 608 return self.msix_uninstall(); 609 } 610 IrqType::Msi { .. } => { 611 return self.msi_uninstall(); 612 } 613 IrqType::Unused => { 614 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 615 } 616 _ => { 617 return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported)); 618 } 619 } 620 } 621 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 622 } 623 /// @brief 进行PCI设备中断的卸载(MSI) 624 /// @param self PCI设备的可变引用 625 fn msi_uninstall(&mut self) -> Result<u8, PciError> { 626 if let Some(irq_type) = self.irq_type_mut() { 627 match *irq_type { 628 IrqType::Msi { 629 address_64, 630 cap_offset, 631 .. 632 } => { 633 for vector in self.irq_vector_mut().unwrap() { 634 let irq = IrqNumber::new((*vector).into()); 635 irq_manager().free_irq(irq, None); 636 } 637 pci_root_0().write_config( 638 self.common_header().bus_device_function, 639 cap_offset.into(), 640 0, 641 ); 642 pci_root_0().write_config( 643 self.common_header().bus_device_function, 644 (cap_offset + 4).into(), 645 0, 646 ); 647 pci_root_0().write_config( 648 self.common_header().bus_device_function, 649 (cap_offset + 8).into(), 650 0, 651 ); 652 if address_64 { 653 pci_root_0().write_config( 654 self.common_header().bus_device_function, 655 (cap_offset + 12).into(), 656 0, 657 ); 658 } 659 return Ok(0); 660 } 661 IrqType::Unused => { 662 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 663 } 664 _ => { 665 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 666 } 667 } 668 } 669 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 670 } 671 /// @brief 进行PCI设备中断的卸载(MSIX) 672 /// @param self PCI设备的可变引用 673 fn msix_uninstall(&mut self) -> Result<u8, PciError> { 674 if let Some(irq_type) = self.irq_type_mut() { 675 match *irq_type { 676 IrqType::Msix { 677 irq_max_num, 678 cap_offset, 679 msix_table_bar, 680 msix_table_offset, 681 .. 682 } => { 683 for vector in self.irq_vector_mut().unwrap() { 684 let irq = IrqNumber::new((*vector).into()); 685 irq_manager().free_irq(irq, None); 686 } 687 pci_root_0().write_config( 688 self.common_header().bus_device_function, 689 cap_offset.into(), 690 0, 691 ); 692 let pcistandardbar = self 693 .bar() 694 .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited)) 695 .unwrap(); 696 let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap(); 697 for index in 0..irq_max_num { 698 let vaddr = msix_bar 699 .virtual_address() 700 .ok_or(PciError::PciIrqError(PciIrqError::BarGetVaddrFailed)) 701 .unwrap() 702 + msix_table_offset as usize 703 + index as usize * size_of::<MsixEntry>(); 704 let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap(); 705 unsafe { 706 volwrite!(msix_entry, vector_control, 0); 707 volwrite!(msix_entry, msg_data, 0); 708 volwrite!(msix_entry, msg_upper_addr, 0); 709 volwrite!(msix_entry, msg_addr, 0); 710 } 711 } 712 return Ok(0); 713 } 714 IrqType::Unused => { 715 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 716 } 717 _ => { 718 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 719 } 720 } 721 } 722 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 723 } 724 /// @brief 屏蔽相应位置的中断 725 /// @param self PCI设备的可变引用 726 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 727 fn irq_mask(&mut self, irq_index: u16) -> Result<u8, PciError> { 728 if let Some(irq_type) = self.irq_type_mut() { 729 match *irq_type { 730 IrqType::Msix { .. } => { 731 return self.msix_mask(irq_index); 732 } 733 IrqType::Msi { .. } => { 734 return self.msi_mask(irq_index); 735 } 736 IrqType::Unused => { 737 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 738 } 739 _ => { 740 return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported)); 741 } 742 } 743 } 744 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 745 } 746 /// @brief 屏蔽相应位置的中断(MSI) 747 /// @param self PCI设备的可变引用 748 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 749 fn msi_mask(&mut self, irq_index: u16) -> Result<u8, PciError> { 750 if let Some(irq_type) = self.irq_type_mut() { 751 match *irq_type { 752 IrqType::Msi { 753 maskable, 754 address_64, 755 cap_offset, 756 irq_max_num, 757 } => { 758 if irq_index >= irq_max_num { 759 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 760 irq_index, 761 ))); 762 } 763 if maskable { 764 match address_64 { 765 true => { 766 let mut mask = pci_root_0().read_config( 767 self.common_header().bus_device_function, 768 (cap_offset + 16).into(), 769 ); 770 mask |= 1 << irq_index; 771 pci_root_0().write_config( 772 self.common_header().bus_device_function, 773 cap_offset.into(), 774 mask, 775 ); 776 } 777 false => { 778 let mut mask = pci_root_0().read_config( 779 self.common_header().bus_device_function, 780 (cap_offset + 12).into(), 781 ); 782 mask |= 1 << irq_index; 783 pci_root_0().write_config( 784 self.common_header().bus_device_function, 785 cap_offset.into(), 786 mask, 787 ); 788 } 789 } 790 return Ok(0); 791 } 792 return Err(PciError::PciIrqError(PciIrqError::MaskNotSupported)); 793 } 794 IrqType::Unused => { 795 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 796 } 797 _ => { 798 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 799 } 800 } 801 } 802 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 803 } 804 /// @brief 屏蔽相应位置的中断(MSIX) 805 /// @param self PCI设备的可变引用 806 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 807 fn msix_mask(&mut self, irq_index: u16) -> Result<u8, PciError> { 808 if let Some(irq_type) = self.irq_type_mut() { 809 match *irq_type { 810 IrqType::Msix { 811 irq_max_num, 812 msix_table_bar, 813 msix_table_offset, 814 .. 815 } => { 816 if irq_index >= irq_max_num { 817 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 818 irq_index, 819 ))); 820 } 821 let pcistandardbar = self 822 .bar() 823 .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited)) 824 .unwrap(); 825 let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap(); 826 let vaddr = msix_bar.virtual_address().unwrap() 827 + msix_table_offset as usize 828 + irq_index as usize * size_of::<MsixEntry>(); 829 let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap(); 830 unsafe { 831 volwrite!(msix_entry, vector_control, 1); 832 } 833 return Ok(0); 834 } 835 IrqType::Unused => { 836 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 837 } 838 _ => { 839 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 840 } 841 } 842 } 843 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 844 } 845 /// @brief 解除屏蔽相应位置的中断 846 /// @param self PCI设备的可变引用 847 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 848 fn irq_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> { 849 if let Some(irq_type) = self.irq_type_mut() { 850 match *irq_type { 851 IrqType::Msix { .. } => { 852 return self.msix_unmask(irq_index); 853 } 854 IrqType::Msi { .. } => { 855 return self.msi_unmask(irq_index); 856 } 857 IrqType::Unused => { 858 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 859 } 860 _ => { 861 return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported)); 862 } 863 } 864 } 865 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 866 } 867 /// @brief 解除屏蔽相应位置的中断(MSI) 868 /// @param self PCI设备的可变引用 869 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 870 fn msi_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> { 871 if let Some(irq_type) = self.irq_type_mut() { 872 match *irq_type { 873 IrqType::Msi { 874 maskable, 875 address_64, 876 cap_offset, 877 irq_max_num, 878 } => { 879 if irq_index >= irq_max_num { 880 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 881 irq_index, 882 ))); 883 } 884 if maskable { 885 match address_64 { 886 true => { 887 let mut mask = pci_root_0().read_config( 888 self.common_header().bus_device_function, 889 (cap_offset + 16).into(), 890 ); 891 mask &= !(1 << irq_index); 892 pci_root_0().write_config( 893 self.common_header().bus_device_function, 894 cap_offset.into(), 895 mask, 896 ); 897 } 898 false => { 899 let mut mask = pci_root_0().read_config( 900 self.common_header().bus_device_function, 901 (cap_offset + 12).into(), 902 ); 903 mask &= !(1 << irq_index); 904 pci_root_0().write_config( 905 self.common_header().bus_device_function, 906 cap_offset.into(), 907 mask, 908 ); 909 } 910 } 911 } 912 return Err(PciError::PciIrqError(PciIrqError::MaskNotSupported)); 913 } 914 IrqType::Unused => { 915 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 916 } 917 _ => { 918 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 919 } 920 } 921 } 922 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 923 } 924 /// @brief 解除屏蔽相应位置的中断(MSIX) 925 /// @param self PCI设备的可变引用 926 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 927 fn msix_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> { 928 if let Some(irq_type) = self.irq_type_mut() { 929 match *irq_type { 930 IrqType::Msix { 931 irq_max_num, 932 msix_table_bar, 933 msix_table_offset, 934 .. 935 } => { 936 if irq_index >= irq_max_num { 937 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 938 irq_index, 939 ))); 940 } 941 let pcistandardbar = self 942 .bar() 943 .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited)) 944 .unwrap(); 945 let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap(); 946 let vaddr = msix_bar.virtual_address().unwrap() 947 + msix_table_offset as usize 948 + irq_index as usize * size_of::<MsixEntry>(); 949 let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap(); 950 unsafe { 951 volwrite!(msix_entry, vector_control, 0); 952 } 953 return Ok(0); 954 } 955 IrqType::Unused => { 956 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 957 } 958 _ => { 959 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 960 } 961 } 962 } 963 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 964 } 965 /// @brief 检查被挂起的中断是否在挂起的时候产生了 966 /// @param self PCI设备的可变引用 967 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 968 /// @return 是否在挂起过程中产生中断(异常情况也返回false) 969 fn irq_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> { 970 if let Some(irq_type) = self.irq_type_mut() { 971 match *irq_type { 972 IrqType::Msix { .. } => { 973 return self.msix_check_pending(irq_index); 974 } 975 IrqType::Msi { .. } => { 976 return self.msi_check_pending(irq_index); 977 } 978 IrqType::Unused => { 979 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 980 } 981 _ => { 982 return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported)); 983 } 984 } 985 } 986 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 987 } 988 /// @brief 检查被挂起的中断是否在挂起的时候产生了(MSI) 989 /// @param self PCI设备的可变引用 990 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 991 /// @return 是否在挂起过程中产生中断(异常情况也返回false) 992 fn msi_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> { 993 if let Some(irq_type) = self.irq_type_mut() { 994 match *irq_type { 995 IrqType::Msi { 996 maskable, 997 address_64, 998 cap_offset, 999 irq_max_num, 1000 } => { 1001 if irq_index >= irq_max_num { 1002 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 1003 irq_index, 1004 ))); 1005 } 1006 if maskable { 1007 match address_64 { 1008 true => { 1009 let mut pend = pci_root_0().read_config( 1010 self.common_header().bus_device_function, 1011 (cap_offset + 20).into(), 1012 ); 1013 pend &= 1 << irq_index; 1014 return Ok(pend != 0); 1015 } 1016 false => { 1017 let mut pend = pci_root_0().read_config( 1018 self.common_header().bus_device_function, 1019 (cap_offset + 16).into(), 1020 ); 1021 pend &= 1 << irq_index; 1022 return Ok(pend != 0); 1023 } 1024 } 1025 } 1026 } 1027 IrqType::Unused => { 1028 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 1029 } 1030 _ => { 1031 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 1032 } 1033 } 1034 } 1035 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 1036 } 1037 /// @brief 检查被挂起的中断是否在挂起的时候产生了(MSIX) 1038 /// @param self PCI设备的可变引用 1039 /// @param irq_index 中断的位置(在vec中的index和安装的index相同) 1040 /// @return 是否在挂起过程中产生中断(异常情况也返回false) 1041 fn msix_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> { 1042 if let Some(irq_type) = self.irq_type_mut() { 1043 match *irq_type { 1044 IrqType::Msix { 1045 irq_max_num, 1046 pending_table_bar, 1047 pending_table_offset, 1048 .. 1049 } => { 1050 if irq_index >= irq_max_num { 1051 return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex( 1052 irq_index, 1053 ))); 1054 } 1055 let pcistandardbar = self 1056 .bar() 1057 .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited)) 1058 .unwrap(); 1059 let pending_bar = pcistandardbar.get_bar(pending_table_bar).unwrap(); 1060 let vaddr = pending_bar.virtual_address().unwrap() 1061 + pending_table_offset as usize 1062 + (irq_index as usize / 64) * size_of::<PendingEntry>(); 1063 let pending_entry = NonNull::new(vaddr.data() as *mut PendingEntry).unwrap(); 1064 let pending_entry = unsafe { volread!(pending_entry, entry) }; 1065 return Ok(pending_entry & (1 << (irq_index as u64 % 64)) != 0); 1066 } 1067 IrqType::Unused => { 1068 return Err(PciError::PciIrqError(PciIrqError::IrqNotInited)); 1069 } 1070 _ => { 1071 return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch)); 1072 } 1073 } 1074 } 1075 return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq)); 1076 } 1077 } 1078 /// PCI标准设备的msi/msix中断相关函数块 1079 impl PciInterrupt for PciDeviceStructureGeneralDevice {} 1080