ソースを参照

add start_msi to pci module

fslongjin 2 年 前
コミット
20a191d149
4 ファイル変更73 行追加7 行削除
  1. 59 6
      kernel/driver/pci/pci.c
  2. 8 0
      kernel/driver/pci/pci.h
  3. 2 1
      kernel/exception/irq.c
  4. 4 0
      kernel/exception/irq.h

+ 59 - 6
kernel/driver/pci/pci.c

@@ -576,6 +576,64 @@ int pci_enable_msi(void *header, uint8_t vector, uint32_t processor, uint8_t edg
     return 0;
 }
 
+/**
+ * @brief 在已配置好msi寄存器的设备上,使能msi
+ *
+ * @param header 设备头部
+ * @return int 返回码
+ */
+int pci_start_msi(void *header)
+{
+    struct pci_device_structure_header_t *ptr = (struct pci_device_structure_header_t *)header;
+    uint32_t cap_ptr;
+    uint32_t tmp;
+
+    switch (ptr->HeaderType)
+    {
+    case 0x00: // general device
+        if (!(ptr->Status & 0x10))
+            return E_NOT_SUPPORT_MSI;
+        cap_ptr = ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer;
+
+        tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
+
+        if (tmp & 0xff != 0x5)
+            return E_NOT_SUPPORT_MSI;
+
+        // 使能msi
+        tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
+        tmp |= (1 << 16);
+        pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp);
+
+        break;
+
+    case 0x01: // pci to pci bridge
+        if (!(ptr->Status & 0x10))
+            return E_NOT_SUPPORT_MSI;
+        cap_ptr = ((struct pci_device_structure_pci_to_pci_bridge_t *)ptr)->Capability_Pointer;
+
+        tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
+
+        if (tmp & 0xff != 0x5)
+            return E_NOT_SUPPORT_MSI;
+
+        //使能msi
+        tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
+        tmp |= (1 << 16);
+        pci_write_config(ptr->bus, ptr->device, ptr->func, cap_ptr, tmp);
+
+        break;
+    case 0x02: // pci to card bus bridge
+        return E_NOT_SUPPORT_MSI;
+        break;
+
+    default: // 不应该到达这里
+        return E_WRONG_HEADER_TYPE;
+        break;
+    }
+
+    return 0;
+}
 /**
  * @brief 禁用指定设备的msi
  *
@@ -587,8 +645,7 @@ int pci_disable_msi(void *header)
     struct pci_device_structure_header_t *ptr = (struct pci_device_structure_header_t *)header;
     uint32_t cap_ptr;
     uint32_t tmp;
-    uint16_t message_control;
-    uint64_t message_addr;
+
     switch (ptr->HeaderType)
     {
     case 0x00: // general device
@@ -598,8 +655,6 @@ int pci_disable_msi(void *header)
 
         tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
 
-        message_control = (tmp >> 16) & 0xffff;
-
         if (tmp & 0xff != 0x5)
             return E_NOT_SUPPORT_MSI;
 
@@ -617,8 +672,6 @@ int pci_disable_msi(void *header)
 
         tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, cap_ptr); // 读取cap+0x0处的值
 
-        message_control = (tmp >> 16) & 0xffff;
-
         if (tmp & 0xff != 0x5)
             return E_NOT_SUPPORT_MSI;
 

+ 8 - 0
kernel/driver/pci/pci.h

@@ -226,6 +226,14 @@ int pci_enable_msi(void * header, uint8_t vector, uint32_t processor, uint8_t ed
  */
 int pci_disable_msi(void *header);
 
+/**
+ * @brief 在已配置好msi寄存器的设备上,使能msi
+ *
+ * @param header 设备头部
+ * @return int 返回码
+ */
+int pci_start_msi(void *header);
+
 /**
  * @brief 获取 device structure
  * 

+ 2 - 1
kernel/exception/irq.c

@@ -230,7 +230,8 @@ int irq_unregister(ul irq_num)
     p->controller->uninstall(irq_num);
 
     p->controller = NULL;
-    kfree(p->irq_name);
+    if (p->irq_name)
+        kfree(p->irq_name);
     p->irq_name = NULL;
     p->parameter = NULL;
     p->flags = 0;

+ 4 - 0
kernel/exception/irq.h

@@ -94,6 +94,10 @@ extern void (*local_apic_interrupt_table[LOCAL_APIC_IRQ_NUM])(void);
 	154	LINT0
 	155	LINT1
 	156	Error
+	157 xhci_controller_0
+	158 xhci_controller_1
+	159 xhci_controller_2
+	160 xhci_controller_3
 
 200 ~   255	MP IPI