aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/pci/mmconfig-shared.c
diff options
context:
space:
mode:
authorOlivier Galibert <galibert@pobox.com>2007-02-13 07:26:20 -0500
committerAndi Kleen <andi@basil.nowhere.org>2007-02-13 07:26:20 -0500
commitb78673944b22b662b270c8bba5c198f19e4ee4e1 (patch)
tree3cbbe3808335fc297fb3daf01dcbf26d4243a2db /arch/i386/pci/mmconfig-shared.c
parent2e188938ab2358034801938c2329b016ca135823 (diff)
[PATCH] mmconfig: Share parts of mmconfig code between i386 and x86-64
i386 and x86-64 pci mmconfig code have a lot in common. So share what's shareable between the two. Signed-off-by: Olivier Galibert <galibert@pobox.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org>
Diffstat (limited to 'arch/i386/pci/mmconfig-shared.c')
-rw-r--r--arch/i386/pci/mmconfig-shared.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/arch/i386/pci/mmconfig-shared.c b/arch/i386/pci/mmconfig-shared.c
new file mode 100644
index 000000000000..998e04f6d68f
--- /dev/null
+++ b/arch/i386/pci/mmconfig-shared.c
@@ -0,0 +1,86 @@
1/*
2 * mmconfig-shared.c - Low-level direct PCI config space access via
3 * MMCONFIG - common code between i386 and x86-64.
4 *
5 * This code does:
6 * - ACPI decoding and validation
7 *
8 * Per-architecture code takes care of the mappings and accesses
9 * themselves.
10 */
11
12#include <linux/pci.h>
13#include <linux/init.h>
14#include <linux/acpi.h>
15#include <linux/bitmap.h>
16#include <asm/e820.h>
17
18#include "pci.h"
19
20/* aperture is up to 256MB but BIOS may reserve less */
21#define MMCONFIG_APER_MIN (2 * 1024*1024)
22#define MMCONFIG_APER_MAX (256 * 1024*1024)
23
24/* Verify the first 16 busses. We assume that systems with more busses
25 get MCFG right. */
26#define PCI_MMCFG_MAX_CHECK_BUS 16
27
28DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
29
30/* K8 systems have some devices (typically in the builtin northbridge)
31 that are only accessible using type1
32 Normally this can be expressed in the MCFG by not listing them
33 and assigning suitable _SEGs, but this isn't implemented in some BIOS.
34 Instead try to discover all devices on bus 0 that are unreachable using MM
35 and fallback for them. */
36static __init void unreachable_devices(void)
37{
38 int i, k;
39 /* Use the max bus number from ACPI here? */
40 for (k = 0; k < PCI_MMCFG_MAX_CHECK_BUS; k++) {
41 for (i = 0; i < 32; i++) {
42 u32 val1, val2;
43
44 pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1);
45 if (val1 == 0xffffffff)
46 continue;
47
48 raw_pci_ops->read(0, k, PCI_DEVFN(i, 0), 0, 4, &val2);
49 if (val1 != val2) {
50 set_bit(i + 32*k, pci_mmcfg_fallback_slots);
51 printk(KERN_NOTICE "PCI: No mmconfig possible"
52 " on device %02x:%02x\n", k, i);
53 }
54 }
55 }
56}
57
58void __init pci_mmcfg_init(int type)
59{
60 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
61 return;
62
63 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
64
65 if ((pci_mmcfg_config_num == 0) ||
66 (pci_mmcfg_config == NULL) ||
67 (pci_mmcfg_config[0].address == 0))
68 return;
69
70 /* Only do this check when type 1 works. If it doesn't work
71 assume we run on a Mac and always use MCFG */
72 if (type == 1 &&
73 !e820_all_mapped(pci_mmcfg_config[0].address,
74 pci_mmcfg_config[0].address + MMCONFIG_APER_MIN,
75 E820_RESERVED)) {
76 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not E820-reserved\n",
77 pci_mmcfg_config[0].address);
78 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
79 return;
80 }
81
82 if (pci_mmcfg_arch_init()) {
83 unreachable_devices();
84 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
85 }
86}