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


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (C) 2001,2002,2003 Broadcom Corporation
      4 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
      5 */
      6
      7/*
      8 * BCM1250-specific PCI support
      9 *
     10 * This module provides the glue between Linux's PCI subsystem
     11 * and the hardware.  We basically provide glue for accessing
     12 * configuration space, and set up the translation for I/O
     13 * space accesses.
     14 *
     15 * To access configuration space, we use ioremap.  In the 32-bit
     16 * kernel, this consumes either 4 or 8 page table pages, and 16MB of
     17 * kernel mapped memory.  Hopefully neither of these should be a huge
     18 * problem.
     19 */
     20#include <linux/types.h>
     21#include <linux/pci.h>
     22#include <linux/kernel.h>
     23#include <linux/init.h>
     24#include <linux/mm.h>
     25#include <linux/console.h>
     26#include <linux/tty.h>
     27#include <linux/vt.h>
     28
     29#include <asm/io.h>
     30
     31#include <asm/sibyte/sb1250_defs.h>
     32#include <asm/sibyte/sb1250_regs.h>
     33#include <asm/sibyte/sb1250_scd.h>
     34#include <asm/sibyte/board.h>
     35
     36/*
     37 * Macros for calculating offsets into config space given a device
     38 * structure or dev/fun/reg
     39 */
     40#define CFGOFFSET(bus, devfn, where) (((bus)<<16) + ((devfn)<<8) + (where))
     41#define CFGADDR(bus, devfn, where)   CFGOFFSET((bus)->number, (devfn), where)
     42
     43static void *cfg_space;
     44
     45#define PCI_BUS_ENABLED 1
     46#define LDT_BUS_ENABLED 2
     47#define PCI_DEVICE_MODE 4
     48
     49static int sb1250_bus_status;
     50
     51#define PCI_BRIDGE_DEVICE  0
     52#define LDT_BRIDGE_DEVICE  1
     53
     54#ifdef CONFIG_SIBYTE_HAS_LDT
     55/*
     56 * HT's level-sensitive interrupts require EOI, which is generated
     57 * through a 4MB memory-mapped region
     58 */
     59unsigned long ldt_eoi_space;
     60#endif
     61
     62/*
     63 * Read/write 32-bit values in config space.
     64 */
     65static inline u32 READCFG32(u32 addr)
     66{
     67	return *(u32 *) (cfg_space + (addr & ~3));
     68}
     69
     70static inline void WRITECFG32(u32 addr, u32 data)
     71{
     72	*(u32 *) (cfg_space + (addr & ~3)) = data;
     73}
     74
     75int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
     76{
     77	return dev->irq;
     78}
     79
     80/* Do platform specific device initialization at pci_enable_device() time */
     81int pcibios_plat_dev_init(struct pci_dev *dev)
     82{
     83	return 0;
     84}
     85
     86/*
     87 * Some checks before doing config cycles:
     88 * In PCI Device Mode, hide everything on bus 0 except the LDT host
     89 * bridge.  Otherwise, access is controlled by bridge MasterEn bits.
     90 */
     91static int sb1250_pci_can_access(struct pci_bus *bus, int devfn)
     92{
     93	u32 devno;
     94
     95	if (!(sb1250_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE)))
     96		return 0;
     97
     98	if (bus->number == 0) {
     99		devno = PCI_SLOT(devfn);
    100		if (devno == LDT_BRIDGE_DEVICE)
    101			return (sb1250_bus_status & LDT_BUS_ENABLED) != 0;
    102		else if (sb1250_bus_status & PCI_DEVICE_MODE)
    103			return 0;
    104		else
    105			return 1;
    106	} else
    107		return 1;
    108}
    109
    110/*
    111 * Read/write access functions for various sizes of values
    112 * in config space.  Return all 1's for disallowed accesses
    113 * for a kludgy but adequate simulation of master aborts.
    114 */
    115
    116static int sb1250_pcibios_read(struct pci_bus *bus, unsigned int devfn,
    117			       int where, int size, u32 * val)
    118{
    119	u32 data = 0;
    120
    121	if ((size == 2) && (where & 1))
    122		return PCIBIOS_BAD_REGISTER_NUMBER;
    123	else if ((size == 4) && (where & 3))
    124		return PCIBIOS_BAD_REGISTER_NUMBER;
    125
    126	if (sb1250_pci_can_access(bus, devfn))
    127		data = READCFG32(CFGADDR(bus, devfn, where));
    128	else
    129		data = 0xFFFFFFFF;
    130
    131	if (size == 1)
    132		*val = (data >> ((where & 3) << 3)) & 0xff;
    133	else if (size == 2)
    134		*val = (data >> ((where & 3) << 3)) & 0xffff;
    135	else
    136		*val = data;
    137
    138	return PCIBIOS_SUCCESSFUL;
    139}
    140
    141static int sb1250_pcibios_write(struct pci_bus *bus, unsigned int devfn,
    142				int where, int size, u32 val)
    143{
    144	u32 cfgaddr = CFGADDR(bus, devfn, where);
    145	u32 data = 0;
    146
    147	if ((size == 2) && (where & 1))
    148		return PCIBIOS_BAD_REGISTER_NUMBER;
    149	else if ((size == 4) && (where & 3))
    150		return PCIBIOS_BAD_REGISTER_NUMBER;
    151
    152	if (!sb1250_pci_can_access(bus, devfn))
    153		return PCIBIOS_BAD_REGISTER_NUMBER;
    154
    155	data = READCFG32(cfgaddr);
    156
    157	if (size == 1)
    158		data = (data & ~(0xff << ((where & 3) << 3))) |
    159		    (val << ((where & 3) << 3));
    160	else if (size == 2)
    161		data = (data & ~(0xffff << ((where & 3) << 3))) |
    162		    (val << ((where & 3) << 3));
    163	else
    164		data = val;
    165
    166	WRITECFG32(cfgaddr, data);
    167
    168	return PCIBIOS_SUCCESSFUL;
    169}
    170
    171struct pci_ops sb1250_pci_ops = {
    172	.read	= sb1250_pcibios_read,
    173	.write	= sb1250_pcibios_write,
    174};
    175
    176static struct resource sb1250_mem_resource = {
    177	.name	= "SB1250 PCI MEM",
    178	.start	= 0x40000000UL,
    179	.end	= 0x5fffffffUL,
    180	.flags	= IORESOURCE_MEM,
    181};
    182
    183static struct resource sb1250_io_resource = {
    184	.name	= "SB1250 PCI I/O",
    185	.start	= 0x00000000UL,
    186	.end	= 0x01ffffffUL,
    187	.flags	= IORESOURCE_IO,
    188};
    189
    190struct pci_controller sb1250_controller = {
    191	.pci_ops	= &sb1250_pci_ops,
    192	.mem_resource	= &sb1250_mem_resource,
    193	.io_resource	= &sb1250_io_resource,
    194};
    195
    196static int __init sb1250_pcibios_init(void)
    197{
    198	void __iomem *io_map_base;
    199	uint32_t cmdreg;
    200	uint64_t reg;
    201
    202	/* CFE will assign PCI resources */
    203	pci_set_flags(PCI_PROBE_ONLY);
    204
    205	/* Avoid ISA compat ranges.  */
    206	PCIBIOS_MIN_IO = 0x00008000UL;
    207	PCIBIOS_MIN_MEM = 0x01000000UL;
    208
    209	/* Set I/O resource limits.  */
    210	ioport_resource.end = 0x01ffffffUL;	/* 32MB accessible by sb1250 */
    211	iomem_resource.end = 0xffffffffUL;	/* no HT support yet */
    212
    213	cfg_space =
    214	    ioremap(A_PHYS_LDTPCI_CFG_MATCH_BITS, 16 * 1024 * 1024);
    215
    216	/*
    217	 * See if the PCI bus has been configured by the firmware.
    218	 */
    219	reg = __raw_readq(IOADDR(A_SCD_SYSTEM_CFG));
    220	if (!(reg & M_SYS_PCI_HOST)) {
    221		sb1250_bus_status |= PCI_DEVICE_MODE;
    222	} else {
    223		cmdreg =
    224		    READCFG32(CFGOFFSET
    225			      (0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0),
    226			       PCI_COMMAND));
    227		if (!(cmdreg & PCI_COMMAND_MASTER)) {
    228			printk
    229			    ("PCI: Skipping PCI probe.	Bus is not initialized.\n");
    230			iounmap(cfg_space);
    231			return 0;
    232		}
    233		sb1250_bus_status |= PCI_BUS_ENABLED;
    234	}
    235
    236	/*
    237	 * Establish mappings in KSEG2 (kernel virtual) to PCI I/O
    238	 * space.  Use "match bytes" policy to make everything look
    239	 * little-endian.  So, you need to also set
    240	 * CONFIG_SWAP_IO_SPACE, but this is the combination that
    241	 * works correctly with most of Linux's drivers.
    242	 * XXX ehs: Should this happen in PCI Device mode?
    243	 */
    244	io_map_base = ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 1024 * 1024);
    245	sb1250_controller.io_map_base = (unsigned long)io_map_base;
    246	set_io_port_base((unsigned long)io_map_base);
    247
    248#ifdef CONFIG_SIBYTE_HAS_LDT
    249	/*
    250	 * Also check the LDT bridge's enable, just in case we didn't
    251	 * initialize that one.
    252	 */
    253
    254	cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(LDT_BRIDGE_DEVICE, 0),
    255				     PCI_COMMAND));
    256	if (cmdreg & PCI_COMMAND_MASTER) {
    257		sb1250_bus_status |= LDT_BUS_ENABLED;
    258
    259		/*
    260		 * Need bits 23:16 to convey vector number.  Note that
    261		 * this consumes 4MB of kernel-mapped memory
    262		 * (Kseg2/Kseg3) for 32-bit kernel.
    263		 */
    264		ldt_eoi_space = (unsigned long)
    265		    ioremap(A_PHYS_LDT_SPECIAL_MATCH_BYTES,
    266			    4 * 1024 * 1024);
    267	}
    268#endif
    269
    270	register_pci_controller(&sb1250_controller);
    271
    272#ifdef CONFIG_VGA_CONSOLE
    273	console_lock();
    274	do_take_over_console(&vga_con, 0, MAX_NR_CONSOLES - 1, 1);
    275	console_unlock();
    276#endif
    277	return 0;
    278}
    279arch_initcall(sb1250_pcibios_init);