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

host_soc.c (4577B)


      1/*
      2 * Sonics Silicon Backplane SoC host related functions.
      3 * Subsystem core
      4 *
      5 * Copyright 2005, Broadcom Corporation
      6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
      7 *
      8 * Licensed under the GNU/GPL. See COPYING for details.
      9 */
     10
     11#include "ssb_private.h"
     12
     13#include <linux/bcm47xx_nvram.h>
     14#include <linux/ssb/ssb.h>
     15
     16static u8 ssb_host_soc_read8(struct ssb_device *dev, u16 offset)
     17{
     18	struct ssb_bus *bus = dev->bus;
     19
     20	offset += dev->core_index * SSB_CORE_SIZE;
     21	return readb(bus->mmio + offset);
     22}
     23
     24static u16 ssb_host_soc_read16(struct ssb_device *dev, u16 offset)
     25{
     26	struct ssb_bus *bus = dev->bus;
     27
     28	offset += dev->core_index * SSB_CORE_SIZE;
     29	return readw(bus->mmio + offset);
     30}
     31
     32static u32 ssb_host_soc_read32(struct ssb_device *dev, u16 offset)
     33{
     34	struct ssb_bus *bus = dev->bus;
     35
     36	offset += dev->core_index * SSB_CORE_SIZE;
     37	return readl(bus->mmio + offset);
     38}
     39
     40#ifdef CONFIG_SSB_BLOCKIO
     41static void ssb_host_soc_block_read(struct ssb_device *dev, void *buffer,
     42				    size_t count, u16 offset, u8 reg_width)
     43{
     44	struct ssb_bus *bus = dev->bus;
     45	void __iomem *addr;
     46
     47	offset += dev->core_index * SSB_CORE_SIZE;
     48	addr = bus->mmio + offset;
     49
     50	switch (reg_width) {
     51	case sizeof(u8): {
     52		u8 *buf = buffer;
     53
     54		while (count) {
     55			*buf = __raw_readb(addr);
     56			buf++;
     57			count--;
     58		}
     59		break;
     60	}
     61	case sizeof(u16): {
     62		__le16 *buf = buffer;
     63
     64		WARN_ON(count & 1);
     65		while (count) {
     66			*buf = (__force __le16)__raw_readw(addr);
     67			buf++;
     68			count -= 2;
     69		}
     70		break;
     71	}
     72	case sizeof(u32): {
     73		__le32 *buf = buffer;
     74
     75		WARN_ON(count & 3);
     76		while (count) {
     77			*buf = (__force __le32)__raw_readl(addr);
     78			buf++;
     79			count -= 4;
     80		}
     81		break;
     82	}
     83	default:
     84		WARN_ON(1);
     85	}
     86}
     87#endif /* CONFIG_SSB_BLOCKIO */
     88
     89static void ssb_host_soc_write8(struct ssb_device *dev, u16 offset, u8 value)
     90{
     91	struct ssb_bus *bus = dev->bus;
     92
     93	offset += dev->core_index * SSB_CORE_SIZE;
     94	writeb(value, bus->mmio + offset);
     95}
     96
     97static void ssb_host_soc_write16(struct ssb_device *dev, u16 offset, u16 value)
     98{
     99	struct ssb_bus *bus = dev->bus;
    100
    101	offset += dev->core_index * SSB_CORE_SIZE;
    102	writew(value, bus->mmio + offset);
    103}
    104
    105static void ssb_host_soc_write32(struct ssb_device *dev, u16 offset, u32 value)
    106{
    107	struct ssb_bus *bus = dev->bus;
    108
    109	offset += dev->core_index * SSB_CORE_SIZE;
    110	writel(value, bus->mmio + offset);
    111}
    112
    113#ifdef CONFIG_SSB_BLOCKIO
    114static void ssb_host_soc_block_write(struct ssb_device *dev, const void *buffer,
    115				     size_t count, u16 offset, u8 reg_width)
    116{
    117	struct ssb_bus *bus = dev->bus;
    118	void __iomem *addr;
    119
    120	offset += dev->core_index * SSB_CORE_SIZE;
    121	addr = bus->mmio + offset;
    122
    123	switch (reg_width) {
    124	case sizeof(u8): {
    125		const u8 *buf = buffer;
    126
    127		while (count) {
    128			__raw_writeb(*buf, addr);
    129			buf++;
    130			count--;
    131		}
    132		break;
    133	}
    134	case sizeof(u16): {
    135		const __le16 *buf = buffer;
    136
    137		WARN_ON(count & 1);
    138		while (count) {
    139			__raw_writew((__force u16)(*buf), addr);
    140			buf++;
    141			count -= 2;
    142		}
    143		break;
    144	}
    145	case sizeof(u32): {
    146		const __le32 *buf = buffer;
    147
    148		WARN_ON(count & 3);
    149		while (count) {
    150			__raw_writel((__force u32)(*buf), addr);
    151			buf++;
    152			count -= 4;
    153		}
    154		break;
    155	}
    156	default:
    157		WARN_ON(1);
    158	}
    159}
    160#endif /* CONFIG_SSB_BLOCKIO */
    161
    162/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
    163const struct ssb_bus_ops ssb_host_soc_ops = {
    164	.read8		= ssb_host_soc_read8,
    165	.read16		= ssb_host_soc_read16,
    166	.read32		= ssb_host_soc_read32,
    167	.write8		= ssb_host_soc_write8,
    168	.write16	= ssb_host_soc_write16,
    169	.write32	= ssb_host_soc_write32,
    170#ifdef CONFIG_SSB_BLOCKIO
    171	.block_read	= ssb_host_soc_block_read,
    172	.block_write	= ssb_host_soc_block_write,
    173#endif
    174};
    175
    176int ssb_host_soc_get_invariants(struct ssb_bus *bus,
    177				struct ssb_init_invariants *iv)
    178{
    179	char buf[20];
    180	int len, err;
    181
    182	/* Fill boardinfo structure */
    183	memset(&iv->boardinfo, 0, sizeof(struct ssb_boardinfo));
    184
    185	len = bcm47xx_nvram_getenv("boardvendor", buf, sizeof(buf));
    186	if (len > 0) {
    187		err = kstrtou16(strim(buf), 0, &iv->boardinfo.vendor);
    188		if (err)
    189			pr_warn("Couldn't parse nvram board vendor entry with value \"%s\"\n",
    190				buf);
    191	}
    192	if (!iv->boardinfo.vendor)
    193		iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
    194
    195	len = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf));
    196	if (len > 0) {
    197		err = kstrtou16(strim(buf), 0, &iv->boardinfo.type);
    198		if (err)
    199			pr_warn("Couldn't parse nvram board type entry with value \"%s\"\n",
    200				buf);
    201	}
    202
    203	memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
    204	ssb_fill_sprom_with_fallback(bus, &iv->sprom);
    205
    206	if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
    207		iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
    208
    209	return 0;
    210}