Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 48404
b: refs/heads/master
c: 9358c69
h: refs/heads/master
v: v3
  • Loading branch information
Olivier Galibert authored and Andi Kleen committed Feb 13, 2007
1 parent 5d14e5f commit 4238f11
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5f027387bbdb5a4a4c1babd557fd976cd09d7495
refs/heads/master: 9358c693c5ac1afde28f24ac651f7903d32a850c
121 changes: 119 additions & 2 deletions trunk/arch/i386/pci/mmconfig-shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* MMCONFIG - common code between i386 and x86-64.
*
* This code does:
* - known chipset handling
* - ACPI decoding and validation
*
* Per-architecture code takes care of the mappings and accesses
Expand Down Expand Up @@ -55,12 +56,128 @@ static __init void unreachable_devices(void)
}
}

static __init const char *pci_mmcfg_e7520(void)
{
u32 win;
pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win);

pci_mmcfg_config_num = 1;
pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
if (!pci_mmcfg_config)
return NULL;
pci_mmcfg_config[0].address = (win & 0xf000) << 16;
pci_mmcfg_config[0].pci_segment = 0;
pci_mmcfg_config[0].start_bus_number = 0;
pci_mmcfg_config[0].end_bus_number = 255;

return "Intel Corporation E7520 Memory Controller Hub";
}

static __init const char *pci_mmcfg_intel_945(void)
{
u32 pciexbar, mask = 0, len = 0;

pci_mmcfg_config_num = 1;

pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0x48, 4, &pciexbar);

/* Enable bit */
if (!(pciexbar & 1))
pci_mmcfg_config_num = 0;

/* Size bits */
switch ((pciexbar >> 1) & 3) {
case 0:
mask = 0xf0000000U;
len = 0x10000000U;
break;
case 1:
mask = 0xf8000000U;
len = 0x08000000U;
break;
case 2:
mask = 0xfc000000U;
len = 0x04000000U;
break;
default:
pci_mmcfg_config_num = 0;
}

/* Errata #2, things break when not aligned on a 256Mb boundary */
/* Can only happen in 64M/128M mode */

if ((pciexbar & mask) & 0x0fffffffU)
pci_mmcfg_config_num = 0;

if (pci_mmcfg_config_num) {
pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
if (!pci_mmcfg_config)
return NULL;
pci_mmcfg_config[0].address = pciexbar & mask;
pci_mmcfg_config[0].pci_segment = 0;
pci_mmcfg_config[0].start_bus_number = 0;
pci_mmcfg_config[0].end_bus_number = (len >> 20) - 1;
}

return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
}

struct pci_mmcfg_hostbridge_probe {
u32 vendor;
u32 device;
const char *(*probe)(void);
};

static __initdata struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] = {
{ 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 },
};

static int __init pci_mmcfg_check_hostbridge(void)
{
u32 l;
u16 vendor, device;
int i;
const char *name;

pci_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++)
if ((pci_mmcfg_probes[i].vendor == PCI_ANY_ID ||
pci_mmcfg_probes[i].vendor == vendor) &&
(pci_mmcfg_probes[i].device == PCI_ANY_ID ||
pci_mmcfg_probes[i].device == device))
name = pci_mmcfg_probes[i].probe();

if (name) {
if (pci_mmcfg_config_num)
printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n", name);
else
printk(KERN_INFO "PCI: Found %s without MMCONFIG support.\n",
name);
}

return name != NULL;
}

void __init pci_mmcfg_init(int type)
{
int known_bridge = 0;

if ((pci_probe & PCI_PROBE_MMCONF) == 0)
return;

acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
if (type == 1 && pci_mmcfg_check_hostbridge())
known_bridge = 1;

if (!known_bridge)
acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);

if ((pci_mmcfg_config_num == 0) ||
(pci_mmcfg_config == NULL) ||
Expand All @@ -69,7 +186,7 @@ void __init pci_mmcfg_init(int type)

/* Only do this check when type 1 works. If it doesn't work
assume we run on a Mac and always use MCFG */
if (type == 1 &&
if (type == 1 && !known_bridge &&
!e820_all_mapped(pci_mmcfg_config[0].address,
pci_mmcfg_config[0].address + MMCONFIG_APER_MIN,
E820_RESERVED)) {
Expand Down

0 comments on commit 4238f11

Please sign in to comment.