^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * mmconfig.c - Low-level direct PCI config space access via MMCONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This is an 64bit optimized version that always keeps the full mmconfig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * space mapped. This allows lockless config space operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/e820/api.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/pci_x86.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define PREFIX "PCI: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) if (cfg && cfg->virt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned int devfn, int reg, int len, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) char __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) err: *value = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) addr = pci_dev_base(seg, bus, devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (!addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) switch (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *value = mmio_config_readb(addr + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *value = mmio_config_readw(addr + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *value = mmio_config_readl(addr + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) unsigned int devfn, int reg, int len, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) char __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) addr = pci_dev_base(seg, bus, devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (!addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) switch (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) mmio_config_writeb(addr + reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) mmio_config_writew(addr + reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) mmio_config_writel(addr + reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) const struct pci_raw_ops pci_mmcfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .read = pci_mmcfg_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .write = pci_mmcfg_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void __iomem *mcfg_ioremap(struct pci_mmcfg_region *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u64 start, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int num_buses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) num_buses = cfg->end_bus - cfg->start_bus + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) size = PCI_MMCFG_BUS_OFFSET(num_buses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) addr = ioremap(start, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int __init pci_mmcfg_arch_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct pci_mmcfg_region *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) list_for_each_entry(cfg, &pci_mmcfg_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (pci_mmcfg_arch_map(cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) pci_mmcfg_arch_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) raw_pci_ext_ops = &pci_mmcfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) void __init pci_mmcfg_arch_free(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct pci_mmcfg_region *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) list_for_each_entry(cfg, &pci_mmcfg_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) pci_mmcfg_arch_unmap(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int pci_mmcfg_arch_map(struct pci_mmcfg_region *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) cfg->virt = mcfg_ioremap(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (!cfg->virt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) pr_err(PREFIX "can't map MMCONFIG at %pR\n", &cfg->res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) void pci_mmcfg_arch_unmap(struct pci_mmcfg_region *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (cfg && cfg->virt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) cfg->virt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }