From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1761249AbYBLAp7 (ORCPT ); Mon, 11 Feb 2008 19:45:59 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752111AbYBLAox (ORCPT ); Mon, 11 Feb 2008 19:44:53 -0500 Received: from sca-es-mail-1.Sun.COM ([192.18.43.132]:34549 "EHLO sca-es-mail-1.sun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751430AbYBLAou (ORCPT ); Mon, 11 Feb 2008 19:44:50 -0500 Date: Mon, 11 Feb 2008 16:48:35 -0800 From: Yinghai Lu Subject: [PATCH 4/4] x86_64: check msr to get mmconfig for amd family 10h opteron v3 In-reply-to: <200802111647.11154.yinghai.lu@sun.com> To: Andrew Morton Cc: Greg KH , Ingo Molnar , Linux Kernel Mailing List Message-id: <200802111648.35299.yinghai.lu@sun.com> Organization: Sun MIME-version: 1.0 Content-type: text/plain; charset=iso-8859-1 Content-transfer-encoding: 7BIT Content-disposition: inline References: <200802111643.17265.yinghai.lu@sun.com> <200802111645.38984.yinghai.lu@sun.com> <200802111647.11154.yinghai.lu@sun.com> User-Agent: KMail/1.9.6 (enterprise 20070904.708012) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Yinghai Lu so even booting kernel with acpi=off or even MCFG is not there, we still can use MMCONFIG. Signed-off-by: Yinghai Lu Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Andi Kleen Cc: Greg KH Cc: "H. Peter Anvin" Signed-off-by: Andrew Morton --- arch/x86/pci/mmconfig-shared.c | 67 ++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 6 deletions(-) Index: linux-2.6/arch/x86/pci/mmconfig-shared.c =================================================================== --- linux-2.6.orig/arch/x86/pci/mmconfig-shared.c +++ linux-2.6/arch/x86/pci/mmconfig-shared.c @@ -100,33 +100,88 @@ static const char __init *pci_mmcfg_inte return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; } +static const char __init *pci_mmcfg_amd_fam10h(void) +{ + u32 low, high, address; + u64 base, msr; + int i; + unsigned segnbits = 0, busnbits; + + address = MSR_FAM10H_MMIO_CONF_BASE; + if (rdmsr_safe(address, &low, &high)) + return NULL; + + msr = high; + msr <<= 32; + msr |= low; + + /* mmconfig is not enable */ + if (!(msr & FAM10H_MMIO_CONF_ENABLE)) + return NULL; + + base = msr & (FAM10H_MMIO_CONF_BASE_MASK<> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) & + FAM10H_MMIO_CONF_BUSRANGE_MASK; + if (busnbits > 8) { + segnbits = busnbits - 8; + busnbits = 8; + } + + pci_mmcfg_config_num = (1 << segnbits); + pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]) * + pci_mmcfg_config_num, GFP_KERNEL); + if (!pci_mmcfg_config) + return NULL; + + for (i = 0; i < (1 << segnbits); i++) { + pci_mmcfg_config[i].address = base + (1<<28) * i; + pci_mmcfg_config[i].pci_segment = i; + pci_mmcfg_config[i].start_bus_number = 0; + pci_mmcfg_config[i].end_bus_number = (1 << busnbits) - 1; + } + + return "AMD Family 10h NB"; +} + struct pci_mmcfg_hostbridge_probe { + u32 bus; + u32 devfn; u32 vendor; u32 device; const char *(*probe)(void); }; static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = { - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 }, + { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 }, + { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 }, + { 0, PCI_DEVFN(0x18, 0), PCI_VENDOR_ID_AMD, + 0x1200, pci_mmcfg_amd_fam10h }, + { 0xff, PCI_DEVFN(0, 0), PCI_VENDOR_ID_AMD, + 0x1200, pci_mmcfg_amd_fam10h }, }; static int __init pci_mmcfg_check_hostbridge(void) { u32 l; + u32 bus, devfn; u16 vendor, device; int i; const char *name; - pci_direct_conf1.read(0, 0, PCI_DEVFN(0,0), 0, 4, &l); - vendor = l & 0xffff; - device = (l >> 16) & 0xffff; - pci_mmcfg_config_num = 0; pci_mmcfg_config = NULL; name = NULL; for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) { + bus = pci_mmcfg_probes[i].bus; + devfn = pci_mmcfg_probes[i].devfn; + pci_direct_conf1.read(0, bus, devfn, 0, 4, &l); + vendor = l & 0xffff; + device = (l >> 16) & 0xffff; + if (pci_mmcfg_probes[i].vendor == vendor && pci_mmcfg_probes[i].device == device) name = pci_mmcfg_probes[i].probe();