linux/lib/iomap.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Implement the default iomap interfaces
 *
 * (C) Copyright 2004 Linus Torvalds
 */
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/kmsan-checks.h>

#include <linux/export.h>

/*
 * Read/write from/to an (offsettable) iomem cookie. It might be a PIO
 * access or a MMIO access, these functions don't care. The info is
 * encoded in the hardware mapping set up by the mapping functions
 * (or the cookie itself, depending on implementation and hw).
 *
 * The generic routines don't assume any hardware mappings, and just
 * encode the PIO/MMIO as part of the cookie. They coldly assume that
 * the MMIO IO mappings are not in the low address range.
 *
 * Architectures for which this is not true can't use this generic
 * implementation and should do their own copy.
 */

#ifndef HAVE_ARCH_PIO_SIZE
/*
 * We encode the physical PIO addresses (0-0xffff) into the
 * pointer by offsetting them with a constant (0x10000) and
 * assuming that all the low addresses are always PIO. That means
 * we can do some sanity checks on the low bits, and don't
 * need to just take things for granted.
 */
#define PIO_OFFSET
#define PIO_MASK
#define PIO_RESERVED
#endif

static void bad_io_access(unsigned long port, const char *access)
{}

/*
 * Ugly macros are a way of life.
 */
#define IO_COND(addr, is_pio, is_mmio)

#ifndef pio_read16be
#define pio_read16be(port)
#define pio_read32be(port)
#endif

#ifndef mmio_read16be
#define mmio_read16be(addr)
#define mmio_read32be(addr)
#define mmio_read64be(addr)
#endif

/*
 * Here and below, we apply __no_kmsan_checks to functions reading data from
 * hardware, to ensure that KMSAN marks their return values as initialized.
 */
__no_kmsan_checks
unsigned int ioread8(const void __iomem *addr)
{}
__no_kmsan_checks
unsigned int ioread16(const void __iomem *addr)
{}
__no_kmsan_checks
unsigned int ioread16be(const void __iomem *addr)
{}
__no_kmsan_checks
unsigned int ioread32(const void __iomem *addr)
{}
__no_kmsan_checks
unsigned int ioread32be(const void __iomem *addr)
{}
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();

#ifdef readq
static u64 pio_read64_lo_hi(unsigned long port)
{}

static u64 pio_read64_hi_lo(unsigned long port)
{}

static u64 pio_read64be_lo_hi(unsigned long port)
{}

static u64 pio_read64be_hi_lo(unsigned long port)
{}

__no_kmsan_checks
u64 ioread64_lo_hi(const void __iomem *addr)
{}

__no_kmsan_checks
u64 ioread64_hi_lo(const void __iomem *addr)
{}

__no_kmsan_checks
u64 ioread64be_lo_hi(const void __iomem *addr)
{}

__no_kmsan_checks
u64 ioread64be_hi_lo(const void __iomem *addr)
{}

EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();

#endif /* readq */

#ifndef pio_write16be
#define pio_write16be(val,port)
#define pio_write32be(val,port)
#endif

#ifndef mmio_write16be
#define mmio_write16be(val,port)
#define mmio_write32be(val,port)
#define mmio_write64be(val,port)
#endif

void iowrite8(u8 val, void __iomem *addr)
{}
void iowrite16(u16 val, void __iomem *addr)
{}
void iowrite16be(u16 val, void __iomem *addr)
{}
void iowrite32(u32 val, void __iomem *addr)
{}
void iowrite32be(u32 val, void __iomem *addr)
{}
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();

#ifdef writeq
static void pio_write64_lo_hi(u64 val, unsigned long port)
{}

static void pio_write64_hi_lo(u64 val, unsigned long port)
{}

static void pio_write64be_lo_hi(u64 val, unsigned long port)
{}

static void pio_write64be_hi_lo(u64 val, unsigned long port)
{}

void iowrite64_lo_hi(u64 val, void __iomem *addr)
{}

void iowrite64_hi_lo(u64 val, void __iomem *addr)
{}

void iowrite64be_lo_hi(u64 val, void __iomem *addr)
{}

void iowrite64be_hi_lo(u64 val, void __iomem *addr)
{}

EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();

#endif /* readq */

/*
 * These are the "repeat MMIO read/write" functions.
 * Note the "__raw" accesses, since we don't want to
 * convert to CPU byte order. We write in "IO byte
 * order" (we also don't have IO barriers).
 */
#ifndef mmio_insb
static inline void mmio_insb(const void __iomem *addr, u8 *dst, int count)
{}
static inline void mmio_insw(const void __iomem *addr, u16 *dst, int count)
{}
static inline void mmio_insl(const void __iomem *addr, u32 *dst, int count)
{}
#endif

#ifndef mmio_outsb
static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
{}
static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count)
{}
static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
{}
#endif

void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
{}
void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)
{}
void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)
{}
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();

void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
{}
void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
{}
void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
{}
EXPORT_SYMBOL();
EXPORT_SYMBOL();
EXPORT_SYMBOL();

#ifdef CONFIG_HAS_IOPORT_MAP
/* Create a virtual mapping cookie for an IO port range */
void __iomem *ioport_map(unsigned long port, unsigned int nr)
{}

void ioport_unmap(void __iomem *addr)
{}
EXPORT_SYMBOL();
EXPORT_SYMBOL();
#endif /* CONFIG_HAS_IOPORT_MAP */

#ifdef CONFIG_PCI
/* Hide the details if this is a MMIO or PIO address space and just do what
 * you expect in the correct way. */
void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
{}
EXPORT_SYMBOL();
#endif /* CONFIG_PCI */