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

leon_pci.c (2283B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * leon_pci.c: LEON Host PCI support
      4 *
      5 * Copyright (C) 2011 Aeroflex Gaisler AB, Daniel Hellstrom
      6 *
      7 * Code is partially derived from pcic.c
      8 */
      9
     10#include <linux/of_device.h>
     11#include <linux/kernel.h>
     12#include <linux/pci.h>
     13#include <linux/export.h>
     14#include <asm/leon.h>
     15#include <asm/leon_pci.h>
     16
     17/* The LEON architecture does not rely on a BIOS or bootloader to setup
     18 * PCI for us. The Linux generic routines are used to setup resources,
     19 * reset values of configuration-space register settings are preserved.
     20 *
     21 * PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is
     22 * accessed through a Window which is translated to low 64KB in PCI space, the
     23 * first 4KB is not used so 60KB is available.
     24 */
     25void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
     26{
     27	LIST_HEAD(resources);
     28	struct pci_bus *root_bus;
     29	struct pci_host_bridge *bridge;
     30	int ret;
     31
     32	bridge = pci_alloc_host_bridge(0);
     33	if (!bridge)
     34		return;
     35
     36	pci_add_resource_offset(&resources, &info->io_space,
     37				info->io_space.start - 0x1000);
     38	pci_add_resource(&resources, &info->mem_space);
     39	info->busn.flags = IORESOURCE_BUS;
     40	pci_add_resource(&resources, &info->busn);
     41
     42	list_splice_init(&resources, &bridge->windows);
     43	bridge->dev.parent = &ofdev->dev;
     44	bridge->sysdata = info;
     45	bridge->busnr = 0;
     46	bridge->ops = info->ops;
     47	bridge->swizzle_irq = pci_common_swizzle;
     48	bridge->map_irq = info->map_irq;
     49
     50	ret = pci_scan_root_bus_bridge(bridge);
     51	if (ret) {
     52		pci_free_host_bridge(bridge);
     53		return;
     54	}
     55
     56	root_bus = bridge->bus;
     57
     58	/* Assign devices with resources */
     59	pci_assign_unassigned_resources();
     60	pci_bus_add_devices(root_bus);
     61}
     62
     63int pcibios_enable_device(struct pci_dev *dev, int mask)
     64{
     65	u16 cmd, oldcmd;
     66	int i;
     67
     68	pci_read_config_word(dev, PCI_COMMAND, &cmd);
     69	oldcmd = cmd;
     70
     71	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
     72		struct resource *res = &dev->resource[i];
     73
     74		/* Only set up the requested stuff */
     75		if (!(mask & (1<<i)))
     76			continue;
     77
     78		if (res->flags & IORESOURCE_IO)
     79			cmd |= PCI_COMMAND_IO;
     80		if (res->flags & IORESOURCE_MEM)
     81			cmd |= PCI_COMMAND_MEMORY;
     82	}
     83
     84	if (cmd != oldcmd) {
     85		pci_info(dev, "enabling device (%04x -> %04x)\n", oldcmd, cmd);
     86		pci_write_config_word(dev, PCI_COMMAND, cmd);
     87	}
     88	return 0;
     89}