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-mace.c (2285B)


      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) 2000, 2001 Keith M Wesolowski
      7 */
      8#include <linux/kernel.h>
      9#include <linux/pci.h>
     10#include <linux/types.h>
     11#include <asm/ip32/mace.h>
     12
     13#if 0
     14# define DPRINTK(args...) printk(args);
     15#else
     16# define DPRINTK(args...)
     17#endif
     18
     19/*
     20 * O2 has up to 5 PCI devices connected into the MACE bridge.  The device
     21 * map looks like this:
     22 *
     23 * 0  aic7xxx 0
     24 * 1  aic7xxx 1
     25 * 2  expansion slot
     26 * 3  N/C
     27 * 4  N/C
     28 */
     29
     30static inline int mkaddr(struct pci_bus *bus, unsigned int devfn,
     31	unsigned int reg)
     32{
     33	return ((bus->number & 0xff) << 16) |
     34		((devfn & 0xff) << 8) |
     35		(reg & 0xfc);
     36}
     37
     38
     39static int
     40mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
     41		     int reg, int size, u32 *val)
     42{
     43	u32 control = mace->pci.control;
     44
     45	/* disable master aborts interrupts during config read */
     46	mace->pci.control = control & ~MACEPCI_CONTROL_MAR_INT;
     47	mace->pci.config_addr = mkaddr(bus, devfn, reg);
     48	switch (size) {
     49	case 1:
     50		*val = mace->pci.config_data.b[(reg & 3) ^ 3];
     51		break;
     52	case 2:
     53		*val = mace->pci.config_data.w[((reg >> 1) & 1) ^ 1];
     54		break;
     55	case 4:
     56		*val = mace->pci.config_data.l;
     57		break;
     58	}
     59	/* ack possible master abort */
     60	mace->pci.error &= ~MACEPCI_ERROR_MASTER_ABORT;
     61	mace->pci.control = control;
     62	/*
     63	 * someone forgot to set the ultra bit for the onboard
     64	 * scsi chips; we fake it here
     65	 */
     66	if (bus->number == 0 && reg == 0x40 && size == 4 &&
     67	    (devfn == (1 << 3) || devfn == (2 << 3)))
     68		*val |= 0x1000;
     69
     70	DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val);
     71
     72	return PCIBIOS_SUCCESSFUL;
     73}
     74
     75static int
     76mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
     77		      int reg, int size, u32 val)
     78{
     79	mace->pci.config_addr = mkaddr(bus, devfn, reg);
     80	switch (size) {
     81	case 1:
     82		mace->pci.config_data.b[(reg & 3) ^ 3] = val;
     83		break;
     84	case 2:
     85		mace->pci.config_data.w[((reg >> 1) & 1) ^ 1] = val;
     86		break;
     87	case 4:
     88		mace->pci.config_data.l = val;
     89		break;
     90	}
     91
     92	DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val);
     93
     94	return PCIBIOS_SUCCESSFUL;
     95}
     96
     97struct pci_ops mace_pci_ops = {
     98	.read = mace_pci_read_config,
     99	.write = mace_pci_write_config,
    100};