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