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

opal-lpc.c (10157B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * PowerNV LPC bus handling.
      4 *
      5 * Copyright 2013 IBM Corp.
      6 */
      7
      8#include <linux/kernel.h>
      9#include <linux/of.h>
     10#include <linux/bug.h>
     11#include <linux/io.h>
     12#include <linux/slab.h>
     13#include <linux/debugfs.h>
     14
     15#include <asm/machdep.h>
     16#include <asm/firmware.h>
     17#include <asm/opal.h>
     18#include <asm/prom.h>
     19#include <linux/uaccess.h>
     20#include <asm/isa-bridge.h>
     21
     22static int opal_lpc_chip_id = -1;
     23
     24static u8 opal_lpc_inb(unsigned long port)
     25{
     26	int64_t rc;
     27	__be32 data;
     28
     29	if (opal_lpc_chip_id < 0 || port > 0xffff)
     30		return 0xff;
     31	rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 1);
     32	return rc ? 0xff : be32_to_cpu(data);
     33}
     34
     35static __le16 __opal_lpc_inw(unsigned long port)
     36{
     37	int64_t rc;
     38	__be32 data;
     39
     40	if (opal_lpc_chip_id < 0 || port > 0xfffe)
     41		return 0xffff;
     42	if (port & 1)
     43		return (__le16)opal_lpc_inb(port) << 8 | opal_lpc_inb(port + 1);
     44	rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 2);
     45	return rc ? 0xffff : be32_to_cpu(data);
     46}
     47static u16 opal_lpc_inw(unsigned long port)
     48{
     49	return le16_to_cpu(__opal_lpc_inw(port));
     50}
     51
     52static __le32 __opal_lpc_inl(unsigned long port)
     53{
     54	int64_t rc;
     55	__be32 data;
     56
     57	if (opal_lpc_chip_id < 0 || port > 0xfffc)
     58		return 0xffffffff;
     59	if (port & 3)
     60		return (__le32)opal_lpc_inb(port    ) << 24 |
     61		       (__le32)opal_lpc_inb(port + 1) << 16 |
     62		       (__le32)opal_lpc_inb(port + 2) <<  8 |
     63			       opal_lpc_inb(port + 3);
     64	rc = opal_lpc_read(opal_lpc_chip_id, OPAL_LPC_IO, port, &data, 4);
     65	return rc ? 0xffffffff : be32_to_cpu(data);
     66}
     67
     68static u32 opal_lpc_inl(unsigned long port)
     69{
     70	return le32_to_cpu(__opal_lpc_inl(port));
     71}
     72
     73static void opal_lpc_outb(u8 val, unsigned long port)
     74{
     75	if (opal_lpc_chip_id < 0 || port > 0xffff)
     76		return;
     77	opal_lpc_write(opal_lpc_chip_id, OPAL_LPC_IO, port, val, 1);
     78}
     79
     80static void __opal_lpc_outw(__le16 val, unsigned long port)
     81{
     82	if (opal_lpc_chip_id < 0 || port > 0xfffe)
     83		return;
     84	if (port & 1) {
     85		opal_lpc_outb(val >> 8, port);
     86		opal_lpc_outb(val     , port + 1);
     87		return;
     88	}
     89	opal_lpc_write(opal_lpc_chip_id, OPAL_LPC_IO, port, val, 2);
     90}
     91
     92static void opal_lpc_outw(u16 val, unsigned long port)
     93{
     94	__opal_lpc_outw(cpu_to_le16(val), port);
     95}
     96
     97static void __opal_lpc_outl(__le32 val, unsigned long port)
     98{
     99	if (opal_lpc_chip_id < 0 || port > 0xfffc)
    100		return;
    101	if (port & 3) {
    102		opal_lpc_outb(val >> 24, port);
    103		opal_lpc_outb(val >> 16, port + 1);
    104		opal_lpc_outb(val >>  8, port + 2);
    105		opal_lpc_outb(val      , port + 3);
    106		return;
    107	}
    108	opal_lpc_write(opal_lpc_chip_id, OPAL_LPC_IO, port, val, 4);
    109}
    110
    111static void opal_lpc_outl(u32 val, unsigned long port)
    112{
    113	__opal_lpc_outl(cpu_to_le32(val), port);
    114}
    115
    116static void opal_lpc_insb(unsigned long p, void *b, unsigned long c)
    117{
    118	u8 *ptr = b;
    119
    120	while(c--)
    121		*(ptr++) = opal_lpc_inb(p);
    122}
    123
    124static void opal_lpc_insw(unsigned long p, void *b, unsigned long c)
    125{
    126	__le16 *ptr = b;
    127
    128	while(c--)
    129		*(ptr++) = __opal_lpc_inw(p);
    130}
    131
    132static void opal_lpc_insl(unsigned long p, void *b, unsigned long c)
    133{
    134	__le32 *ptr = b;
    135
    136	while(c--)
    137		*(ptr++) = __opal_lpc_inl(p);
    138}
    139
    140static void opal_lpc_outsb(unsigned long p, const void *b, unsigned long c)
    141{
    142	const u8 *ptr = b;
    143
    144	while(c--)
    145		opal_lpc_outb(*(ptr++), p);
    146}
    147
    148static void opal_lpc_outsw(unsigned long p, const void *b, unsigned long c)
    149{
    150	const __le16 *ptr = b;
    151
    152	while(c--)
    153		__opal_lpc_outw(*(ptr++), p);
    154}
    155
    156static void opal_lpc_outsl(unsigned long p, const void *b, unsigned long c)
    157{
    158	const __le32 *ptr = b;
    159
    160	while(c--)
    161		__opal_lpc_outl(*(ptr++), p);
    162}
    163
    164static const struct ppc_pci_io opal_lpc_io = {
    165	.inb	= opal_lpc_inb,
    166	.inw	= opal_lpc_inw,
    167	.inl	= opal_lpc_inl,
    168	.outb	= opal_lpc_outb,
    169	.outw	= opal_lpc_outw,
    170	.outl	= opal_lpc_outl,
    171	.insb	= opal_lpc_insb,
    172	.insw	= opal_lpc_insw,
    173	.insl	= opal_lpc_insl,
    174	.outsb	= opal_lpc_outsb,
    175	.outsw	= opal_lpc_outsw,
    176	.outsl	= opal_lpc_outsl,
    177};
    178
    179#ifdef CONFIG_DEBUG_FS
    180struct lpc_debugfs_entry {
    181	enum OpalLPCAddressType lpc_type;
    182};
    183
    184static ssize_t lpc_debug_read(struct file *filp, char __user *ubuf,
    185			      size_t count, loff_t *ppos)
    186{
    187	struct lpc_debugfs_entry *lpc = filp->private_data;
    188	u32 data, pos, len, todo;
    189	int rc;
    190
    191	if (!access_ok(ubuf, count))
    192		return -EFAULT;
    193
    194	todo = count;
    195	while (todo) {
    196		pos = *ppos;
    197
    198		/*
    199		 * Select access size based on count and alignment and
    200		 * access type. IO and MEM only support byte accesses,
    201		 * FW supports all 3.
    202		 */
    203		len = 1;
    204		if (lpc->lpc_type == OPAL_LPC_FW) {
    205			if (todo > 3 && (pos & 3) == 0)
    206				len = 4;
    207			else if (todo > 1 && (pos & 1) == 0)
    208				len = 2;
    209		}
    210		rc = opal_lpc_read(opal_lpc_chip_id, lpc->lpc_type, pos,
    211				   &data, len);
    212		if (rc)
    213			return -ENXIO;
    214
    215		/*
    216		 * Now there is some trickery with the data returned by OPAL
    217		 * as it's the desired data right justified in a 32-bit BE
    218		 * word.
    219		 *
    220		 * This is a very bad interface and I'm to blame for it :-(
    221		 *
    222		 * So we can't just apply a 32-bit swap to what comes from OPAL,
    223		 * because user space expects the *bytes* to be in their proper
    224		 * respective positions (ie, LPC position).
    225		 *
    226		 * So what we really want to do here is to shift data right
    227		 * appropriately on a LE kernel.
    228		 *
    229		 * IE. If the LPC transaction has bytes B0, B1, B2 and B3 in that
    230		 * order, we have in memory written to by OPAL at the "data"
    231		 * pointer:
    232		 *
    233		 *               Bytes:      OPAL "data"   LE "data"
    234		 *   32-bit:   B0 B1 B2 B3   B0B1B2B3      B3B2B1B0
    235		 *   16-bit:   B0 B1         0000B0B1      B1B00000
    236		 *    8-bit:   B0            000000B0      B0000000
    237		 *
    238		 * So a BE kernel will have the leftmost of the above in the MSB
    239		 * and rightmost in the LSB and can just then "cast" the u32 "data"
    240		 * down to the appropriate quantity and write it.
    241		 *
    242		 * However, an LE kernel can't. It doesn't need to swap because a
    243		 * load from data followed by a store to user are going to preserve
    244		 * the byte ordering which is the wire byte order which is what the
    245		 * user wants, but in order to "crop" to the right size, we need to
    246		 * shift right first.
    247		 */
    248		switch(len) {
    249		case 4:
    250			rc = __put_user((u32)data, (u32 __user *)ubuf);
    251			break;
    252		case 2:
    253#ifdef __LITTLE_ENDIAN__
    254			data >>= 16;
    255#endif
    256			rc = __put_user((u16)data, (u16 __user *)ubuf);
    257			break;
    258		default:
    259#ifdef __LITTLE_ENDIAN__
    260			data >>= 24;
    261#endif
    262			rc = __put_user((u8)data, (u8 __user *)ubuf);
    263			break;
    264		}
    265		if (rc)
    266			return -EFAULT;
    267		*ppos += len;
    268		ubuf += len;
    269		todo -= len;
    270	}
    271
    272	return count;
    273}
    274
    275static ssize_t lpc_debug_write(struct file *filp, const char __user *ubuf,
    276			       size_t count, loff_t *ppos)
    277{
    278	struct lpc_debugfs_entry *lpc = filp->private_data;
    279	u32 data, pos, len, todo;
    280	int rc;
    281
    282	if (!access_ok(ubuf, count))
    283		return -EFAULT;
    284
    285	todo = count;
    286	while (todo) {
    287		pos = *ppos;
    288
    289		/*
    290		 * Select access size based on count and alignment and
    291		 * access type. IO and MEM only support byte acceses,
    292		 * FW supports all 3.
    293		 */
    294		len = 1;
    295		if (lpc->lpc_type == OPAL_LPC_FW) {
    296			if (todo > 3 && (pos & 3) == 0)
    297				len = 4;
    298			else if (todo > 1 && (pos & 1) == 0)
    299				len = 2;
    300		}
    301
    302		/*
    303		 * Similarly to the read case, we have some trickery here but
    304		 * it's different to handle. We need to pass the value to OPAL in
    305		 * a register whose layout depends on the access size. We want
    306		 * to reproduce the memory layout of the user, however we aren't
    307		 * doing a load from user and a store to another memory location
    308		 * which would achieve that. Here we pass the value to OPAL via
    309		 * a register which is expected to contain the "BE" interpretation
    310		 * of the byte sequence. IE: for a 32-bit access, byte 0 should be
    311		 * in the MSB. So here we *do* need to byteswap on LE.
    312		 *
    313		 *           User bytes:    LE "data"  OPAL "data"
    314		 *  32-bit:  B0 B1 B2 B3    B3B2B1B0   B0B1B2B3
    315		 *  16-bit:  B0 B1          0000B1B0   0000B0B1
    316		 *   8-bit:  B0             000000B0   000000B0
    317		 */
    318		switch(len) {
    319		case 4:
    320			rc = __get_user(data, (u32 __user *)ubuf);
    321			data = cpu_to_be32(data);
    322			break;
    323		case 2:
    324			rc = __get_user(data, (u16 __user *)ubuf);
    325			data = cpu_to_be16(data);
    326			break;
    327		default:
    328			rc = __get_user(data, (u8 __user *)ubuf);
    329			break;
    330		}
    331		if (rc)
    332			return -EFAULT;
    333
    334		rc = opal_lpc_write(opal_lpc_chip_id, lpc->lpc_type, pos,
    335				    data, len);
    336		if (rc)
    337			return -ENXIO;
    338		*ppos += len;
    339		ubuf += len;
    340		todo -= len;
    341	}
    342
    343	return count;
    344}
    345
    346static const struct file_operations lpc_fops = {
    347	.read =		lpc_debug_read,
    348	.write =	lpc_debug_write,
    349	.open =		simple_open,
    350	.llseek =	default_llseek,
    351};
    352
    353static int opal_lpc_debugfs_create_type(struct dentry *folder,
    354					const char *fname,
    355					enum OpalLPCAddressType type)
    356{
    357	struct lpc_debugfs_entry *entry;
    358	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
    359	if (!entry)
    360		return -ENOMEM;
    361	entry->lpc_type = type;
    362	debugfs_create_file(fname, 0600, folder, entry, &lpc_fops);
    363	return 0;
    364}
    365
    366static int opal_lpc_init_debugfs(void)
    367{
    368	struct dentry *root;
    369	int rc = 0;
    370
    371	if (opal_lpc_chip_id < 0)
    372		return -ENODEV;
    373
    374	root = debugfs_create_dir("lpc", arch_debugfs_dir);
    375
    376	rc |= opal_lpc_debugfs_create_type(root, "io", OPAL_LPC_IO);
    377	rc |= opal_lpc_debugfs_create_type(root, "mem", OPAL_LPC_MEM);
    378	rc |= opal_lpc_debugfs_create_type(root, "fw", OPAL_LPC_FW);
    379	return rc;
    380}
    381machine_device_initcall(powernv, opal_lpc_init_debugfs);
    382#endif  /* CONFIG_DEBUG_FS */
    383
    384void __init opal_lpc_init(void)
    385{
    386	struct device_node *np;
    387
    388	/*
    389	 * Look for a Power8 LPC bus tagged as "primary",
    390	 * we currently support only one though the OPAL APIs
    391	 * support any number.
    392	 */
    393	for_each_compatible_node(np, NULL, "ibm,power8-lpc") {
    394		if (!of_device_is_available(np))
    395			continue;
    396		if (!of_get_property(np, "primary", NULL))
    397			continue;
    398		opal_lpc_chip_id = of_get_ibm_chip_id(np);
    399		of_node_put(np);
    400		break;
    401	}
    402	if (opal_lpc_chip_id < 0)
    403		return;
    404
    405	/* Does it support direct mapping ? */
    406	if (of_get_property(np, "ranges", NULL)) {
    407		pr_info("OPAL: Found memory mapped LPC bus on chip %d\n",
    408			opal_lpc_chip_id);
    409		isa_bridge_init_non_pci(np);
    410	} else {
    411		pr_info("OPAL: Found non-mapped LPC bus on chip %d\n",
    412			opal_lpc_chip_id);
    413
    414		/* Setup special IO ops */
    415		ppc_pci_io = opal_lpc_io;
    416		isa_io_special = true;
    417	}
    418}