Browse Source

PCI设备中断重构,删去USB相关代码 (#285)

* 修复ecam无法获取MCFG table的问题

* 完善pcie

* 完善irq的错误检测机制
YJwu2023 1 year ago
parent
commit
cc36cf4a18

+ 2 - 1
.vscode/c_cpp_properties.json

@@ -14,7 +14,8 @@
             "compilerPath": "~/opt/dragonos-gcc/gcc-x86_64-unknown-none/bin/x86_64-elf-gcc",
             "cStandard": "gnu17",
             "cppStandard": "gnu++14",
-            "intelliSenseMode": "linux-gcc-x64"
+            "intelliSenseMode": "linux-gcc-x64",
+            "configurationProvider": "ms-vscode.makefile-tools"
         }
     ],
     "version": 4

+ 3 - 0
kernel/rust-toolchain.toml

@@ -0,0 +1,3 @@
+[toolchain]
+channel = "nightly-2023-01-21"
+components = ["rust-src"]

+ 1 - 0
kernel/src/arch/x86_64/mod.rs

@@ -5,6 +5,7 @@ pub mod cpu;
 pub mod fpu;
 pub mod interrupt;
 pub mod mm;
+pub mod msi;
 pub mod pci;
 pub mod rand;
 pub mod sched;

+ 23 - 0
kernel/src/arch/x86_64/msi.rs

@@ -0,0 +1,23 @@
+use crate::driver::pci::pci_irq::TriggerMode;
+/// @brief 获得MSI Message Address
+/// @param processor 目标CPU ID号
+/// @return MSI Message Address
+pub fn ia64_pci_get_arch_msi_message_address(processor: u16) -> u32 {
+    0xfee00000 as u32 | ((processor as u32) << 12)
+}
+/// @brief 获得MSI Message Data
+/// @param vector 分配的中断向量号
+/// @param processor 目标CPU ID号
+/// @param trigger  申请中断的触发模式,MSI默认为边沿触发
+/// @return MSI Message Address
+pub fn ia64_pci_get_arch_msi_message_data(
+    vector: u16,
+    processor: u16,
+    trigger: TriggerMode,
+) -> u32 {
+    match trigger {
+        TriggerMode::EdgeTrigger => vector as u32,
+        TriggerMode::AssertHigh => vector as u32 | 1 << 15 | 1 << 14,
+        TriggerMode::AssertLow => vector as u32 | 1 << 15,
+    }
+}

+ 4 - 0
kernel/src/arch/x86_64/pci/pci.rs

@@ -50,6 +50,10 @@ impl TraitPciArch for X86_64PciArch {
         unsafe {
             acpi_iter_SDT(Some(acpi_get_MCFG), data_point as *mut usize as *mut c_void);
         };
+        // 防止无PCIE的机器找不到MCFG Table导致的错误
+        if data == 0 {
+            return Err(PciError::McfgTableNotFound);
+        }
         //kdebug!("{}",data);
         //loop{}
         let head = NonNull::new(data as *mut acpi_system_description_table_header_t).unwrap();

+ 1 - 1
kernel/src/driver/Makefile

@@ -1,7 +1,7 @@
 
 CFLAGS += -I .
 
-kernel_driver_subdirs:=video interrupt usb pci acpi disk keyboard mouse multiboot2 timers hid 
+kernel_driver_subdirs:=video interrupt pci acpi disk keyboard mouse multiboot2 timers hid 
 
 ECHO:
 	@echo "$@"

+ 6 - 3
kernel/src/driver/pci/Makefile

@@ -1,11 +1,14 @@
 
-all: pci.o msi.o
+all: pci.o  pci_irq.o msi.o
 
 CFLAGS += -I .
 
-
 pci.o: pci.c
 	$(CC) $(CFLAGS) -c pci.c -o pci.o
-
+	
+pci_irq.o: pci_irq.c
+	$(CC) $(CFLAGS) -c pci_irq.c -o pci_irq.o
+	
 msi.o: msi.c
 	$(CC) $(CFLAGS) -c msi.c -o msi.o
+	

+ 1 - 0
kernel/src/driver/pci/mod.rs

@@ -1 +1,2 @@
 pub mod pci;
+pub mod pci_irq;

+ 102 - 19
kernel/src/driver/pci/pci.rs

@@ -1,6 +1,7 @@
 #![allow(dead_code)]
 // 目前仅支持单主桥单Segment
 
+use super::pci_irq::{IrqType, PciIrqError};
 use crate::arch::{PciArch, TraitPciArch};
 use crate::include::bindings::bindings::{
     initial_mm, mm_map, mm_struct, PAGE_2M_SIZE, VM_DONTCOPY, VM_IO,
@@ -11,12 +12,10 @@ use crate::{kdebug, kerror, kinfo, kwarn};
 use alloc::vec::Vec;
 use alloc::{boxed::Box, collections::LinkedList};
 use bitflags::bitflags;
-
 use core::{
     convert::TryFrom,
     fmt::{self, Debug, Display, Formatter},
 };
-
 // PCI_DEVICE_LINKEDLIST 添加了读写锁的全局链表,里面存储了检索到的PCI设备结构体
 // PCI_ROOT_0 Segment为0的全局PciRoot
 lazy_static! {
@@ -146,6 +145,8 @@ const BAR0_OFFSET: u8 = 0x10;
 const STATUS_COMMAND_OFFSET: u8 = 0x04;
 /// ID for vendor-specific PCI capabilities.(Virtio Capabilities)
 pub const PCI_CAP_ID_VNDR: u8 = 0x09;
+pub const PCI_CAP_ID_MSI: u8 = 0x05;
+pub const PCI_CAP_ID_MSIX: u8 = 0x11;
 pub const PORT_PCI_CONFIG_ADDRESS: u16 = 0xcf8;
 pub const PORT_PCI_CONFIG_DATA: u16 = 0xcfc;
 // pci设备分组的id
@@ -239,9 +240,11 @@ pub enum PciError {
     CreateMmioError,
     InvalidBusDeviceFunction,
     SegmentNotFound,
+    McfgTableNotFound,
     GetWrongHeader,
     UnrecognisedHeaderType,
     PciDeviceStructureTransformError,
+    PciIrqError(PciIrqError),
 }
 ///实现PciError的Display trait,使其可以直接输出
 impl Display for PciError {
@@ -251,11 +254,13 @@ impl Display for PciError {
             Self::CreateMmioError => write!(f, "Error occurred while creating mmio."),
             Self::InvalidBusDeviceFunction => write!(f, "Found invalid BusDeviceFunction."),
             Self::SegmentNotFound => write!(f, "Target segment not found"),
+            Self::McfgTableNotFound => write!(f, "ACPI MCFG Table not found"),
             Self::GetWrongHeader => write!(f, "GetWrongHeader with vendor id 0xffff"),
             Self::UnrecognisedHeaderType => write!(f, "Found device with unrecognised header type"),
             Self::PciDeviceStructureTransformError => {
                 write!(f, "Found None When transform Pci device structure")
             }
+            Self::PciIrqError(err) => write!(f, "Error occurred while setting irq :{:?}.", err),
         }
     }
 }
@@ -266,14 +271,17 @@ pub trait PciDeviceStructure: Send + Sync {
     /// @return HeaderType 设备类型
     fn header_type(&self) -> HeaderType;
     /// @brief 当其为standard设备时返回&Pci_Device_Structure_General_Device,其余情况返回None
+    #[inline(always)]
     fn as_standard_device(&self) -> Option<&PciDeviceStructureGeneralDevice> {
         None
     }
     /// @brief 当其为pci to pci bridge设备时返回&Pci_Device_Structure_Pci_to_Pci_Bridge,其余情况返回None
+    #[inline(always)]
     fn as_pci_to_pci_bridge_device(&self) -> Option<&PciDeviceStructurePciToPciBridge> {
         None
     }
     /// @brief 当其为pci to cardbus bridge设备时返回&Pci_Device_Structure_Pci_to_Cardbus_Bridge,其余情况返回None
+    #[inline(always)]
     fn as_pci_to_carbus_bridge_device(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> {
         None
     }
@@ -281,14 +289,17 @@ pub trait PciDeviceStructure: Send + Sync {
     /// @return 返回其不可变引用
     fn common_header(&self) -> &PciDeviceStructureHeader;
     /// @brief 当其为standard设备时返回&mut Pci_Device_Structure_General_Device,其余情况返回None
+    #[inline(always)]
     fn as_standard_device_mut(&mut self) -> Option<&mut PciDeviceStructureGeneralDevice> {
         None
     }
     /// @brief 当其为pci to pci bridge设备时返回&mut Pci_Device_Structure_Pci_to_Pci_Bridge,其余情况返回None
+    #[inline(always)]
     fn as_pci_to_pci_bridge_device_mut(&mut self) -> Option<&mut PciDeviceStructurePciToPciBridge> {
         None
     }
     /// @brief 当其为pci to cardbus bridge设备时返回&mut Pci_Device_Structure_Pci_to_Cardbus_Bridge,其余情况返回None
+    #[inline(always)]
     fn as_pci_to_carbus_bridge_device_mut(
         &mut self,
     ) -> Option<&mut PciDeviceStructurePciToCardbusBridge> {
@@ -319,28 +330,50 @@ pub trait PciDeviceStructure: Send + Sync {
     /// @brief 获取Pci设备共有的common_header
     /// @return 返回其可变引用
     fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader;
+
     /// @brief 读取standard设备的bar寄存器,映射后将结果加入结构体的standard_device_bar变量
     /// @return 只有standard设备才返回成功或者错误,其余返回None
-    fn bar_init(&mut self) -> Option<Result<u8, PciError>> {
+    #[inline(always)]
+    fn bar_ioremap(&mut self) -> Option<Result<u8, PciError>> {
         None
     }
-    /// todo
-    fn msix_init(&mut self) -> Option<Result<u8, PciError>> {
+    /// @brief 获取PCI设备的bar寄存器的引用
+    /// @return
+    #[inline(always)]
+    fn bar(&mut self) -> Option<&PciStandardDeviceBar> {
         None
     }
+    /// @brief 通过设置该pci设备的command
     fn enable_master(&mut self) {
         self.set_command(Command::IO_SPACE | Command::MEMORY_SPACE | Command::BUS_MASTER);
     }
+    /// @brief 寻找设备的msix空间的offset
+    fn msix_capability_offset(&self) -> Option<u8> {
+        for capability in self.capabilities()? {
+            if capability.id == PCI_CAP_ID_MSIX {
+                return Some(capability.offset);
+            }
+        }
+        None
+    }
+    /// @brief 寻找设备的msi空间的offset
+    fn msi_capability_offset(&self) -> Option<u8> {
+        for capability in self.capabilities()? {
+            if capability.id == PCI_CAP_ID_MSI {
+                return Some(capability.offset);
+            }
+        }
+        None
+    }
+    /// @brief 返回结构体中的irq_type的可变引用
+    fn irq_type_mut(&mut self) -> Option<&mut IrqType>;
+    /// @brief 返回结构体中的irq_vector的可变引用
+    fn irq_vector_mut(&mut self) -> Option<&mut Vec<u16>>;
 }
 
 /// Pci_Device_Structure_Header PCI设备结构体共有的头部
 #[derive(Clone, Debug)]
 pub struct PciDeviceStructureHeader {
-    // 包含msix table地址的bar的mmio基地址 todo:以下四个作为一个结构体统一管理
-    pub msix_mmio_vaddr: u64,
-    pub msix_mmio_size: u64,  // msix映射长度
-    pub msix_offset: u32,     // msix表的offset
-    pub msix_table_size: u16, // msix表的表项数量
     // ==== busdevicefunction变量表示该结构体所处的位置
     pub bus_device_function: BusDeviceFunction,
     pub vendor_id: u16, // 供应商ID 0xffff是一个无效值,在读取访问不存在的设备的配置空间寄存器时返回
@@ -365,6 +398,10 @@ pub struct PciDeviceStructureHeader {
 #[derive(Clone, Debug)]
 pub struct PciDeviceStructureGeneralDevice {
     pub common_header: PciDeviceStructureHeader,
+    // 中断结构体,包括legacy,msi,msix三种情况
+    pub irq_type: IrqType,
+    // 使用的中断号的vec集合
+    pub irq_vector: Vec<u16>,
     pub standard_device_bar: PciStandardDeviceBar,
     pub cardbus_cis_pointer: u32, // 指向卡信息结构,供在 CardBus 和 PCI 之间共享芯片的设备使用。
     pub subsystem_vendor_id: u16,
@@ -380,19 +417,23 @@ pub struct PciDeviceStructureGeneralDevice {
     pub max_latency: u8, // 一个只读寄存器,指定设备需要多长时间访问一次 PCI 总线(以 1/4 微秒为单位)。
 }
 impl PciDeviceStructure for PciDeviceStructureGeneralDevice {
+    #[inline(always)]
     fn header_type(&self) -> HeaderType {
         HeaderType::Standard
     }
+    #[inline(always)]
     fn as_standard_device(&self) -> Option<&PciDeviceStructureGeneralDevice> {
         Some(self)
     }
+    #[inline(always)]
     fn as_standard_device_mut(&mut self) -> Option<&mut PciDeviceStructureGeneralDevice> {
         Some(self)
     }
+    #[inline(always)]
     fn common_header(&self) -> &PciDeviceStructureHeader {
         &self.common_header
     }
-
+    #[inline(always)]
     fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader {
         &mut self.common_header
     }
@@ -402,7 +443,7 @@ impl PciDeviceStructure for PciDeviceStructureGeneralDevice {
             next_capability_offset: Some(self.capabilities_pointer),
         })
     }
-    fn bar_init(&mut self) -> Option<Result<u8, PciError>> {
+    fn bar_ioremap(&mut self) -> Option<Result<u8, PciError>> {
         let common_header = &self.common_header;
         match pci_bar_init(common_header.bus_device_function) {
             Ok(bar) => {
@@ -412,11 +453,27 @@ impl PciDeviceStructure for PciDeviceStructureGeneralDevice {
             Err(e) => Some(Err(e)),
         }
     }
+    fn bar(&mut self) -> Option<&PciStandardDeviceBar> {
+        Some(&self.standard_device_bar)
+    }
+    #[inline(always)]
+    fn irq_type_mut(&mut self) -> Option<&mut IrqType> {
+        Some(&mut self.irq_type)
+    }
+    #[inline(always)]
+    fn irq_vector_mut(&mut self) -> Option<&mut Vec<u16>> {
+        Some(&mut self.irq_vector)
+    }
 }
+
 /// Pci_Device_Structure_Pci_to_Pci_Bridge pci-to-pci桥设备结构体
 #[derive(Clone, Debug)]
 pub struct PciDeviceStructurePciToPciBridge {
     pub common_header: PciDeviceStructureHeader,
+    // 中断结构体,包括legacy,msi,msix三种情况
+    pub irq_type: IrqType,
+    // 使用的中断号的vec集合
+    pub irq_vector: Vec<u16>,
     pub bar0: u32,
     pub bar1: u32,
     pub primary_bus_number: u8,
@@ -443,22 +500,34 @@ pub struct PciDeviceStructurePciToPciBridge {
     pub bridge_control: u16,
 }
 impl PciDeviceStructure for PciDeviceStructurePciToPciBridge {
+    #[inline(always)]
     fn header_type(&self) -> HeaderType {
         HeaderType::PciPciBridge
     }
+    #[inline(always)]
     fn as_pci_to_pci_bridge_device(&self) -> Option<&PciDeviceStructurePciToPciBridge> {
         Some(self)
     }
+    #[inline(always)]
     fn as_pci_to_pci_bridge_device_mut(&mut self) -> Option<&mut PciDeviceStructurePciToPciBridge> {
         Some(self)
     }
+    #[inline(always)]
     fn common_header(&self) -> &PciDeviceStructureHeader {
         &self.common_header
     }
-
+    #[inline(always)]
     fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader {
         &mut self.common_header
     }
+    #[inline(always)]
+    fn irq_type_mut(&mut self) -> Option<&mut IrqType> {
+        Some(&mut self.irq_type)
+    }
+    #[inline(always)]
+    fn irq_vector_mut(&mut self) -> Option<&mut Vec<u16>> {
+        Some(&mut self.irq_vector)
+    }
 }
 /// Pci_Device_Structure_Pci_to_Cardbus_Bridge Pci_to_Cardbus桥设备结构体
 #[derive(Clone, Debug)]
@@ -488,24 +557,36 @@ pub struct PciDeviceStructurePciToCardbusBridge {
     pub pc_card_legacy_mode_base_address_16_bit: u32,
 }
 impl PciDeviceStructure for PciDeviceStructurePciToCardbusBridge {
+    #[inline(always)]
     fn header_type(&self) -> HeaderType {
         HeaderType::PciCardbusBridge
     }
+    #[inline(always)]
     fn as_pci_to_carbus_bridge_device(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> {
         Some(&self)
     }
+    #[inline(always)]
     fn as_pci_to_carbus_bridge_device_mut(
         &mut self,
     ) -> Option<&mut PciDeviceStructurePciToCardbusBridge> {
         Some(self)
     }
+    #[inline(always)]
     fn common_header(&self) -> &PciDeviceStructureHeader {
         &self.common_header
     }
-
+    #[inline(always)]
     fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader {
         &mut self.common_header
     }
+    #[inline(always)]
+    fn irq_type_mut(&mut self) -> Option<&mut IrqType> {
+        None
+    }
+    #[inline(always)]
+    fn irq_vector_mut(&mut self) -> Option<&mut Vec<u16>> {
+        None
+    }
 }
 
 /// 代表一个PCI segement greoup.
@@ -672,10 +753,6 @@ fn pci_read_header(
         return Err(PciError::GetWrongHeader);
     }
     let header = PciDeviceStructureHeader {
-        msix_mmio_vaddr: 0,
-        msix_mmio_size: 0,
-        msix_offset: 0,
-        msix_table_size: 0,
         bus_device_function,
         vendor_id,
         device_id,
@@ -755,6 +832,8 @@ fn pci_read_general_device_header(
     let max_latency = (result >> 24) as u8;
     PciDeviceStructureGeneralDevice {
         common_header,
+        irq_type: IrqType::Unused,
+        irq_vector: Vec::new(),
         standard_device_bar,
         cardbus_cis_pointer,
         subsystem_vendor_id,
@@ -823,6 +902,8 @@ fn pci_read_pci_to_pci_bridge_header(
     let bridge_control = (result >> 16) as u16;
     PciDeviceStructurePciToPciBridge {
         common_header,
+        irq_type: IrqType::Unused,
+        irq_vector: Vec::new(),
         bar0,
         bar1,
         primary_bus_number,
@@ -854,7 +935,7 @@ fn pci_read_pci_to_pci_bridge_header(
 /// 本函数只应被 pci_read_header()调用
 /// @param common_header 共有头部
 /// @param bus_device_function PCI设备的唯一标识
-/// @return ) -> Pci_Device_Structure_Pci_to_Cardbus_Bridge  pci-to-cardbus 桥设备头部
+/// @return   Pci_Device_Structure_Pci_to_Cardbus_Bridge  pci-to-cardbus 桥设备头部
 fn pci_read_pci_to_cardbus_bridge_header(
     common_header: PciDeviceStructureHeader,
     busdevicefunction: &BusDeviceFunction,
@@ -1221,6 +1302,8 @@ impl Display for BarInfo {
         }
     }
 }
+//todo 增加对桥的bar的支持
+pub trait PciDeviceBar {}
 ///一个普通PCI设备(非桥)有6个BAR寄存器,PciStandardDeviceBar存储其全部信息
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub struct PciStandardDeviceBar {

+ 88 - 0
kernel/src/driver/pci/pci_irq.c

@@ -0,0 +1,88 @@
+#include "pci_irq.h"
+#include "exception/irq.h"
+#include <common/errno.h>
+#include <common/kprint.h>
+// 现在pci设备的中断由自己进行控制,这些不执行内容的函数是为了适配旧的中断处理机制
+void pci_irq_enable(ul irq_num)
+{
+
+}
+void pci_irq_disable(ul irq_num)
+{
+    
+}
+void pci_irq_install(ul irq_num)
+{
+    
+}
+void pci_irq_uninstall(ul irq_num)
+{
+    
+}
+/// @brief 与本操作系统的中断机制进行交互,把中断处理函数等注册到中断结构体中(被rust调用)
+/// @param irq_num 要进行注册的中断号
+/// @param pci_irq_handler 对应的中断处理函数
+/// @param parameter 中断处理函数传入参数
+/// @param irq_name 中断名字
+/// @param pci_irq_ack 对于中断的回复,为NULL时会使用默认回应
+uint16_t c_irq_install(ul irq_num,void (*pci_irq_handler)(ul irq_num, ul parameter, struct pt_regs *regs),ul parameter,const char *irq_name,void (*pci_irq_ack)(ul irq_num))
+{
+    // 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素
+    irq_desc_t *p = NULL;
+    if (irq_num >= 32 && irq_num < 0x80)
+        p = &interrupt_desc[irq_num - 32];
+    else if (irq_num >= 150 && irq_num < 200)
+        p = &local_apic_interrupt_desc[irq_num - 150];
+    else
+    {
+        //kerror("irq install for pci irq: invalid irq num: %ld.", irq_num);
+        return EINVAL;
+    }
+    if(p->irq_name!=NULL)
+    {
+        return EAGAIN;
+    }
+    hardware_intr_controller* pci_interrupt_controller = kmalloc(sizeof(hardware_intr_controller),0);
+    pci_interrupt_controller->enable = pci_irq_enable;
+    pci_interrupt_controller->disable = pci_irq_disable;
+    pci_interrupt_controller->install= pci_irq_install;
+    pci_interrupt_controller->uninstall= pci_irq_uninstall;
+    if(pci_irq_ack)
+        pci_interrupt_controller->ack = pci_irq_ack;
+    int namelen = sizeof(strlen(irq_name) + 1);
+    p->irq_name = (char *)kmalloc(namelen, 0);
+    memset(p->irq_name, 0, namelen);
+    strncpy(p->irq_name, irq_name, namelen);
+    p->parameter = parameter;
+    p->flags = 0;
+    p->handler = pci_irq_handler;
+    return 0;
+};
+
+/// @brief 与本操作系统的中断机制进行交互,把中断处理函数等从中断结构体中移除,需要释放空间的进行空间的释放
+/// @param irq_num 要进行注销的中断号
+void c_irq_uninstall(ul irq_num)
+{
+    // 由于为I/O APIC分配的中断向量号是从32开始的,因此要减去32才是对应的interrupt_desc的元素
+    irq_desc_t *p = NULL;
+    if (irq_num >= 32 && irq_num < 0x80)
+        p = &interrupt_desc[irq_num - 32];
+    else if (irq_num >= 150 && irq_num < 200)
+        p = &local_apic_interrupt_desc[irq_num - 150];
+    else
+    {
+        kerror("irq install for pci irq: invalid irq num: %ld.", irq_num);
+    }
+    if(p->irq_name!=NULL)
+    {
+        kfree(p->irq_name);
+        p->irq_name = NULL;
+    }
+    if(p->controller!=NULL)
+    {
+        kfree(p->controller);
+        p->controller = NULL;
+    }
+    p->parameter = 0;
+    p->handler = NULL;
+}

+ 5 - 0
kernel/src/driver/pci/pci_irq.h

@@ -0,0 +1,5 @@
+#pragma once
+#include <common/glib.h>
+#include <process/ptrace.h>
+uint16_t c_irq_install(ul irq_num,void (*pci_irq_handler)(ul irq_num, ul parameter, struct pt_regs *regs),ul parameter,const char *irq_name,void (*pci_irq_ack)(ul irq_num));
+void c_irq_uninstall(ul irq_num);

+ 1005 - 0
kernel/src/driver/pci/pci_irq.rs

@@ -0,0 +1,1005 @@
+#![allow(dead_code)]
+
+use core::mem::size_of;
+use core::ptr::NonNull;
+
+use alloc::ffi::CString;
+use alloc::vec::Vec;
+
+use super::pci::{HeaderType, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError};
+use crate::arch::msi::{ia64_pci_get_arch_msi_message_address, ia64_pci_get_arch_msi_message_data};
+use crate::arch::{PciArch, TraitPciArch};
+use crate::include::bindings::bindings::{
+    c_irq_install, c_irq_uninstall, pt_regs, ul, EAGAIN, EINVAL,
+};
+use crate::libs::volatile::{
+    volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
+};
+use crate::{kdebug, kerror, kinfo, kwarn};
+/// MSIX表的一项
+#[repr(C)]
+struct MsixEntry {
+    vector_control: Volatile<u32>,
+    msg_data: Volatile<u32>,
+    msg_upper_addr: Volatile<u32>,
+    msg_addr: Volatile<u32>,
+}
+/// Pending表的一项
+#[repr(C)]
+struct PendingEntry {
+    entry: Volatile<u64>,
+}
+/// PCI设备中断错误
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum PciIrqError {
+    IrqTypeNotSupported,
+    PciDeviceNotSupportIrq,
+    IrqTypeUnmatch,
+    InvalidIrqIndex(u16),
+    InvalidIrqNum(u16),
+    IrqNumOccupied(u16),
+    DeviceIrqOverflow,
+    MxiIrqNumWrong,
+    PciBarNotInited,
+    BarGetVaddrFailed,
+    MaskNotSupported,
+    IrqNotInited,
+}
+/// PCI设备的中断类型
+#[derive(Copy, Clone, Debug)]
+pub enum IrqType {
+    Msi {
+        address_64: bool,
+        maskable: bool,
+        irq_max_num: u16,
+        cap_offset: u8,
+    },
+    Msix {
+        msix_table_bar: u8,
+        msix_table_offset: u32,
+        pending_table_bar: u8,
+        pending_table_offset: u32,
+        irq_max_num: u16,
+        cap_offset: u8,
+    },
+    Legacy,
+    Unused,
+}
+// PCI设备install中断时需要传递的参数
+#[derive(Clone, Debug)]
+pub struct IrqMsg {
+    irq_common_message: IrqCommonMsg,
+    irq_specific_message: IrqSpecificMsg,
+}
+// PCI设备install中断时需要传递的共同参数
+#[derive(Clone, Debug)]
+pub struct IrqCommonMsg {
+    irq_index: u16,     //要install的中断号在PCI设备中的irq_vector的index
+    irq_name: CString,  //中断名字
+    irq_parameter: u16, //中断额外参数,可传入中断处理函数
+    irq_hander: unsafe extern "C" fn(irq_num: ul, parameter: ul, regs: *mut pt_regs), // 中断处理函数
+    irq_ack: Option<unsafe extern "C" fn(irq_num: ul)>, // 中断的ack,可为None,若为None则中断处理中会正常通知中断结束,不为None则调用传入的函数进行回复
+}
+// PCI设备install中断时需要传递的特有参数,Msi代表MSI与MSIX
+#[derive(Clone, Debug)]
+pub enum IrqSpecificMsg {
+    Legacy,
+    Msi {
+        processor: u16,
+        trigger_mode: TriggerMode,
+    },
+}
+impl IrqSpecificMsg {
+    fn msi_default() -> Self {
+        IrqSpecificMsg::Msi {
+            processor: 0,
+            trigger_mode: TriggerMode::EdgeTrigger,
+        }
+    }
+}
+// 申请中断的触发模式,MSI默认为边沿触发
+#[derive(Copy, Clone, Debug)]
+pub enum TriggerMode {
+    EdgeTrigger,
+    AssertHigh,
+    AssertLow,
+}
+bitflags! {
+    /// 设备中断类型,使用bitflag使得中断类型的选择更多元化
+    pub struct IRQ: u8{
+        const PCI_IRQ_LEGACY = 1 << 0;
+        const PCI_IRQ_MSI = 1 << 1;
+        const PCI_IRQ_MSIX = 1 << 2;
+        const PCI_IRQ_ALL_TYPES=IRQ::PCI_IRQ_LEGACY.bits|IRQ::PCI_IRQ_MSI.bits|IRQ::PCI_IRQ_MSIX.bits;
+    }
+}
+/// PciDeviceStructure的子trait,使用继承以直接使用PciDeviceStructure里的接口
+pub trait PciInterrupt: PciDeviceStructure {
+    /// @brief PCI设备调用该函数选择中断类型
+    /// @param self PCI设备的可变引用
+    /// @param flag 选择的中断类型(支持多个选择),如PCI_IRQ_ALL_TYPES表示所有中断类型均可,让系统按顺序进行选择
+    /// @return Option<IrqType> 失败返回None,成功则返回对应中断类型
+    fn irq_init(&mut self, flag: IRQ) -> Option<IrqType> {
+        // MSIX中断优先
+        if flag.contains(IRQ::PCI_IRQ_MSIX) {
+            if let Some(cap_offset) = self.msix_capability_offset() {
+                let data =
+                    PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 4);
+                let irq_max_num = ((data >> 16) & 0x07ff) as u16;
+                let data =
+                    PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 4);
+                let msix_table_bar = (data & 0x01) as u8;
+                let msix_table_offset = data & 0xfffe;
+                let data =
+                    PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 8);
+                let pending_table_bar = (data & 0x01) as u8;
+                let pending_table_offset = data & 0xfffe;
+                *self.irq_type_mut()? = IrqType::Msix {
+                    msix_table_bar,
+                    msix_table_offset,
+                    pending_table_bar,
+                    pending_table_offset,
+                    irq_max_num,
+                    cap_offset,
+                };
+                return Some(IrqType::Msix {
+                    msix_table_bar,
+                    msix_table_offset,
+                    pending_table_bar,
+                    pending_table_offset,
+                    irq_max_num,
+                    cap_offset,
+                });
+            }
+        }
+        // 其次MSI
+        if flag.contains(IRQ::PCI_IRQ_MSI) {
+            if let Some(cap_offset) = self.msi_capability_offset() {
+                let data =
+                    PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
+                let message_control = (data >> 16) as u16;
+                let maskable = (message_control & 0x0100) != 0;
+                let address_64 = (message_control & 0x0080) != 0;
+                let irq_max_num = (1 << (((message_control & 0x000e) >> 1) + 1)) as u16;
+                *self.irq_type_mut()? = IrqType::Msi {
+                    address_64,
+                    maskable,
+                    irq_max_num,
+                    cap_offset,
+                };
+                return Some(IrqType::Msi {
+                    address_64,
+                    maskable,
+                    irq_max_num,
+                    cap_offset,
+                });
+            }
+        }
+        // 最后选择legacy#
+        if flag.contains(IRQ::PCI_IRQ_LEGACY) {
+            *self.irq_type_mut()? = IrqType::Legacy;
+            return Some(IrqType::Legacy);
+        }
+        None
+    }
+
+    /// @brief 启动/关闭设备中断
+    /// @param self PCI设备的可变引用
+    /// @param enable 开启/关闭
+    fn irq_enable(&mut self, enable: bool) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix { .. } => {
+                    return self.msix_enable(enable);
+                }
+                IrqType::Msi { .. } => {
+                    return self.msi_enable(enable);
+                }
+                IrqType::Legacy => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 启动/关闭设备MSIX中断
+    /// @param self PCI设备的可变引用
+    /// @param enable 开启/关闭
+    fn msix_enable(&mut self, enable: bool) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix { cap_offset, .. } => {
+                    let mut message =
+                        PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
+                    if enable {
+                        message |= 1 << 31;
+                    } else {
+                        message &= !(1 << 31);
+                    }
+                    PciArch::write_config(
+                        &self.common_header().bus_device_function,
+                        cap_offset,
+                        message,
+                    );
+                    return Ok(0);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 启动/关闭设备MSI中断
+    /// @param self PCI设备的可变引用
+    /// @param enable 开启/关闭
+    fn msi_enable(&mut self, enable: bool) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msi { cap_offset, .. } => {
+                    let mut message =
+                        PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
+                    if enable {
+                        message |= 1 << 16;
+                    } else {
+                        message &= !(1 << 16);
+                    }
+                    PciArch::write_config(
+                        &self.common_header().bus_device_function,
+                        cap_offset,
+                        message,
+                    );
+                    return Ok(0);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 获取指定数量的中断号 todo 需要中断重构支持
+    fn irq_alloc(num: u16) -> Option<Vec<u16>> {
+        None
+    }
+    /// @brief 进行PCI设备中断的安装
+    /// @param self PCI设备的可变引用
+    /// @param msg PCI设备install中断时需要传递的共同参数
+    /// @return 一切正常返回Ok(0),有错误返回对应错误原因
+    fn irq_install(&mut self, msg: IrqMsg) -> Result<u8, PciError> {
+        if let Some(irq_vector) = self.irq_vector_mut() {
+            if msg.irq_common_message.irq_index as usize > irq_vector.len() {
+                return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
+                    msg.irq_common_message.irq_index,
+                )));
+            }
+        }
+        self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix { .. } => {
+                    return self.msix_install(msg);
+                }
+                IrqType::Msi { .. } => {
+                    return self.msi_install(msg);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 进行PCI设备中断的安装(MSI)
+    /// @param self PCI设备的可变引用
+    /// @param msg PCI设备install中断时需要传递的共同参数
+    /// @return 一切正常返回Ok(0),有错误返回对应错误原因
+    fn msi_install(&mut self, msg: IrqMsg) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msi {
+                    address_64,
+                    irq_max_num,
+                    cap_offset,
+                    ..
+                } => {
+                    // 注意:MSI中断分配的中断号必须连续且大小为2的倍数
+                    if self.irq_vector_mut().unwrap().len() > irq_max_num as usize {
+                        return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow));
+                    }
+                    let irq_num =
+                        self.irq_vector_mut().unwrap()[msg.irq_common_message.irq_index as usize];
+                    let common_msg = &msg.irq_common_message;
+                    let result = unsafe {
+                        c_irq_install(
+                            irq_num as u64,
+                            Some(common_msg.irq_hander),
+                            common_msg.irq_parameter as u64,
+                            common_msg.irq_name.as_ptr(),
+                            common_msg.irq_ack,
+                        )
+                    };
+                    match result as u32 {
+                        EINVAL => {
+                            return Err(PciError::PciIrqError(PciIrqError::InvalidIrqNum(irq_num)));
+                        }
+                        EAGAIN => {
+                            return Err(PciError::PciIrqError(PciIrqError::IrqNumOccupied(
+                                irq_num,
+                            )));
+                        }
+                        _ => {}
+                    }
+                    //MSI中断只需配置一次PCI寄存器
+                    if common_msg.irq_index == 0 {
+                        let msg_address = ia64_pci_get_arch_msi_message_address(0);
+                        let trigger = match msg.irq_specific_message {
+                            IrqSpecificMsg::Legacy => {
+                                return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                            }
+                            IrqSpecificMsg::Msi { trigger_mode, .. } => trigger_mode,
+                        };
+                        let msg_data = ia64_pci_get_arch_msi_message_data(irq_num, 0, trigger);
+                        //写入Message Data和Message Address
+                        if address_64 {
+                            PciArch::write_config(
+                                &self.common_header().bus_device_function,
+                                cap_offset + 4,
+                                msg_address,
+                            );
+                            PciArch::write_config(
+                                &self.common_header().bus_device_function,
+                                cap_offset + 8,
+                                0,
+                            );
+                            PciArch::write_config(
+                                &self.common_header().bus_device_function,
+                                cap_offset + 12,
+                                msg_data,
+                            );
+                        } else {
+                            PciArch::write_config(
+                                &self.common_header().bus_device_function,
+                                cap_offset + 4,
+                                msg_address,
+                            );
+                            PciArch::write_config(
+                                &self.common_header().bus_device_function,
+                                cap_offset + 8,
+                                msg_data,
+                            );
+                        }
+                        let data = PciArch::read_config(
+                            &self.common_header().bus_device_function,
+                            cap_offset,
+                        );
+                        let message_control = (data >> 16) as u16;
+                        match self.irq_vector_mut().unwrap().len() {
+                            1 => {
+                                let temp = message_control & (!0x0070);
+                                PciArch::write_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset,
+                                    (temp as u32) << 16,
+                                );
+                            }
+                            2 => {
+                                let temp = message_control & (!0x0070);
+                                PciArch::write_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset,
+                                    ((temp | (0x0001 << 4)) as u32) << 16,
+                                );
+                            }
+                            4 => {
+                                let temp = message_control & (!0x0070);
+                                PciArch::write_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset,
+                                    ((temp | (0x0002 << 4)) as u32) << 16,
+                                );
+                            }
+                            8 => {
+                                let temp = message_control & (!0x0070);
+                                PciArch::write_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset,
+                                    ((temp | (0x0003 << 4)) as u32) << 16,
+                                );
+                            }
+                            16 => {
+                                let temp = message_control & (!0x0070);
+                                PciArch::write_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset,
+                                    ((temp | (0x0004 << 4)) as u32) << 16,
+                                );
+                            }
+                            32 => {
+                                let temp = message_control & (!0x0070);
+                                PciArch::write_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset,
+                                    ((temp | (0x0005 << 4)) as u32) << 16,
+                                );
+                            }
+                            _ => {
+                                return Err(PciError::PciIrqError(PciIrqError::MxiIrqNumWrong));
+                            }
+                        }
+                    }
+                    return Ok(0);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 进行PCI设备中断的安装(MSIX)
+    /// @param self PCI设备的可变引用
+    /// @param msg PCI设备install中断时需要传递的共同参数
+    /// @return 一切正常返回Ok(0),有错误返回对应错误原因
+    fn msix_install(&mut self, msg: IrqMsg) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix {
+                    irq_max_num,
+                    msix_table_bar,
+                    msix_table_offset,
+                    ..
+                } => {
+                    if self.irq_vector_mut().unwrap().len() > irq_max_num as usize {
+                        return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow));
+                    }
+                    let irq_num =
+                        self.irq_vector_mut().unwrap()[msg.irq_common_message.irq_index as usize];
+                    let common_msg = &msg.irq_common_message;
+                    let result = unsafe {
+                        c_irq_install(
+                            irq_num as u64,
+                            Some(common_msg.irq_hander),
+                            common_msg.irq_parameter as u64,
+                            common_msg.irq_name.as_ptr(),
+                            common_msg.irq_ack,
+                        )
+                    };
+                    match result as u32 {
+                        EINVAL => {
+                            return Err(PciError::PciIrqError(PciIrqError::InvalidIrqNum(irq_num)));
+                        }
+                        EAGAIN => {
+                            return Err(PciError::PciIrqError(PciIrqError::IrqNumOccupied(
+                                irq_num,
+                            )));
+                        }
+                        _ => {}
+                    }
+
+                    let msg_address = ia64_pci_get_arch_msi_message_address(0);
+                    let trigger = match msg.irq_specific_message {
+                        IrqSpecificMsg::Legacy => {
+                            return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                        }
+                        IrqSpecificMsg::Msi { trigger_mode, .. } => trigger_mode,
+                    };
+                    let msg_data = ia64_pci_get_arch_msi_message_data(irq_num, 0, trigger);
+                    //写入Message Data和Message Address
+                    let pcistandardbar = self
+                        .bar()
+                        .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))?;
+                    let msix_bar = pcistandardbar.get_bar(msix_table_bar)?;
+                    let vaddr = msix_bar
+                        .virtual_address()
+                        .ok_or(PciError::PciIrqError(PciIrqError::BarGetVaddrFailed))?
+                        as usize
+                        + msix_table_offset as usize
+                        + msg.irq_common_message.irq_index as usize * size_of::<MsixEntry>();
+                    let msix_entry = NonNull::new(vaddr as *mut MsixEntry).unwrap();
+                    unsafe {
+                        volwrite!(msix_entry, vector_control, 0);
+                        volwrite!(msix_entry, msg_data, msg_data);
+                        volwrite!(msix_entry, msg_upper_addr, 0);
+                        volwrite!(msix_entry, msg_addr, msg_address);
+                    }
+                    return Ok(0);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 进行PCI设备中断的卸载
+    /// @param self PCI设备的可变引用
+    fn irq_uninstall(&mut self) -> Result<u8, PciError> {
+        self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix { .. } => {
+                    return self.msix_uninstall();
+                }
+                IrqType::Msi { .. } => {
+                    return self.msi_uninstall();
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 进行PCI设备中断的卸载(MSI)
+    /// @param self PCI设备的可变引用
+    fn msi_uninstall(&mut self) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msi {
+                    address_64,
+                    cap_offset,
+                    ..
+                } => {
+                    for vector in self.irq_vector_mut().unwrap() {
+                        unsafe {
+                            c_irq_uninstall(vector.clone() as u64);
+                        }
+                    }
+                    PciArch::write_config(&self.common_header().bus_device_function, cap_offset, 0);
+                    PciArch::write_config(
+                        &self.common_header().bus_device_function,
+                        cap_offset + 4,
+                        0,
+                    );
+                    PciArch::write_config(
+                        &self.common_header().bus_device_function,
+                        cap_offset + 8,
+                        0,
+                    );
+                    if address_64 {
+                        PciArch::write_config(
+                            &self.common_header().bus_device_function,
+                            cap_offset + 12,
+                            0,
+                        );
+                    }
+                    return Ok(0);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 进行PCI设备中断的卸载(MSIX)
+    /// @param self PCI设备的可变引用
+    fn msix_uninstall(&mut self) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix {
+                    irq_max_num,
+                    cap_offset,
+                    msix_table_bar,
+                    msix_table_offset,
+                    ..
+                } => {
+                    for vector in self.irq_vector_mut().unwrap() {
+                        unsafe {
+                            c_irq_uninstall(vector.clone() as u64);
+                        }
+                    }
+                    PciArch::write_config(&self.common_header().bus_device_function, cap_offset, 0);
+                    let pcistandardbar = self
+                        .bar()
+                        .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
+                        .unwrap();
+                    let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
+                    for index in 0..irq_max_num {
+                        let vaddr = msix_bar
+                            .virtual_address()
+                            .ok_or(PciError::PciIrqError(PciIrqError::BarGetVaddrFailed))
+                            .unwrap() as usize
+                            + msix_table_offset as usize
+                            + index as usize * size_of::<MsixEntry>();
+                        let msix_entry = NonNull::new(vaddr as *mut MsixEntry).unwrap();
+                        unsafe {
+                            volwrite!(msix_entry, vector_control, 0);
+                            volwrite!(msix_entry, msg_data, 0);
+                            volwrite!(msix_entry, msg_upper_addr, 0);
+                            volwrite!(msix_entry, msg_addr, 0);
+                        }
+                    }
+                    return Ok(0);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 屏蔽相应位置的中断
+    /// @param self PCI设备的可变引用
+    /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
+    fn irq_mask(&mut self, irq_index: u16) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix { .. } => {
+                    return self.msix_mask(irq_index);
+                }
+                IrqType::Msi { .. } => {
+                    return self.msi_mask(irq_index);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 屏蔽相应位置的中断(MSI)
+    /// @param self PCI设备的可变引用
+    /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
+    fn msi_mask(&mut self, irq_index: u16) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msi {
+                    maskable,
+                    address_64,
+                    cap_offset,
+                    irq_max_num,
+                } => {
+                    if irq_index >= irq_max_num {
+                        return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
+                            irq_index,
+                        )));
+                    }
+                    if maskable {
+                        match address_64 {
+                            true => {
+                                let mut mask = PciArch::read_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset + 16,
+                                );
+                                mask |= 1 << irq_index;
+                                PciArch::write_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset,
+                                    mask,
+                                );
+                            }
+                            false => {
+                                let mut mask = PciArch::read_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset + 12,
+                                );
+                                mask |= 1 << irq_index;
+                                PciArch::write_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset,
+                                    mask,
+                                );
+                            }
+                        }
+                        return Ok(0);
+                    }
+                    return Err(PciError::PciIrqError(PciIrqError::MaskNotSupported));
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 屏蔽相应位置的中断(MSIX)
+    /// @param self PCI设备的可变引用
+    /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
+    fn msix_mask(&mut self, irq_index: u16) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix {
+                    irq_max_num,
+                    msix_table_bar,
+                    msix_table_offset,
+                    ..
+                } => {
+                    if irq_index >= irq_max_num {
+                        return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
+                            irq_index,
+                        )));
+                    }
+                    let pcistandardbar = self
+                        .bar()
+                        .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
+                        .unwrap();
+                    let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
+                    let vaddr = msix_bar.virtual_address().unwrap() as usize
+                        + msix_table_offset as usize
+                        + irq_index as usize * size_of::<MsixEntry>();
+                    let msix_entry = NonNull::new(vaddr as *mut MsixEntry).unwrap();
+                    unsafe {
+                        volwrite!(msix_entry, vector_control, 1);
+                    }
+                    return Ok(0);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 解除屏蔽相应位置的中断
+    /// @param self PCI设备的可变引用
+    /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
+    fn irq_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix { .. } => {
+                    return self.msix_unmask(irq_index);
+                }
+                IrqType::Msi { .. } => {
+                    return self.msi_unmask(irq_index);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 解除屏蔽相应位置的中断(MSI)
+    /// @param self PCI设备的可变引用
+    /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
+    fn msi_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msi {
+                    maskable,
+                    address_64,
+                    cap_offset,
+                    irq_max_num,
+                } => {
+                    if irq_index >= irq_max_num {
+                        return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
+                            irq_index,
+                        )));
+                    }
+                    if maskable {
+                        match address_64 {
+                            true => {
+                                let mut mask = PciArch::read_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset + 16,
+                                );
+                                mask &= !(1 << irq_index);
+                                PciArch::write_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset,
+                                    mask,
+                                );
+                            }
+                            false => {
+                                let mut mask = PciArch::read_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset + 12,
+                                );
+                                mask &= !(1 << irq_index);
+                                PciArch::write_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset,
+                                    mask,
+                                );
+                            }
+                        }
+                    }
+                    return Err(PciError::PciIrqError(PciIrqError::MaskNotSupported));
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 解除屏蔽相应位置的中断(MSIX)
+    /// @param self PCI设备的可变引用
+    /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
+    fn msix_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix {
+                    irq_max_num,
+                    msix_table_bar,
+                    msix_table_offset,
+                    ..
+                } => {
+                    if irq_index >= irq_max_num {
+                        return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
+                            irq_index,
+                        )));
+                    }
+                    let pcistandardbar = self
+                        .bar()
+                        .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
+                        .unwrap();
+                    let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
+                    let vaddr = msix_bar.virtual_address().unwrap() as usize
+                        + msix_table_offset as usize
+                        + irq_index as usize * size_of::<MsixEntry>();
+                    let msix_entry = NonNull::new(vaddr as *mut MsixEntry).unwrap();
+                    unsafe {
+                        volwrite!(msix_entry, vector_control, 0);
+                    }
+                    return Ok(0);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 检查被挂起的中断是否在挂起的时候产生了
+    /// @param self PCI设备的可变引用
+    /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
+    /// @return 是否在挂起过程中产生中断(异常情况也返回false)
+    fn irq_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix { .. } => {
+                    return self.msix_check_pending(irq_index);
+                }
+                IrqType::Msi { .. } => {
+                    return self.msi_check_pending(irq_index);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 检查被挂起的中断是否在挂起的时候产生了(MSI)
+    /// @param self PCI设备的可变引用
+    /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
+    /// @return 是否在挂起过程中产生中断(异常情况也返回false)
+    fn msi_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msi {
+                    maskable,
+                    address_64,
+                    cap_offset,
+                    irq_max_num,
+                } => {
+                    if irq_index >= irq_max_num {
+                        return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
+                            irq_index,
+                        )));
+                    }
+                    if maskable {
+                        match address_64 {
+                            true => {
+                                let mut pend = PciArch::read_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset + 20,
+                                );
+                                pend &= 1 << irq_index;
+                                return Ok(pend != 0);
+                            }
+                            false => {
+                                let mut pend = PciArch::read_config(
+                                    &self.common_header().bus_device_function,
+                                    cap_offset + 16,
+                                );
+                                pend &= 1 << irq_index;
+                                return Ok(pend != 0);
+                            }
+                        }
+                    }
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+    /// @brief 检查被挂起的中断是否在挂起的时候产生了(MSIX)
+    /// @param self PCI设备的可变引用
+    /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
+    /// @return 是否在挂起过程中产生中断(异常情况也返回false)
+    fn msix_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> {
+        if let Some(irq_type) = self.irq_type_mut() {
+            match *irq_type {
+                IrqType::Msix {
+                    irq_max_num,
+                    pending_table_bar,
+                    pending_table_offset,
+                    ..
+                } => {
+                    if irq_index >= irq_max_num {
+                        return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
+                            irq_index,
+                        )));
+                    }
+                    let pcistandardbar = self
+                        .bar()
+                        .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
+                        .unwrap();
+                    let pending_bar = pcistandardbar.get_bar(pending_table_bar).unwrap();
+                    let vaddr = pending_bar.virtual_address().unwrap() as usize
+                        + pending_table_offset as usize
+                        + (irq_index as usize / 64) * size_of::<PendingEntry>();
+                    let pending_entry = NonNull::new(vaddr as *mut PendingEntry).unwrap();
+                    let pending_entry = unsafe { volread!(pending_entry, entry) };
+                    return Ok(pending_entry & (1 << (irq_index as u64 % 64)) != 0);
+                }
+                IrqType::Unused => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
+                }
+                _ => {
+                    return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
+                }
+            }
+        }
+        return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
+    }
+}
+/// PCI标准设备的msi/msix中断相关函数块
+impl PciInterrupt for PciDeviceStructureGeneralDevice {}

+ 0 - 9
kernel/src/driver/usb/Makefile

@@ -1,9 +0,0 @@
-CFLAGS += -I .
-
-all: usb.o xhci.o
-
-usb.o: usb.c
-	$(CC) $(CFLAGS) -c usb.c -o usb.o
-
-xhci.o: xhci/xhci.c
-	$(CC) $(CFLAGS) -c xhci/xhci.c -o xhci/xhci.o

+ 0 - 64
kernel/src/driver/usb/usb.c

@@ -1,64 +0,0 @@
-#include "usb.h"
-#include "xhci/xhci.h"
-#include <common/kprint.h>
-#include <common/errno.h>
-#include <driver/pci/pci.h>
-#include <debug/bug.h>
-#include <common/spinlock.h>
-
-extern spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁
-
-#define MAX_USB_NUM 8 // pci总线上的usb设备的最大数量
-
-// 在pci总线上寻找到的usb设备控制器的header
-static struct pci_device_structure_header_t *usb_pdevs[MAX_USB_NUM];
-static int usb_pdevs_count = 0;
-
-/**
- * @brief 初始化usb驱动程序
- *
- */
-int usb_init(void* unused)
-{
-    kinfo("Initializing usb driver...");
-    spin_init(&xhci_controller_init_lock);
-
-    // 获取所有usb-pci设备的列表
-    pci_get_device_structure(USB_CLASS, USB_SUBCLASS, usb_pdevs, &usb_pdevs_count);
-
-    if (WARN_ON(usb_pdevs_count == 0))
-    {
-        kwarn("There is no usb hardware in this computer!");
-        return 0;
-    }
-    kdebug("usb_pdevs_count=%d", usb_pdevs_count);
-    // 初始化每个usb控制器
-    for (volatile int i = 0; i < usb_pdevs_count; ++i)
-    {
-        io_mfence();
-        switch (usb_pdevs[i]->ProgIF)
-        {
-        case USB_TYPE_UHCI:
-        case USB_TYPE_OHCI:
-        case USB_TYPE_EHCI:
-        case USB_TYPE_UNSPEC:
-        case USB_TYPE_DEVICE:
-            kwarn("Unsupported usb host type: %#02x", usb_pdevs[i]->ProgIF);
-            break;
-
-        case USB_TYPE_XHCI:
-            // 初始化对应的xhci控制器
-            io_mfence();
-            xhci_init((struct pci_device_structure_general_device_t *)usb_pdevs[i]);
-            io_mfence();
-            break;
-
-        default:
-            kerror("Error value of usb_pdevs[%d]->ProgIF: %#02x", i, usb_pdevs[i]->ProgIF);
-            return -EINVAL;
-            break;
-        }
-    }
-    kinfo("Successfully initialized all usb host controllers!");
-    return 0;
-}

+ 0 - 308
kernel/src/driver/usb/usb.h

@@ -1,308 +0,0 @@
-#pragma once
-#include <common/sys/types.h>
-
-// usb设备在pci总线上的class
-#define USB_CLASS 0xC
-#define USB_SUBCLASS 0x3
-
-// 不同的usb设备在pci总线上的prog IF
-#define USB_TYPE_UHCI 0x0
-#define USB_TYPE_OHCI 0x10
-#define USB_TYPE_EHCI 0x20
-#define USB_TYPE_XHCI 0x30
-#define USB_TYPE_UNSPEC 0x80 // Unspecified
-#define USB_TYPE_DEVICE 0xfe // USB Device(Not controller)
-
-// Reset wait times(milliseconds) ,USB 2.0 specs, page 153, section 7.1.7.5, paragraph 3
-#define USB_TIME_RST_RH 50    //  reset on a root hub
-#define USB_TIME_RST_MIN 10   // minimum delay for a reset
-#define USB_TIME_RST_NOMORE 3 // No more than this between resets for root hubs
-#define USB_TIME_RST_REC 10   // reset recovery
-
-/**
- * @brief usb描述符的头部
- *
- * String Descriptor:
- * String Language Descriptor:
- *      先获取头部,然后根据长度申请空间,再获取整个string desc
- */
-struct usb_desc_header
-{
-    uint8_t len; // 整个描述符的大小(字节)
-    uint8_t type;
-} __attribute__((packed));
-
-/**
- * @brief usb 设备描述符
- *
- */
-struct usb_device_desc
-{
-    uint8_t len;
-    uint8_t type;
-    uint16_t usb_version;
-    uint8_t _class;
-    uint8_t subclass;
-    uint8_t protocol;
-    uint8_t max_packet_size;
-
-    uint16_t vendor_id;
-    uint16_t product_id;
-    uint16_t device_rel;
-    uint8_t manufacturer_index;
-    uint8_t procuct_index;
-
-    uint8_t serial_index;
-    uint8_t config; // number of configurations
-} __attribute__((packed));
-
-/**
- * @brief usb设备配置信息描述符
- *
- */
-struct usb_config_desc
-{
-    uint8_t len;            // 当前描述符的大小(字节)
-    uint8_t type;           // USB_DT_CONFIG
-    uint16_t total_len;     /*
-                                Total length of data returned for this
-                                configuration. Includes the combined length
-                                of all descriptors (configuration, interface,
-                                endpoint, and class- or vendor-specific)
-                                returned for this configuration
-                            */
-    uint8_t num_interfaces; // 当前conf对应的接口数量
-    uint8_t value;          /*
-                                Value to use as an argument to the
-                                SetConfiguration() request to select this
-                                configuration
-                            */
-    uint8_t index;          // Index of string descriptor describing this configuration
-    uint8_t bmAttr;         /*
-                                Configuration characteristics:
-                                D7: Reserved (要设置为1)
-                                D6: Self-powered
-                                D5: Remote Wakeup
-                                D4...0: Reserved (设置为0)
-                            */
-    uint8_t max_power;      /*
-                                当这个设备满载时,为在这个conf上提供对应的功能,需要消耗的电流值。
-                                当设备是在High-speed时,这里的单位是2mA (也就是说,值为50,代表最大消耗100mA的电流)
-                                当设备运行在Gen X speed时,这里的单位是8mA
-                            */
-} __attribute__((packed));
-
-/**
- * @brief usb接口描述符
- *
- */
-struct usb_interface_desc
-{
-    uint8_t len;
-    uint8_t type;                // USB_DT_INTERFACE
-    uint8_t interface_number;    // 当前接口序号(从0开始的)
-    uint8_t alternate_setting;   // used to select alt. setting
-    uint8_t num_endpoints;       // 当前interface的端点数量
-    uint8_t interface_class;     // Class code
-    uint8_t interface_sub_class; // Sub class code
-    uint8_t interface_protocol;  // 协议  These codes are qualified by the value of thebInterfaceClass and the
-                                 // bInterfaceSubClass fields.
-    uint8_t index;               // index of String Descriptor describing this interface
-} __attribute__((packed));
-
-/**
- * @brief usb端点描述符
- *
- * 详见usb3.2 Specification Table 9-26
- */
-struct usb_endpoint_desc
-{
-    uint8_t len;
-    uint8_t type;          // descriptor type
-    uint8_t endpoint_addr; /*  Bit 3...0: The endpoint number
-                               Bit 6...4: Reserved, reset to zero
-                               Bit 7: Direction, ignored for
-                               control endpoints
-                               0 = OUT endpoint
-                               1 = IN endpoint
-                               */
-    uint8_t attributes;
-    uint16_t max_packet;
-    uint8_t interval;
-};
-
-// 从endpoint描述符中获取max burst size大小
-#define usb_get_max_burst_from_ep(__ep_desc) (((__ep_desc)->max_packet & 0x1800) >> 11)
-
-/**
- * @brief usb设备请求包
- *
- */
-struct usb_request_packet_t
-{
-    uint8_t request_type;
-    uint8_t request;
-    uint16_t value;
-
-    uint16_t index;
-    uint16_t length;
-} __attribute__((packed));
-// usb设备请求包的request_type字段的值
-#define __USB_REQ_TYPE_H2D 0x00
-#define __USB_REQ_TYPE_D2H 0x80
-
-#define __USB_REQ_TYPE_STANDARD 0x00
-#define __USB_REQ_TYPE_CLASS 0x20
-#define __USB_REQ_TYPE_VENDOR 0x40
-#define __USB_REQ_TYPE_RSVD 0x60
-
-#define __USB_REQ_TYPE_DEVICE 0x00
-#define __USB_REQ_TYPE_INTERFACE 0x01
-#define __USB_REQ_TYPE_ENDPOINT 0x02
-#define __USB_REQ_TYPE_OTHER 0x03
-
-#define USB_REQ_TYPE_GET_REQUEST (__USB_REQ_TYPE_D2H | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_DEVICE)
-#define USB_REQ_TYPE_SET_REQUEST (__USB_REQ_TYPE_H2D | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_DEVICE)
-#define USB_REQ_TYPE_GET_INTERFACE_REQUEST (__USB_REQ_TYPE_D2H | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_INTERFACE)
-#define USB_REQ_TYPE_SET_INTERFACE (__USB_REQ_TYPE_H2D | __USB_REQ_TYPE_STANDARD | __USB_REQ_TYPE_INTERFACE)
-#define USB_REQ_TYPE_SET_CLASS_INTERFACE (__USB_REQ_TYPE_H2D | __USB_REQ_TYPE_CLASS | __USB_REQ_TYPE_INTERFACE)
-
-// device requests
-enum
-{
-    USB_REQ_GET_STATUS = 0,
-    USB_REQ_CLEAR_FEATURE,
-    USB_REQ_SET_FEATURE = 3,
-    USB_REQ_SET_ADDRESS = 5,
-    USB_REQ_GET_DESCRIPTOR = 6,
-    USB_REQ_SET_DESCRIPTOR,
-    USB_REQ_GET_CONFIGURATION,
-    USB_REQ_SET_CONFIGURATION,
-    // interface requests
-    USB_REQ_GET_INTERFACE,
-    USB_REQ_SET_INTERFACE,
-    // standard endpoint requests
-    USB_REQ_SYNCH_FRAME,
-    USB_REQ_SET_ENCRYPTION,
-    USB_REQ_GET_ENCRYPTION,
-    USB_REQ_SET_HANDSHAKE,
-    USB_REQ_GET_HANDSHAKE,
-    USB_REQ_SET_CONNECTION,
-    USB_REQ_SET_SECURITY_DATA,
-    USB_REQ_GET_SECURITY_DATA,
-    USB_REQ_SET_WUSB_DATA,
-    USB_REQ_LOOPBACK_DATA_WRITE,
-    USB_REQ_LOOPBACK_DATA_READ,
-    USB_REQ_SET_INTERFACE_DS,
-    USB_REQ_GET_FW_STATUS = 26,
-    USB_REQ_SET_FW_STATUS,
-    USB_REQ_SET_SEL = 48,
-    USB_REQ_SET_ISOCH_DELAY,
-    // Device specific
-    USB_REQ_GET_MAX_LUNS = 0xFE,
-    USB_REQ_BULK_ONLY_RESET
-};
-
-// Descriptor types
-enum
-{
-    USB_DT_DEVICE = 1,
-    USB_DT_CONFIG,
-    USB_DT_STRING,
-    USB_DT_INTERFACE,
-    USB_DT_ENDPOINT,
-    USB_DT_DEVICE_QUALIFIER,
-    USB_DT_OTHER_SPEED_CONFIG,
-    USB_DT_INTERFACE_POWER,
-    USB_DT_OTG,
-    USB_DT_DEBUG,
-    USB_DT_INTERFACE_ASSOSIATION,
-    USB_DT_BOS = 15,
-    USB_DT_DEVICE_CAPABILITY,
-
-    USB_DT_HID = 0x21,
-    USB_DT_HID_REPORT,
-    USB_DT_HID_PHYSICAL,
-
-    USB_DT_INTERFACE_FUNCTION = 0x24,
-    USB_DT_ENDPOINT_FUNCTION,
-
-    // HUB = 0x29
-
-    USB_DT_SUPERSPEED_USB_ENDPOINT_COMPANION = 48,
-    USB_DT_SUPERSPEEDPLUS_ISOCHRONOUS_ENDPOINT_COMPANION,
-};
-
-// transfer types (Endpoint types) (USB 2.0 page 270)
-enum
-{
-    USB_EP_CONTROL = 0,
-    USB_EP_ISOCHRONOUS,
-    USB_EP_BULK,
-    USB_EP_INTERRUPT
-};
-
-/**
- * @brief 该宏定义用于声明usb请求包,并初始化其中的各个字段
- *
- */
-#define DECLARE_USB_PACKET(pak_name, _trans_req_type, _trans_request, _trans_value, _trans_index, _transfer_length)    \
-    struct usb_request_packet_t pak_name = {0};                                                                        \
-    pak_name.request_type = (_trans_req_type);                                                                         \
-    pak_name.request = (_trans_request);                                                                               \
-    pak_name.value = (_trans_value);                                                                                   \
-    pak_name.index = (_trans_index);                                                                                   \
-    pak_name.length = (_transfer_length);
-
-/*
-    usb class codes
-    refs: https://www.usb.org/defined-class-codes
-*/
-enum
-{
-    USB_CLASS_IF = 0x00,
-    USB_CLASS_AUDIO,
-    USB_CLASS_CDC,
-    USB_CLASS_HID,
-    USB_CLASS_PHYSICAL = 0x05,
-    USB_CLASS_IMAGE,
-    USB_CLASS_PRINTER,
-    USB_CLASS_MASS_STORAGE,
-    USB_CLASS_HUB,
-    USB_CLASS_CDC_DATA,
-    USB_CLASS_SMART_CARD,
-    USB_CLASS_CONTENT_SEC = 0x0d,
-    USB_CLASS_VIDEO,
-    USB_CLASS_PERSONAL_HEALTHCARE = 0x0f,
-    USB_CLASS_AV,
-    USB_CLASS_BILLBOARD,
-    USB_CLASS_TYPEC_BRIDGE,
-    USB_CLASS_I3C = 0x3c,
-    USB_CLASS_DIAGNOSTIC = 0xdc,
-    USB_CLASS_WIRELESS_CTRL = 0xe0,
-    USB_CLASS_MISC = 0xef,
-    USB_CLASS_APP_SPEC = 0xfe,
-    USB_CLASS_VENDOR_SPEC = 0XFF,
-};
-
-/**
- * @brief usb hid descriptor的结构体
- *
- */
-struct usb_hid_desc
-{
-    uint8_t len;
-    uint8_t type;    // USB_DT_HID
-    uint16_t bcdHID; // 标识HIDClass规范版本的数字表达式。
-
-    uint8_t country_code;
-    uint8_t descriptors_num;  //  the number of class descriptors
-    uint8_t desc_type;        // Constant name identifying type of class descriptor
-    uint16_t report_desc_len; // Report descriptor的大小
-};
-
-/**
- * @brief 初始化usb驱动程序
- *
- */
-int usb_init();

+ 0 - 87
kernel/src/driver/usb/xhci/internal.h

@@ -1,87 +0,0 @@
-#pragma once
-
-/*
-    注意!!!
-
-    尽管采用MMI/O的方式访问寄存器,但是对于指定大小的寄存器,
-    在发起读请求的时候,只能从寄存器的起始地址位置开始读取。
-
-    例子:不能在一个32bit的寄存器中的偏移量8的位置开始读取1个字节
-            这种情况下,我们必须从32bit的寄存器的0地址处开始读取32bit,然后通过移位的方式得到其中的字节。
-*/
-
-#define xhci_read_cap_reg32(id, offset) (__read4b(xhci_hc[id].vbase + (offset)))
-#define xhci_get_ptr_cap_reg32(id, offset) ((uint32_t *)(xhci_hc[id].vbase + (offset)))
-#define xhci_write_cap_reg32(id, offset, value) (__write4b(xhci_hc[id].vbase + (offset), (value)))
-
-#define xhci_read_cap_reg64(id, offset) (__read8b(xhci_hc[id].vbase + (offset)))
-#define xhci_get_ptr_reg64(id, offset) ((uint64_t *)(xhci_hc[id].vbase + (offset)))
-#define xhci_write_cap_reg64(id, offset, value) (__write8b(xhci_hc[id].vbase + (offset), (value)))
-
-#define xhci_read_op_reg8(id, offset) (*(uint8_t *)(xhci_hc[id].vbase_op + (offset)))
-#define xhci_get_ptr_op_reg8(id, offset) ((uint8_t *)(xhci_hc[id].vbase_op + (offset)))
-#define xhci_write_op_reg8(id, offset, value) (*(uint8_t *)(xhci_hc[id].vbase_op + (offset)) = (uint8_t)(value))
-
-#define xhci_read_op_reg32(id, offset) (__read4b(xhci_hc[id].vbase_op + (offset)))
-#define xhci_get_ptr_op_reg32(id, offset) ((uint32_t *)(xhci_hc[id].vbase_op + (offset)))
-#define xhci_write_op_reg32(id, offset, value) (__write4b(xhci_hc[id].vbase_op + (offset), (value)))
-
-#define xhci_read_op_reg64(id, offset) (__read8b(xhci_hc[id].vbase_op + (offset)))
-#define xhci_get_ptr_op_reg64(id, offset) ((uint64_t *)(xhci_hc[id].vbase_op + (offset)))
-#define xhci_write_op_reg64(id, offset, value) (__write8b(xhci_hc[id].vbase_op + (offset), (value)))
-
-/**
- * @brief 计算中断寄存器组虚拟地址
- * @param id 主机控制器id
- * @param num xhci中断寄存器组号
- */
-#define xhci_calc_intr_vaddr(id, num) (xhci_hc[id].vbase + xhci_hc[id].rts_offset + XHCI_RT_IR0 + (num)*XHCI_IR_SIZE)
-/**
- * @brief 读取/写入中断寄存器
- * @param id 主机控制器id
- * @param num xhci中断寄存器组号
- * @param intr_offset 寄存器在当前寄存器组中的偏移量
- */
-#define xhci_read_intr_reg32(id, num, intr_offset) (__read4b(xhci_calc_intr_vaddr(id, num) + (intr_offset)))
-#define xhci_write_intr_reg32(id, num, intr_offset, value) (__write4b(xhci_calc_intr_vaddr(id, num) + (intr_offset), (value)))
-#define xhci_read_intr_reg64(id, num, intr_offset) (__read8b(xhci_calc_intr_vaddr(id, num) + (intr_offset)))
-#define xhci_write_intr_reg64(id, num, intr_offset, value) (__write8b(xhci_calc_intr_vaddr(id, num) + (intr_offset), (value)))
-
-#define xhci_is_aligned64(addr) (((addr)&0x3f) == 0) // 是否64bytes对齐
-
-/**
- * @brief 判断端口信息
- * @param cid 主机控制器id
- * @param pid 端口id
- */
-#define XHCI_PORT_IS_USB2(cid, pid) ((xhci_hc[cid].ports[pid].flags & XHCI_PROTOCOL_INFO) == XHCI_PROTOCOL_USB2)
-#define XHCI_PORT_IS_USB3(cid, pid) ((xhci_hc[cid].ports[pid].flags & XHCI_PROTOCOL_INFO) == XHCI_PROTOCOL_USB3)
-
-#define XHCI_PORT_IS_USB2_HSO(cid, pid) ((xhci_hc[cid].ports[pid].flags & XHCI_PROTOCOL_HSO) == XHCI_PROTOCOL_HSO)
-#define XHCI_PORT_HAS_PAIR(cid, pid) ((xhci_hc[cid].ports[pid].flags & XHCI_PROTOCOL_HAS_PAIR) == XHCI_PROTOCOL_HAS_PAIR)
-#define XHCI_PORT_IS_ACTIVE(cid, pid) ((xhci_hc[cid].ports[pid].flags & XHCI_PROTOCOL_ACTIVE) == XHCI_PROTOCOL_ACTIVE)
-
-#define XHCI_PORT_REGISTER_OFFSET(__port_id) (XHCI_OPS_PRS + 16 * (__port_id))
-
-// 获取端口速度 full=1, low=2, high=3, super=4
-#define xhci_get_port_speed(__id, __port_id) ((xhci_read_op_reg32((__id), XHCI_PORT_REGISTER_OFFSET(__port_id) + XHCI_PORT_PORTSC) >> 10) & 0xf)
-
-/**
- * @brief 设置link TRB的命令(dword3)
- *
- */
-#define xhci_TRB_set_link_cmd(trb_vaddr)                                         \
-    do                                                                           \
-    {                                                                            \
-        struct xhci_TRB_normal_t *ptr = (struct xhci_TRB_normal_t *)(trb_vaddr); \
-        ptr->TRB_type = TRB_TYPE_LINK;                                           \
-        ptr->ioc = 0;                                                            \
-        ptr->chain = 0;                                                          \
-        ptr->ent = 0;                                                            \
-        ptr->cycle = 1;                                                          \
-    } while (0)
-
-// 设置endpoint结构体的dequeue_cycle_state bit
-#define xhci_ep_set_dequeue_cycle_state(ep_ctx_ptr, state) ((ep_ctx_ptr)->tr_dequeue_ptr |= ((state)&1))
-// 获取endpoint结构体的dequeue_cycle_state bit
-#define xhci_ep_get_dequeue_cycle_state(ep_ctx_ptr) (((ep_ctx_ptr)->tr_dequeue_ptr) & 1)

+ 0 - 2271
kernel/src/driver/usb/xhci/xhci.c

