0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/pci.h>
0014 #include <asm/pci_x86.h>
0015 #include <asm/numachip/numachip.h>
0016
0017 static u8 limit __read_mostly;
0018
0019 static inline char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
0020 {
0021 struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
0022
0023 if (cfg && cfg->virt)
0024 return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
0025 return NULL;
0026 }
0027
0028 static int pci_mmcfg_read_numachip(unsigned int seg, unsigned int bus,
0029 unsigned int devfn, int reg, int len, u32 *value)
0030 {
0031 char __iomem *addr;
0032
0033
0034 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
0035 err: *value = -1;
0036 return -EINVAL;
0037 }
0038
0039
0040 if (unlikely(bus == 0 && devfn >= limit)) {
0041 *value = -1;
0042 return 0;
0043 }
0044
0045 rcu_read_lock();
0046 addr = pci_dev_base(seg, bus, devfn);
0047 if (!addr) {
0048 rcu_read_unlock();
0049 goto err;
0050 }
0051
0052 switch (len) {
0053 case 1:
0054 *value = mmio_config_readb(addr + reg);
0055 break;
0056 case 2:
0057 *value = mmio_config_readw(addr + reg);
0058 break;
0059 case 4:
0060 *value = mmio_config_readl(addr + reg);
0061 break;
0062 }
0063 rcu_read_unlock();
0064
0065 return 0;
0066 }
0067
0068 static int pci_mmcfg_write_numachip(unsigned int seg, unsigned int bus,
0069 unsigned int devfn, int reg, int len, u32 value)
0070 {
0071 char __iomem *addr;
0072
0073
0074 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
0075 return -EINVAL;
0076
0077
0078 if (unlikely(bus == 0 && devfn >= limit))
0079 return 0;
0080
0081 rcu_read_lock();
0082 addr = pci_dev_base(seg, bus, devfn);
0083 if (!addr) {
0084 rcu_read_unlock();
0085 return -EINVAL;
0086 }
0087
0088 switch (len) {
0089 case 1:
0090 mmio_config_writeb(addr + reg, value);
0091 break;
0092 case 2:
0093 mmio_config_writew(addr + reg, value);
0094 break;
0095 case 4:
0096 mmio_config_writel(addr + reg, value);
0097 break;
0098 }
0099 rcu_read_unlock();
0100
0101 return 0;
0102 }
0103
0104 static const struct pci_raw_ops pci_mmcfg_numachip = {
0105 .read = pci_mmcfg_read_numachip,
0106 .write = pci_mmcfg_write_numachip,
0107 };
0108
0109 int __init pci_numachip_init(void)
0110 {
0111 int ret = 0;
0112 u32 val;
0113
0114
0115
0116 ret = raw_pci_read(0, 0, PCI_DEVFN(0x18, 0), 0x60, sizeof(val), &val);
0117 if (ret)
0118 goto out;
0119
0120
0121 limit = PCI_DEVFN(0x18 + ((val >> 4) & 7) + 1, 0);
0122
0123
0124 raw_pci_ops = raw_pci_ext_ops = &pci_mmcfg_numachip;
0125 out:
0126 return ret;
0127 }