cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pci-host-generic.c (2279B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Simple, generic PCI host controller driver targeting firmware-initialised
      4 * systems and virtual machines (e.g. the PCI emulation provided by kvmtool).
      5 *
      6 * Copyright (C) 2014 ARM Limited
      7 *
      8 * Author: Will Deacon <will.deacon@arm.com>
      9 */
     10
     11#include <linux/kernel.h>
     12#include <linux/init.h>
     13#include <linux/module.h>
     14#include <linux/pci-ecam.h>
     15#include <linux/platform_device.h>
     16
     17static const struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = {
     18	.bus_shift	= 16,
     19	.pci_ops	= {
     20		.map_bus	= pci_ecam_map_bus,
     21		.read		= pci_generic_config_read,
     22		.write		= pci_generic_config_write,
     23	}
     24};
     25
     26static bool pci_dw_valid_device(struct pci_bus *bus, unsigned int devfn)
     27{
     28	struct pci_config_window *cfg = bus->sysdata;
     29
     30	/*
     31	 * The Synopsys DesignWare PCIe controller in ECAM mode will not filter
     32	 * type 0 config TLPs sent to devices 1 and up on its downstream port,
     33	 * resulting in devices appearing multiple times on bus 0 unless we
     34	 * filter out those accesses here.
     35	 */
     36	if (bus->number == cfg->busr.start && PCI_SLOT(devfn) > 0)
     37		return false;
     38
     39	return true;
     40}
     41
     42static void __iomem *pci_dw_ecam_map_bus(struct pci_bus *bus,
     43					 unsigned int devfn, int where)
     44{
     45	if (!pci_dw_valid_device(bus, devfn))
     46		return NULL;
     47
     48	return pci_ecam_map_bus(bus, devfn, where);
     49}
     50
     51static const struct pci_ecam_ops pci_dw_ecam_bus_ops = {
     52	.pci_ops	= {
     53		.map_bus	= pci_dw_ecam_map_bus,
     54		.read		= pci_generic_config_read,
     55		.write		= pci_generic_config_write,
     56	}
     57};
     58
     59static const struct of_device_id gen_pci_of_match[] = {
     60	{ .compatible = "pci-host-cam-generic",
     61	  .data = &gen_pci_cfg_cam_bus_ops },
     62
     63	{ .compatible = "pci-host-ecam-generic",
     64	  .data = &pci_generic_ecam_ops },
     65
     66	{ .compatible = "marvell,armada8k-pcie-ecam",
     67	  .data = &pci_dw_ecam_bus_ops },
     68
     69	{ .compatible = "socionext,synquacer-pcie-ecam",
     70	  .data = &pci_dw_ecam_bus_ops },
     71
     72	{ .compatible = "snps,dw-pcie-ecam",
     73	  .data = &pci_dw_ecam_bus_ops },
     74
     75	{ },
     76};
     77MODULE_DEVICE_TABLE(of, gen_pci_of_match);
     78
     79static struct platform_driver gen_pci_driver = {
     80	.driver = {
     81		.name = "pci-host-generic",
     82		.of_match_table = gen_pci_of_match,
     83	},
     84	.probe = pci_host_common_probe,
     85	.remove = pci_host_common_remove,
     86};
     87module_platform_driver(gen_pci_driver);
     88
     89MODULE_LICENSE("GPL v2");