@@ -1,2271 +0,0 @@
-#include "xhci.h"
-#include "internal.h"
-#include <common/hid.h>
-#include <common/kprint.h>
-#include <common/spinlock.h>
-#include <common/time.h>
-#include <debug/bug.h>
-#include <debug/traceback/traceback.h>
-#include <driver/interrupt/apic/apic.h>
-#include <exception/irq.h>
-#include <mm/mm.h>
-#include <mm/slab.h>
-
-// 由于xhci寄存器读取需要对齐,因此禁用GCC优化选项
-#pragma GCC optimize("O0")
-
-spinlock_t xhci_controller_init_lock = {0}; // xhci控制器初始化锁(在usb_init中被初始化)
-
-static int xhci_ctrl_count = 0; // xhci控制器计数
-
-static struct xhci_host_controller_t xhci_hc[XHCI_MAX_HOST_CONTROLLERS] = {0};
-
-void xhci_hc_irq_enable(uint64_t irq_num);
-void xhci_hc_irq_disable(uint64_t irq_num);
-uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg);
-void xhci_hc_irq_uninstall(uint64_t irq_num);
-
-static int xhci_hc_find_available_id();
-static int xhci_hc_stop(int id);
-static int xhci_hc_reset(int id);
-static int xhci_hc_stop_legacy(int id);
-static int xhci_hc_start_sched(int id);
-static int xhci_hc_stop_sched(int id);
-static uint32_t xhci_hc_get_protocol_offset(int id, uint32_t list_off, const int version, uint32_t *offset,
-                                            uint32_t *count, uint16_t *protocol_flag);
-static int xhci_hc_pair_ports(int id);
-static uint64_t xhci_create_ring(int trbs);
-static uint64_t xhci_create_event_ring(int trbs, uint64_t *ret_ring_addr);
-void xhci_hc_irq_handler(uint64_t irq_num, uint64_t cid, struct pt_regs *regs);
-static int xhci_hc_init_intr(int id);
-static int xhci_hc_start_ports(int id);
-
-static int xhci_send_command(int id, struct xhci_TRB_t *trb, const bool do_ring);
-static uint64_t xhci_initialize_slot(const int id, const int port, const int speed, const int max_packet);
-static void xhci_initialize_ep(const int id, const uint64_t slot_vaddr, const int port_id, const int ep_num,
-                               const int max_packet, const int max_burst, const int type, const int direction,
-                               const int speed, const int ep_interval);
-static int xhci_set_address(const int id, const uint64_t slot_vaddr, const int slot_id, const bool block);
-static int xhci_control_in(const int id, struct usb_request_packet_t *packet, void *target, const int port_id,
-                           const int max_packet);
-static int xhci_control_out(const int id, struct usb_request_packet_t *packet, void *target, const int slot_id,
-                            const int max_packet);
-static int xhci_setup_stage(struct xhci_ep_info_t *ep, const struct usb_request_packet_t *packet,
-                            const uint8_t direction);
-static int xhci_data_stage(struct xhci_ep_info_t *ep, uint64_t buf_vaddr, uint8_t trb_type, const uint32_t size,
-                           uint8_t direction, const int max_packet, const uint64_t status_vaddr);
-static int xhci_status_stage(struct xhci_ep_info_t *ep, uint8_t direction, uint64_t status_buf_vaddr);
-static int xhci_wait_for_interrupt(const int id, uint64_t status_vaddr);
-static inline int xhci_get_desc(const int id, const int port_id, void *target, const uint16_t desc_type,
-                                const uint8_t desc_index, const uint16_t lang_id, const uint16_t length);
-static int xhci_get_config_desc(const int id, const int port_id, struct usb_config_desc *conf_desc);
-static inline int xhci_get_config_desc_full(const int id, const int port_id, const struct usb_config_desc *conf_desc,
-                                            void *target);
-static int xhci_get_interface_desc(const void *in_buf, const uint8_t if_num, struct usb_interface_desc **if_desc);
-static inline int xhci_get_endpoint_desc(const struct usb_interface_desc *if_desc, const uint8_t ep_num,
-                                         struct usb_endpoint_desc **ep_desc);
-static int xhci_get_descriptor(const int id, const int port_id, struct usb_device_desc *dev_desc);
-static int xhci_configure_port(const int id, const int port_id);
-static int xhci_configure_endpoint(const int id, const int port_id, const uint8_t ep_num, const uint8_t ep_type,
-                                   struct usb_endpoint_desc *ep_desc);
-static int xhci_get_hid_report(int id, int port_id, int interface_number, void *ret_hid_report,
-                               uint32_t hid_report_len);
-static int xhci_get_hid_descriptor(int id, int port_id, const void *full_conf, int interface_number,
-                                   struct usb_hid_desc **ret_hid_desc);
-
-hardware_intr_controller xhci_hc_intr_controller = {
-    .enable = xhci_hc_irq_enable,
-    .disable = xhci_hc_irq_disable,
-    .install = xhci_hc_irq_install,
-    .uninstall = xhci_hc_irq_uninstall,
-    .ack = apic_local_apic_edge_ack,
-};
-
-/**
- * @brief 在controller数组之中寻找可用插槽
- *
- * 注意:该函数只能被获得init锁的进程所调用
- * @return int 可用id(无空位时返回-1)
- */
-static int xhci_hc_find_available_id()
-{
-    if (unlikely(xhci_ctrl_count >= XHCI_MAX_HOST_CONTROLLERS))
-        return -1;
-
-    for (int i = 0; i < XHCI_MAX_HOST_CONTROLLERS; ++i)
-    {
-        if (xhci_hc[i].pci_dev_hdr == NULL)
-            return i;
-    }
-    return -1;
-}
-
-/**
- * @brief 从指定地址读取trb
- *
- * @param trb 要存储到的trb的地址
- * @param address 待读取trb的地址
- */
-static __always_inline void xhci_get_trb(struct xhci_TRB_t *trb, const uint64_t address)
-{
-    trb->param = __read8b(address);
-    trb->status = __read4b(address + 8);
-    trb->command = __read4b(address + 12);
-}
-
-/**
- * @brief 将给定的trb写入指定的地址
- *
- * @param trb 源trb
- * @param address 拷贝的目标地址
- */
-static __always_inline void xhci_set_trb(struct xhci_TRB_t *trb, const uint64_t address)
-{
-    __write8b(address, trb->param);
-    __write4b(address + 8, trb->status);
-    __write4b(address + 12, trb->command);
-}
-
-/**
- * @brief 将ep结构体写入到设备上下文中的对应块内
- *
- * @param id 主机控制器id
- * @param slot_vaddr 设备上下文虚拟地址
- * @param ep_num ep结构体要写入到哪个块中(在设备上下文中的块号)
- * @param ep 源数据
- */
-static __always_inline void __write_ep(int id, uint64_t slot_vaddr, int ep_num, struct xhci_ep_context_t *ep)
-{
-    memcpy((void *)(slot_vaddr + ep_num * xhci_hc[id].context_size), ep, sizeof(struct xhci_ep_context_t));
-}
-
-/**
- * @brief 从设备上下文中的对应块内读取数据到ep结构体
- *
- * @param id 主机控制器id
- * @param slot_vaddr 设备上下文虚拟地址
- * @param ep_num 要从哪个块中读取(在设备上下文中的块号)
- * @param ep 目标地址
- */
-static __always_inline void __read_from_ep(int id, uint64_t slot_vaddr, int ep_num, struct xhci_ep_context_t *ep)
-{
-    memcpy(ep, (void *)(slot_vaddr + ep_num * xhci_hc[id].context_size), sizeof(struct xhci_ep_context_t));
-}
-
-/**
- * @brief 将slot上下文数组结构体写入插槽的上下文空间
- *
- * @param vaddr 目标地址
- * @param slot_ctx slot上下文数组
- */
-static __always_inline void __write_slot(const uint64_t vaddr, struct xhci_slot_context_t *slot_ctx)
-{
-    memcpy((void *)vaddr, slot_ctx, sizeof(struct xhci_slot_context_t));
-}
-
-/**
- * @brief 从指定地址读取slot context
- *
- * @param slot_ctx 目标地址
- * @param slot_vaddr 源地址
- * @return __always_inline
- */
-static __always_inline void __read_from_slot(struct xhci_slot_context_t *slot_ctx, uint64_t slot_vaddr)
-{
-    memcpy(slot_ctx, (void *)slot_vaddr, sizeof(struct xhci_slot_context_t));
-}
-
-/**
- * @brief 写入doorbell寄存器
- *
- * @param id 主机控制器id
- * @param slot_id usb控制器插槽id(0用作命令门铃,其他的用于具体的设备的门铃)
- * @param value endpoint
- */
-static __always_inline void __xhci_write_doorbell(const int id, const uint16_t slot_id, const uint32_t value)
-{
-    // 确保写入门铃寄存器之前,所有的写操作均已完成
-    io_mfence();
-    xhci_write_cap_reg32(id, xhci_hc[id].db_offset + slot_id * sizeof(uint32_t), value);
-    io_mfence();
-}
-
-/**
- * @brief 将trb写入指定的ring中,并更新下一个要写入的地址的值
- *
- * @param ep_info 端点信息结构体
- * @param trb 待写入的trb
- */
-static __always_inline void __xhci_write_trb(struct xhci_ep_info_t *ep_info, struct xhci_TRB_t *trb)
-{
-    memcpy((void *)ep_info->current_ep_ring_vaddr, trb, sizeof(struct xhci_TRB_t));
-
-    ep_info->current_ep_ring_vaddr += sizeof(struct xhci_TRB_t);
-
-    struct xhci_TRB_normal_t *ptr = (struct xhci_TRB_normal_t *)(ep_info->current_ep_ring_vaddr);
-
-    // ring到头了,转换cycle,然后回到第一个trb
-    if (unlikely(ptr->TRB_type == TRB_TYPE_LINK))
-    {
-        ptr->cycle = ep_info->current_ep_ring_cycle;
-        ep_info->current_ep_ring_vaddr = ep_info->ep_ring_vbase;
-        ep_info->current_ep_ring_cycle ^= 1;
-    }
-}
-
-/**
- * @brief 获取设备上下文缓冲区的虚拟地址
- *
- * @param id 主机控制器id
- * @param port_id 端口id
- * @return 设备上下文缓冲区的虚拟地址
- */
-static __always_inline uint64_t xhci_get_device_context_vaddr(const int id, const int port_id)
-{
-    return (uint64_t)phys_2_virt(
-        __read8b(xhci_hc[id].dcbaap_vaddr + (xhci_hc[id].ports[port_id].slot_id * sizeof(uint64_t))));
-}
-
-/**
- * @brief 停止xhci主机控制器
- *
- * @param id 主机控制器id
- * @return int
- */
-static int xhci_hc_stop(int id)
-{
-
-    // 判断是否已经停止
-    if (unlikely((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 1))
-        return 0;
-    io_mfence();
-    xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00000000);
-    io_mfence();
-    char timeout = 17;
-    while ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
-    {
-        io_mfence();
-        rs_usleep(1000);
-        if (--timeout == 0)
-            return -ETIMEDOUT;
-    }
-
-    return 0;
-}
-
-/**
- * @brief reset xHCI主机控制器
- *
- * @param id 主机控制器id
- * @return int
- */
-static int xhci_hc_reset(int id)
-{
-    int retval = 0;
-    io_mfence();
-    // 判断HCHalted是否置位
-    if ((xhci_read_op_reg32(id, XHCI_OPS_USBSTS) & (1 << 0)) == 0)
-    {
-        io_mfence();
-        kdebug("stopping usb hc...");
-        // 未置位,需要先尝试停止usb主机控制器
-        retval = xhci_hc_stop(id);
-        if (unlikely(retval))
-            return retval;
-    }
-    int timeout = 500; // wait 500ms
-    // reset
-    uint32_t cmd = xhci_read_op_reg32(id, XHCI_OPS_USBCMD);
-    io_mfence();
-
-    cmd |= (1 << 1);
-    xhci_write_op_reg32(id, XHCI_OPS_USBCMD, cmd);
-    io_mfence();
-    io_mfence();
-    while (xhci_read_op_reg32(id, XHCI_OPS_USBCMD) & (1 << 1))
-    {
-        io_mfence();
-        rs_usleep(1000);
-        if (--timeout == 0)
-            return -ETIMEDOUT;
-    }
-
-    return retval;
-}
-
-/**
- * @brief 停止指定xhci控制器的legacy support
- *
- * @param id 控制器id
- * @return int
- */
-static int xhci_hc_stop_legacy(int id)
-{
-    uint64_t current_offset = xhci_hc[id].ext_caps_off;
-
-    do
-    {
-        // 判断当前entry是否为legacy support entry
-        if ((xhci_read_cap_reg32(id, current_offset) & 0xff) == XHCI_XECP_ID_LEGACY)
-        {
-            io_mfence();
-            // 接管控制权
-            xhci_write_cap_reg32(id, current_offset,
-                                 xhci_read_cap_reg32(id, current_offset) | XHCI_XECP_LEGACY_OS_OWNED);
-            io_mfence();
-            // 等待响应完成
-            int timeout = XHCI_XECP_LEGACY_TIMEOUT;
-            while ((xhci_read_cap_reg32(id, current_offset) & XHCI_XECP_LEGACY_OWNING_MASK) !=
-                   XHCI_XECP_LEGACY_OS_OWNED)
-            {
-                io_mfence();
-                rs_usleep(1000);
-                if (--timeout == 0)
-                {
-                    kerror("The BIOS doesn't stop legacy support.");
-                    return -ETIMEDOUT;
-                }
-            }
-            // 处理完成
-            return 0;
-        }
-        io_mfence();
-        // 读取下一个entry的偏移增加量
-        int next_off = ((xhci_read_cap_reg32(id, current_offset) & 0xff00) >> 8) << 2;
-        io_mfence();
-        // 将指针跳转到下一个entry
-        current_offset = next_off ? (current_offset + next_off) : 0;
-    } while (current_offset);
-
-    // 当前controller不存在legacy支持,也问题不大,不影响
-    return 0;
-}
-
-/**
- * @brief 启用指定xhci控制器的调度
- *
- * @param id 控制器id
- * @return int
- */
-static int xhci_hc_start_sched(int id)
-{
-    io_mfence();
-    xhci_write_op_reg32(id, XHCI_OPS_USBCMD, (1 << 0) | (1 << 2) | (1 << 3));
-    io_mfence();
-    rs_usleep(100 * 1000);
-}
-
-/**
- * @brief 停止指定xhci控制器的调度
- *
- * @param id 控制器id
- * @return int
- */
-static int xhci_hc_stop_sched(int id)
-{
-    io_mfence();
-    xhci_write_op_reg32(id, XHCI_OPS_USBCMD, 0x00);
-    io_mfence();
-}
-
-/**
- * @brief 在Ex capability list中寻找符合指定的协议号的寄存器offset、count、flag信息
- *
- * @param id 主机控制器id
- * @param list_off 列表项位置距离控制器虚拟基地址的偏移量
- * @param version 要寻找的端口版本号(2或3)
- * @param offset 返回的 Compatible Port Offset
- * @param count 返回的 Compatible Port Count
- * @param protocol_flag 返回的与协议相关的flag
- * @return uint32_t 下一个列表项的偏移量
- */
-static uint32_t xhci_hc_get_protocol_offset(int id, uint32_t list_off, const int version, uint32_t *offset,
-                                            uint32_t *count, uint16_t *protocol_flag)
-{
-    if (count)
-        *count = 0;
-
-    do
-    {
-        uint32_t dw0 = xhci_read_cap_reg32(id, list_off);
-        io_mfence();
-        uint32_t next_list_off = (dw0 >> 8) & 0xff;
-        next_list_off = next_list_off ? (list_off + (next_list_off << 2)) : 0;
-
-        if ((dw0 & 0xff) == XHCI_XECP_ID_PROTOCOL && ((dw0 & 0xff000000) >> 24) == version)
-        {
-            uint32_t dw2 = xhci_read_cap_reg32(id, list_off + 8);
-            io_mfence();
-            if (offset != NULL)
-                *offset = (uint32_t)(dw2 & 0xff) - 1; // 使其转换为zero based
-            if (count != NULL)
-                *count = (uint32_t)((dw2 & 0xff00) >> 8);
-            if (protocol_flag != NULL && version == 2)
-                *protocol_flag = (uint16_t)((dw2 >> 16) & 0x0fff);
-
-            return next_list_off;
-        }
-
-        list_off = next_list_off;
-    } while (list_off);
-
-    return 0;
-}
-/**
- * @brief 配对xhci主机控制器的usb2、usb3端口
- *
- * @param id 主机控制器id
- * @return int 返回码
- */
-static int xhci_hc_pair_ports(int id)
-{
-
-    struct xhci_caps_HCSPARAMS1_reg_t hcs1;
-    io_mfence();
-    memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t));
-    io_mfence();
-    // 从hcs1获取端口数量
-    xhci_hc[id].port_num = hcs1.max_ports;
-
-    // 找到所有的端口并标记其端口信息
-
-    xhci_hc[id].port_num_u2 = 0;
-    xhci_hc[id].port_num_u3 = 0;
-
-    uint32_t next_off = xhci_hc[id].ext_caps_off;
-    uint32_t offset, cnt;
-    uint16_t protocol_flags = 0;
-
-    // 寻找所有的usb2端口
-    while (next_off)
-    {
-        io_mfence();
-        next_off = xhci_hc_get_protocol_offset(id, next_off, 2, &offset, &cnt, &protocol_flags);
-        io_mfence();
-
-        if (cnt)
-        {
-            for (int i = 0; i < cnt; ++i)
-            {
-                io_mfence();
-                xhci_hc[id].ports[offset + i].offset = xhci_hc[id].port_num_u2++;
-                xhci_hc[id].ports[offset + i].flags = XHCI_PROTOCOL_USB2;
-                io_mfence();
-                // usb2 high speed only
-                if (protocol_flags & 2)
-                    xhci_hc[id].ports[offset + i].flags |= XHCI_PROTOCOL_HSO;
-            }
-        }
-    }
-
-    // 寻找所有的usb3端口
-    next_off = xhci_hc[id].ext_caps_off;
-    while (next_off)
-    {
-        io_mfence();
-        next_off = xhci_hc_get_protocol_offset(id, next_off, 3, &offset, &cnt, &protocol_flags);
-        io_mfence();
-
-        if (cnt)
-        {
-            for (int i = 0; i < cnt; ++i)
-            {
-                io_mfence();
-                xhci_hc[id].ports[offset + i].offset = xhci_hc[id].port_num_u3++;
-                xhci_hc[id].ports[offset + i].flags = XHCI_PROTOCOL_USB3;
-            }
-        }
-    }
-
-    // 将对应的USB2端口和USB3端口进行配对
-    for (int i = 0; i < xhci_hc[id].port_num; ++i)
-    {
-        for (int j = 0; j < xhci_hc[id].port_num; ++j)
-        {
-            if (unlikely(i == j))
-                continue;
-            io_mfence();
-            if ((xhci_hc[id].ports[i].offset == xhci_hc[id].ports[j].offset) &&
-                ((xhci_hc[id].ports[i].flags & XHCI_PROTOCOL_INFO) !=
-                 (xhci_hc[id].ports[j].flags & XHCI_PROTOCOL_INFO)))
-            {
-                xhci_hc[id].ports[i].paired_port_num = j;
-                xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_HAS_PAIR;
-                io_mfence();
-                xhci_hc[id].ports[j].paired_port_num = i;
-                xhci_hc[id].ports[j].flags |= XHCI_PROTOCOL_HAS_PAIR;
-            }
-        }
-    }
-
-    // 标记所有的usb3、单独的usb2端口为激活状态
-    for (int i = 0; i < xhci_hc[id].port_num; ++i)
-    {
-        io_mfence();
-        if (XHCI_PORT_IS_USB3(id, i) || (XHCI_PORT_IS_USB2(id, i) && (!XHCI_PORT_HAS_PAIR(id, i))))
-            xhci_hc[id].ports[i].flags |= XHCI_PROTOCOL_ACTIVE;
-    }
-    kinfo("Found %d ports on root hub, usb2 ports:%d, usb3 ports:%d", xhci_hc[id].port_num, xhci_hc[id].port_num_u2,
-          xhci_hc[id].port_num_u3);
-
-    /*
-    // 打印配对结果
-    for (int i = 1; i <= xhci_hc[id].port_num; ++i)
-    {
-        if (XHCI_PORT_IS_USB3(id, i))
-        {
-            kdebug("USB3 port %d, offset=%d, pair with usb2 port %d, current port is %s", i,
-    xhci_hc[id].ports[i].offset, xhci_hc[id].ports[i].paired_port_num, XHCI_PORT_IS_ACTIVE(id, i) ? "active" :
-    "inactive");
-        }
-        else if (XHCI_PORT_IS_USB2(id, i) && (!XHCI_PORT_HAS_PAIR(id, i))) // 单独的2.0接口
-        {
-            kdebug("Stand alone USB2 port %d, offset=%d, current port is %s", i, xhci_hc[id].ports[i].offset,
-                   XHCI_PORT_IS_ACTIVE(id, i) ? "active" : "inactive");
-        }
-        else if (XHCI_PORT_IS_USB2(id, i))
-        {
-            kdebug("USB2 port %d, offset=%d, current port is %s, has pair=%s", i, xhci_hc[id].ports[i].offset,
-                   XHCI_PORT_IS_ACTIVE(id, i) ? "active" : "inactive", XHCI_PORT_HAS_PAIR(id, i) ? "true" : "false");
-        }
-    }
-    */
-
-    return 0;
-}
-
-/**
- * @brief 创建ring,并将最后一个trb指向头一个trb
- *
- * @param trbs 要创建的trb数量
- * @return uint64_t trb数组的起始虚拟地址
- */
-static uint64_t xhci_create_ring(int trbs)
-{
-    int total_size = trbs * sizeof(struct xhci_TRB_t);
-    const uint64_t vaddr = (uint64_t)kmalloc(total_size, 0);
-    io_mfence();
-    memset((void *)vaddr, 0, total_size);
-    io_mfence();
-    // 设置最后一个trb为link trb
-    xhci_TRB_set_link_cmd(vaddr + total_size - sizeof(struct xhci_TRB_t));
-    io_mfence();
-    return vaddr;
-}
-
-/**
- * @brief 创建新的event ring table和对应的ring segment
- *
- * @param trbs 包含的trb的数量
- * @param ret_ring_addr 返回的第一个event ring segment的基地址(虚拟)
- * @return uint64_t trb table的虚拟地址
- */
-static uint64_t xhci_create_event_ring(int trbs, uint64_t *ret_ring_addr)
-{
-    const uint64_t table_vaddr = (const uint64_t)kmalloc(64, 0); // table支持8个segment
-    io_mfence();
-    if (unlikely(table_vaddr == NULL))
-        return -ENOMEM;
-    memset((void *)table_vaddr, 0, 64);
-
-    // 暂时只创建1个segment
-    const uint64_t seg_vaddr = (const uint64_t)kmalloc(trbs * sizeof(struct xhci_TRB_t), 0);
-    io_mfence();
-    if (unlikely(seg_vaddr == NULL))
-        return -ENOMEM;
-
-    memset((void *)seg_vaddr, 0, trbs * sizeof(struct xhci_TRB_t));
-    io_mfence();
-    // 将segment地址和大小写入table
-    *(uint64_t *)(table_vaddr) = virt_2_phys(seg_vaddr);
-    *(uint64_t *)(table_vaddr + 8) = trbs;
-
-    *ret_ring_addr = seg_vaddr;
-    return table_vaddr;
-}
-
-void xhci_hc_irq_enable(uint64_t irq_num)
-{
-    int cid = xhci_find_hcid_by_irq_num(irq_num);
-    io_mfence();
-    if (WARN_ON(cid == -1))
-        return;
-
-    io_mfence();
-    pci_start_msi(xhci_hc[cid].pci_dev_hdr);
-
-    io_mfence();
-    xhci_hc_start_sched(cid);
-    io_mfence();
-    xhci_hc_start_ports(cid);
-}
-
-void xhci_hc_irq_disable(uint64_t irq_num)
-{
-    int cid = xhci_find_hcid_by_irq_num(irq_num);
-    io_mfence();
-    if (WARN_ON(cid == -1))
-        return;
-
-    xhci_hc_stop_sched(cid);
-    io_mfence();
-    pci_disable_msi(xhci_hc[cid].pci_dev_hdr);
-    io_mfence();
-}
-
-/**
- * @brief xhci中断的安装函数
- *
- * @param irq_num 要安装的中断向量号
- * @param arg 参数
- * @return uint64_t 错误码
- */
-uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg)
-{
-    int cid = xhci_find_hcid_by_irq_num(irq_num);
-    io_mfence();
-    if (WARN_ON(cid == -1))
-        return -EINVAL;
-
-    struct xhci_hc_irq_install_info_t *info = (struct xhci_hc_irq_install_info_t *)arg;
-    struct msi_desc_t msi_desc;
-    memset(&msi_desc, 0, sizeof(struct msi_desc_t));
-    io_mfence();
-    msi_desc.irq_num = irq_num;
-    msi_desc.msi_index = 0;
-    msi_desc.pci_dev = (struct pci_device_structure_header_t *)xhci_hc[cid].pci_dev_hdr;
-    msi_desc.assert = info->assert;
-    msi_desc.edge_trigger = info->edge_trigger;
-    msi_desc.processor = info->processor;
-    msi_desc.pci.msi_attribute.is_64 = 1;
-    msi_desc.pci.msi_attribute.is_msix = 1;
-    io_mfence();
-    // 因pci_enable_msi不再单独映射MSIX表,所以需要对pci设备的bar进行映射
-
-    int retval = pci_enable_msi(&msi_desc);
-
-    return 0;
-}
-
-void xhci_hc_irq_uninstall(uint64_t irq_num)
-{
-    // todo
-    int cid = xhci_find_hcid_by_irq_num(irq_num);
-    io_mfence();
-    if (WARN_ON(cid == -1))
-        return;
-    xhci_hc_stop(cid);
-    io_mfence();
-}
-/**
- * @brief xhci主机控制器的中断处理函数
- *
- * @param irq_num 中断向量号
- * @param cid 控制器号
- * @param regs 寄存器值
- */
-void xhci_hc_irq_handler(uint64_t irq_num, uint64_t cid, struct pt_regs *regs)
-{
-    // kdebug("USB irq received.");
-    /*
-        写入usb status寄存器,以表明当前收到了中断,清除usb status寄存器中的EINT位
-        需要先清除这个位,再清除interrupter中的pending bit)
-    */
-    xhci_write_op_reg32(cid, XHCI_OPS_USBSTS, xhci_read_op_reg32(cid, XHCI_OPS_USBSTS));
-
-    // 读取第0个usb interrupter的intr management寄存器
-    const uint32_t iman0 = xhci_read_intr_reg32(cid, 0, XHCI_IR_MAN);
-    uint64_t dequeue_reg = xhci_read_intr_reg64(cid, 0, XHCI_IR_DEQUEUE);
-
-    if (((iman0 & 3) == 3) || (dequeue_reg & 8)) // 中断被启用,且pending不为0
-    {
-        // kdebug("to handle");
-        // 写入1以清除该interrupter的pending bit
-        xhci_write_intr_reg32(cid, 0, XHCI_IR_MAN, iman0 | 3);
-        io_mfence();
-        struct xhci_TRB_t event_trb, origin_trb; // event ring trb以及其对应的command trb
-        uint64_t origin_vaddr;
-        // 暂存当前trb的起始地址
-        uint64_t last_event_ring_vaddr = xhci_hc[cid].current_event_ring_vaddr;
-        xhci_get_trb(&event_trb, xhci_hc[cid].current_event_ring_vaddr);
-
-        {
-            struct xhci_TRB_cmd_complete_t *event_trb_ptr = (struct xhci_TRB_cmd_complete_t *)&event_trb;
-            // kdebug("TRB_type=%d, comp_code=%d", event_trb_ptr->TRB_type, event_trb_ptr->code);
-        }
-        while ((event_trb.command & 1) == xhci_hc[cid].current_event_ring_cycle) // 循环处理处于当前周期的所有event ring
-        {
-
-            struct xhci_TRB_cmd_complete_t *event_trb_ptr = (struct xhci_TRB_cmd_complete_t *)&event_trb;
-            // kdebug("TRB_type=%d, comp_code=%d", event_trb_ptr->TRB_type, event_trb_ptr->code);
-            if ((event_trb.command & (1 << 2)) == 0) // 当前event trb不是由于short packet产生的
-            {
-                // kdebug("event_trb_ptr->code=%d", event_trb_ptr->code);
-                // kdebug("event_trb_ptr->TRB_type=%d", event_trb_ptr->TRB_type);
-                switch (event_trb_ptr->code) // 判断它的完成码
-                {
-                case TRB_COMP_TRB_SUCCESS: // trb执行成功,则将结果返回到对应的command ring的trb里面
-
-                    switch (event_trb_ptr->TRB_type) // 根据event trb类型的不同,采取不同的措施
-                    {
-                    case TRB_TYPE_COMMAND_COMPLETION: // 命令已经完成
-                        origin_vaddr = (uint64_t)phys_2_virt(event_trb.param);
-                        // 获取对应的command trb
-                        xhci_get_trb(&origin_trb, origin_vaddr);
-
-                        switch (((struct xhci_TRB_normal_t *)&origin_trb)->TRB_type)
-                        {
-                        case TRB_TYPE_ENABLE_SLOT: // 源命令为enable slot
-                            // 将slot id返回到命令TRB的command字段中
-                            origin_trb.command &= 0x00ffffff;
-                            origin_trb.command |= (event_trb.command & 0xff000000);
-                            origin_trb.status = event_trb.status;
-                            break;
-                        default:
-                            origin_trb.status = event_trb.status;
-                            break;
-                        }
-
-                        // 标记该命令已经执行完成
-                        origin_trb.status |= XHCI_IRQ_DONE;
-                        // 将command trb写入到表中
-                        xhci_set_trb(&origin_trb, origin_vaddr);
-                        // kdebug("set origin:%#018lx", origin_vaddr);
-                        break;
-                    }
-                    break;
-
-                default:
-                    break;
-                }
-            }
-            else // 当前TRB是由short packet产生的
-            {
-                switch (event_trb_ptr->TRB_type)
-                {
-                case TRB_TYPE_TRANS_EVENT: // 当前 event trb是 transfer event TRB
-                    // If SPD was encountered in this TD, comp_code will be SPD, else it should be SUCCESS
-                    // (specs 4.10.1.1)
-                    __write4b((uint64_t)phys_2_virt(event_trb.param),
-                              (event_trb.status | XHCI_IRQ_DONE)); // return code + bytes *not* transferred
-                    break;
-
-                default:
-                    break;
-                }
-            }
-
-            // 获取下一个event ring TRB
-            last_event_ring_vaddr = xhci_hc[cid].current_event_ring_vaddr;
-            xhci_hc[cid].current_event_ring_vaddr += sizeof(struct xhci_TRB_t);
-            xhci_get_trb(&event_trb, xhci_hc[cid].current_event_ring_vaddr);
-            if (((struct xhci_TRB_normal_t *)&event_trb)->TRB_type == TRB_TYPE_LINK)
-            {
-                xhci_hc[cid].current_event_ring_vaddr = xhci_hc[cid].event_ring_vaddr;
-                xhci_get_trb(&event_trb, xhci_hc[cid].current_event_ring_vaddr);
-            }
-        }
-
-        // 当前event ring cycle的TRB处理结束
-        // 更新dequeue指针, 并清除event handler busy标志位
-        xhci_write_intr_reg64(cid, 0, XHCI_IR_DEQUEUE, virt_2_phys(last_event_ring_vaddr) | (1 << 3));
-        io_mfence();
-    }
-}
-/**
- * @brief 重置端口
- *
- * @param id 控制器id
- * @param port 端口id
- * @return int
- */
-static int xhci_reset_port(const int id, const int port)
-{
-    int retval = 0;
-    // 相对于op寄存器基地址的偏移量
-    uint64_t port_status_offset = XHCI_OPS_PRS + port * 16;
-
-    io_mfence();
-    // 检查端口电源状态
-    if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0)
-    {
-        kdebug("port is power off, starting...");
-        io_mfence();
-        xhci_write_cap_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9));
-        io_mfence();
-        rs_usleep(2000);
-        // 检测端口是否被启用, 若未启用,则报错
-        if ((xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC) & (1 << 9)) == 0)
-        {
-            kdebug("cannot power on %d", port);
-            return -EAGAIN;
-        }
-    }
-    // kdebug("port:%d, power check ok", port);
-    io_mfence();
-    // 确保端口的status被清0
-    xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS);
-    // kdebug("to reset timeout;");
-    io_mfence();
-    // 重置当前端口
-    if (XHCI_PORT_IS_USB3(id, port))
-        xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1U << 31));
-    else
-        xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | (1 << 4));
-
-    retval = -ETIMEDOUT;
-    // kdebug("to wait reset timeout;");
-    // 等待portsc的port reset change位被置位,说明reset完成
-    int timeout = 100;
-    while (timeout)
-    {
-        io_mfence();
-        uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC);
-        io_mfence();
-        if (val & (1 << 21))
-            break;
-            // QEMU对usb的模拟有bug,因此需要检测这里
-#ifdef __QEMU_EMULATION__
-
-        if (XHCI_PORT_IS_USB3(id, port) && (val & (1U << 31)) == 0)
-            break;
-        else if (XHCI_PORT_IS_USB2(id, port) && (val & (1 << 4)) == 0)
-            break;
-#endif
-        --timeout;
-        rs_usleep(500);
-    }
-    // kdebug("timeout= %d", timeout);
-
-    if (timeout > 0)
-    {
-        // 等待恢复
-        rs_usleep(USB_TIME_RST_REC * 100);
-        uint32_t val = xhci_read_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC);
-        io_mfence();
-
-        // kdebug("to check if reset ok, val=%#010lx", val);
-
-        // 如果reset之后,enable bit仍然是1,那么说明reset成功
-        if (val & (1 << 1))
-        {
-            // kdebug("reset ok");
-            retval = 0;
-            io_mfence();
-            // 清除status change bit
-            xhci_write_op_reg32(id, port_status_offset + XHCI_PORT_PORTSC, (1 << 9) | XHCI_PORTUSB_CHANGE_BITS);
-            io_mfence();
-        }
-        else
-            retval = -1;
-    }
-    // kdebug("reset ok!");
-    // 如果usb2端口成功reset,则处理该端口的active状态
-    if (retval == 0 && XHCI_PORT_IS_USB2(id, port))
-    {
-        xhci_hc[id].ports[port].flags |= XHCI_PROTOCOL_ACTIVE;
-        if (XHCI_PORT_HAS_PAIR(id, port)) // 如果有对应的usb3端口,则将usb3端口设置为未激活
-            xhci_hc[id].ports[xhci_hc[id].ports[port].paired_port_num].flags &= ~(XHCI_PROTOCOL_ACTIVE);
-    }
-
-    // 如果usb3端口reset失败,则启用与之配对的usb2端口
-    if (retval != 0 && XHCI_PORT_IS_USB3(id, port))
-    {
-        xhci_hc[id].ports[port].flags &= ~XHCI_PROTOCOL_ACTIVE;
-        xhci_hc[id].ports[xhci_hc[id].ports[port].paired_port_num].flags |= XHCI_PROTOCOL_ACTIVE;
-    }
-
-    return retval;
-}
-
-/**
- * @brief 初始化设备slot的上下文,并将其写入dcbaap中的上下文index数组
- * - at this time, we don't know if the device is a hub or not, so we don't
- *   set the slot->hub, ->mtt, ->ttt, ->etc, items.
- *
- * @param id 控制器id
- * @param port 端口号
- * @param speed 端口速度
- * @param max_packet 最大数据包大小
- * @return uint64_t 初始化好的设备上下文空间的虚拟地址
- */
-static uint64_t xhci_initialize_slot(const int id, const int port, const int speed, const int max_packet)
-{
-    // 为所有的endpoint分配上下文空间
-    // todo: 按需分配上下文空间
-    uint64_t device_context_vaddr = (uint64_t)kzalloc(xhci_hc[id].context_size * 32, 0);
-    // kdebug("slot id=%d, device_context_vaddr=%#018lx, port=%d", slot_id, device_context_vaddr, port);
-    // 写到数组中
-    __write8b(xhci_hc[id].dcbaap_vaddr + (xhci_hc[id].ports[port].slot_id * sizeof(uint64_t)),
-              virt_2_phys(device_context_vaddr));
-    struct xhci_slot_context_t slot_ctx = {0};
-    slot_ctx.entries = 1;
-    slot_ctx.speed = speed;
-    slot_ctx.route_string = 0;
-    slot_ctx.rh_port_num = port + 1; // 由于xhci控制器是1-base的,因此把驱动程序中存储的端口号加1,才是真实的端口号
-    slot_ctx.max_exit_latency = 0;   // 稍后会计算这个值
-    slot_ctx.int_target = 0;         // 当前全部使用第0个interrupter
-    slot_ctx.slot_state = XHCI_SLOT_STATE_DISABLED_OR_ENABLED;
-    slot_ctx.device_address = 0;
-
-    // 将slot信息写入上下文空间
-    __write_slot(device_context_vaddr, &slot_ctx);
-
-    // 初始化控制端点
-    xhci_initialize_ep(id, device_context_vaddr, port, XHCI_EP_CONTROL, max_packet, 0, USB_EP_CONTROL, 0, speed, 0);
-
-    return device_context_vaddr;
-}
-
-/**
- * @brief 初始化endpoint
- *
- * @param id 控制器id
- * @param slot_vaddr slot上下文的虚拟地址
- * @param port_id 插槽id
- * @param ep_num 端点上下文在slot上下文区域内的编号
- * @param max_packet 最大数据包大小
- * @param type 端点类型
- * @param direction 传输方向
- * @param speed 传输速度
- * @param ep_interval 端点的连续请求间隔
- */
-static void xhci_initialize_ep(const int id, const uint64_t slot_vaddr, const int port_id, const int ep_num,
-                               const int max_packet, const int max_burst, const int type, const int direction,
-                               const int speed, const int ep_interval)
-{
-    // 由于目前只实现获取设备的描述符,因此暂时只支持control ep
-    if (type != USB_EP_CONTROL && type != USB_EP_INTERRUPT)
-        return;
-    struct xhci_ep_context_t ep_ctx = {0};
-    memset(&ep_ctx, 0, sizeof(struct xhci_ep_context_t));
-
-    xhci_hc[id].ports[port_id].ep_info[ep_num].ep_ring_vbase = xhci_create_ring(XHCI_TRBS_PER_RING);
-    // 申请ep的 transfer ring
-    ep_ctx.tr_dequeue_ptr = virt_2_phys(xhci_hc[id].ports[port_id].ep_info[ep_num].ep_ring_vbase);
-    xhci_ep_set_dequeue_cycle_state(&ep_ctx, XHCI_TRB_CYCLE_ON);
-
-    xhci_hc[id].ports[port_id].ep_info[ep_num].current_ep_ring_vaddr =
-        xhci_hc[id].ports[port_id].ep_info[ep_num].ep_ring_vbase;
-    xhci_hc[id].ports[port_id].ep_info[ep_num].current_ep_ring_cycle = xhci_ep_get_dequeue_cycle_state(&ep_ctx);
-    // kdebug("ep_ctx.tr_dequeue_ptr = %#018lx", ep_ctx.tr_dequeue_ptr);
-    // kdebug("xhci_hc[id].control_ep_info.current_ep_ring_cycle  = %d",
-    // xhci_hc[id].control_ep_info.current_ep_ring_cycle);
-    kdebug("max_packet=%d, max_burst=%d", max_packet, max_burst);
-    switch (type)
-    {
-    case USB_EP_CONTROL: // Control ep
-        // 设置初始值
-        ep_ctx.max_packet_size = max_packet;
-        ep_ctx.linear_stream_array = 0;
-        ep_ctx.max_primary_streams = 0;
-        ep_ctx.mult = 0;
-        ep_ctx.ep_state = XHCI_EP_STATE_DISABLED;
-        ep_ctx.hid = 0;
-        ep_ctx.ep_type = XHCI_EP_TYPE_CONTROL;
-        ep_ctx.average_trb_len = 8; // 所有的control ep的该值均为8
-        ep_ctx.err_cnt = 3;
-        ep_ctx.max_burst_size = max_burst;
-        ep_ctx.interval = ep_interval;
-
-        break;
-    case USB_EP_INTERRUPT:
-        ep_ctx.max_packet_size = max_packet & 0x7ff;
-        ep_ctx.max_burst_size = max_burst;
-        ep_ctx.ep_state = XHCI_EP_STATE_DISABLED;
-        ep_ctx.mult = 0;
-        ep_ctx.err_cnt = 3;
-        ep_ctx.max_esti_payload_hi = ((max_packet * (max_burst + 1)) >> 8) & 0xff;
-        ep_ctx.max_esti_payload_lo = ((max_packet * (max_burst + 1))) & 0xff;
-        ep_ctx.interval = ep_interval;
-        ep_ctx.average_trb_len = 8; // todo: It's not sure how much to fill in this value
-        // ep_ctx.ep_type = XHCI_EP_TYPE_INTR_IN;
-        ep_ctx.ep_type = ((ep_num % 2) ? XHCI_EP_TYPE_INTR_IN : XHCI_EP_TYPE_INTR_OUT);
-
-        break;
-    default:
-        break;
-    }
-
-    // 将ep的信息写入到slot上下文中对应的ep的块中
-    __write_ep(id, slot_vaddr, ep_num, &ep_ctx);
-}
-
-/**
- * @brief 向usb控制器发送 address_device命令
- *
- * @param id 主机控制器id
- * @param slot_vaddr 插槽上下文的虚拟基地址
- * @param slot_id 插槽id
- * @param block 是否阻断 set address 信息向usb设备的传输
- * @return int 错误码
- */
-static int xhci_set_address(const int id, const uint64_t slot_vaddr, const int slot_id, const bool block)
-{
-    int retval = 0;
-    struct xhci_slot_context_t slot;
-    struct xhci_ep_context_t ep;
-    // 创建输入上下文缓冲区
-    uint64_t input_ctx_buffer = (uint64_t)kzalloc(xhci_hc[id].context_size * 33, 0);
-
-    // 置位input control context和slot context的add bit
-    __write4b(input_ctx_buffer + 4, 0x3);
-
-    // 拷贝slot上下文和control ep上下文到输入上下文中
-
-    //  __write_ep(id, input_ctx_buffer, 2, &ep_ctx);
-    __read_from_slot(&slot, slot_vaddr);
-    __read_from_ep(id, slot_vaddr, 1, &ep);
-    ep.err_cnt = 3;
-    kdebug("slot.slot_state=%d, speed=%d, root hub port num=%d", slot.slot_state, slot.speed, slot.rh_port_num);
-    kdebug("ep.type=%d, max_packet=%d, dequeue_ptr=%#018lx", ep.ep_type, ep.max_packet_size, ep.tr_dequeue_ptr);
-
-    __write_slot(input_ctx_buffer + xhci_hc[id].context_size, &slot);
-    __write_ep(id, input_ctx_buffer, 2, &ep);
-
-    struct xhci_TRB_normal_t trb = {0};
-    trb.buf_paddr = virt_2_phys(input_ctx_buffer);
-    trb.bei = (block ? 1 : 0);
-    trb.TRB_type = TRB_TYPE_ADDRESS_DEVICE;
-    trb.intr_target = 0;
-    trb.cycle = xhci_hc[id].cmd_trb_cycle;
-    trb.Reserved |= ((slot_id << 8) & 0xffff);
-
-    retval = xhci_send_command(id, (struct xhci_TRB_t *)&trb, true);
-    if (unlikely(retval != 0))
-    {
-        kerror("slotid:%d, address device failed", slot_id);
-        goto failed;
-    }
-
-    struct xhci_TRB_cmd_complete_t *trb_done = (struct xhci_TRB_cmd_complete_t *)&trb;
-    if (trb_done->code == TRB_COMP_TRB_SUCCESS) // 成功执行
-    {
-        // 如果要从控制器获取刚刚设置的设备地址的话,可以在这里读取slot context
-        ksuccess("slot %d successfully addressed.", slot_id);
-
-        retval = 0;
-    }
-    else
-        retval = -EAGAIN;
-done:;
-failed:;
-    kfree((void *)input_ctx_buffer);
-    return retval;
-}
-
-/**
- * @brief 在指定的端点的ring中,写入一个setup stage TRB
- *
- * @param ep 端点信息结构体
- * @param packet usb请求包
- * @param direction 传输的方向
- * @return int 产生的TRB数量
- */
-static int xhci_setup_stage(struct xhci_ep_info_t *ep, const struct usb_request_packet_t *packet,
-                            const uint8_t direction)
-{
-    // kdebug("ep->current_ep_ring_cycle=%d", ep->current_ep_ring_cycle);
-    struct xhci_TRB_setup_stage_t trb = {0};
-    trb.bmRequestType = packet->request_type;
-    trb.bRequest = packet->request;
-    trb.wValue = packet->value;
-    trb.wIndex = packet->index;
-    trb.wLength = packet->length;
-    trb.transfer_legth = 8;
-    trb.intr_target = 0; // 使用第0个interrupter
-    trb.cycle = ep->current_ep_ring_cycle;
-    trb.ioc = 0;
-    trb.idt = 1;
-    trb.TRB_type = TRB_TYPE_SETUP_STAGE;
-    trb.trt = direction;
-
-    // 将setup stage trb拷贝到ep的transfer ring中
-    __xhci_write_trb(ep, (struct xhci_TRB_t *)&trb);
-    return 1;
-}
-
-/**
- * @brief 向指定的端点中写入data stage trb
- *
- * @param ep 端点信息结构体
- * @param buf_vaddr 数据缓冲区虚拟地址
- * @param trb_type trb类型
- * @param size 要传输的数据大小
- * @param direction 传输方向
- * @param max_packet 最大请求包大小
- * @param status_vaddr event data TRB的缓冲区(4字节,且地址按照16字节对齐)
- * @return int 产生的TRB数量
- */
-static int xhci_data_stage(struct xhci_ep_info_t *ep, uint64_t buf_vaddr, uint8_t trb_type, const uint32_t size,
-                           uint8_t direction, const int max_packet, const uint64_t status_vaddr)
-{
-    if (size == 0)
-        return 0;
-    int64_t remain_bytes = size;
-    uint32_t remain_packets = (size + max_packet - 1) / max_packet;
-    struct xhci_TRB_data_stage_t trb = {0};
-    int count_packets = 0;
-    // 分多个trb来执行
-    while (remain_bytes > 0)
-    {
-        --remain_packets;
-
-        trb.buf_paddr = virt_2_phys(buf_vaddr);
-        trb.intr_target = 0;
-        trb.TD_size = remain_packets;
-        trb.transfer_length = (remain_bytes < max_packet ? size : max_packet);
-        trb.dir = direction;
-        trb.TRB_type = trb_type;
-        trb.chain = 1;
-        trb.ent = (remain_packets == 0);
-        trb.cycle = ep->current_ep_ring_cycle;
-        trb.ioc = 0;
-
-        // 将data stage trb拷贝到ep的transfer ring中
-        __xhci_write_trb(ep, (struct xhci_TRB_t *)&trb);
-
-        buf_vaddr += max_packet;
-        remain_bytes -= max_packet;
-        ++count_packets;
-
-        // 对于data stage trb而言,除了第一个trb以外,剩下的trb都是NORMAL的,并且dir是无用的
-        trb_type = TRB_TYPE_NORMAL;
-        direction = 0;
-    }
-
-    // 写入data event trb, 待完成后,完成信息将会存到status_vaddr指向的地址中
-    memset(&trb, 0, sizeof(struct xhci_TRB_data_stage_t *));
-    trb.buf_paddr = virt_2_phys(status_vaddr);
-    trb.intr_target = 0;
-    trb.cycle = ep->current_ep_ring_cycle;
-    trb.ioc = 1;
-    trb.TRB_type = TRB_TYPE_EVENT_DATA;
-    __xhci_write_trb(ep, (struct xhci_TRB_t *)&trb);
-
-    return count_packets + 1;
-}
-
-/**
- * @brief 填写xhci status stage TRB到control ep的transfer ring
- *
- * @param ep 端点信息结构体
- * @param direction 方向:(h2d:0, d2h:1)
- * @param status_buf_vaddr
- * @return int 创建的TRB数量
- */
-static int xhci_status_stage(struct xhci_ep_info_t *ep, uint8_t direction, uint64_t status_buf_vaddr)
-{
-    // kdebug("write status stage trb");
-
-    {
-        struct xhci_TRB_status_stage_t trb = {0};
-
-        // 写入status stage trb
-        trb.intr_target = 0;
-        trb.cycle = ep->current_ep_ring_cycle;
-        trb.ent = 0;
-        trb.ioc = 1;
-        trb.TRB_type = TRB_TYPE_STATUS_STAGE;
-        trb.dir = direction;
-        __xhci_write_trb(ep, (struct xhci_TRB_t *)&trb);
-    }
-
-    {
-        // 写入event data TRB
-        struct xhci_TRB_data_stage_t trb = {0};
-        trb.buf_paddr = virt_2_phys(status_buf_vaddr);
-        trb.intr_target = 0;
-        trb.TRB_type = TRB_TYPE_EVENT_DATA;
-        trb.ioc = 1;
-
-        trb.cycle = ep->current_ep_ring_cycle;
-
-        __xhci_write_trb(ep, (struct xhci_TRB_t *)&trb);
-    }
-
-    return 2;
-}
-
-/**
- * @brief 等待状态数据被拷贝到status缓冲区中
- *
- * @param id 主机控制器id
- * @param status_vaddr status 缓冲区
- * @return int 错误码
- */
-static int xhci_wait_for_interrupt(const int id, uint64_t status_vaddr)
-{
-    int timer = 500;
-    while (timer)
-    {
-        if (__read4b(status_vaddr) & XHCI_IRQ_DONE)
-        {
-            uint32_t status = __read4b(status_vaddr);
-            // 判断完成码
-            switch (xhci_get_comp_code(status))
-            {
-            case TRB_COMP_TRB_SUCCESS:
-            case TRB_COMP_SHORT_PACKET:
-                return 0;
-                break;
-            case TRB_COMP_STALL_ERROR:
-            case TRB_COMP_DATA_BUFFER_ERROR:
-            case TRB_COMP_BABBLE_DETECTION:
-                return -EINVAL;
-            default:
-                kerror("xhci wait interrupt: status=%#010x, complete_code=%d", status, xhci_get_comp_code(status));
-                return -EIO;
-            }
-        }
-        --timer;
-        rs_usleep(1000);
-    }
-
-    kerror(" USB xHCI Interrupt wait timed out.");
-    return -ETIMEDOUT;
-}
-
-/**
- * @brief 从指定插槽的control endpoint读取信息
- *
- * @param id 主机控制器id
- * @param packet usb数据包
- * @param target 读取到的信息存放到的位置
- * @param port_id 端口id
- * @param max_packet 最大数据包大小
- * @return int 读取到的数据的大小
- */
-static int xhci_control_in(const int id, struct usb_request_packet_t *packet, void *target, const int port_id,
-                           const int max_packet)
-{
-
-    uint64_t status_buf_vaddr =
-        (uint64_t)kzalloc(16, 0); // 本来是要申请4bytes的buffer的,但是因为xhci控制器需要16bytes对齐,因此申请16bytes
-    uint64_t data_buf_vaddr = 0;
-    int retval = 0;
-
-    // 往control ep写入一个setup stage trb
-    xhci_setup_stage(&xhci_hc[id].ports[port_id].ep_info[XHCI_EP_CONTROL], packet, XHCI_DIR_IN);
-    if (packet->length)
-    {
-        data_buf_vaddr = (uint64_t)kzalloc(packet->length, 0);
-        xhci_data_stage(&xhci_hc[id].ports[port_id].ep_info[XHCI_EP_CONTROL], data_buf_vaddr, TRB_TYPE_DATA_STAGE,
-                        packet->length, XHCI_DIR_IN_BIT, max_packet, status_buf_vaddr);
-    }
-
-/*
-    QEMU doesn't quite handle SETUP/DATA/STATUS transactions correctly.
-    It will wait for the STATUS TRB before it completes the transfer.
-    Technically, you need to check for a good transfer before you send the
-    STATUS TRB.  However, since QEMU doesn't update the status until after
-    the STATUS TRB, waiting here will not complete a successful transfer.
-    Bochs and real hardware handles this correctly, however QEMU does not.
-    If you are using QEMU, do not ring the doorbell here.  Ring the doorbell
-    *after* you place the STATUS TRB on the ring.
-    (See bug report: https://bugs.launchpad.net/qemu/+bug/1859378 )
-*/
-#ifndef __QEMU_EMULATION__
-    // 如果不是qemu虚拟机,则可以直接发起传输
-    // kdebug(" not qemu");
-    __xhci_write_doorbell(id, xhci_hc[id].ports[port_id].slot_id, XHCI_EP_CONTROL);
-    retval = xhci_wait_for_interrupt(id, status_buf_vaddr);
-    if (unlikely(retval != 0))
-        goto failed;
-#endif
-    memset((void *)status_buf_vaddr, 0, 16);
-    xhci_status_stage(&xhci_hc[id].ports[port_id].ep_info[XHCI_EP_CONTROL], XHCI_DIR_OUT_BIT, status_buf_vaddr);
-
-    __xhci_write_doorbell(id, xhci_hc[id].ports[port_id].slot_id, XHCI_EP_CONTROL);
-
-    retval = xhci_wait_for_interrupt(id, status_buf_vaddr);
-
-    if (unlikely(retval != 0))
-        goto failed;
-
-    // 将读取到的数据拷贝到目标区域
-    if (packet->length)
-        memcpy(target, (void *)data_buf_vaddr, packet->length);
-    retval = packet->length;
-    goto done;
-
-failed:;
-    kdebug("wait 4 interrupt failed");
-    retval = 0;
-done:;
-    // 释放内存
-    kfree((void *)status_buf_vaddr);
-    if (packet->length)
-        kfree((void *)data_buf_vaddr);
-    return retval;
-}
-
-/**
- * @brief 向指定插槽的control ep输出信息
- *
- * @param id 主机控制器id
- * @param packet usb数据包
- * @param target 返回的数据存放的位置
- * @param port_id 端口id
- * @param max_packet 最大数据包大小
- * @return int 读取到的数据的大小
- */
-static int xhci_control_out(const int id, struct usb_request_packet_t *packet, void *target, const int port_id,
-                            const int max_packet)
-{
-    uint64_t status_buf_vaddr = (uint64_t)kzalloc(16, 0);
-    uint64_t data_buf_vaddr = 0;
-    int retval = 0;
-
-    // 往control ep写入一个setup stage trb
-    xhci_setup_stage(&xhci_hc[id].ports[port_id].ep_info[XHCI_EP_CONTROL], packet, XHCI_DIR_OUT);
-
-    if (packet->length)
-    {
-        data_buf_vaddr = (uint64_t)kzalloc(packet->length, 0);
-        xhci_data_stage(&xhci_hc[id].ports[port_id].ep_info[XHCI_EP_CONTROL], data_buf_vaddr, TRB_TYPE_DATA_STAGE,
-                        packet->length, XHCI_DIR_OUT_BIT, max_packet, status_buf_vaddr);
-    }
-
-#ifndef __QEMU_EMULATION__
-    // 如果不是qemu虚拟机,则可以直接发起传输
-    __xhci_write_doorbell(id, xhci_hc[id].ports[port_id].slot_id, XHCI_EP_CONTROL);
-    retval = xhci_wait_for_interrupt(id, status_buf_vaddr);
-    if (unlikely(retval != 0))
-        goto failed;
-#endif
-
-    memset((void *)status_buf_vaddr, 0, 16);
-    xhci_status_stage(&xhci_hc[id].ports[port_id].ep_info[XHCI_EP_CONTROL], XHCI_DIR_IN_BIT, status_buf_vaddr);
-
-    __xhci_write_doorbell(id, xhci_hc[id].ports[port_id].slot_id, XHCI_EP_CONTROL);
-#ifndef __QEMU_EMULATION__
-    // qemu对于这个操作的处理有问题,status_buf并不会被修改。而真机不存在该问题
-    retval = xhci_wait_for_interrupt(id, status_buf_vaddr);
-#endif
-
-    if (unlikely(retval != 0))
-        goto failed;
-
-    // 将读取到的数据拷贝到目标区域
-    if (packet->length)
-        memcpy(target, (void *)data_buf_vaddr, packet->length);
-    retval = packet->length;
-    goto done;
-failed:;
-    kdebug("wait 4 interrupt failed");
-    retval = 0;
-done:;
-    // 释放内存
-    kfree((void *)status_buf_vaddr);
-    if (packet->length)
-        kfree((void *)data_buf_vaddr);
-    return retval;
-}
-
-/**
- * @brief 获取描述符
- *
- * @param id 控制器号
- * @param port_id 端口号
- * @param target 获取到的数据要拷贝到的地址
- * @param desc_type 描述符类型
- * @param desc_index 描述符的索引号
- * @param lang_id 语言id(默认为0)
- * @param length 要传输的数据长度
- * @return int 错误码
- */
-static inline int xhci_get_desc(const int id, const int port_id, void *target, const uint16_t desc_type,
-                                const uint8_t desc_index, const uint16_t lang_id, const uint16_t length)
-{
-    struct usb_device_desc *dev_desc = xhci_hc[id].ports[port_id].dev_desc;
-    int count;
-
-    BUG_ON(dev_desc == NULL);
-    // 设备端口没有对应的描述符
-    if (unlikely(dev_desc == NULL))
-        return -EINVAL;
-
-    uint8_t req_type = USB_REQ_TYPE_GET_REQUEST;
-    if (desc_type == USB_DT_HID_REPORT)
-        req_type = USB_REQ_TYPE_GET_INTERFACE_REQUEST;
-
-    DECLARE_USB_PACKET(ctrl_in_packet, req_type, USB_REQ_GET_DESCRIPTOR, (desc_type << 8) | desc_index, lang_id,
-                       length);
-    count = xhci_control_in(id, &ctrl_in_packet, target, port_id, dev_desc->max_packet_size);
-    if (unlikely(count == 0))
-        return -EAGAIN;
-    return 0;
-}
-
-static inline int xhci_set_configuration(const int id, const int port_id, const uint8_t conf_value)
-{
-    struct usb_device_desc *dev_desc = xhci_hc[id].ports[port_id].dev_desc;
-    int count;
-
-    BUG_ON(dev_desc == NULL);
-    // 设备端口没有对应的描述符
-    if (unlikely(dev_desc == NULL))
-        return -EINVAL;
-    DECLARE_USB_PACKET(ctrl_out_packet, USB_REQ_TYPE_SET_REQUEST, USB_REQ_SET_CONFIGURATION, conf_value & 0xff, 0, 0);
-    // kdebug("set conf: to control out");
-    count = xhci_control_out(id, &ctrl_out_packet, NULL, port_id, dev_desc->max_packet_size);
-    // kdebug("set conf: count=%d", count);
-    return 0;
-}
-
-/**
- * @brief 获取usb 设备的config_desc
- *
- * @param id 主机控制器id
- * @param port_id 端口id
- * @param conf_desc 要获取的conf_desc
- * @return int 错误码
- */
-static int xhci_get_config_desc(const int id, const int port_id, struct usb_config_desc *conf_desc)
-{
-    if (unlikely(conf_desc == NULL))
-        return -EINVAL;
-
-    kdebug("to get conf for port %d", port_id);
-    int retval = xhci_get_desc(id, port_id, conf_desc, USB_DT_CONFIG, 0, 0, 9);
-    if (unlikely(retval != 0))
-        return retval;
-    kdebug("port %d got conf ok. type=%d, len=%d, total_len=%d, num_interfaces=%d, max_power=%dmA", port_id,
-           conf_desc->type, conf_desc->len, conf_desc->total_len, conf_desc->num_interfaces,
-           (xhci_get_port_speed(id, port_id) == XHCI_PORT_SPEED_SUPER) ? (conf_desc->max_power * 8)
-                                                                       : (conf_desc->max_power * 2));
-    return 0;
-}
-
-/**
- * @brief 获取完整的config desc(包含conf、interface、endpoint)
- *
- * @param id 控制器id
- * @param port_id 端口id
- * @param conf_desc 之前已经获取好的config_desc
- * @param target 最终结果要拷贝到的地址
- * @return int 错误码
- */
-static inline int xhci_get_config_desc_full(const int id, const int port_id, const struct usb_config_desc *conf_desc,
-                                            void *target)
-{
-    if (unlikely(conf_desc == NULL || target == NULL))
-        return -EINVAL;
-
-    return xhci_get_desc(id, port_id, target, USB_DT_CONFIG, 0, 0, conf_desc->total_len);
-}
-
-/**
- * @brief 从完整的conf_desc数据中获取指定的interface_desc的指针
- *
- * @param in_buf 存储了完整的conf_desc的缓冲区
- * @param if_num 接口号
- * @param if_desc 返回的指向接口结构体的指针
- * @return int 错误码
- */
-static int xhci_get_interface_desc(const void *in_buf, const uint8_t if_num, struct usb_interface_desc **if_desc)
-{
-    if (unlikely(if_desc == NULL || in_buf == NULL))
-        return -EINVAL;
-    // 判断接口index是否合理
-    if (if_num >= ((struct usb_config_desc *)in_buf)->num_interfaces)
-        return -EINVAL;
-    uint32_t total_len = ((struct usb_config_desc *)in_buf)->total_len;
-    uint32_t pos = 0;
-    while (pos < total_len)
-    {
-        struct usb_interface_desc *ptr = (struct usb_interface_desc *)(in_buf + pos);
-        if (ptr->type != USB_DT_INTERFACE)
-        {
-            pos += ptr->len;
-            continue;
-        }
-
-        if (ptr->interface_number == if_num) // 找到目标interface desc
-        {
-            kdebug("get interface desc ok. interface_number=%d, num_endpoints=%d, class=%d, subclass=%d",
-                   ptr->interface_number, ptr->num_endpoints, ptr->interface_class, ptr->interface_sub_class);
-            *if_desc = ptr;
-            return 0;
-        }
-        pos += ptr->len;
-    }
-
-    return -EINVAL;
-}
-
-/**
- * @brief 获取端点描述符
- *
- * @param if_desc 接口描述符
- * @param ep_num 端点号
- * @param ep_desc 返回的指向端点描述符的指针
- * @return int 错误码
- */
-static inline int xhci_get_endpoint_desc(const struct usb_interface_desc *if_desc, const uint8_t ep_num,
-                                         struct usb_endpoint_desc **ep_desc)
-{
-    if (unlikely(if_desc == NULL || ep_desc == NULL))
-        return -EINVAL;
-    BUG_ON(ep_num >= if_desc->num_endpoints);
-
-    *ep_desc = (struct usb_endpoint_desc *)((uint64_t)(if_desc + 1) + ep_num * sizeof(struct usb_endpoint_desc));
-    kdebug("get endpoint desc: ep_addr=%d, max_packet=%d, attr=%#06x, interval=%d", (*ep_desc)->endpoint_addr,
-           (*ep_desc)->max_packet, (*ep_desc)->attributes, (*ep_desc)->interval);
-    return 0;
-}
-
-/**
- * @brief 初始化设备端口,并获取端口的描述信息
- *
- * @param id 主机控制器id
- * @param port_id 端口id
- * @param dev_desc 设备描述符
- * @return int 错误码
- */
-static int xhci_get_descriptor(const int id, const int port_id, struct usb_device_desc *dev_desc)
-{
-    int retval = 0;
-    int count = 0;
-    if (unlikely(dev_desc == NULL))
-        return -EINVAL;
-    // 读取端口速度。 full=1, low=2, high=3, super=4
-    uint32_t speed = xhci_get_port_speed(id, port_id);
-
-    /*
-     * Some devices will only send the first 8 bytes of the device descriptor
-     *  while in the default state.  We must request the first 8 bytes, then reset
-     *  the port, set address, then request all 18 bytes.
-     */
-    struct xhci_TRB_normal_t trb = {0};
-    trb.TRB_type = TRB_TYPE_ENABLE_SLOT;
-    // kdebug("to enable slot");
-    if (xhci_send_command(id, (struct xhci_TRB_t *)&trb, true) != 0)
-    {
-        kerror("portid:%d: send enable slot failed", port_id);
-        return -ETIMEDOUT;
-    }
-    // kdebug("send enable slot ok");
-
-    uint32_t slot_id = ((struct xhci_TRB_cmd_complete_t *)&trb)->slot_id;
-    int16_t max_packet;
-    if (slot_id != 0) // slot id不为0时,是合法的slot id
-    {
-        // 为不同速度的设备确定最大的数据包大小
-        switch (speed)
-        {
-        case XHCI_PORT_SPEED_LOW:
-            max_packet = 8;
-            break;
-        case XHCI_PORT_SPEED_FULL:
-        case XHCI_PORT_SPEED_HI:
-            max_packet = 64;
-            break;
-        case XHCI_PORT_SPEED_SUPER:
-            max_packet = 512;
-            break;
-        }
-    }
-    else
-        return -EAGAIN; // slot id 不合法
-
-    xhci_hc[id].ports[port_id].slot_id = slot_id;
-    // kdebug("speed=%d", speed);
-    // 初始化接口的上下文
-    uint64_t slot_vaddr = xhci_initialize_slot(id, port_id, speed, max_packet);
-
-    retval = xhci_set_address(id, slot_vaddr, slot_id, true);
-    // kdebug("set addr again");
-    // 再次发送 set_address命令
-    // kdebug("to set addr again");
-    retval = xhci_set_address(id, slot_vaddr, slot_id, false);
-    if (retval != 0)
-        return retval;
-
-    memset(dev_desc, 0, sizeof(struct usb_device_desc));
-    DECLARE_USB_PACKET(ctrl_in_packet, USB_REQ_TYPE_GET_REQUEST, USB_REQ_GET_DESCRIPTOR, (USB_DT_DEVICE << 8), 0, 18);
-    count = xhci_control_in(id, &ctrl_in_packet, dev_desc, port_id, max_packet);
-    if (unlikely(count == 0))
-        return -EAGAIN;
-    /*
-        TODO: if the dev_desc->max_packet was different than what we have as max_packet,
-          you would need to change it here and in the slot context by doing a
-          evaluate_slot_context call.
-    */
-
-    xhci_hc[id].ports[port_id].dev_desc = dev_desc;
-
-    // print the descriptor
-    printk("  Found USB Device:\n"
-           "                port: %i\n"
-           "                 len: %i\n"
-           "                type: %i\n"
-           "             version: %01X.%02X\n"
-           "               class: %i\n"
-           "            subclass: %i\n"
-           "            protocol: %i\n"
-           "     max packet size: %i\n"
-           "           vendor id: 0x%04X\n"
-           "          product id: 0x%04X\n"
-           "         release ver: %i%i.%i%i\n"
-           "   manufacture index: %i (index to a string)\n"
-           "       product index: %i\n"
-           "        serial index: %i\n"
-           "   number of configs: %i\n",
-           port_id, dev_desc->len, dev_desc->type, dev_desc->usb_version >> 8, dev_desc->usb_version & 0xFF,
-           dev_desc->_class, dev_desc->subclass, dev_desc->protocol, dev_desc->max_packet_size, dev_desc->vendor_id,
-           dev_desc->product_id, (dev_desc->device_rel & 0xF000) >> 12, (dev_desc->device_rel & 0x0F00) >> 8,
-           (dev_desc->device_rel & 0x00F0) >> 4, (dev_desc->device_rel & 0x000F) >> 0, dev_desc->manufacturer_index,
-           dev_desc->procuct_index, dev_desc->serial_index, dev_desc->config);
-    return 0;
-}
-
-/**
- * @brief 启用xhci控制器的端口
- *
- * @param id 控制器id
- * @return int
- */
-static int xhci_hc_start_ports(int id)
-{
-    int cnt = 0;
-    // 注意,这两个循环应该不能合并到一起,因为可能存在usb2端口offset在前,usb3端口在后的情况,那样的话就会出错
-
-    // 循环启动所有的usb3端口
-    for (int i = 0; i < xhci_hc[id].port_num; ++i)
-    {
-        if (XHCI_PORT_IS_USB3(id, i) && XHCI_PORT_IS_ACTIVE(id, i))
-        {
-            io_mfence();
-            // kdebug("to reset port %d, rflags=%#018lx", id, get_rflags());
-            int rst_ret = xhci_reset_port(id, i);
-            // kdebug("reset done!, val=%d", rst_ret);
-            // reset该端口
-            if (likely(rst_ret == 0)) // 如果端口reset成功,就获取它的描述符
-                                      // 否则,reset函数会把它给设置为未激活,并且标志配对的usb2端口是激活的
-            {
-                // kdebug("reset port %d ok", id);
-                struct usb_device_desc dev_desc = {0};
-                if (xhci_get_descriptor(id, i, &dev_desc) == 0)
-                {
-                    xhci_configure_port(id, i);
-                    ++cnt;
-                }
-                kdebug("usb3 port %d get desc ok", i);
-            }
-        }
-    }
-    kdebug("Active usb3 ports:%d", cnt);
-
-    // 循环启动所有的usb2端口
-    for (int i = 0; i < xhci_hc[id].port_num; ++i)
-    {
-        if (XHCI_PORT_IS_USB2(id, i) && XHCI_PORT_IS_ACTIVE(id, i))
-        {
-            // kdebug("initializing usb2: %d", i);
-            // reset该端口
-            // kdebug("to reset port %d, rflags=%#018lx", i, get_rflags());
-            if (likely(xhci_reset_port(id, i) ==
-                       0)) // 如果端口reset成功,就获取它的描述符
-                           // 否则,reset函数会把它给设置为未激活,并且标志配对的usb2端口是激活的
-            {
-                // kdebug("reset port %d ok", id);
-
-                struct usb_device_desc dev_desc = {0};
-                if (xhci_get_descriptor(id, i, &dev_desc) == 0)
-                {
-                    xhci_configure_port(id, i);
-                    ++cnt;
-                }
-                kdebug("USB2 port %d get desc ok", i);
-            }
-        }
-    }
-    kinfo("xHCI controller %d: Started %d ports.", id, cnt);
-    return 0;
-}
-
-/**
- * @brief 发送HID设备的IDLE数据包
- *
- * @param id 主机控制器号
- * @param port_id 端口号
- * @param if_desc 接口结构体
- * @return int
- */
-static int xhci_hid_set_idle(const int id, const int port_id, struct usb_interface_desc *if_desc)
-{
-    struct usb_device_desc *dev_desc = xhci_hc[id].ports[port_id].dev_desc;
-    if (unlikely(dev_desc) == NULL)
-    {
-        BUG_ON(1);
-        return -EINVAL;
-    }
-
-    DECLARE_USB_PACKET(ctrl_out_packet, USB_REQ_TYPE_SET_CLASS_INTERFACE, 0x0a, 0, 0, 0);
-    xhci_control_out(id, &ctrl_out_packet, NULL, port_id, dev_desc->max_packet_size);
-    kdebug("xhci set idle done!");
-    return 0;
-}
-
-/**
- * @brief 配置端点上下文,并发送configure endpoint命令
- *
- * @param id 主机控制器id
- * @param port_id 端口号
- * @param ep_num 端点号
- * @param ep_type 端点类型
- * @param ep_desc 端点描述符
- * @return int 错误码
- */
-static int xhci_configure_endpoint(const int id, const int port_id, const uint8_t ep_num, const uint8_t ep_type,
-                                   struct usb_endpoint_desc *ep_desc)
-{
-
-    int retval = 0;
-    uint64_t slot_context_vaddr = xhci_get_device_context_vaddr(id, port_id);
-
-    xhci_initialize_ep(id, slot_context_vaddr, port_id, ep_num, xhci_hc[id].ports[port_id].dev_desc->max_packet_size,
-                       usb_get_max_burst_from_ep(ep_desc), ep_type, (ep_num % 2) ? XHCI_DIR_IN_BIT : XHCI_DIR_OUT_BIT,
-                       xhci_get_port_speed(id, port_id), ep_desc->interval);
-
-    struct xhci_slot_context_t slot;
-    struct xhci_ep_context_t ep = {0};
-    // 创建输入上下文缓冲区
-    uint64_t input_ctx_buffer = (uint64_t)kzalloc(xhci_hc[id].context_size * 33, 0);
-    // 置位对应的add bit
-    __write4b(input_ctx_buffer + 4, (1 << ep_num) | 1);
-    __write4b(input_ctx_buffer + 0x1c, 1);
-
-    // 拷贝slot上下文
-    __read_from_slot(&slot, slot_context_vaddr);
-    // 设置该端口的最大端点号。注意,必须设置这里,否则会出错
-    slot.entries = (ep_num > slot.entries) ? ep_num : slot.entries;
-
-    __write_slot(input_ctx_buffer + xhci_hc[id].context_size, &slot);
-
-    // __write_ep(id, input_ctx_buffer, 2, &ep);
-    // kdebug("ep_num=%d", ep_num);
-    // 拷贝将要被配置的端点的信息
-    __read_from_ep(id, slot_context_vaddr, ep_num, &ep);
-    // kdebug("ep.tr_dequeue_ptr=%#018lx", ep.tr_dequeue_ptr);
-    ep.err_cnt = 3;
-    // 加一是因为input_context头部比slot_context多了一个input_control_ctx
-    __write_ep(id, input_ctx_buffer, ep_num + 1, &ep);
-
-    struct xhci_TRB_normal_t trb = {0};
-    trb.buf_paddr = virt_2_phys(input_ctx_buffer);
-    trb.TRB_type = TRB_TYPE_CONFIG_EP;
-    trb.cycle = xhci_hc[id].cmd_trb_cycle;
-    trb.Reserved |= (((uint16_t)xhci_hc[id].ports[port_id].slot_id) << 8) & 0xffff;
-
-    // kdebug("addr=%#018lx", ((struct xhci_TRB_t *)&trb)->param);
-    // kdebug("status=%#018lx", ((struct xhci_TRB_t *)&trb)->status);
-    // kdebug("command=%#018lx", ((struct xhci_TRB_t *)&trb)->command);
-    retval = xhci_send_command(id, (struct xhci_TRB_t *)&trb, true);
-
-    if (unlikely(retval != 0))
-    {
-        kerror("port_id:%d, configure endpoint %d failed", port_id, ep_num);
-        goto failed;
-    }
-
-    struct xhci_TRB_cmd_complete_t *trb_done = (struct xhci_TRB_cmd_complete_t *)&trb;
-    if (trb_done->code == TRB_COMP_TRB_SUCCESS) // 成功执行
-    {
-        // 如果要从控制器获取刚刚设置的设备地址的话,可以在这里读取slot context
-        ksuccess("port_id:%d, ep:%d successfully configured.", port_id, ep_num);
-        retval = 0;
-    }
-    else
-        retval = -EAGAIN;
-done:;
-failed:;
-    kfree((void *)input_ctx_buffer);
-    return retval;
-}
-
-/**
- * @brief 配置连接在指定端口上的设备
- *
- * @param id 主机控制器id
- * @param port_id 端口id
- * @param full_conf 完整的config
- * @return int 错误码
- */
-static int xhci_configure_port(const int id, const int port_id)
-{
-    void *full_conf = NULL;
-    struct usb_interface_desc *if_desc = NULL;
-    struct usb_endpoint_desc *ep_desc = NULL;
-    int retval = 0;
-
-    // hint: 暂时只考虑对键盘的初始化
-    // 获取完整的config
-    {
-        struct usb_config_desc conf_desc = {0};
-        retval = xhci_get_config_desc(id, port_id, &conf_desc);
-        if (unlikely(retval != 0))
-            return retval;
-
-        full_conf = kzalloc(conf_desc.total_len, 0);
-        if (unlikely(full_conf == NULL))
-            return -ENOMEM;
-
-        retval = xhci_get_config_desc_full(id, port_id, &conf_desc, full_conf);
-        if (unlikely(retval != 0))
-            goto failed;
-    }
-
-    retval = xhci_get_interface_desc(full_conf, 0, &if_desc);
-    if (unlikely(retval != 0))
-        goto failed;
-
-    if (if_desc->interface_class == USB_CLASS_HID)
-    {
-        // 由于暂时只支持键盘,因此把键盘的驱动也写在这里
-        // todo: 分离usb键盘驱动
-
-        retval = xhci_get_endpoint_desc(if_desc, 0, &ep_desc);
-        if (unlikely(retval != 0))
-            goto failed;
-        // kdebug("to set conf, val=%#010lx", ((struct usb_config_desc *)full_conf)->value);
-        retval = xhci_set_configuration(id, port_id, ((struct usb_config_desc *)full_conf)->value);
-        if (unlikely(retval != 0))
-            goto failed;
-        // kdebug("set conf ok");
-
-        // configure endpoint
-        retval = xhci_configure_endpoint(id, port_id, ep_desc->endpoint_addr, USB_EP_INTERRUPT, ep_desc);
-        if (unlikely(retval != 0))
-            goto failed;
-
-        retval = xhci_hid_set_idle(id, port_id, if_desc);
-        if (unlikely(retval != 0))
-            goto failed;
-
-        struct usb_hid_desc *hid_desc = NULL;
-        uint32_t hid_desc_len = 0;
-        // 获取hid desc
-        retval = xhci_get_hid_descriptor(id, port_id, full_conf, if_desc->interface_number, &hid_desc);
-        if (unlikely(retval != 0))
-            goto failed;
-
-        // 获取hid report
-        void *hid_report_data = kzalloc(hid_desc->report_desc_len, 0);
-        if (unlikely(hid_report_data == NULL))
-            goto failed;
-        retval =
-            xhci_get_hid_report(id, port_id, if_desc->interface_number, hid_report_data, hid_desc->report_desc_len);
-        if (unlikely(retval != 0))
-        {
-            kfree(hid_report_data);
-            goto failed;
-        }
-
-        kdebug("to parse hid report");
-        // todo:这里的parse有问题,详见hid_parse函数的注释
-        // hid_parse_report(hid_report_data, hid_desc->report_desc_len);
-        kdebug("parse hid report done");
-
-        // kdebug("to find object from hid path");
-        // struct hid_data_t data = {0};
-        // data.type = HID_ITEM_INPUT;
-        // data.path.node[0].u_page = HID_USAGE_PAGE_GEN_DESKTOP;
-        // data.path.node[0].usage = 0xff;
-        // data.path.node[2].usage = USAGE_POINTER_Y;     // to get the Y Coordinate, comment X above and uncomment this
-        // line data.path.node[2].usage = USAGE_POINTER_WHEEL; // to get the Wheel Coordinate, comment X above and
-        // uncomment this line
-        // data.path.size = 1;
-        // hid_parse_find_object(hid_report_data, hid_desc->report_desc_len, &data);
-        kfree(hid_report_data);
-    }
-    goto out;
-failed:;
-    kerror("failed at xhci_configure_port, retval=%d", retval);
-out:;
-    kfree(full_conf);
-    return retval;
-}
-/**
- * @brief 初始化xhci主机控制器的中断控制
- *
- * @param id 主机控制器id
- * @return int 返回码
- */
-static int xhci_hc_init_intr(int id)
-{
-    uint64_t retval = 0;
-
-    struct xhci_caps_HCSPARAMS1_reg_t hcs1;
-    struct xhci_caps_HCSPARAMS2_reg_t hcs2;
-    io_mfence();
-    memcpy(&hcs1, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t));
-    io_mfence();
-    memcpy(&hcs2, xhci_get_ptr_cap_reg32(id, XHCI_CAPS_HCSPARAMS2), sizeof(struct xhci_caps_HCSPARAMS2_reg_t));
-    io_mfence();
-
-    uint32_t max_segs = (1 << (uint32_t)(hcs2.ERST_Max));
-    uint32_t max_interrupters = hcs1.max_intrs;
-
-    // 创建 event ring
-    retval = xhci_create_event_ring(4096, &xhci_hc[id].event_ring_vaddr);
-    io_mfence();
-    if (unlikely((int64_t)(retval) == -ENOMEM))
-        return -ENOMEM;
-    xhci_hc[id].event_ring_table_vaddr = retval;
-    xhci_hc[id].current_event_ring_vaddr =
-        xhci_hc[id].event_ring_vaddr; // 设置驱动程序要读取的下一个event ring trb的地址
-    retval = 0;
-
-    xhci_hc[id].current_event_ring_cycle = 1;
-
-    // 写入第0个中断寄存器组
-    io_mfence();
-    xhci_write_intr_reg32(id, 0, XHCI_IR_MAN, 0x3); // 使能中断并清除pending位(这个pending位是写入1就清0的)
-    io_mfence();
-    xhci_write_intr_reg32(id, 0, XHCI_IR_MOD, 0); // 关闭中断管制
-    io_mfence();
-    xhci_write_intr_reg32(id, 0, XHCI_IR_TABLE_SIZE, 1); // 当前只有1个segment
-    io_mfence();
-    xhci_write_intr_reg64(id, 0, XHCI_IR_DEQUEUE,
-                          virt_2_phys(xhci_hc[id].current_event_ring_vaddr) |
-                              (1 << 3)); // 写入dequeue寄存器,并清除busy位(写1就会清除)
-    io_mfence();
-    xhci_write_intr_reg64(id, 0, XHCI_IR_TABLE_ADDR, virt_2_phys(xhci_hc[id].event_ring_table_vaddr)); // 写入table地址
-    io_mfence();
-
-    // 清除状态位
-    xhci_write_op_reg32(id, XHCI_OPS_USBSTS, (1 << 10) | (1 << 4) | (1 << 3) | (1 << 2));
-    io_mfence();
-    // 开启usb中断
-    // 注册中断处理程序
-    struct xhci_hc_irq_install_info_t install_info;
-    install_info.assert = 1;
-    install_info.edge_trigger = 1;
-    install_info.processor = 0; // 投递到bsp
-
-    char *buf = (char *)kmalloc(16, 0);
-    memset(buf, 0, 16);
-    sprintk(buf, "xHCI HC%d", id);
-    io_mfence();
-    irq_register(xhci_controller_irq_num[id], &install_info, &xhci_hc_irq_handler, id, &xhci_hc_intr_controller, buf);
-    io_mfence();
-    kfree(buf);
-
-    kdebug("xhci host controller %d: interrupt registered. irq num=%d", id, xhci_controller_irq_num[id]);
-
-    return 0;
-}
-
-/**
- * @brief 往xhci控制器发送trb, 并将返回的数据存入原始的trb中
- *
- * @param id xhci控制器号
- * @param trb 传输请求块
- * @param do_ring 是否通知doorbell register
- * @return int 错误码
- */
-static int xhci_send_command(int id, struct xhci_TRB_t *trb, const bool do_ring)
-{
-    uint64_t origin_trb_vaddr = xhci_hc[id].cmd_trb_vaddr;
-
-    // 必须先写入参数和状态数据,最后写入command
-    __write8b(xhci_hc[id].cmd_trb_vaddr, trb->param);                                    // 参数
-    __write4b(xhci_hc[id].cmd_trb_vaddr + 8, trb->status);                               // 状态
-    __write4b(xhci_hc[id].cmd_trb_vaddr + 12, trb->command | xhci_hc[id].cmd_trb_cycle); // 命令
-
-    xhci_hc[id].cmd_trb_vaddr += sizeof(struct xhci_TRB_t); // 跳转到下一个trb
-
-    {
-        // 如果下一个trb是link trb,则将下一个要操作的地址是设置为第一个trb
-        struct xhci_TRB_normal_t *ptr = (struct xhci_TRB_normal_t *)xhci_hc[id].cmd_trb_vaddr;
-        if (ptr->TRB_type == TRB_TYPE_LINK)
-        {
-            ptr->cycle = xhci_hc[id].cmd_trb_cycle;
-            xhci_hc[id].cmd_trb_vaddr = xhci_hc[id].cmd_ring_vaddr;
-            xhci_hc[id].cmd_trb_cycle ^= 1;
-        }
-    }
-
-    if (do_ring) // 按响命令门铃
-    {
-        __xhci_write_doorbell(id, 0, 0);
-
-        // 等待中断产生
-        int timer = 400;
-        const uint32_t iman0 = xhci_read_intr_reg32(id, 0, XHCI_IR_MAN);
-
-        // Now wait for the interrupt to happen
-        // We use bit 31 of the command dword since it is reserved
-        while (timer && ((__read4b(origin_trb_vaddr + 8) & XHCI_IRQ_DONE) == 0))
-        {
-            rs_usleep(1000);
-            --timer;
-        }
-        uint32_t x = xhci_read_cap_reg32(id, xhci_hc[id].rts_offset + 0x20);
-        if (timer == 0)
-            return -ETIMEDOUT;
-        else
-        {
-            xhci_get_trb(trb, origin_trb_vaddr);
-            trb->status &= (~XHCI_IRQ_DONE);
-        }
-    }
-    return 0;
-}
-
-/**
- * @brief 获取接口的hid descriptor
- *
- * @param id 主机控制器号
- * @param port_id 端口号
- * @param full_conf 完整的cofig缓冲区
- * @param interface_number 接口号
- * @param ret_hid_desc 返回的指向hid描述符的指针
- * @return int 错误码
- */
-static int xhci_get_hid_descriptor(int id, int port_id, const void *full_conf, int interface_number,
-                                   struct usb_hid_desc **ret_hid_desc)
-{
-    if (unlikely(ret_hid_desc == NULL || full_conf == NULL))
-        return -EINVAL;
-    kdebug("to get hid_descriptor.");
-    // 判断接口index是否合理
-    if (interface_number >= ((struct usb_config_desc *)full_conf)->num_interfaces)
-        return -EINVAL;
-    uint32_t total_len = ((struct usb_config_desc *)full_conf)->total_len;
-    uint32_t pos = 0;
-    while (pos < total_len)
-    {
-        struct usb_hid_desc *ptr = (struct usb_hid_desc *)(full_conf + pos);
-        if (ptr->type != USB_DT_HID)
-        {
-            pos += ptr->len;
-            continue;
-        }
-        // 找到目标hid描述符
-        *ret_hid_desc = ptr;
-        kdebug("Found hid descriptor for port:%d, if:%d, report_desc_len=%d", port_id, interface_number,
-               ptr->report_desc_len);
-        return 0;
-    }
-
-    return -EINVAL;
-}
-
-/**
- * @brief 发送get_hid_descriptor请求,将hid
- *
- * @param id 主机控制器号
- * @param port_id 端口号
- * @param interface_number 接口号
- * @param ret_hid_report hid report要拷贝到的地址
- * @param hid_report_len hid report的长度
- * @return int 错误码
- */
-static int xhci_get_hid_report(int id, int port_id, int interface_number, void *ret_hid_report, uint32_t hid_report_len)
-{
-    int retval = xhci_get_desc(id, port_id, ret_hid_report, USB_DT_HID_REPORT, 0, interface_number, hid_report_len);
-    if (unlikely(retval != 0))
-        kerror("xhci_get_hid_report failed: host_controller:%d, port:%d, interface %d", id, port_id, interface_number);
-    return retval;
-}
-/**
- * @brief 初始化xhci控制器
- *
- * @param header 指定控制器的pci device头部
- */
-void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
-{
-
-    if (xhci_ctrl_count >= XHCI_MAX_HOST_CONTROLLERS)
-    {
-        kerror("Initialize xhci controller failed: exceed the limit of max controllers.");
-        return;
-    }
-
-    spin_lock(&xhci_controller_init_lock);
-    kinfo("Initializing xhci host controller: bus=%#02x, device=%#02x, func=%#02x, VendorID=%#04x, irq_line=%d, "
-          "irq_pin=%d",
-          dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, dev_hdr->header.Vendor_ID,
-          dev_hdr->Interrupt_Line, dev_hdr->Interrupt_PIN);
-    io_mfence();
-    int cid = xhci_hc_find_available_id();
-    if (cid < 0)
-    {
-        kerror("Initialize xhci controller failed: exceed the limit of max controllers.");
-        goto failed_exceed_max;
-    }
-
-    memset(&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));
-    xhci_hc[cid].controller_id = cid;
-    xhci_hc[cid].pci_dev_hdr = dev_hdr;
-    io_mfence();
-    {
-        uint32_t tmp = pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x4);
-        tmp |= 0x6;
-        // mem I/O access enable and bus master enable
-        pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x4, tmp);
-    }
-    io_mfence();
-    // 为当前控制器映射寄存器地址空间
-    xhci_hc[cid].vbase =
-        SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + XHCI_MAPPING_OFFSET + 65536 * xhci_hc[cid].controller_id;
-    // kdebug("dev_hdr->BAR0 & (~0xf)=%#018lx", dev_hdr->BAR0 & (~0xf));
-    mm_map_phys_addr(xhci_hc[cid].vbase, dev_hdr->BAR0 & (~0xf), 65536, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, true);
-    io_mfence();
-
-    // 计算operational registers的地址
-    xhci_hc[cid].vbase_op = xhci_hc[cid].vbase + (xhci_read_cap_reg32(cid, XHCI_CAPS_CAPLENGTH) & 0xff);
-    io_mfence();
-    // 重置xhci控制器
-    FAIL_ON_TO(xhci_hc_reset(cid), failed);
-    io_mfence();
-
-    // 读取xhci控制寄存器
-    uint16_t iversion = *(uint16_t *)(xhci_hc[cid].vbase + XHCI_CAPS_HCIVERSION);
-
-    struct xhci_caps_HCCPARAMS1_reg_t hcc1;
-    struct xhci_caps_HCCPARAMS2_reg_t hcc2;
-
-    struct xhci_caps_HCSPARAMS1_reg_t hcs1;
-    struct xhci_caps_HCSPARAMS2_reg_t hcs2;
-    memcpy(&hcc1, xhci_get_ptr_cap_reg32(cid, XHCI_CAPS_HCCPARAMS1), sizeof(struct xhci_caps_HCCPARAMS1_reg_t));
-    memcpy(&hcc2, xhci_get_ptr_cap_reg32(cid, XHCI_CAPS_HCCPARAMS2), sizeof(struct xhci_caps_HCCPARAMS2_reg_t));
-    memcpy(&hcs1, xhci_get_ptr_cap_reg32(cid, XHCI_CAPS_HCSPARAMS1), sizeof(struct xhci_caps_HCSPARAMS1_reg_t));
-    memcpy(&hcs2, xhci_get_ptr_cap_reg32(cid, XHCI_CAPS_HCSPARAMS2), sizeof(struct xhci_caps_HCSPARAMS2_reg_t));
-
-    xhci_hc[cid].db_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_DBOFF) & (~0x3); // bits [1:0] reserved
-    io_mfence();
-    xhci_hc[cid].rts_offset = xhci_read_cap_reg32(cid, XHCI_CAPS_RTSOFF) & (~0x1f); // bits [4:0] reserved.
-    io_mfence();
-
-    xhci_hc[cid].ext_caps_off = 1UL * (hcc1.xECP) * 4;
-    xhci_hc[cid].context_size = (hcc1.csz) ? 64 : 32;
-
-    if (iversion < 0x95)
-        kwarn("Unsupported/Unknowned xHCI controller version: %#06x. This may cause unexpected behavior.", iversion);
-
-    {
-
-        // Write to the FLADJ register incase the BIOS didn't
-        uint32_t tmp = pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x60);
-        tmp |= (0x20 << 8);
-        pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0x60, tmp);
-    }
-    // if it is a Panther Point device, make sure sockets are xHCI controlled.
-    if (((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0) & 0xffff) == 0x8086) &&
-        (((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0) >> 16) & 0xffff) ==
-         0x1E31) &&
-        ((pci_read_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 8) & 0xff) == 4))
-    {
-        kdebug("Is a Panther Point device");
-        pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd8, 0xffffffff);
-        pci_write_config(dev_hdr->header.bus, dev_hdr->header.device, dev_hdr->header.func, 0xd0, 0xffffffff);
-    }
-    io_mfence();
-    // 关闭legacy支持
-    FAIL_ON_TO(xhci_hc_stop_legacy(cid), failed);
-    io_mfence();
-
-    // 端口配对
-    FAIL_ON_TO(xhci_hc_pair_ports(cid), failed);
-    io_mfence();
-
-    // ========== 设置USB host controller =========
-    // 获取页面大小
-    xhci_hc[cid].page_size = (xhci_read_op_reg32(cid, XHCI_OPS_PAGESIZE) & 0xffff) << 12;
-    io_mfence();
-    // 获取设备上下文空间
-    xhci_hc[cid].dcbaap_vaddr = (uint64_t)kzalloc(2048, 0); // 分配2KB的设备上下文地址数组空间
-
-    io_mfence();
-    // kdebug("dcbaap_vaddr=%#018lx", xhci_hc[cid].dcbaap_vaddr);
-    if (unlikely(!xhci_is_aligned64(xhci_hc[cid].dcbaap_vaddr))) // 地址不是按照64byte对齐
-    {
-        kerror("dcbaap isn't 64 byte aligned.");
-        goto failed_free_dyn;
-    }
-    // 写入dcbaap
-    xhci_write_op_reg64(cid, XHCI_OPS_DCBAAP, virt_2_phys(xhci_hc[cid].dcbaap_vaddr));
-    io_mfence();
-
-    // 创建scratchpad buffer array
-    uint32_t max_scratchpad_buf = (((uint32_t)hcs2.max_scratchpad_buf_HI5) << 5) | hcs2.max_scratchpad_buf_LO5;
-    kdebug("max scratchpad buffer=%d", max_scratchpad_buf);
-    if (max_scratchpad_buf > 0)
-    {
-        xhci_hc[cid].scratchpad_buf_array_vaddr = (uint64_t)kzalloc(sizeof(uint64_t) * max_scratchpad_buf, 0);
-        __write8b(xhci_hc[cid].dcbaap_vaddr, virt_2_phys(xhci_hc[cid].scratchpad_buf_array_vaddr));
-
-        // 创建scratchpad buffers
-        for (int i = 0; i < max_scratchpad_buf; ++i)
-        {
-            uint64_t buf_vaddr = (uint64_t)kzalloc(xhci_hc[cid].page_size, 0);
-            __write8b(xhci_hc[cid].scratchpad_buf_array_vaddr, virt_2_phys(buf_vaddr));
-        }
-    }
-
-    // 创建command ring
-    xhci_hc[cid].cmd_ring_vaddr = xhci_create_ring(XHCI_CMND_RING_TRBS);
-    xhci_hc[cid].cmd_trb_vaddr = xhci_hc[cid].cmd_ring_vaddr;
-
-    if (unlikely(!xhci_is_aligned64(xhci_hc[cid].cmd_ring_vaddr))) // 地址不是按照64byte对齐
-    {
-        kerror("cmd ring isn't 64 byte aligned.");
-        goto failed_free_dyn;
-    }
-
-    // 设置初始cycle bit为1
-    xhci_hc[cid].cmd_trb_cycle = XHCI_TRB_CYCLE_ON;
-    io_mfence();
-    // 写入command ring控制寄存器
-    xhci_write_op_reg64(cid, XHCI_OPS_CRCR, virt_2_phys(xhci_hc[cid].cmd_ring_vaddr) | xhci_hc[cid].cmd_trb_cycle);
-    // 写入配置寄存器
-    uint32_t max_slots = hcs1.max_slots;
-    // kdebug("max slots = %d", max_slots);
-    io_mfence();
-    xhci_write_op_reg32(cid, XHCI_OPS_CONFIG, max_slots);
-    io_mfence();
-    // 写入设备通知控制寄存器
-    xhci_write_op_reg32(cid, XHCI_OPS_DNCTRL, (1 << 1)); // 目前只有N1被支持
-    io_mfence();
-
-    FAIL_ON_TO(xhci_hc_init_intr(cid), failed_free_dyn);
-    io_mfence();
-
-    ++xhci_ctrl_count;
-    io_mfence();
-    spin_unlock(&xhci_controller_init_lock);
-    io_mfence();
-
-    return;
-
-failed_free_dyn:; // 释放动态申请的内存
-    if (xhci_hc[cid].dcbaap_vaddr)
-        kfree((void *)xhci_hc[cid].dcbaap_vaddr);
-
-    if (xhci_hc[cid].cmd_ring_vaddr)
-        kfree((void *)xhci_hc[cid].cmd_ring_vaddr);
-
-    if (xhci_hc[cid].event_ring_table_vaddr)
-        kfree((void *)xhci_hc[cid].event_ring_table_vaddr);
-
-    if (xhci_hc[cid].event_ring_vaddr)
-        kfree((void *)xhci_hc[cid].event_ring_vaddr);
-
-failed:;
-    io_mfence();
-    // 取消地址映射
-    mm_unmap_addr(xhci_hc[cid].vbase, 65536);
-    io_mfence();
-    // 清空数组
-    memset((void *)&xhci_hc[cid], 0, sizeof(struct xhci_host_controller_t));
-
-failed_exceed_max:;
-    kerror("Failed to initialize controller: bus=%d, dev=%d, func=%d", dev_hdr->header.bus, dev_hdr->header.device,
-           dev_hdr->header.func);
-    spin_unlock(&xhci_controller_init_lock);
-}

