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