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.c (7035B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Intel(R) Trace Hub pci driver
      4 *
      5 * Copyright (C) 2014-2015 Intel Corporation.
      6 */
      7
      8#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
      9
     10#include <linux/types.h>
     11#include <linux/module.h>
     12#include <linux/device.h>
     13#include <linux/sysfs.h>
     14#include <linux/pci.h>
     15
     16#include "intel_th.h"
     17
     18#define DRIVER_NAME "intel_th_pci"
     19
     20enum {
     21	TH_PCI_CONFIG_BAR	= 0,
     22	TH_PCI_STH_SW_BAR	= 2,
     23	TH_PCI_RTIT_BAR		= 4,
     24};
     25
     26#define BAR_MASK (BIT(TH_PCI_CONFIG_BAR) | BIT(TH_PCI_STH_SW_BAR))
     27
     28#define PCI_REG_NPKDSC	0x80
     29#define NPKDSC_TSACT	BIT(5)
     30
     31static int intel_th_pci_activate(struct intel_th *th)
     32{
     33	struct pci_dev *pdev = to_pci_dev(th->dev);
     34	u32 npkdsc;
     35	int err;
     36
     37	if (!INTEL_TH_CAP(th, tscu_enable))
     38		return 0;
     39
     40	err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
     41	if (!err) {
     42		npkdsc |= NPKDSC_TSACT;
     43		err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
     44	}
     45
     46	if (err)
     47		dev_err(&pdev->dev, "failed to read NPKDSC register\n");
     48
     49	return err;
     50}
     51
     52static void intel_th_pci_deactivate(struct intel_th *th)
     53{
     54	struct pci_dev *pdev = to_pci_dev(th->dev);
     55	u32 npkdsc;
     56	int err;
     57
     58	if (!INTEL_TH_CAP(th, tscu_enable))
     59		return;
     60
     61	err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
     62	if (!err) {
     63		npkdsc |= NPKDSC_TSACT;
     64		err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
     65	}
     66
     67	if (err)
     68		dev_err(&pdev->dev, "failed to read NPKDSC register\n");
     69}
     70
     71static int intel_th_pci_probe(struct pci_dev *pdev,
     72			      const struct pci_device_id *id)
     73{
     74	const struct intel_th_drvdata *drvdata = (void *)id->driver_data;
     75	struct resource resource[TH_MMIO_END + TH_NVEC_MAX] = {
     76		[TH_MMIO_CONFIG]	= pdev->resource[TH_PCI_CONFIG_BAR],
     77		[TH_MMIO_SW]		= pdev->resource[TH_PCI_STH_SW_BAR],
     78	};
     79	int err, r = TH_MMIO_SW + 1, i;
     80	struct intel_th *th;
     81
     82	err = pcim_enable_device(pdev);
     83	if (err)
     84		return err;
     85
     86	err = pcim_iomap_regions_request_all(pdev, BAR_MASK, DRIVER_NAME);
     87	if (err)
     88		return err;
     89
     90	if (pdev->resource[TH_PCI_RTIT_BAR].start) {
     91		resource[TH_MMIO_RTIT] = pdev->resource[TH_PCI_RTIT_BAR];
     92		r++;
     93	}
     94
     95	err = pci_alloc_irq_vectors(pdev, 1, 8, PCI_IRQ_ALL_TYPES);
     96	if (err > 0)
     97		for (i = 0; i < err; i++, r++) {
     98			resource[r].flags = IORESOURCE_IRQ;
     99			resource[r].start = pci_irq_vector(pdev, i);
    100		}
    101
    102	th = intel_th_alloc(&pdev->dev, drvdata, resource, r);
    103	if (IS_ERR(th))
    104		return PTR_ERR(th);
    105
    106	th->activate   = intel_th_pci_activate;
    107	th->deactivate = intel_th_pci_deactivate;
    108
    109	pci_set_master(pdev);
    110
    111	return 0;
    112}
    113
    114static void intel_th_pci_remove(struct pci_dev *pdev)
    115{
    116	struct intel_th *th = pci_get_drvdata(pdev);
    117
    118	intel_th_free(th);
    119
    120	pci_free_irq_vectors(pdev);
    121}
    122
    123static const struct intel_th_drvdata intel_th_1x_multi_is_broken = {
    124	.multi_is_broken	= 1,
    125};
    126
    127static const struct intel_th_drvdata intel_th_2x = {
    128	.tscu_enable	= 1,
    129	.has_mintctl	= 1,
    130};
    131
    132static const struct pci_device_id intel_th_pci_id_table[] = {
    133	{
    134		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26),
    135		.driver_data = (kernel_ulong_t)0,
    136	},
    137	{
    138		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa126),
    139		.driver_data = (kernel_ulong_t)0,
    140	},
    141	{
    142		/* Apollo Lake */
    143		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a8e),
    144		.driver_data = (kernel_ulong_t)0,
    145	},
    146	{
    147		/* Broxton */
    148		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80),
    149		.driver_data = (kernel_ulong_t)0,
    150	},
    151	{
    152		/* Broxton B-step */
    153		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e),
    154		.driver_data = (kernel_ulong_t)0,
    155	},
    156	{
    157		/* Kaby Lake PCH-H */
    158		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),
    159		.driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken,
    160	},
    161	{
    162		/* Denverton */
    163		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1),
    164		.driver_data = (kernel_ulong_t)0,
    165	},
    166	{
    167		/* Lewisburg PCH */
    168		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6),
    169		.driver_data = (kernel_ulong_t)0,
    170	},
    171	{
    172		/* Lewisburg PCH */
    173		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa226),
    174		.driver_data = (kernel_ulong_t)0,
    175	},
    176	{
    177		/* Gemini Lake */
    178		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
    179		.driver_data = (kernel_ulong_t)&intel_th_2x,
    180	},
    181	{
    182		/* Cannon Lake H */
    183		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),
    184		.driver_data = (kernel_ulong_t)&intel_th_2x,
    185	},
    186	{
    187		/* Cannon Lake LP */
    188		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),
    189		.driver_data = (kernel_ulong_t)&intel_th_2x,
    190	},
    191	{
    192		/* Cedar Fork PCH */
    193		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1),
    194		.driver_data = (kernel_ulong_t)&intel_th_2x,
    195	},
    196	{
    197		/* Ice Lake PCH */
    198		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6),
    199		.driver_data = (kernel_ulong_t)&intel_th_2x,
    200	},
    201	{
    202		/* Comet Lake */
    203		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6),
    204		.driver_data = (kernel_ulong_t)&intel_th_2x,
    205	},
    206	{
    207		/* Comet Lake PCH */
    208		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x06a6),
    209		.driver_data = (kernel_ulong_t)&intel_th_2x,
    210	},
    211	{
    212		/* Comet Lake PCH-V */
    213		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6),
    214		.driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken,
    215	},
    216	{
    217		/* Ice Lake NNPI */
    218		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5),
    219		.driver_data = (kernel_ulong_t)&intel_th_2x,
    220	},
    221	{
    222		/* Ice Lake CPU */
    223		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29),
    224		.driver_data = (kernel_ulong_t)&intel_th_2x,
    225	},
    226	{
    227		/* Tiger Lake CPU */
    228		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33),
    229		.driver_data = (kernel_ulong_t)&intel_th_2x,
    230	},
    231	{
    232		/* Tiger Lake PCH */
    233		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6),
    234		.driver_data = (kernel_ulong_t)&intel_th_2x,
    235	},
    236	{
    237		/* Tiger Lake PCH-H */
    238		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x43a6),
    239		.driver_data = (kernel_ulong_t)&intel_th_2x,
    240	},
    241	{
    242		/* Jasper Lake PCH */
    243		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6),
    244		.driver_data = (kernel_ulong_t)&intel_th_2x,
    245	},
    246	{
    247		/* Jasper Lake CPU */
    248		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4e29),
    249		.driver_data = (kernel_ulong_t)&intel_th_2x,
    250	},
    251	{
    252		/* Elkhart Lake CPU */
    253		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529),
    254		.driver_data = (kernel_ulong_t)&intel_th_2x,
    255	},
    256	{
    257		/* Elkhart Lake */
    258		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26),
    259		.driver_data = (kernel_ulong_t)&intel_th_2x,
    260	},
    261	{
    262		/* Emmitsburg PCH */
    263		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1bcc),
    264		.driver_data = (kernel_ulong_t)&intel_th_2x,
    265	},
    266	{
    267		/* Alder Lake */
    268		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7aa6),
    269		.driver_data = (kernel_ulong_t)&intel_th_2x,
    270	},
    271	{
    272		/* Alder Lake-P */
    273		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x51a6),
    274		.driver_data = (kernel_ulong_t)&intel_th_2x,
    275	},
    276	{
    277		/* Alder Lake-M */
    278		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x54a6),
    279		.driver_data = (kernel_ulong_t)&intel_th_2x,
    280	},
    281	{
    282		/* Alder Lake CPU */
    283		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f),
    284		.driver_data = (kernel_ulong_t)&intel_th_2x,
    285	},
    286	{
    287		/* Rocket Lake CPU */
    288		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c19),
    289		.driver_data = (kernel_ulong_t)&intel_th_2x,
    290	},
    291	{ 0 },
    292};
    293
    294MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table);
    295
    296static struct pci_driver intel_th_pci_driver = {
    297	.name		= DRIVER_NAME,
    298	.id_table	= intel_th_pci_id_table,
    299	.probe		= intel_th_pci_probe,
    300	.remove		= intel_th_pci_remove,
    301};
    302
    303module_pci_driver(intel_th_pci_driver);
    304
    305MODULE_LICENSE("GPL v2");
    306MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver");
    307MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>");