0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/pci.h>
0012 #include <linux/init.h>
0013 #include <linux/rcupdate.h>
0014 #include <asm/e820/api.h>
0015 #include <asm/pci_x86.h>
0016
0017
0018 #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
0019
0020
0021 static u32 mmcfg_last_accessed_device;
0022 static int mmcfg_last_accessed_cpu;
0023
0024
0025
0026
0027 static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
0028 {
0029 struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
0030
0031 if (cfg)
0032 return cfg->address;
0033 return 0;
0034 }
0035
0036
0037
0038
0039 static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
0040 {
0041 u32 dev_base = base | PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12);
0042 int cpu = smp_processor_id();
0043 if (dev_base != mmcfg_last_accessed_device ||
0044 cpu != mmcfg_last_accessed_cpu) {
0045 mmcfg_last_accessed_device = dev_base;
0046 mmcfg_last_accessed_cpu = cpu;
0047 set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
0048 }
0049 }
0050
0051 static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
0052 unsigned int devfn, int reg, int len, u32 *value)
0053 {
0054 unsigned long flags;
0055 u32 base;
0056
0057 if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
0058 err: *value = -1;
0059 return -EINVAL;
0060 }
0061
0062 rcu_read_lock();
0063 base = get_base_addr(seg, bus, devfn);
0064 if (!base) {
0065 rcu_read_unlock();
0066 goto err;
0067 }
0068
0069 raw_spin_lock_irqsave(&pci_config_lock, flags);
0070
0071 pci_exp_set_dev_base(base, bus, devfn);
0072
0073 switch (len) {
0074 case 1:
0075 *value = mmio_config_readb(mmcfg_virt_addr + reg);
0076 break;
0077 case 2:
0078 *value = mmio_config_readw(mmcfg_virt_addr + reg);
0079 break;
0080 case 4:
0081 *value = mmio_config_readl(mmcfg_virt_addr + reg);
0082 break;
0083 }
0084 raw_spin_unlock_irqrestore(&pci_config_lock, flags);
0085 rcu_read_unlock();
0086
0087 return 0;
0088 }
0089
0090 static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
0091 unsigned int devfn, int reg, int len, u32 value)
0092 {
0093 unsigned long flags;
0094 u32 base;
0095
0096 if ((bus > 255) || (devfn > 255) || (reg > 4095))
0097 return -EINVAL;
0098
0099 rcu_read_lock();
0100 base = get_base_addr(seg, bus, devfn);
0101 if (!base) {
0102 rcu_read_unlock();
0103 return -EINVAL;
0104 }
0105
0106 raw_spin_lock_irqsave(&pci_config_lock, flags);
0107
0108 pci_exp_set_dev_base(base, bus, devfn);
0109
0110 switch (len) {
0111 case 1:
0112 mmio_config_writeb(mmcfg_virt_addr + reg, value);
0113 break;
0114 case 2:
0115 mmio_config_writew(mmcfg_virt_addr + reg, value);
0116 break;
0117 case 4:
0118 mmio_config_writel(mmcfg_virt_addr + reg, value);
0119 break;
0120 }
0121 raw_spin_unlock_irqrestore(&pci_config_lock, flags);
0122 rcu_read_unlock();
0123
0124 return 0;
0125 }
0126
0127 const struct pci_raw_ops pci_mmcfg = {
0128 .read = pci_mmcfg_read,
0129 .write = pci_mmcfg_write,
0130 };
0131
0132 int __init pci_mmcfg_arch_init(void)
0133 {
0134 printk(KERN_INFO "PCI: Using MMCONFIG for extended config space\n");
0135 raw_pci_ext_ops = &pci_mmcfg;
0136 return 1;
0137 }
0138
0139 void __init pci_mmcfg_arch_free(void)
0140 {
0141 }
0142
0143 int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
0144 {
0145 return 0;
0146 }
0147
0148 void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
0149 {
0150 unsigned long flags;
0151
0152
0153 raw_spin_lock_irqsave(&pci_config_lock, flags);
0154 mmcfg_last_accessed_device = 0;
0155 raw_spin_unlock_irqrestore(&pci_config_lock, flags);
0156 }