[PATCH] x86_64: Introduce e820_all_mapped
[deliverable/linux.git] / arch / x86_64 / pci / mmconfig.c
CommitLineData
1da177e4
LT
1/*
2 * mmconfig.c - Low-level direct PCI config space access via MMCONFIG
3 *
4 * This is an 64bit optimized version that always keeps the full mmconfig
5 * space mapped. This allows lockless config space operation.
6 */
7
8#include <linux/pci.h>
9#include <linux/init.h>
54549391 10#include <linux/acpi.h>
d6ece549 11#include <linux/bitmap.h>
1da177e4
LT
12#include "pci.h"
13
14#define MMCONFIG_APER_SIZE (256*1024*1024)
15
d6ece549
AK
16static DECLARE_BITMAP(fallback_slots, 32);
17
1da177e4 18/* Static virtual mapping of the MMCONFIG aperture */
1cde8a16
GKH
19struct mmcfg_virt {
20 struct acpi_table_mcfg_config *cfg;
8b8a4e33 21 char __iomem *virt;
1cde8a16
GKH
22};
23static struct mmcfg_virt *pci_mmcfg_virt;
1da177e4 24
8b8a4e33 25static char __iomem *get_virt(unsigned int seg, unsigned bus)
1da177e4 26{
1cde8a16
GKH
27 int cfg_num = -1;
28 struct acpi_table_mcfg_config *cfg;
29
30 while (1) {
31 ++cfg_num;
3103039c
AK
32 if (cfg_num >= pci_mmcfg_config_num)
33 break;
1cde8a16
GKH
34 cfg = pci_mmcfg_virt[cfg_num].cfg;
35 if (cfg->pci_segment_group_number != seg)
36 continue;
37 if ((cfg->start_bus_number <= bus) &&
38 (cfg->end_bus_number >= bus))
39 return pci_mmcfg_virt[cfg_num].virt;
40 }
3103039c
AK
41
42 /* Handle more broken MCFG tables on Asus etc.
43 They only contain a single entry for bus 0-0. Assume
44 this applies to all busses. */
45 cfg = &pci_mmcfg_config[0];
46 if (pci_mmcfg_config_num == 1 &&
47 cfg->pci_segment_group_number == 0 &&
48 (cfg->start_bus_number | cfg->end_bus_number) == 0)
1de6bf33 49 return pci_mmcfg_virt[0].virt;
3103039c
AK
50
51 /* Fall back to type 0 */
cc59853b 52 return NULL;
1cde8a16
GKH
53}
54
8b8a4e33 55static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
1cde8a16 56{
8b8a4e33 57 char __iomem *addr;
3d1712c9 58 if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), fallback_slots))
d6ece549
AK
59 return NULL;
60 addr = get_virt(seg, bus);
928cf8c6
AK
61 if (!addr)
62 return NULL;
63 return addr + ((bus << 20) | (devfn << 12));
1da177e4
LT
64}
65
66static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
67 unsigned int devfn, int reg, int len, u32 *value)
68{
8b8a4e33 69 char __iomem *addr;
1da177e4 70
928cf8c6 71 /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
1da177e4
LT
72 if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
73 return -EINVAL;
74
928cf8c6
AK
75 addr = pci_dev_base(seg, bus, devfn);
76 if (!addr)
77 return pci_conf1_read(seg,bus,devfn,reg,len,value);
78
1da177e4
LT
79 switch (len) {
80 case 1:
81 *value = readb(addr + reg);
82 break;
83 case 2:
84 *value = readw(addr + reg);
85 break;
86 case 4:
87 *value = readl(addr + reg);
88 break;
89 }
90
91 return 0;
92}
93
94static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
95 unsigned int devfn, int reg, int len, u32 value)
96{
8b8a4e33 97 char __iomem *addr;
1da177e4 98
928cf8c6 99 /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
1da177e4
LT
100 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
101 return -EINVAL;
102
928cf8c6
AK
103 addr = pci_dev_base(seg, bus, devfn);
104 if (!addr)
105 return pci_conf1_write(seg,bus,devfn,reg,len,value);
106
1da177e4
LT
107 switch (len) {
108 case 1:
109 writeb(value, addr + reg);
110 break;
111 case 2:
112 writew(value, addr + reg);
113 break;
114 case 4:
115 writel(value, addr + reg);
116 break;
117 }
118
119 return 0;
120}
121
122static struct pci_raw_ops pci_mmcfg = {
123 .read = pci_mmcfg_read,
124 .write = pci_mmcfg_write,
125};
126
d6ece549
AK
127/* K8 systems have some devices (typically in the builtin northbridge)
128 that are only accessible using type1
129 Normally this can be expressed in the MCFG by not listing them
130 and assigning suitable _SEGs, but this isn't implemented in some BIOS.
131 Instead try to discover all devices on bus 0 that are unreachable using MM
132 and fallback for them.
133 We only do this for bus 0/seg 0 */
134static __init void unreachable_devices(void)
135{
136 int i;
137 for (i = 0; i < 32; i++) {
138 u32 val1;
8b8a4e33 139 char __iomem *addr;
d6ece549
AK
140
141 pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1);
142 if (val1 == 0xffffffff)
143 continue;
144 addr = pci_dev_base(0, 0, PCI_DEVFN(i, 0));
145 if (addr == NULL|| readl(addr) != val1) {
3d1712c9 146 set_bit(i, fallback_slots);
d6ece549
AK
147 }
148 }
149}
150
3d1712c9 151void __init pci_mmcfg_init(void)
1da177e4 152{
1cde8a16
GKH
153 int i;
154
1da177e4 155 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
3d1712c9 156 return;
54549391
GKH
157
158 acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
159 if ((pci_mmcfg_config_num == 0) ||
160 (pci_mmcfg_config == NULL) ||
161 (pci_mmcfg_config[0].base_address == 0))
3d1712c9 162 return;
1da177e4 163
1da177e4 164 /* RED-PEN i386 doesn't do _nocache right now */
1cde8a16
GKH
165 pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
166 if (pci_mmcfg_virt == NULL) {
167 printk("PCI: Can not allocate memory for mmconfig structures\n");
3d1712c9 168 return;
1cde8a16
GKH
169 }
170 for (i = 0; i < pci_mmcfg_config_num; ++i) {
171 pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i];
172 pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE);
173 if (!pci_mmcfg_virt[i].virt) {
174 printk("PCI: Cannot map mmconfig aperture for segment %d\n",
175 pci_mmcfg_config[i].pci_segment_group_number);
3d1712c9 176 return;
1cde8a16
GKH
177 }
178 printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);
179 }
1da177e4 180
d6ece549
AK
181 unreachable_devices();
182
1da177e4
LT
183 raw_pci_ops = &pci_mmcfg;
184 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
1da177e4 185}
This page took 0.1206 seconds and 5 git commands to generate.