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


      1// SPDX-License-Identifier: GPL-2.0
      2/* pci_common.c: PCI controller common support.
      3 *
      4 * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net)
      5 */
      6
      7#include <linux/string.h>
      8#include <linux/slab.h>
      9#include <linux/pci.h>
     10#include <linux/device.h>
     11#include <linux/of_device.h>
     12
     13#include <asm/prom.h>
     14#include <asm/oplib.h>
     15
     16#include "pci_impl.h"
     17#include "pci_sun4v.h"
     18
     19static int config_out_of_range(struct pci_pbm_info *pbm,
     20			       unsigned long bus,
     21			       unsigned long devfn,
     22			       unsigned long reg)
     23{
     24	if (bus < pbm->pci_first_busno ||
     25	    bus > pbm->pci_last_busno)
     26		return 1;
     27	return 0;
     28}
     29
     30static void *sun4u_config_mkaddr(struct pci_pbm_info *pbm,
     31				 unsigned long bus,
     32				 unsigned long devfn,
     33				 unsigned long reg)
     34{
     35	unsigned long rbits = pbm->config_space_reg_bits;
     36
     37	if (config_out_of_range(pbm, bus, devfn, reg))
     38		return NULL;
     39
     40	reg = (reg & ((1 << rbits) - 1));
     41	devfn <<= rbits;
     42	bus <<= rbits + 8;
     43
     44	return (void *)	(pbm->config_space | bus | devfn | reg);
     45}
     46
     47/* At least on Sabre, it is necessary to access all PCI host controller
     48 * registers at their natural size, otherwise zeros are returned.
     49 * Strange but true, and I see no language in the UltraSPARC-IIi
     50 * programmer's manual that mentions this even indirectly.
     51 */
     52static int sun4u_read_pci_cfg_host(struct pci_pbm_info *pbm,
     53				   unsigned char bus, unsigned int devfn,
     54				   int where, int size, u32 *value)
     55{
     56	u32 tmp32, *addr;
     57	u16 tmp16;
     58	u8 tmp8;
     59
     60	addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
     61	if (!addr)
     62		return PCIBIOS_SUCCESSFUL;
     63
     64	switch (size) {
     65	case 1:
     66		if (where < 8) {
     67			unsigned long align = (unsigned long) addr;
     68
     69			align &= ~1;
     70			pci_config_read16((u16 *)align, &tmp16);
     71			if (where & 1)
     72				*value = tmp16 >> 8;
     73			else
     74				*value = tmp16 & 0xff;
     75		} else {
     76			pci_config_read8((u8 *)addr, &tmp8);
     77			*value = (u32) tmp8;
     78		}
     79		break;
     80
     81	case 2:
     82		if (where < 8) {
     83			pci_config_read16((u16 *)addr, &tmp16);
     84			*value = (u32) tmp16;
     85		} else {
     86			pci_config_read8((u8 *)addr, &tmp8);
     87			*value = (u32) tmp8;
     88			pci_config_read8(((u8 *)addr) + 1, &tmp8);
     89			*value |= ((u32) tmp8) << 8;
     90		}
     91		break;
     92
     93	case 4:
     94		tmp32 = 0xffffffff;
     95		sun4u_read_pci_cfg_host(pbm, bus, devfn,
     96					where, 2, &tmp32);
     97		*value = tmp32;
     98
     99		tmp32 = 0xffffffff;
    100		sun4u_read_pci_cfg_host(pbm, bus, devfn,
    101					where + 2, 2, &tmp32);
    102		*value |= tmp32 << 16;
    103		break;
    104	}
    105	return PCIBIOS_SUCCESSFUL;
    106}
    107
    108static int sun4u_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
    109			      int where, int size, u32 *value)
    110{
    111	struct pci_pbm_info *pbm = bus_dev->sysdata;
    112	unsigned char bus = bus_dev->number;
    113	u32 *addr;
    114	u16 tmp16;
    115	u8 tmp8;
    116
    117	switch (size) {
    118	case 1:
    119		*value = 0xff;
    120		break;
    121	case 2:
    122		*value = 0xffff;
    123		break;
    124	case 4:
    125		*value = 0xffffffff;
    126		break;
    127	}
    128
    129	if (!bus_dev->number && !PCI_SLOT(devfn))
    130		return sun4u_read_pci_cfg_host(pbm, bus, devfn, where,
    131					       size, value);
    132
    133	addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
    134	if (!addr)
    135		return PCIBIOS_SUCCESSFUL;
    136
    137	switch (size) {
    138	case 1:
    139		pci_config_read8((u8 *)addr, &tmp8);
    140		*value = (u32) tmp8;
    141		break;
    142
    143	case 2:
    144		if (where & 0x01) {
    145			printk("pci_read_config_word: misaligned reg [%x]\n",
    146			       where);
    147			return PCIBIOS_SUCCESSFUL;
    148		}
    149		pci_config_read16((u16 *)addr, &tmp16);
    150		*value = (u32) tmp16;
    151		break;
    152
    153	case 4:
    154		if (where & 0x03) {
    155			printk("pci_read_config_dword: misaligned reg [%x]\n",
    156			       where);
    157			return PCIBIOS_SUCCESSFUL;
    158		}
    159		pci_config_read32(addr, value);
    160		break;
    161	}
    162	return PCIBIOS_SUCCESSFUL;
    163}
    164
    165static int sun4u_write_pci_cfg_host(struct pci_pbm_info *pbm,
    166				    unsigned char bus, unsigned int devfn,
    167				    int where, int size, u32 value)
    168{
    169	u32 *addr;
    170
    171	addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
    172	if (!addr)
    173		return PCIBIOS_SUCCESSFUL;
    174
    175	switch (size) {
    176	case 1:
    177		if (where < 8) {
    178			unsigned long align = (unsigned long) addr;
    179			u16 tmp16;
    180
    181			align &= ~1;
    182			pci_config_read16((u16 *)align, &tmp16);
    183			if (where & 1) {
    184				tmp16 &= 0x00ff;
    185				tmp16 |= value << 8;
    186			} else {
    187				tmp16 &= 0xff00;
    188				tmp16 |= value;
    189			}
    190			pci_config_write16((u16 *)align, tmp16);
    191		} else
    192			pci_config_write8((u8 *)addr, value);
    193		break;
    194	case 2:
    195		if (where < 8) {
    196			pci_config_write16((u16 *)addr, value);
    197		} else {
    198			pci_config_write8((u8 *)addr, value & 0xff);
    199			pci_config_write8(((u8 *)addr) + 1, value >> 8);
    200		}
    201		break;
    202	case 4:
    203		sun4u_write_pci_cfg_host(pbm, bus, devfn,
    204					 where, 2, value & 0xffff);
    205		sun4u_write_pci_cfg_host(pbm, bus, devfn,
    206					 where + 2, 2, value >> 16);
    207		break;
    208	}
    209	return PCIBIOS_SUCCESSFUL;
    210}
    211
    212static int sun4u_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
    213			       int where, int size, u32 value)
    214{
    215	struct pci_pbm_info *pbm = bus_dev->sysdata;
    216	unsigned char bus = bus_dev->number;
    217	u32 *addr;
    218
    219	if (!bus_dev->number && !PCI_SLOT(devfn))
    220		return sun4u_write_pci_cfg_host(pbm, bus, devfn, where,
    221						size, value);
    222
    223	addr = sun4u_config_mkaddr(pbm, bus, devfn, where);
    224	if (!addr)
    225		return PCIBIOS_SUCCESSFUL;
    226
    227	switch (size) {
    228	case 1:
    229		pci_config_write8((u8 *)addr, value);
    230		break;
    231
    232	case 2:
    233		if (where & 0x01) {
    234			printk("pci_write_config_word: misaligned reg [%x]\n",
    235			       where);
    236			return PCIBIOS_SUCCESSFUL;
    237		}
    238		pci_config_write16((u16 *)addr, value);
    239		break;
    240
    241	case 4:
    242		if (where & 0x03) {
    243			printk("pci_write_config_dword: misaligned reg [%x]\n",
    244			       where);
    245			return PCIBIOS_SUCCESSFUL;
    246		}
    247		pci_config_write32(addr, value);
    248	}
    249	return PCIBIOS_SUCCESSFUL;
    250}
    251
    252struct pci_ops sun4u_pci_ops = {
    253	.read =		sun4u_read_pci_cfg,
    254	.write =	sun4u_write_pci_cfg,
    255};
    256
    257static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
    258			      int where, int size, u32 *value)
    259{
    260	struct pci_pbm_info *pbm = bus_dev->sysdata;
    261	u32 devhandle = pbm->devhandle;
    262	unsigned int bus = bus_dev->number;
    263	unsigned int device = PCI_SLOT(devfn);
    264	unsigned int func = PCI_FUNC(devfn);
    265	unsigned long ret;
    266
    267	if (config_out_of_range(pbm, bus, devfn, where)) {
    268		ret = ~0UL;
    269	} else {
    270		ret = pci_sun4v_config_get(devhandle,
    271				HV_PCI_DEVICE_BUILD(bus, device, func),
    272				where, size);
    273	}
    274	switch (size) {
    275	case 1:
    276		*value = ret & 0xff;
    277		break;
    278	case 2:
    279		*value = ret & 0xffff;
    280		break;
    281	case 4:
    282		*value = ret & 0xffffffff;
    283		break;
    284	}
    285
    286
    287	return PCIBIOS_SUCCESSFUL;
    288}
    289
    290static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
    291			       int where, int size, u32 value)
    292{
    293	struct pci_pbm_info *pbm = bus_dev->sysdata;
    294	u32 devhandle = pbm->devhandle;
    295	unsigned int bus = bus_dev->number;
    296	unsigned int device = PCI_SLOT(devfn);
    297	unsigned int func = PCI_FUNC(devfn);
    298
    299	if (config_out_of_range(pbm, bus, devfn, where)) {
    300		/* Do nothing. */
    301	} else {
    302		/* We don't check for hypervisor errors here, but perhaps
    303		 * we should and influence our return value depending upon
    304		 * what kind of error is thrown.
    305		 */
    306		pci_sun4v_config_put(devhandle,
    307				     HV_PCI_DEVICE_BUILD(bus, device, func),
    308				     where, size, value);
    309	}
    310	return PCIBIOS_SUCCESSFUL;
    311}
    312
    313struct pci_ops sun4v_pci_ops = {
    314	.read =		sun4v_read_pci_cfg,
    315	.write =	sun4v_write_pci_cfg,
    316};
    317
    318void pci_get_pbm_props(struct pci_pbm_info *pbm)
    319{
    320	const u32 *val = of_get_property(pbm->op->dev.of_node, "bus-range", NULL);
    321
    322	pbm->pci_first_busno = val[0];
    323	pbm->pci_last_busno = val[1];
    324
    325	val = of_get_property(pbm->op->dev.of_node, "ino-bitmap", NULL);
    326	if (val) {
    327		pbm->ino_bitmap = (((u64)val[1] << 32UL) |
    328				   ((u64)val[0] <<  0UL));
    329	}
    330}
    331
    332static void pci_register_iommu_region(struct pci_pbm_info *pbm)
    333{
    334	const u32 *vdma = of_get_property(pbm->op->dev.of_node, "virtual-dma",
    335					  NULL);
    336
    337	if (vdma) {
    338		struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
    339
    340		if (!rp) {
    341			pr_info("%s: Cannot allocate IOMMU resource.\n",
    342				pbm->name);
    343			return;
    344		}
    345		rp->name = "IOMMU";
    346		rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
    347		rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
    348		rp->flags = IORESOURCE_BUSY;
    349		if (request_resource(&pbm->mem_space, rp)) {
    350			pr_info("%s: Unable to request IOMMU resource.\n",
    351				pbm->name);
    352			kfree(rp);
    353		}
    354	}
    355}
    356
    357void pci_determine_mem_io_space(struct pci_pbm_info *pbm)
    358{
    359	const struct linux_prom_pci_ranges *pbm_ranges;
    360	int i, saw_mem, saw_io;
    361	int num_pbm_ranges;
    362
    363	/* Corresponding generic code in of_pci_get_host_bridge_resources() */
    364
    365	saw_mem = saw_io = 0;
    366	pbm_ranges = of_get_property(pbm->op->dev.of_node, "ranges", &i);
    367	if (!pbm_ranges) {
    368		prom_printf("PCI: Fatal error, missing PBM ranges property "
    369			    " for %s\n",
    370			    pbm->name);
    371		prom_halt();
    372	}
    373
    374	num_pbm_ranges = i / sizeof(*pbm_ranges);
    375	memset(&pbm->mem64_space, 0, sizeof(struct resource));
    376
    377	for (i = 0; i < num_pbm_ranges; i++) {
    378		const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
    379		unsigned long a, size, region_a;
    380		u32 parent_phys_hi, parent_phys_lo;
    381		u32 child_phys_mid, child_phys_lo;
    382		u32 size_hi, size_lo;
    383		int type;
    384
    385		parent_phys_hi = pr->parent_phys_hi;
    386		parent_phys_lo = pr->parent_phys_lo;
    387		child_phys_mid = pr->child_phys_mid;
    388		child_phys_lo = pr->child_phys_lo;
    389		if (tlb_type == hypervisor)
    390			parent_phys_hi &= 0x0fffffff;
    391
    392		size_hi = pr->size_hi;
    393		size_lo = pr->size_lo;
    394
    395		type = (pr->child_phys_hi >> 24) & 0x3;
    396		a = (((unsigned long)parent_phys_hi << 32UL) |
    397		     ((unsigned long)parent_phys_lo  <<  0UL));
    398		region_a = (((unsigned long)child_phys_mid << 32UL) |
    399		     ((unsigned long)child_phys_lo  <<  0UL));
    400		size = (((unsigned long)size_hi << 32UL) |
    401			((unsigned long)size_lo  <<  0UL));
    402
    403		switch (type) {
    404		case 0:
    405			/* PCI config space, 16MB */
    406			pbm->config_space = a;
    407			break;
    408
    409		case 1:
    410			/* 16-bit IO space, 16MB */
    411			pbm->io_space.start = a;
    412			pbm->io_space.end = a + size - 1UL;
    413			pbm->io_space.flags = IORESOURCE_IO;
    414			pbm->io_offset = a - region_a;
    415			saw_io = 1;
    416			break;
    417
    418		case 2:
    419			/* 32-bit MEM space, 2GB */
    420			pbm->mem_space.start = a;
    421			pbm->mem_space.end = a + size - 1UL;
    422			pbm->mem_space.flags = IORESOURCE_MEM;
    423			pbm->mem_offset = a - region_a;
    424			saw_mem = 1;
    425			break;
    426
    427		case 3:
    428			/* 64-bit MEM handling */
    429			pbm->mem64_space.start = a;
    430			pbm->mem64_space.end = a + size - 1UL;
    431			pbm->mem64_space.flags = IORESOURCE_MEM;
    432			pbm->mem64_offset = a - region_a;
    433			saw_mem = 1;
    434			break;
    435
    436		default:
    437			break;
    438		}
    439	}
    440
    441	if (!saw_io || !saw_mem) {
    442		prom_printf("%s: Fatal error, missing %s PBM range.\n",
    443			    pbm->name,
    444			    (!saw_io ? "IO" : "MEM"));
    445		prom_halt();
    446	}
    447
    448	if (pbm->io_space.flags)
    449		printk("%s: PCI IO %pR offset %llx\n",
    450		       pbm->name, &pbm->io_space, pbm->io_offset);
    451	if (pbm->mem_space.flags)
    452		printk("%s: PCI MEM %pR offset %llx\n",
    453		       pbm->name, &pbm->mem_space, pbm->mem_offset);
    454	if (pbm->mem64_space.flags && pbm->mem_space.flags) {
    455		if (pbm->mem64_space.start <= pbm->mem_space.end)
    456			pbm->mem64_space.start = pbm->mem_space.end + 1;
    457		if (pbm->mem64_space.start > pbm->mem64_space.end)
    458			pbm->mem64_space.flags = 0;
    459	}
    460
    461	if (pbm->mem64_space.flags)
    462		printk("%s: PCI MEM64 %pR offset %llx\n",
    463		       pbm->name, &pbm->mem64_space, pbm->mem64_offset);
    464
    465	pbm->io_space.name = pbm->mem_space.name = pbm->name;
    466	pbm->mem64_space.name = pbm->name;
    467
    468	request_resource(&ioport_resource, &pbm->io_space);
    469	request_resource(&iomem_resource, &pbm->mem_space);
    470	if (pbm->mem64_space.flags)
    471		request_resource(&iomem_resource, &pbm->mem64_space);
    472
    473	pci_register_iommu_region(pbm);
    474}
    475
    476/* Generic helper routines for PCI error reporting. */
    477void pci_scan_for_target_abort(struct pci_pbm_info *pbm,
    478			       struct pci_bus *pbus)
    479{
    480	struct pci_dev *pdev;
    481	struct pci_bus *bus;
    482
    483	list_for_each_entry(pdev, &pbus->devices, bus_list) {
    484		u16 status, error_bits;
    485
    486		pci_read_config_word(pdev, PCI_STATUS, &status);
    487		error_bits =
    488			(status & (PCI_STATUS_SIG_TARGET_ABORT |
    489				   PCI_STATUS_REC_TARGET_ABORT));
    490		if (error_bits) {
    491			pci_write_config_word(pdev, PCI_STATUS, error_bits);
    492			pci_info(pdev, "%s: Device saw Target Abort [%016x]\n",
    493				 pbm->name, status);
    494		}
    495	}
    496
    497	list_for_each_entry(bus, &pbus->children, node)
    498		pci_scan_for_target_abort(pbm, bus);
    499}
    500
    501void pci_scan_for_master_abort(struct pci_pbm_info *pbm,
    502			       struct pci_bus *pbus)
    503{
    504	struct pci_dev *pdev;
    505	struct pci_bus *bus;
    506
    507	list_for_each_entry(pdev, &pbus->devices, bus_list) {
    508		u16 status, error_bits;
    509
    510		pci_read_config_word(pdev, PCI_STATUS, &status);
    511		error_bits =
    512			(status & (PCI_STATUS_REC_MASTER_ABORT));
    513		if (error_bits) {
    514			pci_write_config_word(pdev, PCI_STATUS, error_bits);
    515			pci_info(pdev, "%s: Device received Master Abort "
    516				 "[%016x]\n", pbm->name, status);
    517		}
    518	}
    519
    520	list_for_each_entry(bus, &pbus->children, node)
    521		pci_scan_for_master_abort(pbm, bus);
    522}
    523
    524void pci_scan_for_parity_error(struct pci_pbm_info *pbm,
    525			       struct pci_bus *pbus)
    526{
    527	struct pci_dev *pdev;
    528	struct pci_bus *bus;
    529
    530	list_for_each_entry(pdev, &pbus->devices, bus_list) {
    531		u16 status, error_bits;
    532
    533		pci_read_config_word(pdev, PCI_STATUS, &status);
    534		error_bits =
    535			(status & (PCI_STATUS_PARITY |
    536				   PCI_STATUS_DETECTED_PARITY));
    537		if (error_bits) {
    538			pci_write_config_word(pdev, PCI_STATUS, error_bits);
    539			pci_info(pdev, "%s: Device saw Parity Error [%016x]\n",
    540				 pbm->name, status);
    541		}
    542	}
    543
    544	list_for_each_entry(bus, &pbus->children, node)
    545		pci_scan_for_parity_error(pbm, bus);
    546}