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

ops-bcm63xx.c (12337B)


      1/*
      2 * This file is subject to the terms and conditions of the GNU General Public
      3 * License.  See the file "COPYING" in the main directory of this archive
      4 * for more details.
      5 *
      6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
      7 */
      8
      9#include <linux/types.h>
     10#include <linux/pci.h>
     11#include <linux/kernel.h>
     12#include <linux/delay.h>
     13#include <linux/io.h>
     14
     15#include "pci-bcm63xx.h"
     16
     17/*
     18 * swizzle 32bits data to return only the needed part
     19 */
     20static int postprocess_read(u32 data, int where, unsigned int size)
     21{
     22	u32 ret;
     23
     24	ret = 0;
     25	switch (size) {
     26	case 1:
     27		ret = (data >> ((where & 3) << 3)) & 0xff;
     28		break;
     29	case 2:
     30		ret = (data >> ((where & 3) << 3)) & 0xffff;
     31		break;
     32	case 4:
     33		ret = data;
     34		break;
     35	}
     36	return ret;
     37}
     38
     39static int preprocess_write(u32 orig_data, u32 val, int where,
     40			    unsigned int size)
     41{
     42	u32 ret;
     43
     44	ret = 0;
     45	switch (size) {
     46	case 1:
     47		ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
     48			(val << ((where & 3) << 3));
     49		break;
     50	case 2:
     51		ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
     52			(val << ((where & 3) << 3));
     53		break;
     54	case 4:
     55		ret = val;
     56		break;
     57	}
     58	return ret;
     59}
     60
     61/*
     62 * setup hardware for a configuration cycle with given parameters
     63 */
     64static int bcm63xx_setup_cfg_access(int type, unsigned int busn,
     65				    unsigned int devfn, int where)
     66{
     67	unsigned int slot, func, reg;
     68	u32 val;
     69
     70	slot = PCI_SLOT(devfn);
     71	func = PCI_FUNC(devfn);
     72	reg = where >> 2;
     73
     74	/* sanity check */
     75	if (slot > (MPI_L2PCFG_DEVNUM_MASK >> MPI_L2PCFG_DEVNUM_SHIFT))
     76		return 1;
     77
     78	if (func > (MPI_L2PCFG_FUNC_MASK >> MPI_L2PCFG_FUNC_SHIFT))
     79		return 1;
     80
     81	if (reg > (MPI_L2PCFG_REG_MASK >> MPI_L2PCFG_REG_SHIFT))
     82		return 1;
     83
     84	/* ok, setup config access */
     85	val = (reg << MPI_L2PCFG_REG_SHIFT);
     86	val |= (func << MPI_L2PCFG_FUNC_SHIFT);
     87	val |= (slot << MPI_L2PCFG_DEVNUM_SHIFT);
     88	val |= MPI_L2PCFG_CFG_USEREG_MASK;
     89	val |= MPI_L2PCFG_CFG_SEL_MASK;
     90	/* type 0 cycle for local bus, type 1 cycle for anything else */
     91	if (type != 0) {
     92		/* FIXME: how to specify bus ??? */
     93		val |= (1 << MPI_L2PCFG_CFG_TYPE_SHIFT);
     94	}
     95	bcm_mpi_writel(val, MPI_L2PCFG_REG);
     96
     97	return 0;
     98}
     99
    100static int bcm63xx_do_cfg_read(int type, unsigned int busn,
    101				unsigned int devfn, int where, int size,
    102				u32 *val)
    103{
    104	u32 data;
    105
    106	/* two phase cycle, first we write address, then read data at
    107	 * another location, caller already has a spinlock so no need
    108	 * to add one here  */
    109	if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
    110		return PCIBIOS_DEVICE_NOT_FOUND;
    111	iob();
    112	data = le32_to_cpu(__raw_readl(pci_iospace_start));
    113	/* restore IO space normal behaviour */
    114	bcm_mpi_writel(0, MPI_L2PCFG_REG);
    115
    116	*val = postprocess_read(data, where, size);
    117
    118	return PCIBIOS_SUCCESSFUL;
    119}
    120
    121static int bcm63xx_do_cfg_write(int type, unsigned int busn,
    122				 unsigned int devfn, int where, int size,
    123				 u32 val)
    124{
    125	u32 data;
    126
    127	/* two phase cycle, first we write address, then write data to
    128	 * another location, caller already has a spinlock so no need
    129	 * to add one here  */
    130	if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
    131		return PCIBIOS_DEVICE_NOT_FOUND;
    132	iob();
    133
    134	data = le32_to_cpu(__raw_readl(pci_iospace_start));
    135	data = preprocess_write(data, val, where, size);
    136
    137	__raw_writel(cpu_to_le32(data), pci_iospace_start);
    138	wmb();
    139	/* no way to know the access is done, we have to wait */
    140	udelay(500);
    141	/* restore IO space normal behaviour */
    142	bcm_mpi_writel(0, MPI_L2PCFG_REG);
    143
    144	return PCIBIOS_SUCCESSFUL;
    145}
    146
    147static int bcm63xx_pci_read(struct pci_bus *bus, unsigned int devfn,
    148			     int where, int size, u32 *val)
    149{
    150	int type;
    151
    152	type = bus->parent ? 1 : 0;
    153
    154	if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
    155		return PCIBIOS_DEVICE_NOT_FOUND;
    156
    157	return bcm63xx_do_cfg_read(type, bus->number, devfn,
    158				    where, size, val);
    159}
    160
    161static int bcm63xx_pci_write(struct pci_bus *bus, unsigned int devfn,
    162			      int where, int size, u32 val)
    163{
    164	int type;
    165
    166	type = bus->parent ? 1 : 0;
    167
    168	if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
    169		return PCIBIOS_DEVICE_NOT_FOUND;
    170
    171	return bcm63xx_do_cfg_write(type, bus->number, devfn,
    172				     where, size, val);
    173}
    174
    175struct pci_ops bcm63xx_pci_ops = {
    176	.read	= bcm63xx_pci_read,
    177	.write	= bcm63xx_pci_write
    178};
    179
    180#ifdef CONFIG_CARDBUS
    181/*
    182 * emulate configuration read access on a cardbus bridge
    183 */
    184#define FAKE_CB_BRIDGE_SLOT	0x1e
    185
    186static int fake_cb_bridge_bus_number = -1;
    187
    188static struct {
    189	u16 pci_command;
    190	u8 cb_latency;
    191	u8 subordinate_busn;
    192	u8 cardbus_busn;
    193	u8 pci_busn;
    194	int bus_assigned;
    195	u16 bridge_control;
    196
    197	u32 mem_base0;
    198	u32 mem_limit0;
    199	u32 mem_base1;
    200	u32 mem_limit1;
    201
    202	u32 io_base0;
    203	u32 io_limit0;
    204	u32 io_base1;
    205	u32 io_limit1;
    206} fake_cb_bridge_regs;
    207
    208static int fake_cb_bridge_read(int where, int size, u32 *val)
    209{
    210	unsigned int reg;
    211	u32 data;
    212
    213	data = 0;
    214	reg = where >> 2;
    215	switch (reg) {
    216	case (PCI_VENDOR_ID >> 2):
    217	case (PCI_CB_SUBSYSTEM_VENDOR_ID >> 2):
    218		/* create dummy vendor/device id from our cpu id */
    219		data = (bcm63xx_get_cpu_id() << 16) | PCI_VENDOR_ID_BROADCOM;
    220		break;
    221
    222	case (PCI_COMMAND >> 2):
    223		data = (PCI_STATUS_DEVSEL_SLOW << 16);
    224		data |= fake_cb_bridge_regs.pci_command;
    225		break;
    226
    227	case (PCI_CLASS_REVISION >> 2):
    228		data = (PCI_CLASS_BRIDGE_CARDBUS << 16);
    229		break;
    230
    231	case (PCI_CACHE_LINE_SIZE >> 2):
    232		data = (PCI_HEADER_TYPE_CARDBUS << 16);
    233		break;
    234
    235	case (PCI_INTERRUPT_LINE >> 2):
    236		/* bridge control */
    237		data = (fake_cb_bridge_regs.bridge_control << 16);
    238		/* pin:intA line:0xff */
    239		data |= (0x1 << 8) | 0xff;
    240		break;
    241
    242	case (PCI_CB_PRIMARY_BUS >> 2):
    243		data = (fake_cb_bridge_regs.cb_latency << 24);
    244		data |= (fake_cb_bridge_regs.subordinate_busn << 16);
    245		data |= (fake_cb_bridge_regs.cardbus_busn << 8);
    246		data |= fake_cb_bridge_regs.pci_busn;
    247		break;
    248
    249	case (PCI_CB_MEMORY_BASE_0 >> 2):
    250		data = fake_cb_bridge_regs.mem_base0;
    251		break;
    252
    253	case (PCI_CB_MEMORY_LIMIT_0 >> 2):
    254		data = fake_cb_bridge_regs.mem_limit0;
    255		break;
    256
    257	case (PCI_CB_MEMORY_BASE_1 >> 2):
    258		data = fake_cb_bridge_regs.mem_base1;
    259		break;
    260
    261	case (PCI_CB_MEMORY_LIMIT_1 >> 2):
    262		data = fake_cb_bridge_regs.mem_limit1;
    263		break;
    264
    265	case (PCI_CB_IO_BASE_0 >> 2):
    266		/* | 1 for 32bits io support */
    267		data = fake_cb_bridge_regs.io_base0 | 0x1;
    268		break;
    269
    270	case (PCI_CB_IO_LIMIT_0 >> 2):
    271		data = fake_cb_bridge_regs.io_limit0;
    272		break;
    273
    274	case (PCI_CB_IO_BASE_1 >> 2):
    275		/* | 1 for 32bits io support */
    276		data = fake_cb_bridge_regs.io_base1 | 0x1;
    277		break;
    278
    279	case (PCI_CB_IO_LIMIT_1 >> 2):
    280		data = fake_cb_bridge_regs.io_limit1;
    281		break;
    282	}
    283
    284	*val = postprocess_read(data, where, size);
    285	return PCIBIOS_SUCCESSFUL;
    286}
    287
    288/*
    289 * emulate configuration write access on a cardbus bridge
    290 */
    291static int fake_cb_bridge_write(int where, int size, u32 val)
    292{
    293	unsigned int reg;
    294	u32 data, tmp;
    295	int ret;
    296
    297	ret = fake_cb_bridge_read((where & ~0x3), 4, &data);
    298	if (ret != PCIBIOS_SUCCESSFUL)
    299		return ret;
    300
    301	data = preprocess_write(data, val, where, size);
    302
    303	reg = where >> 2;
    304	switch (reg) {
    305	case (PCI_COMMAND >> 2):
    306		fake_cb_bridge_regs.pci_command = (data & 0xffff);
    307		break;
    308
    309	case (PCI_CB_PRIMARY_BUS >> 2):
    310		fake_cb_bridge_regs.cb_latency = (data >> 24) & 0xff;
    311		fake_cb_bridge_regs.subordinate_busn = (data >> 16) & 0xff;
    312		fake_cb_bridge_regs.cardbus_busn = (data >> 8) & 0xff;
    313		fake_cb_bridge_regs.pci_busn = data & 0xff;
    314		if (fake_cb_bridge_regs.cardbus_busn)
    315			fake_cb_bridge_regs.bus_assigned = 1;
    316		break;
    317
    318	case (PCI_INTERRUPT_LINE >> 2):
    319		tmp = (data >> 16) & 0xffff;
    320		/* disable memory prefetch support */
    321		tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
    322		tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1;
    323		fake_cb_bridge_regs.bridge_control = tmp;
    324		break;
    325
    326	case (PCI_CB_MEMORY_BASE_0 >> 2):
    327		fake_cb_bridge_regs.mem_base0 = data;
    328		break;
    329
    330	case (PCI_CB_MEMORY_LIMIT_0 >> 2):
    331		fake_cb_bridge_regs.mem_limit0 = data;
    332		break;
    333
    334	case (PCI_CB_MEMORY_BASE_1 >> 2):
    335		fake_cb_bridge_regs.mem_base1 = data;
    336		break;
    337
    338	case (PCI_CB_MEMORY_LIMIT_1 >> 2):
    339		fake_cb_bridge_regs.mem_limit1 = data;
    340		break;
    341
    342	case (PCI_CB_IO_BASE_0 >> 2):
    343		fake_cb_bridge_regs.io_base0 = data;
    344		break;
    345
    346	case (PCI_CB_IO_LIMIT_0 >> 2):
    347		fake_cb_bridge_regs.io_limit0 = data;
    348		break;
    349
    350	case (PCI_CB_IO_BASE_1 >> 2):
    351		fake_cb_bridge_regs.io_base1 = data;
    352		break;
    353
    354	case (PCI_CB_IO_LIMIT_1 >> 2):
    355		fake_cb_bridge_regs.io_limit1 = data;
    356		break;
    357	}
    358
    359	return PCIBIOS_SUCCESSFUL;
    360}
    361
    362static int bcm63xx_cb_read(struct pci_bus *bus, unsigned int devfn,
    363			   int where, int size, u32 *val)
    364{
    365	/* snoop access to slot 0x1e on root bus, we fake a cardbus
    366	 * bridge at this location */
    367	if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
    368		fake_cb_bridge_bus_number = bus->number;
    369		return fake_cb_bridge_read(where, size, val);
    370	}
    371
    372	/* a  configuration  cycle for	the  device  behind the	 cardbus
    373	 * bridge is  actually done as a  type 0 cycle	on the primary
    374	 * bus. This means that only  one device can be on the cardbus
    375	 * bus */
    376	if (fake_cb_bridge_regs.bus_assigned &&
    377	    bus->number == fake_cb_bridge_regs.cardbus_busn &&
    378	    PCI_SLOT(devfn) == 0)
    379		return bcm63xx_do_cfg_read(0, 0,
    380					   PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
    381					   where, size, val);
    382
    383	return PCIBIOS_DEVICE_NOT_FOUND;
    384}
    385
    386static int bcm63xx_cb_write(struct pci_bus *bus, unsigned int devfn,
    387			    int where, int size, u32 val)
    388{
    389	if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
    390		fake_cb_bridge_bus_number = bus->number;
    391		return fake_cb_bridge_write(where, size, val);
    392	}
    393
    394	if (fake_cb_bridge_regs.bus_assigned &&
    395	    bus->number == fake_cb_bridge_regs.cardbus_busn &&
    396	    PCI_SLOT(devfn) == 0)
    397		return bcm63xx_do_cfg_write(0, 0,
    398					    PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
    399					    where, size, val);
    400
    401	return PCIBIOS_DEVICE_NOT_FOUND;
    402}
    403
    404struct pci_ops bcm63xx_cb_ops = {
    405	.read	= bcm63xx_cb_read,
    406	.write	 = bcm63xx_cb_write,
    407};
    408
    409/*
    410 * only one IO window, so it  cannot be shared by PCI and cardbus, use
    411 * fixup to choose and detect unhandled configuration
    412 */
    413static void bcm63xx_fixup(struct pci_dev *dev)
    414{
    415	static int io_window = -1;
    416	int i, found, new_io_window;
    417	u32 val;
    418
    419	/* look for any io resource */
    420	found = 0;
    421	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
    422		if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
    423			found = 1;
    424			break;
    425		}
    426	}
    427
    428	if (!found)
    429		return;
    430
    431	/* skip our fake bus with only cardbus bridge on it */
    432	if (dev->bus->number == fake_cb_bridge_bus_number)
    433		return;
    434
    435	/* find on which bus the device is */
    436	if (fake_cb_bridge_regs.bus_assigned &&
    437	    dev->bus->number == fake_cb_bridge_regs.cardbus_busn &&
    438	    PCI_SLOT(dev->devfn) == 0)
    439		new_io_window = 1;
    440	else
    441		new_io_window = 0;
    442
    443	if (new_io_window == io_window)
    444		return;
    445
    446	if (io_window != -1) {
    447		printk(KERN_ERR "bcm63xx: both PCI and cardbus devices "
    448		       "need IO, which hardware cannot do\n");
    449		return;
    450	}
    451
    452	printk(KERN_INFO "bcm63xx: PCI IO window assigned to %s\n",
    453	       (new_io_window == 0) ? "PCI" : "cardbus");
    454
    455	val = bcm_mpi_readl(MPI_L2PIOREMAP_REG);
    456	if (io_window)
    457		val |= MPI_L2PREMAP_IS_CARDBUS_MASK;
    458	else
    459		val &= ~MPI_L2PREMAP_IS_CARDBUS_MASK;
    460	bcm_mpi_writel(val, MPI_L2PIOREMAP_REG);
    461
    462	io_window = new_io_window;
    463}
    464
    465DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup);
    466#endif
    467
    468static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn)
    469{
    470	switch (bus->number) {
    471	case PCIE_BUS_BRIDGE:
    472		return PCI_SLOT(devfn) == 0;
    473	case PCIE_BUS_DEVICE:
    474		if (PCI_SLOT(devfn) == 0)
    475			return bcm_pcie_readl(PCIE_DLSTATUS_REG)
    476					& DLSTATUS_PHYLINKUP;
    477		fallthrough;
    478	default:
    479		return false;
    480	}
    481}
    482
    483static int bcm63xx_pcie_read(struct pci_bus *bus, unsigned int devfn,
    484			     int where, int size, u32 *val)
    485{
    486	u32 data;
    487	u32 reg = where & ~3;
    488
    489	if (!bcm63xx_pcie_can_access(bus, devfn))
    490		return PCIBIOS_DEVICE_NOT_FOUND;
    491
    492	if (bus->number == PCIE_BUS_DEVICE)
    493		reg += PCIE_DEVICE_OFFSET;
    494
    495	data = bcm_pcie_readl(reg);
    496
    497	*val = postprocess_read(data, where, size);
    498
    499	return PCIBIOS_SUCCESSFUL;
    500
    501}
    502
    503static int bcm63xx_pcie_write(struct pci_bus *bus, unsigned int devfn,
    504			      int where, int size, u32 val)
    505{
    506	u32 data;
    507	u32 reg = where & ~3;
    508
    509	if (!bcm63xx_pcie_can_access(bus, devfn))
    510		return PCIBIOS_DEVICE_NOT_FOUND;
    511
    512	if (bus->number == PCIE_BUS_DEVICE)
    513		reg += PCIE_DEVICE_OFFSET;
    514
    515
    516	data = bcm_pcie_readl(reg);
    517
    518	data = preprocess_write(data, val, where, size);
    519	bcm_pcie_writel(data, reg);
    520
    521	return PCIBIOS_SUCCESSFUL;
    522}
    523
    524
    525struct pci_ops bcm63xx_pcie_ops = {
    526	.read	= bcm63xx_pcie_read,
    527	.write	= bcm63xx_pcie_write
    528};