Module Name: src Committed By: matt Date: Fri Jan 7 02:26:15 UTC 2011
Modified Files: src/sys/dev/pci [matt-nb5-pq3]: pci_subr.c pcireg.h pcivar.h Log Message: Add/define some MSI support To generate a diff of this commit: cvs rdiff -u -r1.75.10.1 -r1.75.10.1.8.1 src/sys/dev/pci/pci_subr.c cvs rdiff -u -r1.57.20.1 -r1.57.20.1.2.1 src/sys/dev/pci/pcireg.h cvs rdiff -u -r1.83 -r1.83.18.1 src/sys/dev/pci/pcivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/pci_subr.c diff -u src/sys/dev/pci/pci_subr.c:1.75.10.1 src/sys/dev/pci/pci_subr.c:1.75.10.1.8.1 --- src/sys/dev/pci/pci_subr.c:1.75.10.1 Tue Feb 24 03:50:48 2009 +++ src/sys/dev/pci/pci_subr.c Fri Jan 7 02:26:15 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pci_subr.c,v 1.75.10.1 2009/02/24 03:50:48 snj Exp $ */ +/* $NetBSD: pci_subr.c,v 1.75.10.1.8.1 2011/01/07 02:26:15 matt Exp $ */ /* * Copyright (c) 1997 Zubin D. Dittia. All rights reserved. @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.75.10.1 2009/02/24 03:50:48 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pci_subr.c,v 1.75.10.1.8.1 2011/01/07 02:26:15 matt Exp $"); #ifdef _KERNEL_OPT #include "opt_pci.h" @@ -433,8 +433,9 @@ #define i2o(i) ((i) * 4) #define o2i(o) ((o) / 4) -#define onoff(str, bit) \ - printf(" %s: %s\n", (str), (rval & (bit)) ? "on" : "off"); +#define onoff2(str, bit, onstr, offstr) \ + printf(" %s: %s\n", (str), (rval & (bit)) ? onstr : offstr); +#define onoff(str, bit) onoff2(str, bit, "on", "off") static void pci_conf_print_common( @@ -477,6 +478,7 @@ onoff("Interrupt disable", PCI_COMMAND_INTERRUPT_DISABLE); printf(" Status register: 0x%04x\n", (rval >> 16) & 0xffff); + onoff2("Interrupt status", PCI_STATUS_INT_STATUS, "active", "inactive"); onoff("Capability List support", PCI_STATUS_CAPLIST_SUPPORT); onoff("66 MHz capable", PCI_STATUS_66MHZ_SUPPORT); onoff("User Definable Features (UDF) support", PCI_STATUS_UDF_SUPPORT); @@ -819,6 +821,29 @@ printf(" Slot implemented\n"); printf(" Interrupt Message Number: %x\n", (unsigned int)((regs[o2i(capoff)] & 0x4e000000) >> 27)); + printf(" Link Capabilities Register: 0x%08x\n", + regs[o2i(capoff + 0x0c)]); + printf(" Maximum Link Speed: "); + if ((regs[o2i(capoff + 0x0c)] & 0x000f) != 1) { + printf("unknown %u value\n", + (regs[o2i(capoff + 0x0c)] & 0x000f)); + } else { + printf("2.5Gb/s\n"); + } + printf(" Maximum Link Width: x%u lanes\n", + (regs[o2i(capoff + 0x0c)] & 0x03f0) >> 4); + printf(" Port Number: %u\n", regs[o2i(capoff + 0x0c)] >> 24); + printf(" Link Status Register: 0x%04x\n", + regs[o2i(capoff + 0x10)] >> 16); + printf(" Negotiated Link Speed: "); + if (((regs[o2i(capoff + 0x10)] >> 16) & 0x000f) != 1) { + printf("unknown %u value\n", + (regs[o2i(capoff + 0x10)] >> 16) & 0x000f); + } else { + printf("2.5Gb/s\n"); + } + printf(" Negotiated Link Width: x%u lanes\n", + (regs[o2i(capoff + 0x10)] >> 20) & 0x003f); if ((regs[o2i(capoff + 0x18)] & 0x07ff) != 0) { printf(" Slot Control Register:\n"); if ((regs[o2i(capoff + 0x18)] & 0x0001) != 0) @@ -934,6 +959,41 @@ } static void +pci_conf_print_msi_cap(const pcireg_t *regs, int capoff) +{ + uint32_t ctl, mmc, mme; + + regs += o2i(capoff); + ctl = *regs++; + mmc = (ctl >> PCI_MSI_CTL_MMC_SHIFT) & PCI_MSI_CTL_MMC_MASK; + mme = (ctl >> PCI_MSI_CTL_MME_SHIFT) & PCI_MSI_CTL_MME_MASK; + + printf("\n PCI Message Signaled Interrupt\n"); + + printf(" Message Control register: 0x%04x\n", ctl >> 16); + printf(" MSI Enabled: %s\n", + ctl & PCI_MSI_CTL_MSI_ENABLE ? "yes" : "no"); + printf(" Multiple Message Capable: %s (%d vector%s)\n", + mmc > 0 ? "yes" : "no", 1 << mmc, mmc > 0 ? "s" : ""); + printf(" Multiple Message Enabled: %s (%d vector%s)\n", + mme > 0 ? "on" : "off", 1 << mme, mme > 0 ? "s" : ""); + printf(" 64 Bit Address Capable: %s\n", + ctl & PCI_MSI_CTL_64BIT_ADDR ? "yes" : "no"); + printf(" Per-Vector Masking Capable: %s\n", + ctl & PCI_MSI_CTL_PERVEC_MASK ? "yes" : "no"); + printf(" Message Address %sregister: 0x%08x\n", + ctl & PCI_MSI_CTL_64BIT_ADDR ? "(lower) " : "", *regs++); + if (ctl & PCI_MSI_CTL_64BIT_ADDR) { + printf(" Message Address %sregister: 0x%08x\n", + "(upper) ", *regs++); + } + printf(" Message Data register: 0x%08x\n", *regs++); + if (ctl & PCI_MSI_CTL_PERVEC_MASK) { + printf(" Vector Mask register: 0x%08x\n", *regs++); + printf(" Vector Pending register: 0x%08x\n", *regs++); + } +} +static void pci_conf_print_caplist( #ifdef _KERNEL pci_chipset_tag_t pc, pcitag_t tag, @@ -942,7 +1002,7 @@ { int off; pcireg_t rval; - int pcie_off = -1, pcipm_off = -1; + int pcie_off = -1, pcipm_off = -1, msi_off = -1; for (off = PCI_CAPLIST_PTR(regs[o2i(capoff)]); off != 0; @@ -973,6 +1033,7 @@ break; case PCI_CAP_MSI: printf("MSI"); + msi_off = off; break; case PCI_CAP_CPCI_HOTSWAP: printf("CompactPCI Hot-swapping"); @@ -1013,6 +1074,8 @@ } printf(")\n"); } + if (msi_off != -1) + pci_conf_print_msi_cap(regs, msi_off); if (pcipm_off != -1) pci_conf_print_pcipm_cap(regs, pcipm_off); if (pcie_off != -1) Index: src/sys/dev/pci/pcireg.h diff -u src/sys/dev/pci/pcireg.h:1.57.20.1 src/sys/dev/pci/pcireg.h:1.57.20.1.2.1 --- src/sys/dev/pci/pcireg.h:1.57.20.1 Fri Nov 19 23:40:28 2010 +++ src/sys/dev/pci/pcireg.h Fri Jan 7 02:26:15 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pcireg.h,v 1.57.20.1 2010/11/19 23:40:28 riz Exp $ */ +/* $NetBSD: pcireg.h,v 1.57.20.1.2.1 2011/01/07 02:26:15 matt Exp $ */ /* * Copyright (c) 1995, 1996, 1999, 2000 @@ -87,6 +87,7 @@ #define PCI_COMMAND_BACKTOBACK_ENABLE 0x00000200 #define PCI_COMMAND_INTERRUPT_DISABLE 0x00000400 +#define PCI_STATUS_INT_STATUS 0x00080000 #define PCI_STATUS_CAPLIST_SUPPORT 0x00100000 #define PCI_STATUS_66MHZ_SUPPORT 0x00200000 #define PCI_STATUS_UDF_SUPPORT 0x00400000 @@ -338,9 +339,12 @@ /* * PCI header type */ -#define PCI_HDRTYPE_DEVICE 0 -#define PCI_HDRTYPE_PPB 1 -#define PCI_HDRTYPE_PCB 2 +#define PCI_HDRTYPE_DEVICE 0 /* PCI/PCIX/Cardbus */ +#define PCI_HDRTYPE_PPB 1 /* PCI/PCIX/Cardbus */ +#define PCI_HDRTYPE_PCB 2 /* PCI/PCIX/Cardbus */ +#define PCI_HDRTYPE_EP 0 /* PCI Express */ +#define PCI_HDRTYPE_RC 1 /* PCI Express */ + /* * Mapping registers @@ -351,6 +355,15 @@ #define PCI_MAPREG_PPB_END 0x18 #define PCI_MAPREG_PCB_END 0x14 +#define PCI_BAR0 0x10 +#define PCI_BAR1 0x14 +#define PCI_BAR2 0x18 +#define PCI_BAR3 0x1C +#define PCI_BAR4 0x20 +#define PCI_BAR5 0x24 + +#define PCI_BAR(__n) (0x10 + 4 * (__n)) + #define PCI_MAPREG_TYPE(mr) \ ((mr) & PCI_MAPREG_TYPE_MASK) #define PCI_MAPREG_TYPE_MASK 0x00000001 @@ -448,6 +461,49 @@ #define PCI_VPD_DATAREG(ofs) ((ofs) + 4) #define PCI_VPD_OPFLAG 0x80000000 +#define PCI_MSI_CTL_PERVEC_MASK 0x01000000 +#define PCI_MSI_CTL_64BIT_ADDR 0x00800000 +#define PCI_MSI_CTL_MME_MASK 0x7 +#define PCI_MSI_CTL_MME_SHIFT 20 +#define PCI_MSI_CTL_MME(ofs) (((ofs) & PCI_MSI_CTL_MME_MASK) << PCI_MSI_CTL_MME_SHIFT) +#define PCI_MSI_CTL_MMC_MASK 0x7 +#define PCI_MSI_CTL_MMC_SHIFT 17 +#define PCI_MSI_CTL_MMC(ofs) (((ofs) >> PCI_MSI_CTL_MME_SHIFT) & PCI_MSI_CTL_MME_MASK) +#define PCI_MSI_CTL_MSI_ENABLE 0x00010000 +/* + * MSI Message Address is at offset 4. + * MSI Message Upper Address (if 64bit) is at offset 8. + * MSI Message data is at offset 8 or 12 and is 16 bits. + * [16 bit reserved field] + * MSI Mask Bits (32 bit field) + * MSI Pending Bits (32 bit field) + */ + +#define PCI_MSIX_CTL_ENABLE 0x80000000 +#define PCI_MSIX_CTL_FUNCMASK 0x40000000 +#define PCI_MSIX_CTL_TBLSIZE_MASK 0x07ff0000 +#define PCI_MSIX_CTL_TBLSIZE_SHIFT 16 +#define PCI_MSIX_CTL_TBLSIZE(ofs) (((ofs) >> PCI_MSIX_CTL_TBLSIZE_SHIFT) & PCI_MSIX_CTL_TBLSIZE_MASK) +/* + * 2nd DWORD is the Table Offset + */ +#define PCI_MSIX_TBLOFFSET_MASK 0xfffffff8 +#define PCI_MSIX_TBLBIR_MASK 0x00000007 +/* + * 3rd DWORD is the Pending Bitmap Array Offset + */ +#define PCI_MSIX_PBAOFFSET_MASK 0xfffffff8 +#define PCI_MSIX_PBABIR_MASK 0x00000007 + +struct pci_msix_table_entry { + uint32_t pci_msix_addr_lo; + uint32_t pci_msix_addr_hi; + uint32_t pci_msix_value; + uint32_t pci_msix_vendor_control; +}; +#define PCI_MSIX_VENDCTL_MASK 0x00000001 + + /* * Power Management Capability; access via capability pointer. */ Index: src/sys/dev/pci/pcivar.h diff -u src/sys/dev/pci/pcivar.h:1.83 src/sys/dev/pci/pcivar.h:1.83.18.1 --- src/sys/dev/pci/pcivar.h:1.83 Tue Jul 22 04:52:19 2008 +++ src/sys/dev/pci/pcivar.h Fri Jan 7 02:26:15 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pcivar.h,v 1.83 2008/07/22 04:52:19 bjs Exp $ */ +/* $NetBSD: pcivar.h,v 1.83.18.1 2011/01/07 02:26:15 matt Exp $ */ /* * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. @@ -128,6 +128,10 @@ #define PCI_FLAGS_MRM_OKAY 0x08 /* Memory Read Multiple okay */ #define PCI_FLAGS_MWI_OKAY 0x10 /* Memory Write and Invalidate okay */ +#define PCI_FLAGS_MSI_OKAY 0x20 /* Message Signaled Interrupts + okay */ +#define PCI_FLAGS_MSIX_OKAY 0x40 /* Message Signaled Interrupts + (Extended) okay */ /* * PCI device 'quirks'.