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

isa-bridge.c (9727B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Routines for tracking a legacy ISA bridge
      4 *
      5 * Copyrigh 2007 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
      6 *
      7 * Some bits and pieces moved over from pci_64.c
      8 *
      9 * Copyrigh 2003 Anton Blanchard <anton@au.ibm.com>, IBM Corp.
     10 */
     11
     12#define DEBUG
     13
     14#include <linux/kernel.h>
     15#include <linux/pci.h>
     16#include <linux/string.h>
     17#include <linux/export.h>
     18#include <linux/init.h>
     19#include <linux/mm.h>
     20#include <linux/notifier.h>
     21#include <linux/of_address.h>
     22#include <linux/vmalloc.h>
     23
     24#include <asm/processor.h>
     25#include <asm/io.h>
     26#include <asm/pci-bridge.h>
     27#include <asm/machdep.h>
     28#include <asm/ppc-pci.h>
     29#include <asm/isa-bridge.h>
     30
     31unsigned long isa_io_base;	/* NULL if no ISA bus */
     32EXPORT_SYMBOL(isa_io_base);
     33
     34/* Cached ISA bridge dev. */
     35static struct device_node *isa_bridge_devnode;
     36struct pci_dev *isa_bridge_pcidev;
     37EXPORT_SYMBOL_GPL(isa_bridge_pcidev);
     38
     39#define ISA_SPACE_MASK 0x1
     40#define ISA_SPACE_IO 0x1
     41
     42static void remap_isa_base(phys_addr_t pa, unsigned long size)
     43{
     44	WARN_ON_ONCE(ISA_IO_BASE & ~PAGE_MASK);
     45	WARN_ON_ONCE(pa & ~PAGE_MASK);
     46	WARN_ON_ONCE(size & ~PAGE_MASK);
     47
     48	if (slab_is_available()) {
     49		if (ioremap_page_range(ISA_IO_BASE, ISA_IO_BASE + size, pa,
     50				pgprot_noncached(PAGE_KERNEL)))
     51			vunmap_range(ISA_IO_BASE, ISA_IO_BASE + size);
     52	} else {
     53		early_ioremap_range(ISA_IO_BASE, pa, size,
     54				pgprot_noncached(PAGE_KERNEL));
     55	}
     56}
     57
     58static void pci_process_ISA_OF_ranges(struct device_node *isa_node,
     59				      unsigned long phb_io_base_phys)
     60{
     61	/* We should get some saner parsing here and remove these structs */
     62	struct pci_address {
     63		u32 a_hi;
     64		u32 a_mid;
     65		u32 a_lo;
     66	};
     67
     68	struct isa_address {
     69		u32 a_hi;
     70		u32 a_lo;
     71	};
     72
     73	struct isa_range {
     74		struct isa_address isa_addr;
     75		struct pci_address pci_addr;
     76		unsigned int size;
     77	};
     78
     79	const struct isa_range *range;
     80	unsigned long pci_addr;
     81	unsigned int isa_addr;
     82	unsigned int size;
     83	int rlen = 0;
     84
     85	range = of_get_property(isa_node, "ranges", &rlen);
     86	if (range == NULL || (rlen < sizeof(struct isa_range)))
     87		goto inval_range;
     88
     89	/* From "ISA Binding to 1275"
     90	 * The ranges property is laid out as an array of elements,
     91	 * each of which comprises:
     92	 *   cells 0 - 1:	an ISA address
     93	 *   cells 2 - 4:	a PCI address
     94	 *			(size depending on dev->n_addr_cells)
     95	 *   cell 5:		the size of the range
     96	 */
     97	if ((range->isa_addr.a_hi & ISA_SPACE_MASK) != ISA_SPACE_IO) {
     98		range++;
     99		rlen -= sizeof(struct isa_range);
    100		if (rlen < sizeof(struct isa_range))
    101			goto inval_range;
    102	}
    103	if ((range->isa_addr.a_hi & ISA_SPACE_MASK) != ISA_SPACE_IO)
    104		goto inval_range;
    105
    106	isa_addr = range->isa_addr.a_lo;
    107	pci_addr = (unsigned long) range->pci_addr.a_mid << 32 |
    108		range->pci_addr.a_lo;
    109
    110	/* Assume these are both zero. Note: We could fix that and
    111	 * do a proper parsing instead ... oh well, that will do for
    112	 * now as nobody uses fancy mappings for ISA bridges
    113	 */
    114	if ((pci_addr != 0) || (isa_addr != 0)) {
    115		printk(KERN_ERR "unexpected isa to pci mapping: %s\n",
    116		       __func__);
    117		return;
    118	}
    119
    120	/* Align size and make sure it's cropped to 64K */
    121	size = PAGE_ALIGN(range->size);
    122	if (size > 0x10000)
    123		size = 0x10000;
    124
    125	remap_isa_base(phb_io_base_phys, size);
    126	return;
    127
    128inval_range:
    129	printk(KERN_ERR "no ISA IO ranges or unexpected isa range, "
    130	       "mapping 64k\n");
    131	remap_isa_base(phb_io_base_phys, 0x10000);
    132}
    133
    134
    135/**
    136 * isa_bridge_find_early - Find and map the ISA IO space early before
    137 *                         main PCI discovery. This is optionally called by
    138 *                         the arch code when adding PCI PHBs to get early
    139 *                         access to ISA IO ports
    140 */
    141void __init isa_bridge_find_early(struct pci_controller *hose)
    142{
    143	struct device_node *np, *parent = NULL, *tmp;
    144
    145	/* If we already have an ISA bridge, bail off */
    146	if (isa_bridge_devnode != NULL)
    147		return;
    148
    149	/* For each "isa" node in the system. Note : we do a search by
    150	 * type and not by name. It might be better to do by name but that's
    151	 * what the code used to do and I don't want to break too much at
    152	 * once. We can look into changing that separately
    153	 */
    154	for_each_node_by_type(np, "isa") {
    155		/* Look for our hose being a parent */
    156		for (parent = of_get_parent(np); parent;) {
    157			if (parent == hose->dn) {
    158				of_node_put(parent);
    159				break;
    160			}
    161			tmp = parent;
    162			parent = of_get_parent(parent);
    163			of_node_put(tmp);
    164		}
    165		if (parent != NULL)
    166			break;
    167	}
    168	if (np == NULL)
    169		return;
    170	isa_bridge_devnode = np;
    171
    172	/* Now parse the "ranges" property and setup the ISA mapping */
    173	pci_process_ISA_OF_ranges(np, hose->io_base_phys);
    174
    175	/* Set the global ISA io base to indicate we have an ISA bridge */
    176	isa_io_base = ISA_IO_BASE;
    177
    178	pr_debug("ISA bridge (early) is %pOF\n", np);
    179}
    180
    181/**
    182 * isa_bridge_find_early - Find and map the ISA IO space early before
    183 *                         main PCI discovery. This is optionally called by
    184 *                         the arch code when adding PCI PHBs to get early
    185 *                         access to ISA IO ports
    186 */
    187void __init isa_bridge_init_non_pci(struct device_node *np)
    188{
    189	const __be32 *ranges, *pbasep = NULL;
    190	int rlen, i, rs;
    191	u32 na, ns, pna;
    192	u64 cbase, pbase, size = 0;
    193
    194	/* If we already have an ISA bridge, bail off */
    195	if (isa_bridge_devnode != NULL)
    196		return;
    197
    198	pna = of_n_addr_cells(np);
    199	if (of_property_read_u32(np, "#address-cells", &na) ||
    200	    of_property_read_u32(np, "#size-cells", &ns)) {
    201		pr_warn("ISA: Non-PCI bridge %pOF is missing address format\n",
    202			np);
    203		return;
    204	}
    205
    206	/* Check it's a supported address format */
    207	if (na != 2 || ns != 1) {
    208		pr_warn("ISA: Non-PCI bridge %pOF has unsupported address format\n",
    209			np);
    210		return;
    211	}
    212	rs = na + ns + pna;
    213
    214	/* Grab the ranges property */
    215	ranges = of_get_property(np, "ranges", &rlen);
    216	if (ranges == NULL || rlen < rs) {
    217		pr_warn("ISA: Non-PCI bridge %pOF has absent or invalid ranges\n",
    218			np);
    219		return;
    220	}
    221
    222	/* Parse it. We are only looking for IO space */
    223	for (i = 0; (i + rs - 1) < rlen; i += rs) {
    224		if (be32_to_cpup(ranges + i) != 1)
    225			continue;
    226		cbase = be32_to_cpup(ranges + i + 1);
    227		size = of_read_number(ranges + i + na + pna, ns);
    228		pbasep = ranges + i + na;
    229		break;
    230	}
    231
    232	/* Got something ? */
    233	if (!size || !pbasep) {
    234		pr_warn("ISA: Non-PCI bridge %pOF has no usable IO range\n",
    235			np);
    236		return;
    237	}
    238
    239	/* Align size and make sure it's cropped to 64K */
    240	size = PAGE_ALIGN(size);
    241	if (size > 0x10000)
    242		size = 0x10000;
    243
    244	/* Map pbase */
    245	pbase = of_translate_address(np, pbasep);
    246	if (pbase == OF_BAD_ADDR) {
    247		pr_warn("ISA: Non-PCI bridge %pOF failed to translate IO base\n",
    248			np);
    249		return;
    250	}
    251
    252	/* We need page alignment */
    253	if ((cbase & ~PAGE_MASK) || (pbase & ~PAGE_MASK)) {
    254		pr_warn("ISA: Non-PCI bridge %pOF has non aligned IO range\n",
    255			np);
    256		return;
    257	}
    258
    259	/* Got it */
    260	isa_bridge_devnode = np;
    261
    262	/* Set the global ISA io base to indicate we have an ISA bridge
    263	 * and map it
    264	 */
    265	isa_io_base = ISA_IO_BASE;
    266	remap_isa_base(pbase, size);
    267
    268	pr_debug("ISA: Non-PCI bridge is %pOF\n", np);
    269}
    270
    271/**
    272 * isa_bridge_find_late - Find and map the ISA IO space upon discovery of
    273 *                        a new ISA bridge
    274 */
    275static void isa_bridge_find_late(struct pci_dev *pdev,
    276				 struct device_node *devnode)
    277{
    278	struct pci_controller *hose = pci_bus_to_host(pdev->bus);
    279
    280	/* Store ISA device node and PCI device */
    281	isa_bridge_devnode = of_node_get(devnode);
    282	isa_bridge_pcidev = pdev;
    283
    284	/* Now parse the "ranges" property and setup the ISA mapping */
    285	pci_process_ISA_OF_ranges(devnode, hose->io_base_phys);
    286
    287	/* Set the global ISA io base to indicate we have an ISA bridge */
    288	isa_io_base = ISA_IO_BASE;
    289
    290	pr_debug("ISA bridge (late) is %pOF on %s\n",
    291		 devnode, pci_name(pdev));
    292}
    293
    294/**
    295 * isa_bridge_remove - Remove/unmap an ISA bridge
    296 */
    297static void isa_bridge_remove(void)
    298{
    299	pr_debug("ISA bridge removed !\n");
    300
    301	/* Clear the global ISA io base to indicate that we have no more
    302	 * ISA bridge. Note that drivers don't quite handle that, though
    303	 * we should probably do something about it. But do we ever really
    304	 * have ISA bridges being removed on machines using legacy devices ?
    305	 */
    306	isa_io_base = ISA_IO_BASE;
    307
    308	/* Clear references to the bridge */
    309	of_node_put(isa_bridge_devnode);
    310	isa_bridge_devnode = NULL;
    311	isa_bridge_pcidev = NULL;
    312
    313	/* Unmap the ISA area */
    314	vunmap_range(ISA_IO_BASE, ISA_IO_BASE + 0x10000);
    315}
    316
    317/**
    318 * isa_bridge_notify - Get notified of PCI devices addition/removal
    319 */
    320static int isa_bridge_notify(struct notifier_block *nb, unsigned long action,
    321			     void *data)
    322{
    323	struct device *dev = data;
    324	struct pci_dev *pdev = to_pci_dev(dev);
    325	struct device_node *devnode = pci_device_to_OF_node(pdev);
    326
    327	switch(action) {
    328	case BUS_NOTIFY_ADD_DEVICE:
    329		/* Check if we have an early ISA device, without PCI dev */
    330		if (isa_bridge_devnode && isa_bridge_devnode == devnode &&
    331		    !isa_bridge_pcidev) {
    332			pr_debug("ISA bridge PCI attached: %s\n",
    333				 pci_name(pdev));
    334			isa_bridge_pcidev = pdev;
    335		}
    336
    337		/* Check if we have no ISA device, and this happens to be one,
    338		 * register it as such if it has an OF device
    339		 */
    340		if (!isa_bridge_devnode && of_node_is_type(devnode, "isa"))
    341			isa_bridge_find_late(pdev, devnode);
    342
    343		return 0;
    344	case BUS_NOTIFY_DEL_DEVICE:
    345		/* Check if this our existing ISA device */
    346		if (pdev == isa_bridge_pcidev ||
    347		    (devnode && devnode == isa_bridge_devnode))
    348			isa_bridge_remove();
    349		return 0;
    350	}
    351	return 0;
    352}
    353
    354static struct notifier_block isa_bridge_notifier = {
    355	.notifier_call = isa_bridge_notify
    356};
    357
    358/**
    359 * isa_bridge_init - register to be notified of ISA bridge addition/removal
    360 *
    361 */
    362static int __init isa_bridge_init(void)
    363{
    364	bus_register_notifier(&pci_bus_type, &isa_bridge_notifier);
    365	return 0;
    366}
    367arch_initcall(isa_bridge_init);