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