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