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);