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