1 /* 2 * Copyright (c) 2006-2022, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2022-08-25 GuEe-GUI first version 9 */ 10 11 #ifndef __PCI_MSI_H__ 12 #define __PCI_MSI_H__ 13 14 #include <drivers/pci.h> 15 16 /* 17 * MSI Format: 18 * T0: 32-bit Address 19 * T1: 64-bit Address 20 * T2: 32-bit Address with Per-Vector Masking 21 * T3: 64-bit Address with Per-Vector Masking 22 * 23 * 31 16 15 8 7 0 24 * +---------------------------+-----------------+---------------+ 25 * | Message Control | Next Capability | Capability ID | DW0 26 * | | Pointer | (05h) | 27 * +---------------------------+-----------------+---------------+ 28 * | Message Address [31:0] | DW1 29 * +-------------------------------------------------------------+ 30 * | Message Address [63:32] | DW2 (T1: only 64-bit) 31 * +---------------------------+---------------------------------+ 32 * | Reserved | Message Data | DW3 33 * +---------------------------+---------------------------------+ 34 * | Mask Bits | DW4 (T2/T3: only with Per-Vector Masking) 35 * +-------------------------------------------------------------+ 36 * | Pending Bits | DW5 (T2/T3: only with Per-Vector Masking) 37 * +-------------------------------------------------------------+ 38 * 39 * MSI Message Control: 40 * 41 * 15 9 8 7 6 4 3 1 0 42 * +----------------------+---+---+---------------+----------+---+ 43 * | Reserved | | | | | | 44 * +----------------------+---+---+---------------+----------+---+ 45 * ^ ^ ^ ^ ^ 46 * | | | | | 47 * | | | | +---- MSI Enable (RW) 48 * | | | +----------- Multiple Message Capable (RO, log2n, [n <= 5]) 49 * | | +------------------------- Multiple Message Enable (RW, log2n, [n <= 5]) 50 * | +----------------------------------- 64-bit Address Capable 51 * +--------------------------------------- Per-Vector Masking Capable 52 */ 53 54 struct rt_pci_msi_conf 55 { 56 rt_uint32_t mask; 57 rt_uint8_t mask_pos; 58 int default_irq; 59 60 struct 61 { 62 rt_uint8_t is_masking:1; 63 rt_uint8_t is_64bit:1; 64 rt_uint8_t multi_msg_max:3; /* log2 num of messages allocated */ 65 rt_uint8_t multi_msg_use:3; /* log2 num of messages supported */ 66 } cap; 67 }; 68 69 /* 70 * MSI-X Format: 71 * 72 * 31 16 15 8 7 0 73 * +---------------------------+-----------------+---------------+ 74 * | Message Control | Next Capability | Capability ID | DW0 75 * | | Pointer | (11h) | 76 * +---------------------------+-----------------+---+-----------+ 77 * | MSI-X Table Offset | Table BIR | DW1 (BIR: BAR Index Register) 78 * +-------------------------------------------------+-----------+ | 79 * | Pending Bit Array (PBA) Offset | PBA BIR | DW2 --------+ | 80 * +-------------------------------------------------+-----------+ | | 81 * | | 82 * MSI-X Message Control: | | 83 * | | 84 * 15 14 13 11 10 0 | | 85 * +---+---+----------+------------------------------------------+ | | 86 * | | | Reserved | Table Size in N-1 (RO) | | | 87 * +---+---+----------+------------------------------------------+ | | 88 * ^ ^ | | 89 * | | | | 90 * | +---- Function Mask (RW) | | 91 * +-------- MSI-X Enable (RW) | | 92 * | | 93 * MSI-X Table (BAR[Table BIR] + MSI-X Table Offset): | | 94 * | | 95 * DW3 DW2 DW1 DW0 | | 96 * +----------------+--------------+---------------+---------------+ <---------|-+ 97 * | Vector Control | Message Data | Upper Address | Lower Address | Entry 0 | 98 * +----------------+--------------+---------------+---------------+ | 99 * | Vector Control | Message Data | Upper Address | Lower Address | Entry 1 | 100 * +----------------+--------------+---------------+---------------+ | 101 * | ...... | ...... | ...... | ...... | | 102 * +----------------+--------------+---------------+---------------+ | 103 * | Vector Control | Message Data | Upper Address | Lower Address | Entry N-1 | 104 * +----------------+--------------+---------------+---------------+ | 105 * ^ | 106 * | | 107 * +---- Bit 0 is vector Mask Bit (R/W) | 108 * | 109 * MSI-X Pending Bit Array (BAR[PBA BIR] + Pending Bit Array Offset): | 110 * | 111 * DW1 DW0 | 112 * +-------------------------------+ <-----------------------------------------+ 113 * | Pending Bits 0 - 63 | QW 0 114 * +-------------------------------+ 115 * | Pending Bits 64 - 127 | QW 1 116 * +-------------------------------+ 117 * | ...... | 118 * +-------------------------------+ 119 * | Pending Bits | QW (N-1)/64 120 * +-------------------------------+ 121 */ 122 123 struct rt_pci_msix_conf 124 { 125 int index; 126 127 rt_uint32_t msg_ctrl; 128 void *table_base; 129 }; 130 131 struct rt_pci_msi_msg 132 { 133 rt_uint32_t address_lo; 134 rt_uint32_t address_hi; 135 rt_uint32_t data; 136 }; 137 138 struct rt_pci_msi_desc 139 { 140 rt_list_t list; 141 142 int irq; 143 rt_size_t vector_used; 144 rt_size_t vector_count; 145 146 union 147 { 148 /* For MSI-X */ 149 rt_bitmap_t *affinity; 150 /* For MSI */ 151 rt_bitmap_t **affinities; 152 }; 153 154 struct rt_pci_device *pdev; 155 struct rt_pci_msi_msg msg; 156 157 void *write_msi_msg_data; 158 void (*write_msi_msg)(struct rt_pci_msi_desc *, void *); 159 160 rt_bool_t is_msix; 161 union 162 { 163 struct rt_pci_msi_conf msi; 164 struct rt_pci_msix_conf msix; 165 }; 166 167 void *priv; 168 }; 169 170 #define rt_pci_msi_first_desc(pdev) \ 171 (rt_list_isempty(&(pdev)->msi_desc_nodes) ? RT_NULL : \ 172 rt_list_first_entry(&(pdev)->msi_desc_nodes, struct rt_pci_msi_desc, list)) 173 174 #define rt_pci_msi_for_each_desc(pdev, desc) \ 175 rt_list_for_each_entry(desc, &(pdev)->msi_desc_nodes, list) 176 177 #define rt_pci_msix_table_size(flags) ((flags & PCIM_MSIXCTRL_TABLE_SIZE) + 1) 178 179 rt_err_t rt_pci_msi_setup_irqs(struct rt_pci_device *pdev, int nvec, int type); 180 181 void rt_pci_msi_shutdown(struct rt_pci_device *pdev); 182 void rt_pci_msix_shutdown(struct rt_pci_device *pdev); 183 void rt_pci_msi_free_irqs(struct rt_pci_device *pdev); 184 void rt_pci_msi_write_msg(struct rt_pci_msi_desc *desc, struct rt_pci_msi_msg *msg); 185 186 void rt_pci_msi_mask_irq(struct rt_pic_irq *pirq); 187 void rt_pci_msi_unmask_irq(struct rt_pic_irq *pirq); 188 189 #endif /* __PCI_MSI_H__ */ 190