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