From: Sepherosa Ziehau Date: Thu, 22 Dec 2011 11:52:02 +0000 (+0800) Subject: pci: Bring in HyperTransport MSI mapping support X-Git-Tag: v3.0.0~330 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/941460dad28b09d2985ae8bdea3b8d1027e3fdf1 pci: Bring in HyperTransport MSI mapping support --- diff --git a/sys/bus/pci/pci.c b/sys/bus/pci/pci.c index 610ed62653..920fca13df 100644 --- a/sys/bus/pci/pci.c +++ b/sys/bus/pci/pci.c @@ -45,6 +45,8 @@ #include #include +#include + #include #include #include @@ -597,7 +599,6 @@ pci_read_cap_pmgt(device_t pcib, int ptr, int nextptr, pcicfgregs *cfg) static void pci_read_cap_ht(device_t pcib, int ptr, int nextptr, pcicfgregs *cfg) { -#ifdef notyet #if defined(__i386__) || defined(__x86_64__) #define REG(n, w) \ @@ -610,6 +611,9 @@ pci_read_cap_ht(device_t pcib, int ptr, int nextptr, pcicfgregs *cfg) /* Determine HT-specific capability type. */ val = REG(ptr + PCIR_HT_COMMAND, 2); + if ((val & 0xe000) == PCIM_HTCAP_SLAVE) + cfg->ht.ht_slave = ptr; + if ((val & PCIM_HTCMD_CAP_MASK) != PCIM_HTCAP_MSI_MAPPING) return; @@ -618,14 +622,14 @@ pci_read_cap_ht(device_t pcib, int ptr, int nextptr, pcicfgregs *cfg) addr = REG(ptr + PCIR_HTMSI_ADDRESS_HI, 4); addr <<= 32; addr |= REG(ptr + PCIR_HTMSI_ADDRESS_LO, 4); - if (addr != MSI_INTEL_ADDR_BASE) { + if (addr != MSI_X86_ADDR_BASE) { device_printf(pcib, "HT Bridge at pci%d:%d:%d:%d " "has non-default MSI window 0x%llx\n", cfg->domain, cfg->bus, cfg->slot, cfg->func, (long long)addr); } } else { - addr = MSI_INTEL_ADDR_BASE; + addr = MSI_X86_ADDR_BASE; } ht->ht_msimap = ptr; @@ -635,7 +639,6 @@ pci_read_cap_ht(device_t pcib, int ptr, int nextptr, pcicfgregs *cfg) #undef REG #endif /* __i386__ || __x86_64__ */ -#endif /* notyet */ } static void @@ -828,6 +831,24 @@ pci_read_capabilities(device_t pcib, pcicfgregs *cfg) } } } + +#if defined(__i386__) || defined(__x86_64__) + /* + * Enable the MSI mapping window for all HyperTransport + * slaves. PCI-PCI bridges have their windows enabled via + * PCIB_MAP_MSI(). + */ + if (cfg->ht.ht_slave != 0 && cfg->ht.ht_msimap != 0 && + !(cfg->ht.ht_msictrl & PCIM_HTCMD_MSI_ENABLE)) { + device_printf(pcib, + "Enabling MSI window for HyperTransport slave at pci%d:%d:%d:%d\n", + cfg->domain, cfg->bus, cfg->slot, cfg->func); + cfg->ht.ht_msictrl |= PCIM_HTCMD_MSI_ENABLE; + WREG(cfg->ht.ht_msimap + PCIR_HT_COMMAND, cfg->ht.ht_msictrl, + 2); + } +#endif + /* REG and WREG use carry through to next functions */ } diff --git a/sys/bus/pci/pcivar.h b/sys/bus/pci/pcivar.h index 918fcf6633..2071604f13 100644 --- a/sys/bus/pci/pcivar.h +++ b/sys/bus/pci/pcivar.h @@ -119,6 +119,7 @@ struct pcicfg_msix { /* Interesting values for HyperTransport */ struct pcicfg_ht { + uint8_t ht_slave; /* Non-zero if device is an HT slave. */ uint8_t ht_msimap; /* Offset of MSI mapping cap registers. */ uint16_t ht_msictrl; /* MSI mapping control */ uint64_t ht_msiaddr; /* MSI mapping base address */ diff --git a/sys/platform/pc32/include/msi_machdep.h b/sys/platform/pc32/include/msi_machdep.h new file mode 100644 index 0000000000..4c7967c5ea --- /dev/null +++ b/sys/platform/pc32/include/msi_machdep.h @@ -0,0 +1,6 @@ +#ifndef _ARCH_MSI_MACHDEP_H_ +#define _ARCH_MSI_MACHDEP_H_ + +#define MSI_X86_ADDR_BASE 0xfee00000 + +#endif /* !_ARCH_MSI_MACHDEP_H_ */ diff --git a/sys/platform/pc64/include/msi_machdep.h b/sys/platform/pc64/include/msi_machdep.h new file mode 100644 index 0000000000..4c7967c5ea --- /dev/null +++ b/sys/platform/pc64/include/msi_machdep.h @@ -0,0 +1,6 @@ +#ifndef _ARCH_MSI_MACHDEP_H_ +#define _ARCH_MSI_MACHDEP_H_ + +#define MSI_X86_ADDR_BASE 0xfee00000 + +#endif /* !_ARCH_MSI_MACHDEP_H_ */