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

iomap.c (9365B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Implement the default iomap interfaces
      4 *
      5 * (C) Copyright 2004 Linus Torvalds
      6 */
      7#include <linux/pci.h>
      8#include <linux/io.h>
      9
     10#include <linux/export.h>
     11
     12/*
     13 * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
     14 * access or a MMIO access, these functions don't care. The info is
     15 * encoded in the hardware mapping set up by the mapping functions
     16 * (or the cookie itself, depending on implementation and hw).
     17 *
     18 * The generic routines don't assume any hardware mappings, and just
     19 * encode the PIO/MMIO as part of the cookie. They coldly assume that
     20 * the MMIO IO mappings are not in the low address range.
     21 *
     22 * Architectures for which this is not true can't use this generic
     23 * implementation and should do their own copy.
     24 */
     25
     26#ifndef HAVE_ARCH_PIO_SIZE
     27/*
     28 * We encode the physical PIO addresses (0-0xffff) into the
     29 * pointer by offsetting them with a constant (0x10000) and
     30 * assuming that all the low addresses are always PIO. That means
     31 * we can do some sanity checks on the low bits, and don't
     32 * need to just take things for granted.
     33 */
     34#define PIO_OFFSET	0x10000UL
     35#define PIO_MASK	0x0ffffUL
     36#define PIO_RESERVED	0x40000UL
     37#endif
     38
     39static void bad_io_access(unsigned long port, const char *access)
     40{
     41	static int count = 10;
     42	if (count) {
     43		count--;
     44		WARN(1, KERN_ERR "Bad IO access at port %#lx (%s)\n", port, access);
     45	}
     46}
     47
     48/*
     49 * Ugly macros are a way of life.
     50 */
     51#define IO_COND(addr, is_pio, is_mmio) do {			\
     52	unsigned long port = (unsigned long __force)addr;	\
     53	if (port >= PIO_RESERVED) {				\
     54		is_mmio;					\
     55	} else if (port > PIO_OFFSET) {				\
     56		port &= PIO_MASK;				\
     57		is_pio;						\
     58	} else							\
     59		bad_io_access(port, #is_pio );			\
     60} while (0)
     61
     62#ifndef pio_read16be
     63#define pio_read16be(port) swab16(inw(port))
     64#define pio_read32be(port) swab32(inl(port))
     65#endif
     66
     67#ifndef mmio_read16be
     68#define mmio_read16be(addr) swab16(readw(addr))
     69#define mmio_read32be(addr) swab32(readl(addr))
     70#define mmio_read64be(addr) swab64(readq(addr))
     71#endif
     72
     73unsigned int ioread8(const void __iomem *addr)
     74{
     75	IO_COND(addr, return inb(port), return readb(addr));
     76	return 0xff;
     77}
     78unsigned int ioread16(const void __iomem *addr)
     79{
     80	IO_COND(addr, return inw(port), return readw(addr));
     81	return 0xffff;
     82}
     83unsigned int ioread16be(const void __iomem *addr)
     84{
     85	IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));
     86	return 0xffff;
     87}
     88unsigned int ioread32(const void __iomem *addr)
     89{
     90	IO_COND(addr, return inl(port), return readl(addr));
     91	return 0xffffffff;
     92}
     93unsigned int ioread32be(const void __iomem *addr)
     94{
     95	IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));
     96	return 0xffffffff;
     97}
     98EXPORT_SYMBOL(ioread8);
     99EXPORT_SYMBOL(ioread16);
    100EXPORT_SYMBOL(ioread16be);
    101EXPORT_SYMBOL(ioread32);
    102EXPORT_SYMBOL(ioread32be);
    103
    104#ifdef readq
    105static u64 pio_read64_lo_hi(unsigned long port)
    106{
    107	u64 lo, hi;
    108
    109	lo = inl(port);
    110	hi = inl(port + sizeof(u32));
    111
    112	return lo | (hi << 32);
    113}
    114
    115static u64 pio_read64_hi_lo(unsigned long port)
    116{
    117	u64 lo, hi;
    118
    119	hi = inl(port + sizeof(u32));
    120	lo = inl(port);
    121
    122	return lo | (hi << 32);
    123}
    124
    125static u64 pio_read64be_lo_hi(unsigned long port)
    126{
    127	u64 lo, hi;
    128
    129	lo = pio_read32be(port + sizeof(u32));
    130	hi = pio_read32be(port);
    131
    132	return lo | (hi << 32);
    133}
    134
    135static u64 pio_read64be_hi_lo(unsigned long port)
    136{
    137	u64 lo, hi;
    138
    139	hi = pio_read32be(port);
    140	lo = pio_read32be(port + sizeof(u32));
    141
    142	return lo | (hi << 32);
    143}
    144
    145u64 ioread64_lo_hi(const void __iomem *addr)
    146{
    147	IO_COND(addr, return pio_read64_lo_hi(port), return readq(addr));
    148	return 0xffffffffffffffffULL;
    149}
    150
    151u64 ioread64_hi_lo(const void __iomem *addr)
    152{
    153	IO_COND(addr, return pio_read64_hi_lo(port), return readq(addr));
    154	return 0xffffffffffffffffULL;
    155}
    156
    157u64 ioread64be_lo_hi(const void __iomem *addr)
    158{
    159	IO_COND(addr, return pio_read64be_lo_hi(port),
    160		return mmio_read64be(addr));
    161	return 0xffffffffffffffffULL;
    162}
    163
    164u64 ioread64be_hi_lo(const void __iomem *addr)
    165{
    166	IO_COND(addr, return pio_read64be_hi_lo(port),
    167		return mmio_read64be(addr));
    168	return 0xffffffffffffffffULL;
    169}
    170
    171EXPORT_SYMBOL(ioread64_lo_hi);
    172EXPORT_SYMBOL(ioread64_hi_lo);
    173EXPORT_SYMBOL(ioread64be_lo_hi);
    174EXPORT_SYMBOL(ioread64be_hi_lo);
    175
    176#endif /* readq */
    177
    178#ifndef pio_write16be
    179#define pio_write16be(val,port) outw(swab16(val),port)
    180#define pio_write32be(val,port) outl(swab32(val),port)
    181#endif
    182
    183#ifndef mmio_write16be
    184#define mmio_write16be(val,port) writew(swab16(val),port)
    185#define mmio_write32be(val,port) writel(swab32(val),port)
    186#define mmio_write64be(val,port) writeq(swab64(val),port)
    187#endif
    188
    189void iowrite8(u8 val, void __iomem *addr)
    190{
    191	IO_COND(addr, outb(val,port), writeb(val, addr));
    192}
    193void iowrite16(u16 val, void __iomem *addr)
    194{
    195	IO_COND(addr, outw(val,port), writew(val, addr));
    196}
    197void iowrite16be(u16 val, void __iomem *addr)
    198{
    199	IO_COND(addr, pio_write16be(val,port), mmio_write16be(val, addr));
    200}
    201void iowrite32(u32 val, void __iomem *addr)
    202{
    203	IO_COND(addr, outl(val,port), writel(val, addr));
    204}
    205void iowrite32be(u32 val, void __iomem *addr)
    206{
    207	IO_COND(addr, pio_write32be(val,port), mmio_write32be(val, addr));
    208}
    209EXPORT_SYMBOL(iowrite8);
    210EXPORT_SYMBOL(iowrite16);
    211EXPORT_SYMBOL(iowrite16be);
    212EXPORT_SYMBOL(iowrite32);
    213EXPORT_SYMBOL(iowrite32be);
    214
    215#ifdef writeq
    216static void pio_write64_lo_hi(u64 val, unsigned long port)
    217{
    218	outl(val, port);
    219	outl(val >> 32, port + sizeof(u32));
    220}
    221
    222static void pio_write64_hi_lo(u64 val, unsigned long port)
    223{
    224	outl(val >> 32, port + sizeof(u32));
    225	outl(val, port);
    226}
    227
    228static void pio_write64be_lo_hi(u64 val, unsigned long port)
    229{
    230	pio_write32be(val, port + sizeof(u32));
    231	pio_write32be(val >> 32, port);
    232}
    233
    234static void pio_write64be_hi_lo(u64 val, unsigned long port)
    235{
    236	pio_write32be(val >> 32, port);
    237	pio_write32be(val, port + sizeof(u32));
    238}
    239
    240void iowrite64_lo_hi(u64 val, void __iomem *addr)
    241{
    242	IO_COND(addr, pio_write64_lo_hi(val, port),
    243		writeq(val, addr));
    244}
    245
    246void iowrite64_hi_lo(u64 val, void __iomem *addr)
    247{
    248	IO_COND(addr, pio_write64_hi_lo(val, port),
    249		writeq(val, addr));
    250}
    251
    252void iowrite64be_lo_hi(u64 val, void __iomem *addr)
    253{
    254	IO_COND(addr, pio_write64be_lo_hi(val, port),
    255		mmio_write64be(val, addr));
    256}
    257
    258void iowrite64be_hi_lo(u64 val, void __iomem *addr)
    259{
    260	IO_COND(addr, pio_write64be_hi_lo(val, port),
    261		mmio_write64be(val, addr));
    262}
    263
    264EXPORT_SYMBOL(iowrite64_lo_hi);
    265EXPORT_SYMBOL(iowrite64_hi_lo);
    266EXPORT_SYMBOL(iowrite64be_lo_hi);
    267EXPORT_SYMBOL(iowrite64be_hi_lo);
    268
    269#endif /* readq */
    270
    271/*
    272 * These are the "repeat MMIO read/write" functions.
    273 * Note the "__raw" accesses, since we don't want to
    274 * convert to CPU byte order. We write in "IO byte
    275 * order" (we also don't have IO barriers).
    276 */
    277#ifndef mmio_insb
    278static inline void mmio_insb(const void __iomem *addr, u8 *dst, int count)
    279{
    280	while (--count >= 0) {
    281		u8 data = __raw_readb(addr);
    282		*dst = data;
    283		dst++;
    284	}
    285}
    286static inline void mmio_insw(const void __iomem *addr, u16 *dst, int count)
    287{
    288	while (--count >= 0) {
    289		u16 data = __raw_readw(addr);
    290		*dst = data;
    291		dst++;
    292	}
    293}
    294static inline void mmio_insl(const void __iomem *addr, u32 *dst, int count)
    295{
    296	while (--count >= 0) {
    297		u32 data = __raw_readl(addr);
    298		*dst = data;
    299		dst++;
    300	}
    301}
    302#endif
    303
    304#ifndef mmio_outsb
    305static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
    306{
    307	while (--count >= 0) {
    308		__raw_writeb(*src, addr);
    309		src++;
    310	}
    311}
    312static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
    313{
    314	while (--count >= 0) {
    315		__raw_writew(*src, addr);
    316		src++;
    317	}
    318}
    319static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
    320{
    321	while (--count >= 0) {
    322		__raw_writel(*src, addr);
    323		src++;
    324	}
    325}
    326#endif
    327
    328void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
    329{
    330	IO_COND(addr, insb(port,dst,count), mmio_insb(addr, dst, count));
    331}
    332void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)
    333{
    334	IO_COND(addr, insw(port,dst,count), mmio_insw(addr, dst, count));
    335}
    336void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)
    337{
    338	IO_COND(addr, insl(port,dst,count), mmio_insl(addr, dst, count));
    339}
    340EXPORT_SYMBOL(ioread8_rep);
    341EXPORT_SYMBOL(ioread16_rep);
    342EXPORT_SYMBOL(ioread32_rep);
    343
    344void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
    345{
    346	IO_COND(addr, outsb(port, src, count), mmio_outsb(addr, src, count));
    347}
    348void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
    349{
    350	IO_COND(addr, outsw(port, src, count), mmio_outsw(addr, src, count));
    351}
    352void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
    353{
    354	IO_COND(addr, outsl(port, src,count), mmio_outsl(addr, src, count));
    355}
    356EXPORT_SYMBOL(iowrite8_rep);
    357EXPORT_SYMBOL(iowrite16_rep);
    358EXPORT_SYMBOL(iowrite32_rep);
    359
    360#ifdef CONFIG_HAS_IOPORT_MAP
    361/* Create a virtual mapping cookie for an IO port range */
    362void __iomem *ioport_map(unsigned long port, unsigned int nr)
    363{
    364	if (port > PIO_MASK)
    365		return NULL;
    366	return (void __iomem *) (unsigned long) (port + PIO_OFFSET);
    367}
    368
    369void ioport_unmap(void __iomem *addr)
    370{
    371	/* Nothing to do */
    372}
    373EXPORT_SYMBOL(ioport_map);
    374EXPORT_SYMBOL(ioport_unmap);
    375#endif /* CONFIG_HAS_IOPORT_MAP */
    376
    377#ifdef CONFIG_PCI
    378/* Hide the details if this is a MMIO or PIO address space and just do what
    379 * you expect in the correct way. */
    380void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
    381{
    382	IO_COND(addr, /* nothing */, iounmap(addr));
    383}
    384EXPORT_SYMBOL(pci_iounmap);
    385#endif /* CONFIG_PCI */