1 #pragma once 2 #include <common/glib.h> 3 4 /** 5 * @brief msi消息内容结构体 6 * 7 */ 8 struct msi_msg_t 9 { 10 uint32_t address_lo; 11 uint32_t address_hi; 12 uint32_t data; 13 uint32_t vector_control; 14 }; 15 struct pci_msi_desc_t 16 { 17 union 18 { 19 uint32_t msi_mask; // [PCI MSI] MSI cached mask bits 20 uint32_t msix_ctrl; // [PCI MSI-X] MSI-X cached per vector control bits 21 }; 22 23 struct 24 { 25 uint8_t is_msix : 1; // [PCI MSI/X] True if MSI-X 26 uint8_t can_mask : 1; // [PCI MSI/X] Masking supported? 27 uint8_t is_64 : 1; // [PCI MSI/X] Address size: 0=32bit 1=64bit 28 } msi_attribute; 29 }; 30 31 /** 32 * @brief msi capability list的结构 33 * 34 */ 35 struct pci_msi_cap_t 36 { 37 uint8_t cap_id; 38 uint8_t next_off; 39 uint16_t msg_ctrl; 40 41 uint32_t msg_addr_lo; 42 uint32_t msg_addr_hi; 43 44 uint16_t msg_data; 45 uint16_t Rsvd; 46 47 uint32_t mask; 48 uint32_t pending; 49 }; 50 51 /** 52 * @brief MSI-X的capability list结构体 53 * 54 */ 55 struct pci_msix_cap_t 56 { 57 uint8_t cap_id; 58 uint8_t next_off; 59 uint16_t msg_ctrl; 60 61 uint32_t dword1; // 该DWORD的组成为:[Table Offset][BIR2:0]. 62 // 由于Table Offset是8字节对齐的,因此mask掉该dword的BIR部分,就是table offset的值 63 uint32_t dword2; // 该DWORD的组成为:[Pending Bit Offset][Pending Bit BIR2:0]. 64 // 由于Pending Bit Offset是8字节对齐的,因此mask掉该dword的BIR部分,就是Pending Bit Offset的值 65 }; 66 67 /** 68 * @brief msi描述符 69 * 70 */ 71 struct msi_desc_t 72 { 73 uint16_t irq_num; // 中断向量号 74 uint16_t processor; // 定向投递的处理器 75 uint16_t edge_trigger; // 是否边缘触发 76 uint16_t assert; // 是否高电平触发 77 struct pci_device_structure_header_t *pci_dev; // 对应的pci设备的结构体 78 struct msi_msg_t msg; // msi消息 79 uint16_t msi_index; // msi描述符的index 80 struct pci_msi_desc_t pci; // 与pci相关的msi描述符数据 81 }; 82 83 /** 84 * @brief 启用 Message Signaled Interrupts 85 * 86 * @param header 设备header 87 * @param vector 中断向量号 88 * @param processor 要投递到的处理器 89 * @param edge_trigger 是否边缘触发 90 * @param assert 是否高电平触发 91 * 92 * @return 返回码 93 */ 94 int pci_enable_msi(struct msi_desc_t *msi_desc); 95 96 /** 97 * @brief 禁用指定设备的msi 98 * 99 * @param header pci header 100 * @return int 101 */ 102 int pci_disable_msi(void *header); 103 104 /** 105 * @brief 在已配置好msi寄存器的设备上,使能msi 106 * 107 * @param header 设备头部 108 * @return int 返回码 109 */ 110 int pci_start_msi(void *header);