LCOV - code coverage report
Current view: top level - lib - iomap.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 0 146 0.0 %
Date: 2021-04-22 12:43:58 Functions: 0 27 0.0 %

          Line data    Source code
       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             : 
      39           0 : static void bad_io_access(unsigned long port, const char *access)
      40             : {
      41           0 :         static int count = 10;
      42           0 :         if (count) {
      43           0 :                 count--;
      44           0 :                 WARN(1, KERN_ERR "Bad IO access at port %#lx (%s)\n", port, access);
      45             :         }
      46           0 : }
      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             : 
      73           0 : unsigned int ioread8(const void __iomem *addr)
      74             : {
      75           0 :         IO_COND(addr, return inb(port), return readb(addr));
      76           0 :         return 0xff;
      77             : }
      78           0 : unsigned int ioread16(const void __iomem *addr)
      79             : {
      80           0 :         IO_COND(addr, return inw(port), return readw(addr));
      81           0 :         return 0xffff;
      82             : }
      83           0 : unsigned int ioread16be(const void __iomem *addr)
      84             : {
      85           0 :         IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));
      86           0 :         return 0xffff;
      87             : }
      88           0 : unsigned int ioread32(const void __iomem *addr)
      89             : {
      90           0 :         IO_COND(addr, return inl(port), return readl(addr));
      91           0 :         return 0xffffffff;
      92             : }
      93           0 : unsigned int ioread32be(const void __iomem *addr)
      94             : {
      95           0 :         IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));
      96           0 :         return 0xffffffff;
      97             : }
      98             : EXPORT_SYMBOL(ioread8);
      99             : EXPORT_SYMBOL(ioread16);
     100             : EXPORT_SYMBOL(ioread16be);
     101             : EXPORT_SYMBOL(ioread32);
     102             : EXPORT_SYMBOL(ioread32be);
     103             : 
     104             : #ifdef readq
     105           0 : static u64 pio_read64_lo_hi(unsigned long port)
     106             : {
     107           0 :         u64 lo, hi;
     108             : 
     109           0 :         lo = inl(port);
     110           0 :         hi = inl(port + sizeof(u32));
     111             : 
     112           0 :         return lo | (hi << 32);
     113             : }
     114             : 
     115           0 : static u64 pio_read64_hi_lo(unsigned long port)
     116             : {
     117           0 :         u64 lo, hi;
     118             : 
     119           0 :         hi = inl(port + sizeof(u32));
     120           0 :         lo = inl(port);
     121             : 
     122           0 :         return lo | (hi << 32);
     123             : }
     124             : 
     125           0 : static u64 pio_read64be_lo_hi(unsigned long port)
     126             : {
     127           0 :         u64 lo, hi;
     128             : 
     129           0 :         lo = pio_read32be(port + sizeof(u32));
     130           0 :         hi = pio_read32be(port);
     131             : 
     132           0 :         return lo | (hi << 32);
     133             : }
     134             : 
     135           0 : static u64 pio_read64be_hi_lo(unsigned long port)
     136             : {
     137           0 :         u64 lo, hi;
     138             : 
     139           0 :         hi = pio_read32be(port);
     140           0 :         lo = pio_read32be(port + sizeof(u32));
     141             : 
     142           0 :         return lo | (hi << 32);
     143             : }
     144             : 
     145           0 : u64 ioread64_lo_hi(const void __iomem *addr)
     146             : {
     147           0 :         IO_COND(addr, return pio_read64_lo_hi(port), return readq(addr));
     148           0 :         return 0xffffffffffffffffULL;
     149             : }
     150             : 
     151           0 : u64 ioread64_hi_lo(const void __iomem *addr)
     152             : {
     153           0 :         IO_COND(addr, return pio_read64_hi_lo(port), return readq(addr));
     154           0 :         return 0xffffffffffffffffULL;
     155             : }
     156             : 
     157           0 : u64 ioread64be_lo_hi(const void __iomem *addr)
     158             : {
     159           0 :         IO_COND(addr, return pio_read64be_lo_hi(port),
     160             :                 return mmio_read64be(addr));
     161           0 :         return 0xffffffffffffffffULL;
     162             : }
     163             : 
     164           0 : u64 ioread64be_hi_lo(const void __iomem *addr)
     165             : {
     166           0 :         IO_COND(addr, return pio_read64be_hi_lo(port),
     167             :                 return mmio_read64be(addr));
     168           0 :         return 0xffffffffffffffffULL;
     169             : }
     170             : 
     171             : EXPORT_SYMBOL(ioread64_lo_hi);
     172             : EXPORT_SYMBOL(ioread64_hi_lo);
     173             : EXPORT_SYMBOL(ioread64be_lo_hi);
     174             : EXPORT_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             : 
     189           0 : void iowrite8(u8 val, void __iomem *addr)
     190             : {
     191           0 :         IO_COND(addr, outb(val,port), writeb(val, addr));
     192           0 : }
     193           0 : void iowrite16(u16 val, void __iomem *addr)
     194             : {
     195           0 :         IO_COND(addr, outw(val,port), writew(val, addr));
     196           0 : }
     197           0 : void iowrite16be(u16 val, void __iomem *addr)
     198             : {
     199           0 :         IO_COND(addr, pio_write16be(val,port), mmio_write16be(val, addr));
     200           0 : }
     201           0 : void iowrite32(u32 val, void __iomem *addr)
     202             : {
     203           0 :         IO_COND(addr, outl(val,port), writel(val, addr));
     204           0 : }
     205           0 : void iowrite32be(u32 val, void __iomem *addr)
     206             : {
     207           0 :         IO_COND(addr, pio_write32be(val,port), mmio_write32be(val, addr));
     208           0 : }
     209             : EXPORT_SYMBOL(iowrite8);
     210             : EXPORT_SYMBOL(iowrite16);
     211             : EXPORT_SYMBOL(iowrite16be);
     212             : EXPORT_SYMBOL(iowrite32);
     213             : EXPORT_SYMBOL(iowrite32be);
     214             : 
     215             : #ifdef writeq
     216           0 : static void pio_write64_lo_hi(u64 val, unsigned long port)
     217             : {
     218           0 :         outl(val, port);
     219           0 :         outl(val >> 32, port + sizeof(u32));
     220           0 : }
     221             : 
     222           0 : static void pio_write64_hi_lo(u64 val, unsigned long port)
     223             : {
     224           0 :         outl(val >> 32, port + sizeof(u32));
     225           0 :         outl(val, port);
     226           0 : }
     227             : 
     228           0 : static void pio_write64be_lo_hi(u64 val, unsigned long port)
     229             : {
     230           0 :         pio_write32be(val, port + sizeof(u32));
     231           0 :         pio_write32be(val >> 32, port);
     232           0 : }
     233             : 
     234           0 : static void pio_write64be_hi_lo(u64 val, unsigned long port)
     235             : {
     236           0 :         pio_write32be(val >> 32, port);
     237           0 :         pio_write32be(val, port + sizeof(u32));
     238           0 : }
     239             : 
     240           0 : void iowrite64_lo_hi(u64 val, void __iomem *addr)
     241             : {
     242           0 :         IO_COND(addr, pio_write64_lo_hi(val, port),
     243             :                 writeq(val, addr));
     244           0 : }
     245             : 
     246           0 : void iowrite64_hi_lo(u64 val, void __iomem *addr)
     247             : {
     248           0 :         IO_COND(addr, pio_write64_hi_lo(val, port),
     249             :                 writeq(val, addr));
     250           0 : }
     251             : 
     252           0 : void iowrite64be_lo_hi(u64 val, void __iomem *addr)
     253             : {
     254           0 :         IO_COND(addr, pio_write64be_lo_hi(val, port),
     255             :                 mmio_write64be(val, addr));
     256           0 : }
     257             : 
     258           0 : void iowrite64be_hi_lo(u64 val, void __iomem *addr)
     259             : {
     260           0 :         IO_COND(addr, pio_write64be_hi_lo(val, port),
     261             :                 mmio_write64be(val, addr));
     262           0 : }
     263             : 
     264             : EXPORT_SYMBOL(iowrite64_lo_hi);
     265             : EXPORT_SYMBOL(iowrite64_hi_lo);
     266             : EXPORT_SYMBOL(iowrite64be_lo_hi);
     267             : EXPORT_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
     278           0 : static inline void mmio_insb(const void __iomem *addr, u8 *dst, int count)
     279             : {
     280           0 :         while (--count >= 0) {
     281           0 :                 u8 data = __raw_readb(addr);
     282           0 :                 *dst = data;
     283           0 :                 dst++;
     284             :         }
     285             : }
     286           0 : static inline void mmio_insw(const void __iomem *addr, u16 *dst, int count)
     287             : {
     288           0 :         while (--count >= 0) {
     289           0 :                 u16 data = __raw_readw(addr);
     290           0 :                 *dst = data;
     291           0 :                 dst++;
     292             :         }
     293             : }
     294           0 : static inline void mmio_insl(const void __iomem *addr, u32 *dst, int count)
     295             : {
     296           0 :         while (--count >= 0) {
     297           0 :                 u32 data = __raw_readl(addr);
     298           0 :                 *dst = data;
     299           0 :                 dst++;
     300             :         }
     301             : }
     302             : #endif
     303             : 
     304             : #ifndef mmio_outsb
     305           0 : static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
     306             : {
     307           0 :         while (--count >= 0) {
     308           0 :                 __raw_writeb(*src, addr);
     309           0 :                 src++;
     310             :         }
     311             : }
     312           0 : static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
     313             : {
     314           0 :         while (--count >= 0) {
     315           0 :                 __raw_writew(*src, addr);
     316           0 :                 src++;
     317             :         }
     318             : }
     319           0 : static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
     320             : {
     321           0 :         while (--count >= 0) {
     322           0 :                 __raw_writel(*src, addr);
     323           0 :                 src++;
     324             :         }
     325             : }
     326             : #endif
     327             : 
     328           0 : void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
     329             : {
     330           0 :         IO_COND(addr, insb(port,dst,count), mmio_insb(addr, dst, count));
     331           0 : }
     332           0 : void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)
     333             : {
     334           0 :         IO_COND(addr, insw(port,dst,count), mmio_insw(addr, dst, count));
     335           0 : }
     336           0 : void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)
     337             : {
     338           0 :         IO_COND(addr, insl(port,dst,count), mmio_insl(addr, dst, count));
     339           0 : }
     340             : EXPORT_SYMBOL(ioread8_rep);
     341             : EXPORT_SYMBOL(ioread16_rep);
     342             : EXPORT_SYMBOL(ioread32_rep);
     343             : 
     344           0 : void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
     345             : {
     346           0 :         IO_COND(addr, outsb(port, src, count), mmio_outsb(addr, src, count));
     347           0 : }
     348           0 : void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
     349             : {
     350           0 :         IO_COND(addr, outsw(port, src, count), mmio_outsw(addr, src, count));
     351           0 : }
     352           0 : void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
     353             : {
     354           0 :         IO_COND(addr, outsl(port, src,count), mmio_outsl(addr, src, count));
     355           0 : }
     356             : EXPORT_SYMBOL(iowrite8_rep);
     357             : EXPORT_SYMBOL(iowrite16_rep);
     358             : EXPORT_SYMBOL(iowrite32_rep);
     359             : 
     360             : #ifdef CONFIG_HAS_IOPORT_MAP
     361             : /* Create a virtual mapping cookie for an IO port range */
     362           0 : void __iomem *ioport_map(unsigned long port, unsigned int nr)
     363             : {
     364           0 :         if (port > PIO_MASK)
     365             :                 return NULL;
     366           0 :         return (void __iomem *) (unsigned long) (port + PIO_OFFSET);
     367             : }
     368             : 
     369           0 : void ioport_unmap(void __iomem *addr)
     370             : {
     371             :         /* Nothing to do */
     372           0 : }
     373             : EXPORT_SYMBOL(ioport_map);
     374             : EXPORT_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. */
     380             : void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
     381             : {
     382             :         IO_COND(addr, /* nothing */, iounmap(addr));
     383             : }
     384             : EXPORT_SYMBOL(pci_iounmap);
     385             : #endif /* CONFIG_PCI */

Generated by: LCOV version 1.14