From 20a191d149a3f27da9dd28c46fa06ece5be053b6 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Thu, 21 Jul 2022 12:53:52 +0800 Subject: [PATCH] add start_msi to pci module --- kernel/driver/pci/pci.c | 65 +++++++++++++++++++++++++++++++++++++---- kernel/driver/pci/pci.h | 8 +++++ kernel/exception/irq.c | 3 +- kernel/exception/irq.h | 4 +++ 4 files changed, 73 insertions(+), 7 deletions(-) diff --git a/kernel/driver/pci/pci.c b/kernel/driver/pci/pci.c index 0244c4c1..5ed2cda5 100644 --- a/kernel/driver/pci/pci.c +++ b/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; diff --git a/kernel/driver/pci/pci.h b/kernel/driver/pci/pci.h index 36cbb454..eb5832bb 100644 --- a/kernel/driver/pci/pci.h +++ b/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 * diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index af922d7e..567b8c8c 100644 --- a/kernel/exception/irq.c +++ b/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; diff --git a/kernel/exception/irq.h b/kernel/exception/irq.h index 9777d1bb..9e172f4b 100644 --- a/kernel/exception/irq.h +++ b/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