+ 0 - 649
kernel/src/driver/usb/xhci/xhci.h

@@ -1,649 +0,0 @@
-#pragma once
-#include <driver/usb/usb.h>
-#include <driver/pci/pci.h>
-#include <driver/pci/msi.h>
-// #pragma GCC optimize("O0")
-#define XHCI_MAX_HOST_CONTROLLERS 4 // 本驱动程序最大支持4个xhci root hub controller
-#define XHCI_MAX_ROOT_HUB_PORTS 128 // 本驱动程序最大支持127个root hub 端口(第0个保留)
-
-// ========== irq BEGIN ===========
-
-#define XHCI_IRQ_DONE (1U << 31) // 当command trb 的status的第31位被驱动程序置位时,表明该trb已经执行完成(这是由于xhci规定,第31位可以由驱动程序自行决定用途)
-/**
- * @brief 每个xhci控制器的中断向量号
- *
- */
-const uint8_t xhci_controller_irq_num[XHCI_MAX_HOST_CONTROLLERS] = {157, 158, 159, 160};
-
-/**
- * @brief 通过irq号寻找对应的主机控制器id
- *
- */
-#define xhci_find_hcid_by_irq_num(irq_num) ({           \
-    int retval = -1;                                    \
-    for (int i = 0; i < XHCI_MAX_HOST_CONTROLLERS; ++i) \
-        if (xhci_controller_irq_num[i] == irq_num)      \
-            retval = i;                                 \
-    retval;                                             \
-})
-
-struct xhci_hc_irq_install_info_t
-{
-    int processor;       // 中断目标处理器
-    int8_t edge_trigger; // 是否边缘触发
-    int8_t assert;       // 是否高电平触发
-};
-// ========== irq END ===========
-
-// ======== Capability Register Set BEGIN ============
-
-// xhci Capability Registers offset
-#define XHCI_CAPS_CAPLENGTH 0x00 // Cap 寄存器组的长度
-#define XHCI_CAPS_RESERVED 0x01
-#define XHCI_CAPS_HCIVERSION 0x02 // 接口版本号
-#define XHCI_CAPS_HCSPARAMS1 0x04
-#define XHCI_CAPS_HCSPARAMS2 0x08
-#define XHCI_CAPS_HCSPARAMS3 0x0c
-#define XHCI_CAPS_HCCPARAMS1 0x10 // capability params 1
-#define XHCI_CAPS_DBOFF 0x14      // Doorbell offset
-#define XHCI_CAPS_RTSOFF 0x18     // Runtime register space offset
-#define XHCI_CAPS_HCCPARAMS2 0x1c // capability params 2
-
-struct xhci_caps_HCSPARAMS1_reg_t
-{
-    unsigned max_slots : 8;  // 最大插槽数
-    unsigned max_intrs : 11; // 最大中断数
-    unsigned reserved : 5;
-    unsigned max_ports : 8; // 最大端口数
-} __attribute__((packed));
-
-struct xhci_caps_HCSPARAMS2_reg_t
-{
-    unsigned ist : 4;      // 同步调度阈值
-    unsigned ERST_Max : 4; // Event Ring Segment Table: Max segs
-    unsigned Reserved : 13;
-    unsigned max_scratchpad_buf_HI5 : 5; // 草稿行buffer地址(高5bit)
-    unsigned spr : 1;                    // scratchpad restore
-    unsigned max_scratchpad_buf_LO5 : 5; // 草稿行buffer地址(低5bit)
-} __attribute__((packed));
-
-struct xhci_caps_HCSPARAMS3_reg_t
-{
-    uint8_t u1_device_exit_latency; // 0~10ms
-    uint8_t Reserved;
-    uint16_t u2_device_exit_latency; // 0~2047ms
-} __attribute__((packed));
-
-struct xhci_caps_HCCPARAMS1_reg_t
-{
-    unsigned int ac64 : 1; // 64-bit addressing capability
-    unsigned int bnc : 1;  // bw negotiation capability
-    unsigned int csz : 1;  // context size
-    unsigned int ppc : 1;  // 端口电源控制
-    unsigned int pind : 1; // port indicators
-    unsigned int lhrc : 1; // Light HC reset capability
-    unsigned int ltc : 1;  // latency tolerance messaging capability
-    unsigned int nss : 1;  // no secondary SID support
-
-    unsigned int pae : 1;        // parse all event data
-    unsigned int spc : 1;        // Stopped - Short packet capability
-    unsigned int sec : 1;        // Stopped EDTLA capability
-    unsigned int cfc : 1;        // Continuous Frame ID capability
-    unsigned int MaxPSASize : 4; // Max Primary Stream Array Size
-
-    uint16_t xECP; // xhci extended capabilities pointer
-
-} __attribute__((packed));
-
-struct xhci_caps_HCCPARAMS2_reg_t
-{
-    unsigned u3c : 1; // U3 Entry Capability
-    unsigned cmc : 1; // ConfigEP command Max exit latency too large
-    unsigned fsc : 1; // Force Save Context Capability
-    unsigned ctc : 1; // Compliance Transition Capability
-    unsigned lec : 1; // large ESIT payload capability
-    unsigned cic : 1; // configuration information capability
-    unsigned Reserved : 26;
-} __attribute__((packed));
-// ======== Capability Register Set END ============
-
-// ======== Operational Register Set BEGIN =========
-
-// xhci operational registers offset
-#define XHCI_OPS_USBCMD 0x00   // USB Command
-#define XHCI_OPS_USBSTS 0x04   // USB status
-#define XHCI_OPS_PAGESIZE 0x08 // Page size
-#define XHCI_OPS_DNCTRL 0x14   // Device notification control
-#define XHCI_OPS_CRCR 0x18     // Command ring control
-#define XHCI_OPS_DCBAAP 0x30   // Device context base address array pointer
-#define XHCI_OPS_CONFIG 0x38   // configuire
-#define XHCI_OPS_PRS 0x400     // Port register sets
-
-struct xhci_ops_usbcmd_reg_t
-{
-    unsigned rs : 1;          // Run/Stop
-    unsigned hcrst : 1;       // host controller reset
-    unsigned inte : 1;        // Interrupt enable
-    unsigned hsee : 1;        // Host system error enable
-    unsigned rsvd_psvd1 : 3;  // Reserved and preserved
-    unsigned lhcrst : 1;      // light host controller reset
-    unsigned css : 1;         // controller save state
-    unsigned crs : 1;         // controller restore state
-    unsigned ewe : 1;         // enable wrap event
-    unsigned ue3s : 1;        // enable U3 MFINDEX Stop
-    unsigned spe : 1;         // stopped short packet enable
-    unsigned cme : 1;         // CEM Enable
-    unsigned rsvd_psvd2 : 18; // Reserved and preserved
-} __attribute__((packed));
-
-struct xhci_ops_usbsts_reg_t
-{
-    unsigned HCHalted : 1;
-    unsigned rsvd_psvd1 : 1;  // Reserved and preserved
-    unsigned hse : 1;         // Host system error
-    unsigned eint : 1;        // event interrupt
-    unsigned pcd : 1;         // Port change detected
-    unsigned rsvd_zerod : 3;  // Reserved and Zero'd
-    unsigned sss : 1;         // Save State Status
-    unsigned rss : 1;         // restore state status
-    unsigned sre : 1;         // save/restore error
-    unsigned cnr : 1;         // controller not ready
-    unsigned hce : 1;         // host controller error
-    unsigned rsvd_psvd2 : 19; // Reserved and Preserved
-} __attribute__((packed));
-
-struct xhci_ops_pagesize_reg_t
-{
-    uint16_t page_size; // The actual pagesize is ((this field)<<12)
-    uint16_t reserved;
-} __attribute__((packed));
-
-struct xhci_ops_dnctrl_reg_t
-{
-    uint16_t value;
-    uint16_t reserved;
-} __attribute__((packed));
-
-struct xhci_ops_config_reg_t
-{
-    uint8_t MaxSlotsEn;      // Max slots enabled
-    unsigned u3e : 1;        // U3 Entry Enable
-    unsigned cie : 1;        // Configuration information enable
-    unsigned rsvd_psvd : 22; // Reserved and Preserved
-} __attribute__((packed));
-
-// ======== Operational Register Set END =========
-// ========= TRB begin ===========
-
-// TRB的Transfer Type可用值定义
-#define XHCI_TRB_TRT_NO_DATA 0
-#define XHCI_TRB_TRT_RESERVED 1
-#define XHCI_TRB_TRT_OUT_DATA 2
-#define XHCI_TRB_TRT_IN_DATA 3
-
-#define XHCI_CMND_RING_TRBS 128 // TRB num of command ring,  not more than 4096
-
-#define XHCI_TRBS_PER_RING 256
-
-#define XHCI_TRB_CYCLE_OFF 0
-#define XHCI_TRB_CYCLE_ON 1
-
-// 获取、设置trb中的status部分的complete code
-#define xhci_get_comp_code(status) (((status) >> 24) & 0x7f)
-#define xhci_set_comp_code(code) ((code & 0x7f) << 24)
-
-/**
- * @brief xhci通用TRB结构
- *
- */
-struct xhci_TRB_t
-{
-    uint64_t param; // 参数
-    uint32_t status;
-    uint32_t command;
-} __attribute__((packed));
-struct xhci_TRB_normal_t
-{
-    uint64_t buf_paddr; // 数据缓冲区物理地址
-
-    unsigned transfer_length : 17; // 传输数据长度
-    unsigned TD_size : 5;          // 传输描述符中剩余的数据包的数量
-    unsigned intr_target : 10;     // 中断目标 [0:MaxIntrs-1]
-
-    unsigned cycle : 1;    // used to mark the enqueue pointer of transfer ring
-    unsigned ent : 1;      // evaluate next TRB before updating the endpoint's state
-    unsigned isp : 1;      // Interrupt on short packet bit
-    unsigned ns : 1;       // No snoop
-    unsigned chain : 1;    // The chain bit is used to tell the controller that this
-                           // TRB is associated with the next TRB in the TD
-    unsigned ioc : 1;      // 完成时发起中断
-    unsigned idt : 1;      // Immediate Data
-    unsigned resv : 2;     // Reserved and zero'd
-    unsigned bei : 1;      // Block event interrupt
-    unsigned TRB_type : 6; // TRB类型
-    uint16_t Reserved;     // 保留且置为0
-} __attribute__((packed));
-
-struct xhci_TRB_setup_stage_t
-{
-    uint8_t bmRequestType;
-    uint8_t bRequest;
-    uint16_t wValue;
-
-    uint16_t wIndex;
-    uint16_t wLength;
-
-    unsigned transfer_legth : 17; // TRB transfer length
-    unsigned resv1 : 5;           // Reserved and zero'd
-    unsigned intr_target : 10;
-
-    unsigned cycle : 1;
-    unsigned resv2 : 4; // Reserved and zero'd
-    unsigned ioc : 1;   // interrupt on complete
-    unsigned idt : 1;   // immediate data (should always set for setup TRB)
-    unsigned resv3 : 3; // Reserved and zero'd
-    unsigned TRB_type : 6;
-    unsigned trt : 2;    // Transfer type
-    unsigned resv4 : 14; // Reserved and zero'd
-
-} __attribute__((packed));
-
-struct xhci_TRB_data_stage_t
-{
-    uint64_t buf_paddr; // 数据缓冲区物理地址
-
-    unsigned transfer_length : 17; // 传输数据长度
-    unsigned TD_size : 5;          // 传输描述符中剩余的数据包的数量
-    unsigned intr_target : 10;     // 中断目标 [0:MaxIntrs-1]
-
-    unsigned cycle : 1;     // used to mark the enqueue pointer of transfer ring
-    unsigned ent : 1;       // evaluate next TRB before updating the endpoint's state
-    unsigned isp : 1;       // Interrupt on short packet bit
-    unsigned ns : 1;        // No snoop
-    unsigned chain : 1;     // The chain bit is used to tell the controller that this
-                            // TRB is associated with the next TRB in the TD
-    unsigned ioc : 1;       // 完成时发起中断
-    unsigned idt : 1;       // Immediate Data
-    unsigned resv : 3;      // Reserved and zero'd
-    unsigned TRB_type : 6;  // TRB类型
-    unsigned dir : 1;       // 0 -> out packet
-                            // 1 -> in packet
-    unsigned Reserved : 15; // 保留且置为0
-} __attribute__((packed));
-
-struct xhci_TRB_status_stage_t
-{
-    uint64_t resv1; // Reserved and zero'd
-
-    unsigned resv2 : 22;       // Reserved and zero'd
-    unsigned intr_target : 10; // 中断目标 [0:MaxIntrs-1]
-
-    unsigned cycle : 1;     // used to mark the enqueue pointer of transfer ring
-    unsigned ent : 1;       // evaluate next TRB before updating the endpoint's state
-    unsigned resv3 : 2;     // Reserved and zero'd
-    unsigned chain : 1;     // The chain bit is used to tell the controller that this
-                            // TRB is associated with the next TRB in the TD
-    unsigned ioc : 1;       // 完成时发起中断
-    unsigned resv4 : 4;     // Reserved and zero'd
-    unsigned TRB_type : 6;  // TRB类型
-    unsigned dir : 1;       // 0 -> out packet
-                            // 1 -> in packet
-    unsigned Reserved : 15; // 保留且置为0
-} __attribute__((packed));
-
-struct xhci_TRB_cmd_complete_t
-{
-    uint64_t cmd_trb_pointer_paddr; //  指向生成当前Event TRB的TRB的物理地址(16bytes对齐)
-
-    unsigned resv1 : 24; // Reserved and zero'd
-    uint8_t code;        // Completion code
-
-    unsigned cycle : 1;    // cycle bit
-    unsigned resv2 : 9;    // Reserved and zero'd
-    unsigned TRB_type : 6; // TRB类型
-    uint8_t VF_ID;
-    uint8_t slot_id; // the id of the slot associated with the
-                     // command that generated the event
-} __attribute__((packed));
-// ========= TRB end ===========
-
-// ======== Runtime Register Set Begin =========
-
-#define XHCI_RT_IR0 0x20 // 中断寄存器组0距离runtime Register set起始位置的偏移量
-#define XHCI_IR_SIZE 32  // 中断寄存器组大小
-
-// 中断寄存器组内的偏移量
-#define XHCI_IR_MAN 0x00        // Interrupter Management Register
-#define XHCI_IR_MOD 0x04        // Interrupter Moderation
-#define XHCI_IR_TABLE_SIZE 0x08 // Event Ring Segment Table size (count of segments)
-#define XHCI_IR_TABLE_ADDR 0x10 // Event Ring Segment Table Base Address
-#define XHCI_IR_DEQUEUE 0x18    // Event Ring Dequeue Pointer
-
-// MAN寄存器内的bit的含义
-#define XHCI_IR_IMR_PENDING (1 << 0) // Interrupt pending bit in Management Register
-#define XHCI_IR_IMR_ENABLE (1 << 1)  // Interrupt enable bit in Management Register
-
-struct xhci_intr_moderation_t
-{
-    uint16_t interval; // 产生一个中断的时间,是interval*250ns (wait before next interrupt)
-    uint16_t counter;
-} __attribute__((packed));
-// ======== Runtime Register Set END =========
-
-// ======= xhci Extended Capabilities List BEGIN========
-
-// ID 部分的含义定义
-#define XHCI_XECP_ID_RESERVED 0
-#define XHCI_XECP_ID_LEGACY 1    // USB Legacy Support
-#define XHCI_XECP_ID_PROTOCOL 2  // Supported protocol
-#define XHCI_XECP_ID_POWER 3     // Extended power management
-#define XHCI_XECP_ID_IOVIRT 4    // I/0 virtualization
-#define XHCI_XECP_ID_MSG 5       // Message interrupt
-#define XHCI_XECP_ID_LOCAL_MEM 6 // local memory
-#define XHCI_XECP_ID_DEBUG 10    // USB Debug capability
-#define XHCI_XECP_ID_EXTMSG 17   // Extended message interrupt
-
-#define XHCI_XECP_LEGACY_TIMEOUT 10           // 设置legacy状态的等待时间
-#define XHCI_XECP_LEGACY_BIOS_OWNED (1 << 16) // 当bios控制着该hc时,该位被置位
-#define XHCI_XECP_LEGACY_OS_OWNED (1 << 24)   // 当系统控制着该hc时,该位被置位
-#define XHCI_XECP_LEGACY_OWNING_MASK (XHCI_XECP_LEGACY_BIOS_OWNED | XHCI_XECP_LEGACY_OS_OWNED)
-
-// ======= xhci Extended Capabilities List END ========
-
-// ======= Port status and control registers BEGIN ====
-#define XHCI_PORT_PORTSC 0x00    // Port status and control
-#define XHCI_PORT_PORTPMSC 0x04  // Port power management status and control
-#define XHCI_PORT_PORTLI 0x08    // Port Link info
-#define XHCI_PORT_PORTHLMPC 0x0c // Port hardware LPM control (version 1.10 only
-
-#define XHCI_PORTUSB_CHANGE_BITS ((1 << 17) | (1 << 18) | (1 << 20) | (1 << 21) | (1 << 22))
-
-// 存储于portsc中的端口速度的可用值
-#define XHCI_PORT_SPEED_FULL 1
-#define XHCI_PORT_SPEED_LOW 2
-#define XHCI_PORT_SPEED_HI 3
-#define XHCI_PORT_SPEED_SUPER 4
-
-// ======= Port status and control registers END ====
-
-// ======= Device Slot Context BEGIN ====
-
-/**
- * @brief 设备上下文结构体
- *
- */
-struct xhci_slot_context_t
-{
-    unsigned route_string : 20;
-    unsigned speed : 4;
-    unsigned Rsvd0 : 1; // Reserved and zero'd
-    unsigned mtt : 1;   // multi-TT
-    unsigned hub : 1;
-    unsigned entries : 5; // count of context entries
-
-    uint16_t max_exit_latency;
-    uint8_t rh_port_num; // root hub port number
-    uint8_t num_ports;   // number of ports
-
-    uint8_t tt_hub_slot_id;
-    uint8_t tt_port_num;
-    unsigned ttt : 2; // TT Think Time
-    unsigned Rsvd2 : 4;
-    unsigned int_target : 10; // Interrupter target
-
-    uint8_t device_address;
-    unsigned Rsvd1 : 19;
-    unsigned slot_state : 5;
-} __attribute__((packed));
-
-#define XHCI_SLOT_STATE_DISABLED_OR_ENABLED 0
-#define XHCI_SLOT_STATE_DEFAULT 1
-#define XHCI_SLOT_STATE_ADDRESSED 2
-#define XHCI_SLOT_STATE_CONFIGURED 3
-
-// ======= Device Slot Context END ====
-
-// ======= Device Endpoint Context BEGIN ====
-
-#define XHCI_EP_STATE_DISABLED 0
-#define XHCI_EP_STATE_RUNNING 1
-#define XHCI_EP_STATE_HALTED 2
-#define XHCI_EP_STATE_STOPPED 3
-#define XHCI_EP_STATE_ERROR 4
-
-// End Point Doorbell numbers
-#define XHCI_SLOT_CNTX 0
-#define XHCI_EP_CONTROL 1
-#define XHCI_EP1_OUT 2
-#define XHCI_EP1_IN 3
-#define XHCI_EP2_OUT 4
-#define XHCI_EP2_IN 5
-#define XHCI_EP3_OUT 6
-#define XHCI_EP3_IN 7
-#define XHCI_EP4_OUT 8
-#define XHCI_EP4_IN 9
-#define XHCI_EP5_OUT 10
-#define XHCI_EP5_IN 11
-#define XHCI_EP6_OUT 12
-#define XHCI_EP6_IN 13
-#define XHCI_EP7_OUT 14
-#define XHCI_EP7_IN 15
-#define XHCI_EP8_OUT 16
-#define XHCI_EP8_IN 17
-#define XHCI_EP9_OUT 18
-#define XHCI_EP9_IN 19
-#define XHCI_EP10_OUT 20
-#define XHCI_EP10_IN 21
-#define XHCI_EP11_OUT 22
-#define XHCI_EP11_IN 23
-#define XHCI_EP12_OUT 24
-#define XHCI_EP12_IN 25
-#define XHCI_EP13_OUT 26
-#define XHCI_EP13_IN 27
-#define XHCI_EP14_OUT 28
-#define XHCI_EP14_IN 29
-#define XHCI_EP15_OUT 30
-#define XHCI_EP15_IN 31
-
-// xhci 传输方向(用于setup stage TRB)
-#define XHCI_DIR_NO_DATA 0
-#define XHCI_DIR_OUT 2
-#define XHCI_DIR_IN 3
-
-// xhci传输方向(单个bit的表示)
-#define XHCI_DIR_OUT_BIT 0
-#define XHCI_DIR_IN_BIT 1
-
-/**
- * @brief xhci 端点上下文结构体
- *
- */
-struct xhci_ep_context_t
-{
-    unsigned ep_state : 3;
-    unsigned Rsvd0 : 5; // Reserved and zero'd
-    unsigned mult : 2;  // the maximum supported number of bursts within an interval
-    unsigned max_primary_streams : 5;
-    unsigned linear_stream_array : 1;
-    uint8_t interval;
-    uint8_t max_esti_payload_hi; // Max Endpoint Service Time Interval Payload (High 8bit)
-
-    unsigned Rsvd1 : 1;
-    unsigned err_cnt : 2; // error count. 当错误发生时,该位会自减。当减为0时,控制器会把这个端点挂起
-    unsigned ep_type : 3; // endpoint type
-    unsigned Rsvd2 : 1;
-    unsigned hid : 1; // Host Initiate Disable
-    uint8_t max_burst_size;
-    uint16_t max_packet_size;
-
-    uint64_t tr_dequeue_ptr; // 第0bit为dequeue cycle state, 第1~3bit应保留。
-
-    uint16_t average_trb_len;     // 平均TRB长度。该部分不应为0
-    uint16_t max_esti_payload_lo; // Max Endpoint Service Time Interval Payload (Low 16bit)
-} __attribute__((packed));
-
-// ======= Device Endpoint Context END ====
-
-// 端口信息标志位
-#define XHCI_PROTOCOL_USB2 0
-#define XHCI_PROTOCOL_USB3 1
-#define XHCI_PROTOCOL_INFO (1 << 0)     // 1->usb3, 0->usb2
-#define XHCI_PROTOCOL_HSO (1 << 1)      // 1-> usb2 high speed only
-#define XHCI_PROTOCOL_HAS_PAIR (1 << 2) // 当前位被置位,意味着当前端口具有一个与之配对的端口
-#define XHCI_PROTOCOL_ACTIVE (1 << 3)   // 当前端口是这个配对中,被激活的端口
-
-struct xhci_ep_info_t
-{
-    uint64_t ep_ring_vbase;         // transfer ring的基地址
-    uint64_t current_ep_ring_vaddr; // transfer ring下一个要写入的地址
-    uint8_t current_ep_ring_cycle;  // 当前ep的cycle bit
-};
-
-/**
- * @brief xhci端口信息
- *
- */
-struct xhci_port_info_t
-{
-    uint8_t flags;           // port flags
-    uint8_t paired_port_num; // 与当前端口所配对的另一个端口(相同物理接口的不同速度的port)
-    uint8_t offset;          // offset of this port within this protocal
-    uint8_t reserved;
-    uint8_t slot_id;                   // address device获得的slot id
-    struct usb_device_desc *dev_desc;  // 指向设备描述符结构体的指针
-    struct xhci_ep_info_t ep_info[32]; // 各个端点的信息
-} __attribute__((packed));
-
-struct xhci_host_controller_t
-{
-    struct pci_device_structure_general_device_t *pci_dev_hdr; // 指向pci header结构体的指针
-    int controller_id;                                         // 操作系统给controller的编号
-    uint64_t vbase;                                            // 虚拟地址base(bar0映射到的虚拟地址)
-    uint64_t vbase_op;                                         // Operational registers 起始虚拟地址
-    uint32_t rts_offset;                                       // Runtime Register Space offset
-    uint32_t db_offset;                                        // Doorbell offset
-
-    uint32_t ext_caps_off; // 扩展能力寄存器偏移量
-    uint16_t port_num;     // 总的端口数量
-    uint8_t context_size;  // 设备上下文大小
-    uint8_t port_num_u2;   // usb 2.0端口数量
-
-    uint8_t port_num_u3;              // usb 3端口数量
-    uint8_t current_event_ring_cycle; // 当前event ring cycle
-    uint8_t cmd_trb_cycle;            // 当前command ring cycle
-    uint32_t page_size;               // page size
-
-    uint64_t dcbaap_vaddr;                                  // Device Context Base Address Array Pointer的虚拟地址
-    uint64_t cmd_ring_vaddr;                                // command ring的虚拟地址
-    uint64_t cmd_trb_vaddr;                                 // 下一个要写入的trb的虚拟地址
-    uint64_t event_ring_vaddr;                              // event ring的虚拟地址
-    uint64_t event_ring_table_vaddr;                        // event ring table的虚拟地址
-    uint64_t current_event_ring_vaddr;                      // 下一个要读取的event TRB的虚拟地址
-    uint64_t scratchpad_buf_array_vaddr;                    // 草稿行缓冲区数组的虚拟地址
-    struct xhci_port_info_t ports[XHCI_MAX_ROOT_HUB_PORTS]; // 指向端口信息数组的指针(由于端口offset是从1开始的,因此该数组第0项为空)
-};
-
-// Common TRB types
-enum
-{
-    TRB_TYPE_NORMAL = 1,
-    TRB_TYPE_SETUP_STAGE,
-    TRB_TYPE_DATA_STAGE,
-    TRB_TYPE_STATUS_STAGE,
-    TRB_TYPE_ISOCH,
-    TRB_TYPE_LINK,
-    TRB_TYPE_EVENT_DATA,
-    TRB_TYPE_NO_OP,
-    TRB_TYPE_ENABLE_SLOT,
-    TRB_TYPE_DISABLE_SLOT = 10,
-
-    TRB_TYPE_ADDRESS_DEVICE = 11,
-    TRB_TYPE_CONFIG_EP,
-    TRB_TYPE_EVALUATE_CONTEXT,
-    TRB_TYPE_RESET_EP,
-    TRB_TYPE_STOP_EP = 15,
-    TRB_TYPE_SET_TR_DEQUEUE,
-    TRB_TYPE_RESET_DEVICE,
-    TRB_TYPE_FORCE_EVENT,
-    TRB_TYPE_DEG_BANDWIDTH,
-    TRB_TYPE_SET_LAT_TOLERANCE = 20,
-
-    TRB_TYPE_GET_PORT_BAND = 21,
-    TRB_TYPE_FORCE_HEADER,
-    TRB_TYPE_NO_OP_CMD, // 24 - 31 = reserved
-
-    TRB_TYPE_TRANS_EVENT = 32,
-    TRB_TYPE_COMMAND_COMPLETION,
-    TRB_TYPE_PORT_STATUS_CHANGE,
-    TRB_TYPE_BANDWIDTH_REQUEST,
-    TRB_TYPE_DOORBELL_EVENT,
-    TRB_TYPE_HOST_CONTROLLER_EVENT = 37,
-    TRB_TYPE_DEVICE_NOTIFICATION,
-    TRB_TYPE_MFINDEX_WRAP,
-    // 40 - 47 = reserved
-    // 48 - 63 = Vendor Defined
-};
-
-// event ring trb的完成码
-enum
-{
-    TRB_COMP_TRB_SUCCESS = 1,
-    TRB_COMP_DATA_BUFFER_ERROR,
-    TRB_COMP_BABBLE_DETECTION,
-    TRB_COMP_TRANSACTION_ERROR,
-    TRB_COMP_TRB_ERROR,
-    TRB_COMP_STALL_ERROR,
-    TRB_COMP_RESOURCE_ERROR = 7,
-    TRB_COMP_BANDWIDTH_ERROR,
-    TRB_COMP_NO_SLOTS_ERROR,
-    TRB_COMP_INVALID_STREAM_TYPE,
-    TRB_COMP_SLOT_NOT_ENABLED,
-    TRB_COMP_EP_NOT_ENABLED,
-    TRB_COMP_SHORT_PACKET = 13,
-    TRB_COMP_RING_UNDERRUN,
-    TRB_COMP_RUNG_OVERRUN,
-    TRB_COMP_VF_EVENT_RING_FULL,
-    TRB_COMP_PARAMETER_ERROR,
-    TRB_COMP_BANDWITDH_OVERRUN,
-    TRB_COMP_CONTEXT_STATE_ERROR = 19,
-    TRB_COMP_NO_PING_RESPONSE,
-    TRB_COMP_EVENT_RING_FULL,
-    TRB_COMP_INCOMPATIBLE_DEVICE,
-    TRB_COMP_MISSED_SERVICE,
-    TRB_COMP_COMMAND_RING_STOPPED = 24,
-    TRB_COMP_COMMAND_ABORTED,
-    TRB_COMP_STOPPED,
-    TRB_COMP_STOPPER_LENGTH_ERROR,
-    TRB_COMP_RESERVED,
-    TRB_COMP_ISOCH_BUFFER_OVERRUN,
-    TRB_COMP_EVERN_LOST = 32,
-    TRB_COMP_UNDEFINED,
-    TRB_COMP_INVALID_STREAM_ID,
-    TRB_COMP_SECONDARY_BANDWIDTH,
-    TRB_COMP_SPLIT_TRANSACTION
-    /* 37 - 191 reserved */
-    /* 192 - 223 vender defined errors */
-    /* 224 - 225 vendor defined info */
-};
-
-/**
- * @brief xhci endpoint类型
- * 
- */
-enum
-{
-    XHCI_EP_TYPE_INVALID = 0,
-    XHCI_EP_TYPE_ISO_OUT,
-    XHCI_EP_TYPE_BULK_OUT,
-    XHCI_EP_TYPE_INTR_OUT,
-    XHCI_EP_TYPE_CONTROL,
-    XHCI_EP_TYPE_ISO_IN,
-    XHCI_EP_TYPE_BULK_IN,
-    XHCI_EP_TYPE_INTR_IN,
-};
-/**
- * @brief 初始化xhci控制器
- *
- * @param header 指定控制器的pci device头部
- */
-void xhci_init(struct pci_device_structure_general_device_t *header);

