162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Implement the default iomap interfaces 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * (C) Copyright 2004 Linus Torvalds 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#include <linux/pci.h> 862306a36Sopenharmony_ci#include <linux/io.h> 962306a36Sopenharmony_ci#include <linux/kmsan-checks.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/export.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci * Read/write from/to an (offsettable) iomem cookie. It might be a PIO 1562306a36Sopenharmony_ci * access or a MMIO access, these functions don't care. The info is 1662306a36Sopenharmony_ci * encoded in the hardware mapping set up by the mapping functions 1762306a36Sopenharmony_ci * (or the cookie itself, depending on implementation and hw). 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * The generic routines don't assume any hardware mappings, and just 2062306a36Sopenharmony_ci * encode the PIO/MMIO as part of the cookie. They coldly assume that 2162306a36Sopenharmony_ci * the MMIO IO mappings are not in the low address range. 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * Architectures for which this is not true can't use this generic 2462306a36Sopenharmony_ci * implementation and should do their own copy. 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#ifndef HAVE_ARCH_PIO_SIZE 2862306a36Sopenharmony_ci/* 2962306a36Sopenharmony_ci * We encode the physical PIO addresses (0-0xffff) into the 3062306a36Sopenharmony_ci * pointer by offsetting them with a constant (0x10000) and 3162306a36Sopenharmony_ci * assuming that all the low addresses are always PIO. That means 3262306a36Sopenharmony_ci * we can do some sanity checks on the low bits, and don't 3362306a36Sopenharmony_ci * need to just take things for granted. 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_ci#define PIO_OFFSET 0x10000UL 3662306a36Sopenharmony_ci#define PIO_MASK 0x0ffffUL 3762306a36Sopenharmony_ci#define PIO_RESERVED 0x40000UL 3862306a36Sopenharmony_ci#endif 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic void bad_io_access(unsigned long port, const char *access) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci static int count = 10; 4362306a36Sopenharmony_ci if (count) { 4462306a36Sopenharmony_ci count--; 4562306a36Sopenharmony_ci WARN(1, KERN_ERR "Bad IO access at port %#lx (%s)\n", port, access); 4662306a36Sopenharmony_ci } 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/* 5062306a36Sopenharmony_ci * Ugly macros are a way of life. 5162306a36Sopenharmony_ci */ 5262306a36Sopenharmony_ci#define IO_COND(addr, is_pio, is_mmio) do { \ 5362306a36Sopenharmony_ci unsigned long port = (unsigned long __force)addr; \ 5462306a36Sopenharmony_ci if (port >= PIO_RESERVED) { \ 5562306a36Sopenharmony_ci is_mmio; \ 5662306a36Sopenharmony_ci } else if (port > PIO_OFFSET) { \ 5762306a36Sopenharmony_ci port &= PIO_MASK; \ 5862306a36Sopenharmony_ci is_pio; \ 5962306a36Sopenharmony_ci } else \ 6062306a36Sopenharmony_ci bad_io_access(port, #is_pio ); \ 6162306a36Sopenharmony_ci} while (0) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#ifndef pio_read16be 6462306a36Sopenharmony_ci#define pio_read16be(port) swab16(inw(port)) 6562306a36Sopenharmony_ci#define pio_read32be(port) swab32(inl(port)) 6662306a36Sopenharmony_ci#endif 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci#ifndef mmio_read16be 6962306a36Sopenharmony_ci#define mmio_read16be(addr) swab16(readw(addr)) 7062306a36Sopenharmony_ci#define mmio_read32be(addr) swab32(readl(addr)) 7162306a36Sopenharmony_ci#define mmio_read64be(addr) swab64(readq(addr)) 7262306a36Sopenharmony_ci#endif 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci/* 7562306a36Sopenharmony_ci * Here and below, we apply __no_kmsan_checks to functions reading data from 7662306a36Sopenharmony_ci * hardware, to ensure that KMSAN marks their return values as initialized. 7762306a36Sopenharmony_ci */ 7862306a36Sopenharmony_ci__no_kmsan_checks 7962306a36Sopenharmony_ciunsigned int ioread8(const void __iomem *addr) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci IO_COND(addr, return inb(port), return readb(addr)); 8262306a36Sopenharmony_ci return 0xff; 8362306a36Sopenharmony_ci} 8462306a36Sopenharmony_ci__no_kmsan_checks 8562306a36Sopenharmony_ciunsigned int ioread16(const void __iomem *addr) 8662306a36Sopenharmony_ci{ 8762306a36Sopenharmony_ci IO_COND(addr, return inw(port), return readw(addr)); 8862306a36Sopenharmony_ci return 0xffff; 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ci__no_kmsan_checks 9162306a36Sopenharmony_ciunsigned int ioread16be(const void __iomem *addr) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr)); 9462306a36Sopenharmony_ci return 0xffff; 9562306a36Sopenharmony_ci} 9662306a36Sopenharmony_ci__no_kmsan_checks 9762306a36Sopenharmony_ciunsigned int ioread32(const void __iomem *addr) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci IO_COND(addr, return inl(port), return readl(addr)); 10062306a36Sopenharmony_ci return 0xffffffff; 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci__no_kmsan_checks 10362306a36Sopenharmony_ciunsigned int ioread32be(const void __iomem *addr) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr)); 10662306a36Sopenharmony_ci return 0xffffffff; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ciEXPORT_SYMBOL(ioread8); 10962306a36Sopenharmony_ciEXPORT_SYMBOL(ioread16); 11062306a36Sopenharmony_ciEXPORT_SYMBOL(ioread16be); 11162306a36Sopenharmony_ciEXPORT_SYMBOL(ioread32); 11262306a36Sopenharmony_ciEXPORT_SYMBOL(ioread32be); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#ifdef readq 11562306a36Sopenharmony_cistatic u64 pio_read64_lo_hi(unsigned long port) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci u64 lo, hi; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci lo = inl(port); 12062306a36Sopenharmony_ci hi = inl(port + sizeof(u32)); 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci return lo | (hi << 32); 12362306a36Sopenharmony_ci} 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistatic u64 pio_read64_hi_lo(unsigned long port) 12662306a36Sopenharmony_ci{ 12762306a36Sopenharmony_ci u64 lo, hi; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci hi = inl(port + sizeof(u32)); 13062306a36Sopenharmony_ci lo = inl(port); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci return lo | (hi << 32); 13362306a36Sopenharmony_ci} 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistatic u64 pio_read64be_lo_hi(unsigned long port) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci u64 lo, hi; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci lo = pio_read32be(port + sizeof(u32)); 14062306a36Sopenharmony_ci hi = pio_read32be(port); 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci return lo | (hi << 32); 14362306a36Sopenharmony_ci} 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_cistatic u64 pio_read64be_hi_lo(unsigned long port) 14662306a36Sopenharmony_ci{ 14762306a36Sopenharmony_ci u64 lo, hi; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci hi = pio_read32be(port); 15062306a36Sopenharmony_ci lo = pio_read32be(port + sizeof(u32)); 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci return lo | (hi << 32); 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci__no_kmsan_checks 15662306a36Sopenharmony_ciu64 ioread64_lo_hi(const void __iomem *addr) 15762306a36Sopenharmony_ci{ 15862306a36Sopenharmony_ci IO_COND(addr, return pio_read64_lo_hi(port), return readq(addr)); 15962306a36Sopenharmony_ci return 0xffffffffffffffffULL; 16062306a36Sopenharmony_ci} 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci__no_kmsan_checks 16362306a36Sopenharmony_ciu64 ioread64_hi_lo(const void __iomem *addr) 16462306a36Sopenharmony_ci{ 16562306a36Sopenharmony_ci IO_COND(addr, return pio_read64_hi_lo(port), return readq(addr)); 16662306a36Sopenharmony_ci return 0xffffffffffffffffULL; 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci__no_kmsan_checks 17062306a36Sopenharmony_ciu64 ioread64be_lo_hi(const void __iomem *addr) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci IO_COND(addr, return pio_read64be_lo_hi(port), 17362306a36Sopenharmony_ci return mmio_read64be(addr)); 17462306a36Sopenharmony_ci return 0xffffffffffffffffULL; 17562306a36Sopenharmony_ci} 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci__no_kmsan_checks 17862306a36Sopenharmony_ciu64 ioread64be_hi_lo(const void __iomem *addr) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci IO_COND(addr, return pio_read64be_hi_lo(port), 18162306a36Sopenharmony_ci return mmio_read64be(addr)); 18262306a36Sopenharmony_ci return 0xffffffffffffffffULL; 18362306a36Sopenharmony_ci} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ciEXPORT_SYMBOL(ioread64_lo_hi); 18662306a36Sopenharmony_ciEXPORT_SYMBOL(ioread64_hi_lo); 18762306a36Sopenharmony_ciEXPORT_SYMBOL(ioread64be_lo_hi); 18862306a36Sopenharmony_ciEXPORT_SYMBOL(ioread64be_hi_lo); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci#endif /* readq */ 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci#ifndef pio_write16be 19362306a36Sopenharmony_ci#define pio_write16be(val,port) outw(swab16(val),port) 19462306a36Sopenharmony_ci#define pio_write32be(val,port) outl(swab32(val),port) 19562306a36Sopenharmony_ci#endif 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci#ifndef mmio_write16be 19862306a36Sopenharmony_ci#define mmio_write16be(val,port) writew(swab16(val),port) 19962306a36Sopenharmony_ci#define mmio_write32be(val,port) writel(swab32(val),port) 20062306a36Sopenharmony_ci#define mmio_write64be(val,port) writeq(swab64(val),port) 20162306a36Sopenharmony_ci#endif 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_civoid iowrite8(u8 val, void __iomem *addr) 20462306a36Sopenharmony_ci{ 20562306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 20662306a36Sopenharmony_ci kmsan_check_memory(&val, sizeof(val)); 20762306a36Sopenharmony_ci IO_COND(addr, outb(val,port), writeb(val, addr)); 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_civoid iowrite16(u16 val, void __iomem *addr) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 21262306a36Sopenharmony_ci kmsan_check_memory(&val, sizeof(val)); 21362306a36Sopenharmony_ci IO_COND(addr, outw(val,port), writew(val, addr)); 21462306a36Sopenharmony_ci} 21562306a36Sopenharmony_civoid iowrite16be(u16 val, void __iomem *addr) 21662306a36Sopenharmony_ci{ 21762306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 21862306a36Sopenharmony_ci kmsan_check_memory(&val, sizeof(val)); 21962306a36Sopenharmony_ci IO_COND(addr, pio_write16be(val,port), mmio_write16be(val, addr)); 22062306a36Sopenharmony_ci} 22162306a36Sopenharmony_civoid iowrite32(u32 val, void __iomem *addr) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 22462306a36Sopenharmony_ci kmsan_check_memory(&val, sizeof(val)); 22562306a36Sopenharmony_ci IO_COND(addr, outl(val,port), writel(val, addr)); 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_civoid iowrite32be(u32 val, void __iomem *addr) 22862306a36Sopenharmony_ci{ 22962306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 23062306a36Sopenharmony_ci kmsan_check_memory(&val, sizeof(val)); 23162306a36Sopenharmony_ci IO_COND(addr, pio_write32be(val,port), mmio_write32be(val, addr)); 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite8); 23462306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite16); 23562306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite16be); 23662306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite32); 23762306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite32be); 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci#ifdef writeq 24062306a36Sopenharmony_cistatic void pio_write64_lo_hi(u64 val, unsigned long port) 24162306a36Sopenharmony_ci{ 24262306a36Sopenharmony_ci outl(val, port); 24362306a36Sopenharmony_ci outl(val >> 32, port + sizeof(u32)); 24462306a36Sopenharmony_ci} 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_cistatic void pio_write64_hi_lo(u64 val, unsigned long port) 24762306a36Sopenharmony_ci{ 24862306a36Sopenharmony_ci outl(val >> 32, port + sizeof(u32)); 24962306a36Sopenharmony_ci outl(val, port); 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_cistatic void pio_write64be_lo_hi(u64 val, unsigned long port) 25362306a36Sopenharmony_ci{ 25462306a36Sopenharmony_ci pio_write32be(val, port + sizeof(u32)); 25562306a36Sopenharmony_ci pio_write32be(val >> 32, port); 25662306a36Sopenharmony_ci} 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistatic void pio_write64be_hi_lo(u64 val, unsigned long port) 25962306a36Sopenharmony_ci{ 26062306a36Sopenharmony_ci pio_write32be(val >> 32, port); 26162306a36Sopenharmony_ci pio_write32be(val, port + sizeof(u32)); 26262306a36Sopenharmony_ci} 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_civoid iowrite64_lo_hi(u64 val, void __iomem *addr) 26562306a36Sopenharmony_ci{ 26662306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 26762306a36Sopenharmony_ci kmsan_check_memory(&val, sizeof(val)); 26862306a36Sopenharmony_ci IO_COND(addr, pio_write64_lo_hi(val, port), 26962306a36Sopenharmony_ci writeq(val, addr)); 27062306a36Sopenharmony_ci} 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_civoid iowrite64_hi_lo(u64 val, void __iomem *addr) 27362306a36Sopenharmony_ci{ 27462306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 27562306a36Sopenharmony_ci kmsan_check_memory(&val, sizeof(val)); 27662306a36Sopenharmony_ci IO_COND(addr, pio_write64_hi_lo(val, port), 27762306a36Sopenharmony_ci writeq(val, addr)); 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_civoid iowrite64be_lo_hi(u64 val, void __iomem *addr) 28162306a36Sopenharmony_ci{ 28262306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 28362306a36Sopenharmony_ci kmsan_check_memory(&val, sizeof(val)); 28462306a36Sopenharmony_ci IO_COND(addr, pio_write64be_lo_hi(val, port), 28562306a36Sopenharmony_ci mmio_write64be(val, addr)); 28662306a36Sopenharmony_ci} 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_civoid iowrite64be_hi_lo(u64 val, void __iomem *addr) 28962306a36Sopenharmony_ci{ 29062306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 29162306a36Sopenharmony_ci kmsan_check_memory(&val, sizeof(val)); 29262306a36Sopenharmony_ci IO_COND(addr, pio_write64be_hi_lo(val, port), 29362306a36Sopenharmony_ci mmio_write64be(val, addr)); 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite64_lo_hi); 29762306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite64_hi_lo); 29862306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite64be_lo_hi); 29962306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite64be_hi_lo); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci#endif /* readq */ 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci/* 30462306a36Sopenharmony_ci * These are the "repeat MMIO read/write" functions. 30562306a36Sopenharmony_ci * Note the "__raw" accesses, since we don't want to 30662306a36Sopenharmony_ci * convert to CPU byte order. We write in "IO byte 30762306a36Sopenharmony_ci * order" (we also don't have IO barriers). 30862306a36Sopenharmony_ci */ 30962306a36Sopenharmony_ci#ifndef mmio_insb 31062306a36Sopenharmony_cistatic inline void mmio_insb(const void __iomem *addr, u8 *dst, int count) 31162306a36Sopenharmony_ci{ 31262306a36Sopenharmony_ci while (--count >= 0) { 31362306a36Sopenharmony_ci u8 data = __raw_readb(addr); 31462306a36Sopenharmony_ci *dst = data; 31562306a36Sopenharmony_ci dst++; 31662306a36Sopenharmony_ci } 31762306a36Sopenharmony_ci} 31862306a36Sopenharmony_cistatic inline void mmio_insw(const void __iomem *addr, u16 *dst, int count) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci while (--count >= 0) { 32162306a36Sopenharmony_ci u16 data = __raw_readw(addr); 32262306a36Sopenharmony_ci *dst = data; 32362306a36Sopenharmony_ci dst++; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci} 32662306a36Sopenharmony_cistatic inline void mmio_insl(const void __iomem *addr, u32 *dst, int count) 32762306a36Sopenharmony_ci{ 32862306a36Sopenharmony_ci while (--count >= 0) { 32962306a36Sopenharmony_ci u32 data = __raw_readl(addr); 33062306a36Sopenharmony_ci *dst = data; 33162306a36Sopenharmony_ci dst++; 33262306a36Sopenharmony_ci } 33362306a36Sopenharmony_ci} 33462306a36Sopenharmony_ci#endif 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci#ifndef mmio_outsb 33762306a36Sopenharmony_cistatic inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) 33862306a36Sopenharmony_ci{ 33962306a36Sopenharmony_ci while (--count >= 0) { 34062306a36Sopenharmony_ci __raw_writeb(*src, addr); 34162306a36Sopenharmony_ci src++; 34262306a36Sopenharmony_ci } 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_cistatic inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) 34562306a36Sopenharmony_ci{ 34662306a36Sopenharmony_ci while (--count >= 0) { 34762306a36Sopenharmony_ci __raw_writew(*src, addr); 34862306a36Sopenharmony_ci src++; 34962306a36Sopenharmony_ci } 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_cistatic inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) 35262306a36Sopenharmony_ci{ 35362306a36Sopenharmony_ci while (--count >= 0) { 35462306a36Sopenharmony_ci __raw_writel(*src, addr); 35562306a36Sopenharmony_ci src++; 35662306a36Sopenharmony_ci } 35762306a36Sopenharmony_ci} 35862306a36Sopenharmony_ci#endif 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_civoid ioread8_rep(const void __iomem *addr, void *dst, unsigned long count) 36162306a36Sopenharmony_ci{ 36262306a36Sopenharmony_ci IO_COND(addr, insb(port,dst,count), mmio_insb(addr, dst, count)); 36362306a36Sopenharmony_ci /* KMSAN must treat values read from devices as initialized. */ 36462306a36Sopenharmony_ci kmsan_unpoison_memory(dst, count); 36562306a36Sopenharmony_ci} 36662306a36Sopenharmony_civoid ioread16_rep(const void __iomem *addr, void *dst, unsigned long count) 36762306a36Sopenharmony_ci{ 36862306a36Sopenharmony_ci IO_COND(addr, insw(port,dst,count), mmio_insw(addr, dst, count)); 36962306a36Sopenharmony_ci /* KMSAN must treat values read from devices as initialized. */ 37062306a36Sopenharmony_ci kmsan_unpoison_memory(dst, count * 2); 37162306a36Sopenharmony_ci} 37262306a36Sopenharmony_civoid ioread32_rep(const void __iomem *addr, void *dst, unsigned long count) 37362306a36Sopenharmony_ci{ 37462306a36Sopenharmony_ci IO_COND(addr, insl(port,dst,count), mmio_insl(addr, dst, count)); 37562306a36Sopenharmony_ci /* KMSAN must treat values read from devices as initialized. */ 37662306a36Sopenharmony_ci kmsan_unpoison_memory(dst, count * 4); 37762306a36Sopenharmony_ci} 37862306a36Sopenharmony_ciEXPORT_SYMBOL(ioread8_rep); 37962306a36Sopenharmony_ciEXPORT_SYMBOL(ioread16_rep); 38062306a36Sopenharmony_ciEXPORT_SYMBOL(ioread32_rep); 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_civoid iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) 38362306a36Sopenharmony_ci{ 38462306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 38562306a36Sopenharmony_ci kmsan_check_memory(src, count); 38662306a36Sopenharmony_ci IO_COND(addr, outsb(port, src, count), mmio_outsb(addr, src, count)); 38762306a36Sopenharmony_ci} 38862306a36Sopenharmony_civoid iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) 38962306a36Sopenharmony_ci{ 39062306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 39162306a36Sopenharmony_ci kmsan_check_memory(src, count * 2); 39262306a36Sopenharmony_ci IO_COND(addr, outsw(port, src, count), mmio_outsw(addr, src, count)); 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_civoid iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) 39562306a36Sopenharmony_ci{ 39662306a36Sopenharmony_ci /* Make sure uninitialized memory isn't copied to devices. */ 39762306a36Sopenharmony_ci kmsan_check_memory(src, count * 4); 39862306a36Sopenharmony_ci IO_COND(addr, outsl(port, src,count), mmio_outsl(addr, src, count)); 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite8_rep); 40162306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite16_rep); 40262306a36Sopenharmony_ciEXPORT_SYMBOL(iowrite32_rep); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci#ifdef CONFIG_HAS_IOPORT_MAP 40562306a36Sopenharmony_ci/* Create a virtual mapping cookie for an IO port range */ 40662306a36Sopenharmony_civoid __iomem *ioport_map(unsigned long port, unsigned int nr) 40762306a36Sopenharmony_ci{ 40862306a36Sopenharmony_ci if (port > PIO_MASK) 40962306a36Sopenharmony_ci return NULL; 41062306a36Sopenharmony_ci return (void __iomem *) (unsigned long) (port + PIO_OFFSET); 41162306a36Sopenharmony_ci} 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_civoid ioport_unmap(void __iomem *addr) 41462306a36Sopenharmony_ci{ 41562306a36Sopenharmony_ci /* Nothing to do */ 41662306a36Sopenharmony_ci} 41762306a36Sopenharmony_ciEXPORT_SYMBOL(ioport_map); 41862306a36Sopenharmony_ciEXPORT_SYMBOL(ioport_unmap); 41962306a36Sopenharmony_ci#endif /* CONFIG_HAS_IOPORT_MAP */ 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci#ifdef CONFIG_PCI 42262306a36Sopenharmony_ci/* Hide the details if this is a MMIO or PIO address space and just do what 42362306a36Sopenharmony_ci * you expect in the correct way. */ 42462306a36Sopenharmony_civoid pci_iounmap(struct pci_dev *dev, void __iomem * addr) 42562306a36Sopenharmony_ci{ 42662306a36Sopenharmony_ci IO_COND(addr, /* nothing */, iounmap(addr)); 42762306a36Sopenharmony_ci} 42862306a36Sopenharmony_ciEXPORT_SYMBOL(pci_iounmap); 42962306a36Sopenharmony_ci#endif /* CONFIG_PCI */ 430