2006-07-30 Martin Mares <mj@ucw.cz>
+ * lspci.c, lib/header.h: Added support for MSI per-vector masking.
+ Contributed by Petr Vandrovec.
+
* lspci.c, lib/header.h: Added support for the `bridge subsystem ID'
capability. Contributed by Petr Vandrovec.
/* Message Signalled Interrupts registers */
#define PCI_MSI_FLAGS 2 /* Various flags */
-#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
-#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
-#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
-#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
+#define PCI_MSI_FLAGS_MASK_BIT 0x100 /* interrupt masking & reporting supported */
+#define PCI_MSI_FLAGS_64BIT 0x080 /* 64-bit addresses allowed */
+#define PCI_MSI_FLAGS_QSIZE 0x070 /* Message queue size configured */
+#define PCI_MSI_FLAGS_QMASK 0x00e /* Maximum queue size available */
+#define PCI_MSI_FLAGS_ENABLE 0x001 /* MSI feature enabled */
#define PCI_MSI_RFU 3 /* Rest of capability flags */
#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
+#define PCI_MSI_MASK_BIT_32 12 /* per-vector masking for 32-bit devices */
+#define PCI_MSI_MASK_BIT_64 16 /* per-vector masking for 64-bit devices */
+#define PCI_MSI_PENDING_32 16 /* per-vector interrupt pending for 32-bit devices */
+#define PCI_MSI_PENDING_64 20 /* per-vector interrupt pending for 64-bit devices */
/* PCI-X */
#define PCI_PCIX_COMMAND 2 /* Command register offset */
u32 t;
u16 w;
- printf("Message Signalled Interrupts: 64bit%c Queue=%d/%d Enable%c\n",
+ printf("Message Signalled Interrupts: Mask%c 64bit%c Queue=%d/%d Enable%c\n",
+ FLAG(cap, PCI_MSI_FLAGS_MASK_BIT),
FLAG(cap, PCI_MSI_FLAGS_64BIT),
(cap & PCI_MSI_FLAGS_QSIZE) >> 4,
(cap & PCI_MSI_FLAGS_QMASK) >> 1,
w = get_conf_word(d, where + PCI_MSI_DATA_32);
t = get_conf_long(d, where + PCI_MSI_ADDRESS_LO);
printf("%08x Data: %04x\n", t, w);
+ if (cap & PCI_MSI_FLAGS_MASK_BIT)
+ {
+ u32 mask, pending;
+
+ if (is64)
+ {
+ if (!config_fetch(d, where + PCI_MSI_MASK_BIT_64, 8))
+ return;
+ mask = get_conf_long(d, where + PCI_MSI_MASK_BIT_64);
+ pending = get_conf_long(d, where + PCI_MSI_PENDING_64);
+ }
+ else
+ {
+ if (!config_fetch(d, where + PCI_MSI_MASK_BIT_32, 8))
+ return;
+ mask = get_conf_long(d, where + PCI_MSI_MASK_BIT_32);
+ pending = get_conf_long(d, where + PCI_MSI_PENDING_32);
+ }
+ printf("\t\tMasking: %08x Pending: %08x\n", mask, pending);
+ }
}
static void show_vendor(void)