+ 2 - 2
kernel/src/driver/virtio/transport_pci.rs

@@ -109,7 +109,7 @@ impl PciTransport {
         let mut notify_off_multiplier = 0;
         let mut isr_cfg = None;
         let mut device_cfg = None;
-        device.bar_init().unwrap()?;
+        device.bar_ioremap().unwrap()?;
         device.enable_master();
         //device_capability为迭代器,遍历其相当于遍历所有的cap空间
         for capability in device.capabilities().unwrap() {
@@ -487,7 +487,7 @@ fn get_bar_region<T>(
     Ok(vaddr.cast())
 }
 
-/// @brief 获取虚拟地址并将其转化为对应类型的
+/// @brief 获取虚拟地址并将其转化为对应类型的切片的指针
 /// @param device_bar 存储bar信息的结构体 struct_info 存储cfg空间的位置信息切片的指针
 /// @return Result<NonNull<[T]>, VirtioPciError> 成功则返回对应类型的指针切片,失败则返回Error
 fn get_bar_region_slice<T>(

+ 2 - 0
kernel/src/include/bindings/wrapper.h

@@ -48,3 +48,5 @@
 #include <smp/smp.h>
 #include <time/clocksource.h>
 #include <time/sleep.h>
+#include <driver/pci/pci_irq.h>
+#include <common/errno.h>

+ 1 - 0
kernel/src/libs/volatile.rs

@@ -169,5 +169,6 @@ macro_rules! volwrite {
         VolatileWritable::vwrite(core::ptr::addr_of_mut!((*$nonnull.as_ptr()).$field), $value)
     };
 }
+
 pub(crate) use volread;
 pub(crate) use volwrite;

+ 0 - 1
kernel/src/main.c

@@ -30,7 +30,6 @@
 #include "driver/pci/pci.h"
 #include <driver/timers/HPET/HPET.h>
 #include <driver/uart/uart.h>
-#include <driver/usb/usb.h>
 #include <driver/video/video.h>
 #include <time/timer.h>
 

+ 0 - 1
kernel/src/process/process.c

@@ -17,7 +17,6 @@
 #include <debug/bug.h>
 #include <debug/traceback/traceback.h>
 #include <driver/disk/ahci/ahci.h>
-#include <driver/usb/usb.h>
 #include <driver/video/video.h>
 #include <driver/virtio/virtio.h>
 #include <exception/gate.h>