18d59ecb2SHans Petter Selasky /*- 28d59ecb2SHans Petter Selasky * Copyright (c) 2010 Isilon Systems, Inc. 38d59ecb2SHans Petter Selasky * Copyright (c) 2010 iX Systems, Inc. 48d59ecb2SHans Petter Selasky * Copyright (c) 2010 Panasas, Inc. 586845417SHans Petter Selasky * Copyright (c) 2013-2015 Mellanox Technologies, Ltd. 68d59ecb2SHans Petter Selasky * All rights reserved. 78d59ecb2SHans Petter Selasky * 88d59ecb2SHans Petter Selasky * Redistribution and use in source and binary forms, with or without 98d59ecb2SHans Petter Selasky * modification, are permitted provided that the following conditions 108d59ecb2SHans Petter Selasky * are met: 118d59ecb2SHans Petter Selasky * 1. Redistributions of source code must retain the above copyright 128d59ecb2SHans Petter Selasky * notice unmodified, this list of conditions, and the following 138d59ecb2SHans Petter Selasky * disclaimer. 148d59ecb2SHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright 158d59ecb2SHans Petter Selasky * notice, this list of conditions and the following disclaimer in the 168d59ecb2SHans Petter Selasky * documentation and/or other materials provided with the distribution. 178d59ecb2SHans Petter Selasky * 188d59ecb2SHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 198d59ecb2SHans Petter Selasky * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 208d59ecb2SHans Petter Selasky * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 218d59ecb2SHans Petter Selasky * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 228d59ecb2SHans Petter Selasky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 238d59ecb2SHans Petter Selasky * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 248d59ecb2SHans Petter Selasky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 258d59ecb2SHans Petter Selasky * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 268d59ecb2SHans Petter Selasky * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 278d59ecb2SHans Petter Selasky * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 288d59ecb2SHans Petter Selasky */ 29307f78f3SVladimir Kondratyev #ifndef _LINUXKPI_LINUX_IO_H_ 30307f78f3SVladimir Kondratyev #define _LINUXKPI_LINUX_IO_H_ 318d59ecb2SHans Petter Selasky 328d59ecb2SHans Petter Selasky #include <sys/endian.h> 338e7baabcSHans Petter Selasky #include <sys/types.h> 348d59ecb2SHans Petter Selasky 35588fbadfSHans Petter Selasky #include <machine/vm.h> 36588fbadfSHans Petter Selasky 37684a5fefSHans Petter Selasky #include <linux/compiler.h> 38af787b8eSVladimir Kondratyev #include <linux/err.h> 39cb564d24SMark Johnston #include <linux/types.h> 40521abc32SEmmanuel Vadot #if !defined(__arm__) 41789dbdbbSEmmanuel Vadot #include <asm/set_memory.h> 42d387a1b4SEmmanuel Vadot #endif 43684a5fefSHans Petter Selasky 448d59ecb2SHans Petter Selasky /* 458d59ecb2SHans Petter Selasky * XXX This is all x86 specific. It should be bus space access. 468d59ecb2SHans Petter Selasky */ 478d59ecb2SHans Petter Selasky 48937a05baSJustin Hibbits /* rmb and wmb are declared in machine/atomic.h, so should be included first. */ 49937a05baSJustin Hibbits #ifndef __io_br 50937a05baSJustin Hibbits #define __io_br() __compiler_membar() 51937a05baSJustin Hibbits #endif 52937a05baSJustin Hibbits 53937a05baSJustin Hibbits #ifndef __io_ar 54937a05baSJustin Hibbits #ifdef rmb 55937a05baSJustin Hibbits #define __io_ar() rmb() 56937a05baSJustin Hibbits #else 57937a05baSJustin Hibbits #define __io_ar() __compiler_membar() 58937a05baSJustin Hibbits #endif 59937a05baSJustin Hibbits #endif 60937a05baSJustin Hibbits 61937a05baSJustin Hibbits #ifndef __io_bw 62937a05baSJustin Hibbits #ifdef wmb 63937a05baSJustin Hibbits #define __io_bw() wmb() 64937a05baSJustin Hibbits #else 65937a05baSJustin Hibbits #define __io_bw() __compiler_membar() 66937a05baSJustin Hibbits #endif 67937a05baSJustin Hibbits #endif 68937a05baSJustin Hibbits 69937a05baSJustin Hibbits #ifndef __io_aw 70937a05baSJustin Hibbits #define __io_aw() __compiler_membar() 71937a05baSJustin Hibbits #endif 72937a05baSJustin Hibbits 73642909fdSTijl Coosemans /* Access MMIO registers atomically without barriers and byte swapping. */ 748d59ecb2SHans Petter Selasky 75684a5fefSHans Petter Selasky static inline uint8_t 76642909fdSTijl Coosemans __raw_readb(const volatile void *addr) 77684a5fefSHans Petter Selasky { 78642909fdSTijl Coosemans return (*(const volatile uint8_t *)addr); 79684a5fefSHans Petter Selasky } 80642909fdSTijl Coosemans #define __raw_readb(addr) __raw_readb(addr) 81684a5fefSHans Petter Selasky 82684a5fefSHans Petter Selasky static inline void 83642909fdSTijl Coosemans __raw_writeb(uint8_t v, volatile void *addr) 84684a5fefSHans Petter Selasky { 85684a5fefSHans Petter Selasky *(volatile uint8_t *)addr = v; 86684a5fefSHans Petter Selasky } 87642909fdSTijl Coosemans #define __raw_writeb(v, addr) __raw_writeb(v, addr) 88684a5fefSHans Petter Selasky 89642909fdSTijl Coosemans static inline uint16_t 90642909fdSTijl Coosemans __raw_readw(const volatile void *addr) 91642909fdSTijl Coosemans { 92642909fdSTijl Coosemans return (*(const volatile uint16_t *)addr); 93642909fdSTijl Coosemans } 94642909fdSTijl Coosemans #define __raw_readw(addr) __raw_readw(addr) 95642909fdSTijl Coosemans 96684a5fefSHans Petter Selasky static inline void 97642909fdSTijl Coosemans __raw_writew(uint16_t v, volatile void *addr) 98684a5fefSHans Petter Selasky { 99684a5fefSHans Petter Selasky *(volatile uint16_t *)addr = v; 100684a5fefSHans Petter Selasky } 101642909fdSTijl Coosemans #define __raw_writew(v, addr) __raw_writew(v, addr) 102684a5fefSHans Petter Selasky 103642909fdSTijl Coosemans static inline uint32_t 104642909fdSTijl Coosemans __raw_readl(const volatile void *addr) 105642909fdSTijl Coosemans { 106642909fdSTijl Coosemans return (*(const volatile uint32_t *)addr); 107642909fdSTijl Coosemans } 108642909fdSTijl Coosemans #define __raw_readl(addr) __raw_readl(addr) 109642909fdSTijl Coosemans 110684a5fefSHans Petter Selasky static inline void 111642909fdSTijl Coosemans __raw_writel(uint32_t v, volatile void *addr) 112684a5fefSHans Petter Selasky { 113684a5fefSHans Petter Selasky *(volatile uint32_t *)addr = v; 114684a5fefSHans Petter Selasky } 115642909fdSTijl Coosemans #define __raw_writel(v, addr) __raw_writel(v, addr) 116684a5fefSHans Petter Selasky 117642909fdSTijl Coosemans #ifdef __LP64__ 118642909fdSTijl Coosemans static inline uint64_t 119642909fdSTijl Coosemans __raw_readq(const volatile void *addr) 1208d59ecb2SHans Petter Selasky { 121642909fdSTijl Coosemans return (*(const volatile uint64_t *)addr); 1228d59ecb2SHans Petter Selasky } 123642909fdSTijl Coosemans #define __raw_readq(addr) __raw_readq(addr) 124642909fdSTijl Coosemans 125642909fdSTijl Coosemans static inline void 126642909fdSTijl Coosemans __raw_writeq(uint64_t v, volatile void *addr) 127642909fdSTijl Coosemans { 128642909fdSTijl Coosemans *(volatile uint64_t *)addr = v; 129642909fdSTijl Coosemans } 130642909fdSTijl Coosemans #define __raw_writeq(v, addr) __raw_writeq(v, addr) 131642909fdSTijl Coosemans #endif 132642909fdSTijl Coosemans 133642909fdSTijl Coosemans #define mmiowb() barrier() 134642909fdSTijl Coosemans 135642909fdSTijl Coosemans /* Access little-endian MMIO registers atomically with memory barriers. */ 1368d59ecb2SHans Petter Selasky 13786845417SHans Petter Selasky #undef readb 13886845417SHans Petter Selasky static inline uint8_t 13986845417SHans Petter Selasky readb(const volatile void *addr) 14086845417SHans Petter Selasky { 141642909fdSTijl Coosemans uint8_t v; 142642909fdSTijl Coosemans 143937a05baSJustin Hibbits __io_br(); 144642909fdSTijl Coosemans v = *(const volatile uint8_t *)addr; 145937a05baSJustin Hibbits __io_ar(); 146642909fdSTijl Coosemans return (v); 14786845417SHans Petter Selasky } 148642909fdSTijl Coosemans #define readb(addr) readb(addr) 149642909fdSTijl Coosemans 150642909fdSTijl Coosemans #undef writeb 151642909fdSTijl Coosemans static inline void 152642909fdSTijl Coosemans writeb(uint8_t v, volatile void *addr) 153642909fdSTijl Coosemans { 154937a05baSJustin Hibbits __io_bw(); 155642909fdSTijl Coosemans *(volatile uint8_t *)addr = v; 156937a05baSJustin Hibbits __io_aw(); 157642909fdSTijl Coosemans } 158642909fdSTijl Coosemans #define writeb(v, addr) writeb(v, addr) 15986845417SHans Petter Selasky 16086845417SHans Petter Selasky #undef readw 16186845417SHans Petter Selasky static inline uint16_t 16286845417SHans Petter Selasky readw(const volatile void *addr) 16386845417SHans Petter Selasky { 164642909fdSTijl Coosemans uint16_t v; 165642909fdSTijl Coosemans 166937a05baSJustin Hibbits __io_br(); 167937a05baSJustin Hibbits v = le16toh(__raw_readw(addr)); 168937a05baSJustin Hibbits __io_ar(); 169642909fdSTijl Coosemans return (v); 17086845417SHans Petter Selasky } 171642909fdSTijl Coosemans #define readw(addr) readw(addr) 172642909fdSTijl Coosemans 173642909fdSTijl Coosemans #undef writew 174642909fdSTijl Coosemans static inline void 175642909fdSTijl Coosemans writew(uint16_t v, volatile void *addr) 176642909fdSTijl Coosemans { 177937a05baSJustin Hibbits __io_bw(); 178937a05baSJustin Hibbits __raw_writew(htole16(v), addr); 179937a05baSJustin Hibbits __io_aw(); 180642909fdSTijl Coosemans } 181642909fdSTijl Coosemans #define writew(v, addr) writew(v, addr) 18286845417SHans Petter Selasky 18386845417SHans Petter Selasky #undef readl 18486845417SHans Petter Selasky static inline uint32_t 18586845417SHans Petter Selasky readl(const volatile void *addr) 18686845417SHans Petter Selasky { 187642909fdSTijl Coosemans uint32_t v; 188642909fdSTijl Coosemans 189937a05baSJustin Hibbits __io_br(); 190937a05baSJustin Hibbits v = le32toh(__raw_readl(addr)); 191937a05baSJustin Hibbits __io_ar(); 192642909fdSTijl Coosemans return (v); 19386845417SHans Petter Selasky } 194642909fdSTijl Coosemans #define readl(addr) readl(addr) 195642909fdSTijl Coosemans 196642909fdSTijl Coosemans #undef writel 197642909fdSTijl Coosemans static inline void 198642909fdSTijl Coosemans writel(uint32_t v, volatile void *addr) 199642909fdSTijl Coosemans { 200937a05baSJustin Hibbits __io_bw(); 201937a05baSJustin Hibbits __raw_writel(htole32(v), addr); 202937a05baSJustin Hibbits __io_aw(); 203642909fdSTijl Coosemans } 204642909fdSTijl Coosemans #define writel(v, addr) writel(v, addr) 205642909fdSTijl Coosemans 206642909fdSTijl Coosemans #undef readq 207642909fdSTijl Coosemans #undef writeq 208642909fdSTijl Coosemans #ifdef __LP64__ 209642909fdSTijl Coosemans static inline uint64_t 210642909fdSTijl Coosemans readq(const volatile void *addr) 211642909fdSTijl Coosemans { 212642909fdSTijl Coosemans uint64_t v; 213642909fdSTijl Coosemans 214937a05baSJustin Hibbits __io_br(); 215937a05baSJustin Hibbits v = le64toh(__raw_readq(addr)); 216937a05baSJustin Hibbits __io_ar(); 217642909fdSTijl Coosemans return (v); 218642909fdSTijl Coosemans } 219642909fdSTijl Coosemans #define readq(addr) readq(addr) 220642909fdSTijl Coosemans 221642909fdSTijl Coosemans static inline void 222642909fdSTijl Coosemans writeq(uint64_t v, volatile void *addr) 223642909fdSTijl Coosemans { 224937a05baSJustin Hibbits __io_bw(); 225937a05baSJustin Hibbits __raw_writeq(htole64(v), addr); 226937a05baSJustin Hibbits __io_aw(); 227642909fdSTijl Coosemans } 228642909fdSTijl Coosemans #define writeq(v, addr) writeq(v, addr) 229642909fdSTijl Coosemans #endif 230642909fdSTijl Coosemans 231642909fdSTijl Coosemans /* Access little-endian MMIO registers atomically without memory barriers. */ 232642909fdSTijl Coosemans 233642909fdSTijl Coosemans #undef readb_relaxed 234642909fdSTijl Coosemans static inline uint8_t 235642909fdSTijl Coosemans readb_relaxed(const volatile void *addr) 236642909fdSTijl Coosemans { 237937a05baSJustin Hibbits return (__raw_readb(addr)); 238642909fdSTijl Coosemans } 239642909fdSTijl Coosemans #define readb_relaxed(addr) readb_relaxed(addr) 240642909fdSTijl Coosemans 241642909fdSTijl Coosemans #undef writeb_relaxed 242642909fdSTijl Coosemans static inline void 243642909fdSTijl Coosemans writeb_relaxed(uint8_t v, volatile void *addr) 244642909fdSTijl Coosemans { 245937a05baSJustin Hibbits __raw_writeb(v, addr); 246642909fdSTijl Coosemans } 247642909fdSTijl Coosemans #define writeb_relaxed(v, addr) writeb_relaxed(v, addr) 248642909fdSTijl Coosemans 249642909fdSTijl Coosemans #undef readw_relaxed 250642909fdSTijl Coosemans static inline uint16_t 251642909fdSTijl Coosemans readw_relaxed(const volatile void *addr) 252642909fdSTijl Coosemans { 253937a05baSJustin Hibbits return (le16toh(__raw_readw(addr))); 254642909fdSTijl Coosemans } 255642909fdSTijl Coosemans #define readw_relaxed(addr) readw_relaxed(addr) 256642909fdSTijl Coosemans 257642909fdSTijl Coosemans #undef writew_relaxed 258642909fdSTijl Coosemans static inline void 259642909fdSTijl Coosemans writew_relaxed(uint16_t v, volatile void *addr) 260642909fdSTijl Coosemans { 261937a05baSJustin Hibbits __raw_writew(htole16(v), addr); 262642909fdSTijl Coosemans } 263642909fdSTijl Coosemans #define writew_relaxed(v, addr) writew_relaxed(v, addr) 264642909fdSTijl Coosemans 265642909fdSTijl Coosemans #undef readl_relaxed 266642909fdSTijl Coosemans static inline uint32_t 267642909fdSTijl Coosemans readl_relaxed(const volatile void *addr) 268642909fdSTijl Coosemans { 269937a05baSJustin Hibbits return (le32toh(__raw_readl(addr))); 270642909fdSTijl Coosemans } 271642909fdSTijl Coosemans #define readl_relaxed(addr) readl_relaxed(addr) 272642909fdSTijl Coosemans 273642909fdSTijl Coosemans #undef writel_relaxed 274642909fdSTijl Coosemans static inline void 275642909fdSTijl Coosemans writel_relaxed(uint32_t v, volatile void *addr) 276642909fdSTijl Coosemans { 277937a05baSJustin Hibbits __raw_writel(htole32(v), addr); 278642909fdSTijl Coosemans } 279642909fdSTijl Coosemans #define writel_relaxed(v, addr) writel_relaxed(v, addr) 280642909fdSTijl Coosemans 281642909fdSTijl Coosemans #undef readq_relaxed 282642909fdSTijl Coosemans #undef writeq_relaxed 283642909fdSTijl Coosemans #ifdef __LP64__ 284642909fdSTijl Coosemans static inline uint64_t 285642909fdSTijl Coosemans readq_relaxed(const volatile void *addr) 286642909fdSTijl Coosemans { 287937a05baSJustin Hibbits return (le64toh(__raw_readq(addr))); 288642909fdSTijl Coosemans } 289642909fdSTijl Coosemans #define readq_relaxed(addr) readq_relaxed(addr) 290642909fdSTijl Coosemans 291642909fdSTijl Coosemans static inline void 292642909fdSTijl Coosemans writeq_relaxed(uint64_t v, volatile void *addr) 293642909fdSTijl Coosemans { 294937a05baSJustin Hibbits __raw_writeq(htole64(v), addr); 295642909fdSTijl Coosemans } 296642909fdSTijl Coosemans #define writeq_relaxed(v, addr) writeq_relaxed(v, addr) 297642909fdSTijl Coosemans #endif 298642909fdSTijl Coosemans 299642909fdSTijl Coosemans /* XXX On Linux ioread and iowrite handle both MMIO and port IO. */ 300642909fdSTijl Coosemans 301642909fdSTijl Coosemans #undef ioread8 302642909fdSTijl Coosemans static inline uint8_t 303642909fdSTijl Coosemans ioread8(const volatile void *addr) 304642909fdSTijl Coosemans { 305642909fdSTijl Coosemans return (readb(addr)); 306642909fdSTijl Coosemans } 307642909fdSTijl Coosemans #define ioread8(addr) ioread8(addr) 308642909fdSTijl Coosemans 309642909fdSTijl Coosemans #undef ioread16 310642909fdSTijl Coosemans static inline uint16_t 311642909fdSTijl Coosemans ioread16(const volatile void *addr) 312642909fdSTijl Coosemans { 313642909fdSTijl Coosemans return (readw(addr)); 314642909fdSTijl Coosemans } 315642909fdSTijl Coosemans #define ioread16(addr) ioread16(addr) 316642909fdSTijl Coosemans 317642909fdSTijl Coosemans #undef ioread16be 318642909fdSTijl Coosemans static inline uint16_t 319642909fdSTijl Coosemans ioread16be(const volatile void *addr) 320642909fdSTijl Coosemans { 321937a05baSJustin Hibbits uint16_t v; 322937a05baSJustin Hibbits 323937a05baSJustin Hibbits __io_br(); 324937a05baSJustin Hibbits v = (be16toh(__raw_readw(addr))); 325937a05baSJustin Hibbits __io_ar(); 326937a05baSJustin Hibbits 327937a05baSJustin Hibbits return (v); 328642909fdSTijl Coosemans } 329642909fdSTijl Coosemans #define ioread16be(addr) ioread16be(addr) 330642909fdSTijl Coosemans 331642909fdSTijl Coosemans #undef ioread32 332642909fdSTijl Coosemans static inline uint32_t 333642909fdSTijl Coosemans ioread32(const volatile void *addr) 334642909fdSTijl Coosemans { 335642909fdSTijl Coosemans return (readl(addr)); 336642909fdSTijl Coosemans } 337642909fdSTijl Coosemans #define ioread32(addr) ioread32(addr) 338642909fdSTijl Coosemans 339642909fdSTijl Coosemans #undef ioread32be 340642909fdSTijl Coosemans static inline uint32_t 341642909fdSTijl Coosemans ioread32be(const volatile void *addr) 342642909fdSTijl Coosemans { 343937a05baSJustin Hibbits uint32_t v; 344937a05baSJustin Hibbits 345937a05baSJustin Hibbits __io_br(); 346937a05baSJustin Hibbits v = (be32toh(__raw_readl(addr))); 347937a05baSJustin Hibbits __io_ar(); 348937a05baSJustin Hibbits 349937a05baSJustin Hibbits return (v); 350642909fdSTijl Coosemans } 351642909fdSTijl Coosemans #define ioread32be(addr) ioread32be(addr) 352642909fdSTijl Coosemans 35373ccd188SVladimir Kondratyev #ifdef __LP64__ 354dcfc9833SVladimir Kondratyev #undef ioread64 355dcfc9833SVladimir Kondratyev static inline uint64_t 356dcfc9833SVladimir Kondratyev ioread64(const volatile void *addr) 357dcfc9833SVladimir Kondratyev { 358dcfc9833SVladimir Kondratyev return (readq(addr)); 359dcfc9833SVladimir Kondratyev } 360dcfc9833SVladimir Kondratyev #define ioread64(addr) ioread64(addr) 36173ccd188SVladimir Kondratyev #endif 362dcfc9833SVladimir Kondratyev 363642909fdSTijl Coosemans #undef iowrite8 364642909fdSTijl Coosemans static inline void 365642909fdSTijl Coosemans iowrite8(uint8_t v, volatile void *addr) 366642909fdSTijl Coosemans { 367642909fdSTijl Coosemans writeb(v, addr); 368642909fdSTijl Coosemans } 369642909fdSTijl Coosemans #define iowrite8(v, addr) iowrite8(v, addr) 370642909fdSTijl Coosemans 371642909fdSTijl Coosemans #undef iowrite16 372642909fdSTijl Coosemans static inline void 373642909fdSTijl Coosemans iowrite16(uint16_t v, volatile void *addr) 374642909fdSTijl Coosemans { 375642909fdSTijl Coosemans writew(v, addr); 376642909fdSTijl Coosemans } 377642909fdSTijl Coosemans #define iowrite16 iowrite16 378642909fdSTijl Coosemans 379642909fdSTijl Coosemans #undef iowrite32 380642909fdSTijl Coosemans static inline void 381642909fdSTijl Coosemans iowrite32(uint32_t v, volatile void *addr) 382642909fdSTijl Coosemans { 383642909fdSTijl Coosemans writel(v, addr); 384642909fdSTijl Coosemans } 385642909fdSTijl Coosemans #define iowrite32(v, addr) iowrite32(v, addr) 386642909fdSTijl Coosemans 387642909fdSTijl Coosemans #undef iowrite32be 388642909fdSTijl Coosemans static inline void 389642909fdSTijl Coosemans iowrite32be(uint32_t v, volatile void *addr) 390642909fdSTijl Coosemans { 391937a05baSJustin Hibbits __io_bw(); 392937a05baSJustin Hibbits __raw_writel(htobe32(v), addr); 393937a05baSJustin Hibbits __io_aw(); 394642909fdSTijl Coosemans } 395642909fdSTijl Coosemans #define iowrite32be(v, addr) iowrite32be(v, addr) 39686845417SHans Petter Selasky 39786845417SHans Petter Selasky #if defined(__i386__) || defined(__amd64__) 39894a201beSHans Petter Selasky static inline void 39994a201beSHans Petter Selasky _outb(u_char data, u_int port) 40094a201beSHans Petter Selasky { 40194a201beSHans Petter Selasky __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); 40294a201beSHans Petter Selasky } 40394a201beSHans Petter Selasky #endif 40494a201beSHans Petter Selasky 40560d962e0SJessica Clarke #if defined(__i386__) || defined(__amd64__) || defined(__powerpc__) || defined(__aarch64__) || defined(__riscv) 4068d59ecb2SHans Petter Selasky void *_ioremap_attr(vm_paddr_t phys_addr, unsigned long size, int attr); 40786845417SHans Petter Selasky #else 40834dae08eSJohn Baldwin static __inline void * 40934dae08eSJohn Baldwin _ioremap_attr(vm_paddr_t _phys_addr, unsigned long _size, int _attr) 41034dae08eSJohn Baldwin { 41134dae08eSJohn Baldwin return (NULL); 41234dae08eSJohn Baldwin } 41386845417SHans Petter Selasky #endif 41486845417SHans Petter Selasky 4154cbd4277SBjoern A. Zeeb struct device; 4164cbd4277SBjoern A. Zeeb static inline void * 4174cbd4277SBjoern A. Zeeb devm_ioremap(struct device *dev, resource_size_t offset, resource_size_t size) 4184cbd4277SBjoern A. Zeeb { 4194cbd4277SBjoern A. Zeeb return (NULL); 4204cbd4277SBjoern A. Zeeb } 4214cbd4277SBjoern A. Zeeb 4224d83500fSHans Petter Selasky #ifdef VM_MEMATTR_DEVICE 4234d83500fSHans Petter Selasky #define ioremap_nocache(addr, size) \ 4244d83500fSHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_DEVICE) 4254d83500fSHans Petter Selasky #define ioremap_wt(addr, size) \ 4264d83500fSHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_DEVICE) 4274d83500fSHans Petter Selasky #define ioremap(addr, size) \ 4284d83500fSHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_DEVICE) 4294d83500fSHans Petter Selasky #else 4308d59ecb2SHans Petter Selasky #define ioremap_nocache(addr, size) \ 4318d59ecb2SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE) 432f2dbb750SHans Petter Selasky #define ioremap_wt(addr, size) \ 433f2dbb750SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_THROUGH) 43486845417SHans Petter Selasky #define ioremap(addr, size) \ 43586845417SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE) 4364d83500fSHans Petter Selasky #endif 4378167c92fSJessica Clarke #ifdef VM_MEMATTR_WRITE_COMBINING 4384d83500fSHans Petter Selasky #define ioremap_wc(addr, size) \ 4394d83500fSHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_COMBINING) 4408167c92fSJessica Clarke #else 4418167c92fSJessica Clarke #define ioremap_wc(addr, size) ioremap_nocache(addr, size) 4428167c92fSJessica Clarke #endif 443ed53e350SJean-Sébastien Pédron #define ioremap_cache(addr, size) \ 4444d83500fSHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK) 4458d59ecb2SHans Petter Selasky void iounmap(void *addr); 4468d59ecb2SHans Petter Selasky 4478d59ecb2SHans Petter Selasky #define memset_io(a, b, c) memset((a), (b), (c)) 4488d59ecb2SHans Petter Selasky #define memcpy_fromio(a, b, c) memcpy((a), (b), (c)) 4498d59ecb2SHans Petter Selasky #define memcpy_toio(a, b, c) memcpy((a), (b), (c)) 4508d59ecb2SHans Petter Selasky 4518d59ecb2SHans Petter Selasky static inline void 452046b8284SBjoern A. Zeeb __iowrite32_copy(void *to, const void *from, size_t count) 45386364964SKevin Lo { 454046b8284SBjoern A. Zeeb const uint32_t *src; 45586364964SKevin Lo uint32_t *dst; 45686364964SKevin Lo int i; 45786364964SKevin Lo 45886364964SKevin Lo for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 45986364964SKevin Lo __raw_writel(*src, dst); 46086364964SKevin Lo } 46186364964SKevin Lo 46286364964SKevin Lo static inline void 463046b8284SBjoern A. Zeeb __iowrite64_copy(void *to, const void *from, size_t count) 4648d59ecb2SHans Petter Selasky { 4658d59ecb2SHans Petter Selasky #ifdef __LP64__ 466046b8284SBjoern A. Zeeb const uint64_t *src; 4678d59ecb2SHans Petter Selasky uint64_t *dst; 4688d59ecb2SHans Petter Selasky int i; 4698d59ecb2SHans Petter Selasky 4708d59ecb2SHans Petter Selasky for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 4718d59ecb2SHans Petter Selasky __raw_writeq(*src, dst); 4728d59ecb2SHans Petter Selasky #else 47386364964SKevin Lo __iowrite32_copy(to, from, count * 2); 4748d59ecb2SHans Petter Selasky #endif 4758d59ecb2SHans Petter Selasky } 4768d59ecb2SHans Petter Selasky 477046b8284SBjoern A. Zeeb static inline void 478046b8284SBjoern A. Zeeb __ioread32_copy(void *to, const void *from, size_t count) 479046b8284SBjoern A. Zeeb { 480046b8284SBjoern A. Zeeb const uint32_t *src; 481046b8284SBjoern A. Zeeb uint32_t *dst; 482046b8284SBjoern A. Zeeb int i; 483046b8284SBjoern A. Zeeb 484046b8284SBjoern A. Zeeb for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 485046b8284SBjoern A. Zeeb *dst = __raw_readl(src); 486046b8284SBjoern A. Zeeb } 487046b8284SBjoern A. Zeeb 488046b8284SBjoern A. Zeeb static inline void 489046b8284SBjoern A. Zeeb __ioread64_copy(void *to, const void *from, size_t count) 490046b8284SBjoern A. Zeeb { 491046b8284SBjoern A. Zeeb #ifdef __LP64__ 492046b8284SBjoern A. Zeeb const uint64_t *src; 493046b8284SBjoern A. Zeeb uint64_t *dst; 494046b8284SBjoern A. Zeeb int i; 495046b8284SBjoern A. Zeeb 496046b8284SBjoern A. Zeeb for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 497046b8284SBjoern A. Zeeb *dst = __raw_readq(src); 498046b8284SBjoern A. Zeeb #else 499046b8284SBjoern A. Zeeb __ioread32_copy(to, from, count * 2); 500046b8284SBjoern A. Zeeb #endif 501046b8284SBjoern A. Zeeb } 502046b8284SBjoern A. Zeeb 503684a5fefSHans Petter Selasky enum { 504684a5fefSHans Petter Selasky MEMREMAP_WB = 1 << 0, 505684a5fefSHans Petter Selasky MEMREMAP_WT = 1 << 1, 506684a5fefSHans Petter Selasky MEMREMAP_WC = 1 << 2, 507684a5fefSHans Petter Selasky }; 508684a5fefSHans Petter Selasky 509684a5fefSHans Petter Selasky static inline void * 510684a5fefSHans Petter Selasky memremap(resource_size_t offset, size_t size, unsigned long flags) 511684a5fefSHans Petter Selasky { 512684a5fefSHans Petter Selasky void *addr = NULL; 513684a5fefSHans Petter Selasky 514684a5fefSHans Petter Selasky if ((flags & MEMREMAP_WB) && 515ed53e350SJean-Sébastien Pédron (addr = ioremap_cache(offset, size)) != NULL) 516684a5fefSHans Petter Selasky goto done; 517684a5fefSHans Petter Selasky if ((flags & MEMREMAP_WT) && 518f2dbb750SHans Petter Selasky (addr = ioremap_wt(offset, size)) != NULL) 519684a5fefSHans Petter Selasky goto done; 520684a5fefSHans Petter Selasky if ((flags & MEMREMAP_WC) && 521684a5fefSHans Petter Selasky (addr = ioremap_wc(offset, size)) != NULL) 522684a5fefSHans Petter Selasky goto done; 523684a5fefSHans Petter Selasky done: 524684a5fefSHans Petter Selasky return (addr); 525684a5fefSHans Petter Selasky } 526684a5fefSHans Petter Selasky 527684a5fefSHans Petter Selasky static inline void 528684a5fefSHans Petter Selasky memunmap(void *addr) 529684a5fefSHans Petter Selasky { 530684a5fefSHans Petter Selasky /* XXX May need to check if this is RAM */ 531684a5fefSHans Petter Selasky iounmap(addr); 532684a5fefSHans Petter Selasky } 5338d59ecb2SHans Petter Selasky 534af787b8eSVladimir Kondratyev #define IOMEM_ERR_PTR(err) (void __iomem *)ERR_PTR(err) 535af787b8eSVladimir Kondratyev 53698b12978SVladimir Kondratyev #define __MTRR_ID_BASE 1 53798b12978SVladimir Kondratyev int lkpi_arch_phys_wc_add(unsigned long, unsigned long); 53898b12978SVladimir Kondratyev void lkpi_arch_phys_wc_del(int); 53998b12978SVladimir Kondratyev #define arch_phys_wc_add(...) lkpi_arch_phys_wc_add(__VA_ARGS__) 54098b12978SVladimir Kondratyev #define arch_phys_wc_del(...) lkpi_arch_phys_wc_del(__VA_ARGS__) 54198b12978SVladimir Kondratyev #define arch_phys_wc_index(x) \ 54298b12978SVladimir Kondratyev (((x) < __MTRR_ID_BASE) ? -1 : ((x) - __MTRR_ID_BASE)) 54398b12978SVladimir Kondratyev 544789dbdbbSEmmanuel Vadot static inline int 545789dbdbbSEmmanuel Vadot arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size) 546789dbdbbSEmmanuel Vadot { 547*2ae0f5a4STijl Coosemans #if defined(__amd64__) 5481e99b2eeSJean-Sébastien Pédron vm_offset_t va; 549789dbdbbSEmmanuel Vadot 5501e99b2eeSJean-Sébastien Pédron va = PHYS_TO_DMAP(start); 5511e99b2eeSJean-Sébastien Pédron return (-pmap_change_attr(va, size, VM_MEMATTR_WRITE_COMBINING)); 5521e99b2eeSJean-Sébastien Pédron #else 553*2ae0f5a4STijl Coosemans return (0); 5541e99b2eeSJean-Sébastien Pédron #endif 555789dbdbbSEmmanuel Vadot } 556789dbdbbSEmmanuel Vadot 557789dbdbbSEmmanuel Vadot static inline void 558789dbdbbSEmmanuel Vadot arch_io_free_memtype_wc(resource_size_t start, resource_size_t size) 559789dbdbbSEmmanuel Vadot { 560*2ae0f5a4STijl Coosemans #if defined(__amd64__) 5611e99b2eeSJean-Sébastien Pédron vm_offset_t va; 5621e99b2eeSJean-Sébastien Pédron 5631e99b2eeSJean-Sébastien Pédron va = PHYS_TO_DMAP(start); 5641e99b2eeSJean-Sébastien Pédron 5651e99b2eeSJean-Sébastien Pédron pmap_change_attr(va, size, VM_MEMATTR_WRITE_BACK); 566789dbdbbSEmmanuel Vadot #endif 567*2ae0f5a4STijl Coosemans } 568789dbdbbSEmmanuel Vadot 569307f78f3SVladimir Kondratyev #endif /* _LINUXKPI_LINUX_IO_H_ */ 570