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