| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2022-08-25 GuEe-GUI first version
- */
- #ifndef __PCI_MSI_H__
- #define __PCI_MSI_H__
- #include <drivers/pci.h>
- /*
- * MSI Format:
- * T0: 32-bit Address
- * T1: 64-bit Address
- * T2: 32-bit Address with Per-Vector Masking
- * T3: 64-bit Address with Per-Vector Masking
- *
- * 31 16 15 8 7 0
- * +---------------------------+-----------------+---------------+
- * | Message Control | Next Capability | Capability ID | DW0
- * | | Pointer | (05h) |
- * +---------------------------+-----------------+---------------+
- * | Message Address [31:0] | DW1
- * +-------------------------------------------------------------+
- * | Message Address [63:32] | DW2 (T1: only 64-bit)
- * +---------------------------+---------------------------------+
- * | Reserved | Message Data | DW3
- * +---------------------------+---------------------------------+
- * | Mask Bits | DW4 (T2/T3: only with Per-Vector Masking)
- * +-------------------------------------------------------------+
- * | Pending Bits | DW5 (T2/T3: only with Per-Vector Masking)
- * +-------------------------------------------------------------+
- *
- * MSI Message Control:
- *
- * 15 9 8 7 6 4 3 1 0
- * +----------------------+---+---+---------------+----------+---+
- * | Reserved | | | | | |
- * +----------------------+---+---+---------------+----------+---+
- * ^ ^ ^ ^ ^
- * | | | | |
- * | | | | +---- MSI Enable (RW)
- * | | | +----------- Multiple Message Capable (RO, log2n, [n <= 5])
- * | | +------------------------- Multiple Message Enable (RW, log2n, [n <= 5])
- * | +----------------------------------- 64-bit Address Capable
- * +--------------------------------------- Per-Vector Masking Capable
- */
- struct rt_pci_msi_conf
- {
- rt_uint32_t mask;
- rt_uint8_t mask_pos;
- int default_irq;
- struct
- {
- rt_uint8_t is_masking:1;
- rt_uint8_t is_64bit:1;
- rt_uint8_t multi_msg_max:3; /* log2 num of messages allocated */
- rt_uint8_t multi_msg_use:3; /* log2 num of messages supported */
- } cap;
- };
- /*
- * MSI-X Format:
- *
- * 31 16 15 8 7 0
- * +---------------------------+-----------------+---------------+
- * | Message Control | Next Capability | Capability ID | DW0
- * | | Pointer | (11h) |
- * +---------------------------+-----------------+---+-----------+
- * | MSI-X Table Offset | Table BIR | DW1 (BIR: BAR Index Register)
- * +-------------------------------------------------+-----------+ |
- * | Pending Bit Array (PBA) Offset | PBA BIR | DW2 --------+ |
- * +-------------------------------------------------+-----------+ | |
- * | |
- * MSI-X Message Control: | |
- * | |
- * 15 14 13 11 10 0 | |
- * +---+---+----------+------------------------------------------+ | |
- * | | | Reserved | Table Size in N-1 (RO) | | |
- * +---+---+----------+------------------------------------------+ | |
- * ^ ^ | |
- * | | | |
- * | +---- Function Mask (RW) | |
- * +-------- MSI-X Enable (RW) | |
- * | |
- * MSI-X Table (BAR[Table BIR] + MSI-X Table Offset): | |
- * | |
- * DW3 DW2 DW1 DW0 | |
- * +----------------+--------------+---------------+---------------+ <---------|-+
- * | Vector Control | Message Data | Upper Address | Lower Address | Entry 0 |
- * +----------------+--------------+---------------+---------------+ |
- * | Vector Control | Message Data | Upper Address | Lower Address | Entry 1 |
- * +----------------+--------------+---------------+---------------+ |
- * | ...... | ...... | ...... | ...... | |
- * +----------------+--------------+---------------+---------------+ |
- * | Vector Control | Message Data | Upper Address | Lower Address | Entry N-1 |
- * +----------------+--------------+---------------+---------------+ |
- * ^ |
- * | |
- * +---- Bit 0 is vector Mask Bit (R/W) |
- * |
- * MSI-X Pending Bit Array (BAR[PBA BIR] + Pending Bit Array Offset): |
- * |
- * DW1 DW0 |
- * +-------------------------------+ <-----------------------------------------+
- * | Pending Bits 0 - 63 | QW 0
- * +-------------------------------+
- * | Pending Bits 64 - 127 | QW 1
- * +-------------------------------+
- * | ...... |
- * +-------------------------------+
- * | Pending Bits | QW (N-1)/64
- * +-------------------------------+
- */
- struct rt_pci_msix_conf
- {
- int index;
- rt_uint32_t msg_ctrl;
- void *table_base;
- };
- struct rt_pci_msi_msg
- {
- rt_uint32_t address_lo;
- rt_uint32_t address_hi;
- rt_uint32_t data;
- };
- struct rt_pci_msi_desc
- {
- rt_list_t list;
- int irq;
- rt_size_t vector_used;
- rt_size_t vector_count;
- union
- {
- /* For MSI-X */
- rt_bitmap_t *affinity;
- /* For MSI */
- rt_bitmap_t **affinities;
- };
- struct rt_pci_device *pdev;
- struct rt_pci_msi_msg msg;
- void *write_msi_msg_data;
- void (*write_msi_msg)(struct rt_pci_msi_desc *, void *);
- rt_bool_t is_msix;
- union
- {
- struct rt_pci_msi_conf msi;
- struct rt_pci_msix_conf msix;
- };
- void *priv;
- };
- #define rt_pci_msi_first_desc(pdev) \
- (rt_list_isempty(&(pdev)->msi_desc_nodes) ? RT_NULL : \
- rt_list_first_entry(&(pdev)->msi_desc_nodes, struct rt_pci_msi_desc, list))
- #define rt_pci_msi_for_each_desc(pdev, desc) \
- rt_list_for_each_entry(desc, &(pdev)->msi_desc_nodes, list)
- #define rt_pci_msix_table_size(flags) ((flags & PCIM_MSIXCTRL_TABLE_SIZE) + 1)
- rt_err_t rt_pci_msi_setup_irqs(struct rt_pci_device *pdev, int nvec, int type);
- rt_err_t rt_pci_msi_cleanup_irqs(struct rt_pci_device *pdev);
- void rt_pci_msi_shutdown(struct rt_pci_device *pdev);
- void rt_pci_msix_shutdown(struct rt_pci_device *pdev);
- void rt_pci_msi_free_irqs(struct rt_pci_device *pdev);
- void rt_pci_msi_write_msg(struct rt_pci_msi_desc *desc, struct rt_pci_msi_msg *msg);
- void rt_pci_msi_mask_irq(struct rt_pic_irq *pirq);
- void rt_pci_msi_unmask_irq(struct rt_pic_irq *pirq);
- #endif /* __PCI_MSI_H__ */
|