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

PeeCeeI.c (4057B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * PeeCeeI.c: The emerging standard...
      4 *
      5 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
      6 */
      7
      8#include <linux/module.h>
      9
     10#include <asm/io.h>
     11#include <asm/byteorder.h>
     12
     13void outsb(unsigned long __addr, const void *src, unsigned long count)
     14{
     15	void __iomem *addr = (void __iomem *) __addr;
     16	const u8 *p = src;
     17
     18	while (count--)
     19		__raw_writeb(*p++, addr);
     20}
     21EXPORT_SYMBOL(outsb);
     22
     23void outsw(unsigned long __addr, const void *src, unsigned long count)
     24{
     25	void __iomem *addr = (void __iomem *) __addr;
     26
     27	while (count--) {
     28		__raw_writew(*(u16 *)src, addr);
     29		src += sizeof(u16);
     30	}
     31}
     32EXPORT_SYMBOL(outsw);
     33
     34void outsl(unsigned long __addr, const void *src, unsigned long count)
     35{
     36	void __iomem *addr = (void __iomem *) __addr;
     37	u32 l, l2;
     38
     39	if (!count)
     40		return;
     41
     42	switch (((unsigned long)src) & 0x3) {
     43	case 0x0:
     44		/* src is naturally aligned */
     45		while (count--) {
     46			__raw_writel(*(u32 *)src, addr);
     47			src += sizeof(u32);
     48		}
     49		break;
     50	case 0x2:
     51		/* 2-byte alignment */
     52		while (count--) {
     53			l = (*(u16 *)src) << 16;
     54			l |= *(u16 *)(src + sizeof(u16));
     55			__raw_writel(l, addr);
     56			src += sizeof(u32);
     57		}
     58		break;
     59	case 0x1:
     60		/* Hold three bytes in l each time, grab a byte from l2 */
     61		l = (*(u8 *)src) << 24;
     62		l |= (*(u16 *)(src + sizeof(u8))) << 8;
     63		src += sizeof(u8) + sizeof(u16);
     64		while (count--) {
     65			l2 = *(u32 *)src;
     66			l |= (l2 >> 24);
     67			__raw_writel(l, addr);
     68			l = l2 << 8;
     69			src += sizeof(u32);
     70		}
     71		break;
     72	case 0x3:
     73		/* Hold a byte in l each time, grab 3 bytes from l2 */
     74		l = (*(u8 *)src) << 24;
     75		src += sizeof(u8);
     76		while (count--) {
     77			l2 = *(u32 *)src;
     78			l |= (l2 >> 8);
     79			__raw_writel(l, addr);
     80			l = l2 << 24;
     81			src += sizeof(u32);
     82		}
     83		break;
     84	}
     85}
     86EXPORT_SYMBOL(outsl);
     87
     88void insb(unsigned long __addr, void *dst, unsigned long count)
     89{
     90	void __iomem *addr = (void __iomem *) __addr;
     91
     92	if (count) {
     93		u32 *pi;
     94		u8 *pb = dst;
     95
     96		while ((((unsigned long)pb) & 0x3) && count--)
     97			*pb++ = __raw_readb(addr);
     98		pi = (u32 *)pb;
     99		while (count >= 4) {
    100			u32 w;
    101
    102			w  = (__raw_readb(addr) << 24);
    103			w |= (__raw_readb(addr) << 16);
    104			w |= (__raw_readb(addr) << 8);
    105			w |= (__raw_readb(addr) << 0);
    106			*pi++ = w;
    107			count -= 4;
    108		}
    109		pb = (u8 *)pi;
    110		while (count--)
    111			*pb++ = __raw_readb(addr);
    112	}
    113}
    114EXPORT_SYMBOL(insb);
    115
    116void insw(unsigned long __addr, void *dst, unsigned long count)
    117{
    118	void __iomem *addr = (void __iomem *) __addr;
    119
    120	if (count) {
    121		u16 *ps = dst;
    122		u32 *pi;
    123
    124		if (((unsigned long)ps) & 0x2) {
    125			*ps++ = __raw_readw(addr);
    126			count--;
    127		}
    128		pi = (u32 *)ps;
    129		while (count >= 2) {
    130			u32 w;
    131
    132			w  = __raw_readw(addr) << 16;
    133			w |= __raw_readw(addr) << 0;
    134			*pi++ = w;
    135			count -= 2;
    136		}
    137		ps = (u16 *)pi;
    138		if (count)
    139			*ps = __raw_readw(addr);
    140	}
    141}
    142EXPORT_SYMBOL(insw);
    143
    144void insl(unsigned long __addr, void *dst, unsigned long count)
    145{
    146	void __iomem *addr = (void __iomem *) __addr;
    147
    148	if (count) {
    149		if ((((unsigned long)dst) & 0x3) == 0) {
    150			u32 *pi = dst;
    151			while (count--)
    152				*pi++ = __raw_readl(addr);
    153		} else {
    154			u32 l = 0, l2, *pi;
    155			u16 *ps;
    156			u8 *pb;
    157
    158			switch (((unsigned long)dst) & 3) {
    159			case 0x2:
    160				ps = dst;
    161				count -= 1;
    162				l = __raw_readl(addr);
    163				*ps++ = l;
    164				pi = (u32 *)ps;
    165				while (count--) {
    166					l2 = __raw_readl(addr);
    167					*pi++ = (l << 16) | (l2 >> 16);
    168					l = l2;
    169				}
    170				ps = (u16 *)pi;
    171				*ps = l;
    172				break;
    173
    174			case 0x1:
    175				pb = dst;
    176				count -= 1;
    177				l = __raw_readl(addr);
    178				*pb++ = l >> 24;
    179				ps = (u16 *)pb;
    180				*ps++ = ((l >> 8) & 0xffff);
    181				pi = (u32 *)ps;
    182				while (count--) {
    183					l2 = __raw_readl(addr);
    184					*pi++ = (l << 24) | (l2 >> 8);
    185					l = l2;
    186				}
    187				pb = (u8 *)pi;
    188				*pb = l;
    189				break;
    190
    191			case 0x3:
    192				pb = (u8 *)dst;
    193				count -= 1;
    194				l = __raw_readl(addr);
    195				*pb++ = l >> 24;
    196				pi = (u32 *)pb;
    197				while (count--) {
    198					l2 = __raw_readl(addr);
    199					*pi++ = (l << 8) | (l2 >> 24);
    200					l = l2;
    201				}
    202				ps = (u16 *)pi;
    203				*ps++ = ((l >> 8) & 0xffff);
    204				pb = (u8 *)ps;
    205				*pb = l;
    206				break;
    207			}
    208		}
    209	}
    210}
    211EXPORT_SYMBOL(insl);
    212