pci_msi.h 8.0 KB

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