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 * 298d59ecb2SHans Petter Selasky * $FreeBSD$ 308d59ecb2SHans Petter Selasky */ 318d59ecb2SHans Petter Selasky #ifndef _LINUX_IO_H_ 328d59ecb2SHans Petter Selasky #define _LINUX_IO_H_ 338d59ecb2SHans Petter Selasky 348d59ecb2SHans Petter Selasky #include <machine/vm.h> 358d59ecb2SHans Petter Selasky #include <sys/endian.h> 368e7baabcSHans Petter Selasky #include <sys/types.h> 378d59ecb2SHans Petter Selasky 38684a5fefSHans Petter Selasky #include <linux/compiler.h> 39684a5fefSHans Petter Selasky 408d59ecb2SHans Petter Selasky static inline uint32_t 418d59ecb2SHans Petter Selasky __raw_readl(const volatile void *addr) 428d59ecb2SHans Petter Selasky { 438d59ecb2SHans Petter Selasky return *(const volatile uint32_t *)addr; 448d59ecb2SHans Petter Selasky } 458d59ecb2SHans Petter Selasky 468d59ecb2SHans Petter Selasky static inline void 478d59ecb2SHans Petter Selasky __raw_writel(uint32_t b, volatile void *addr) 488d59ecb2SHans Petter Selasky { 498d59ecb2SHans Petter Selasky *(volatile uint32_t *)addr = b; 508d59ecb2SHans Petter Selasky } 518d59ecb2SHans Petter Selasky 528d59ecb2SHans Petter Selasky static inline uint64_t 538d59ecb2SHans Petter Selasky __raw_readq(const volatile void *addr) 548d59ecb2SHans Petter Selasky { 558d59ecb2SHans Petter Selasky return *(const volatile uint64_t *)addr; 568d59ecb2SHans Petter Selasky } 578d59ecb2SHans Petter Selasky 588d59ecb2SHans Petter Selasky static inline void 598d59ecb2SHans Petter Selasky __raw_writeq(uint64_t b, volatile void *addr) 608d59ecb2SHans Petter Selasky { 618d59ecb2SHans Petter Selasky *(volatile uint64_t *)addr = b; 628d59ecb2SHans Petter Selasky } 638d59ecb2SHans Petter Selasky 648d59ecb2SHans Petter Selasky /* 658d59ecb2SHans Petter Selasky * XXX This is all x86 specific. It should be bus space access. 668d59ecb2SHans Petter Selasky */ 67684a5fefSHans Petter Selasky #define mmiowb() barrier() 688d59ecb2SHans Petter Selasky 698d59ecb2SHans Petter Selasky #undef writel 708d59ecb2SHans Petter Selasky static inline void 718d59ecb2SHans Petter Selasky writel(uint32_t b, void *addr) 728d59ecb2SHans Petter Selasky { 738d59ecb2SHans Petter Selasky *(volatile uint32_t *)addr = b; 748d59ecb2SHans Petter Selasky } 758d59ecb2SHans Petter Selasky 768d59ecb2SHans Petter Selasky #undef writeq 778d59ecb2SHans Petter Selasky static inline void 788d59ecb2SHans Petter Selasky writeq(uint64_t b, void *addr) 798d59ecb2SHans Petter Selasky { 808d59ecb2SHans Petter Selasky *(volatile uint64_t *)addr = b; 818d59ecb2SHans Petter Selasky } 828d59ecb2SHans Petter Selasky 838d59ecb2SHans Petter Selasky #undef writeb 848d59ecb2SHans Petter Selasky static inline void 858d59ecb2SHans Petter Selasky writeb(uint8_t b, void *addr) 868d59ecb2SHans Petter Selasky { 878d59ecb2SHans Petter Selasky *(volatile uint8_t *)addr = b; 888d59ecb2SHans Petter Selasky } 898d59ecb2SHans Petter Selasky 908d59ecb2SHans Petter Selasky #undef writew 918d59ecb2SHans Petter Selasky static inline void 928d59ecb2SHans Petter Selasky writew(uint16_t b, void *addr) 938d59ecb2SHans Petter Selasky { 948d59ecb2SHans Petter Selasky *(volatile uint16_t *)addr = b; 958d59ecb2SHans Petter Selasky } 968d59ecb2SHans Petter Selasky 97684a5fefSHans Petter Selasky #undef ioread8 98684a5fefSHans Petter Selasky static inline uint8_t 99684a5fefSHans Petter Selasky ioread8(const volatile void *addr) 100684a5fefSHans Petter Selasky { 101684a5fefSHans Petter Selasky return *(const volatile uint8_t *)addr; 102684a5fefSHans Petter Selasky } 103684a5fefSHans Petter Selasky 104684a5fefSHans Petter Selasky #undef ioread16 105684a5fefSHans Petter Selasky static inline uint16_t 106684a5fefSHans Petter Selasky ioread16(const volatile void *addr) 107684a5fefSHans Petter Selasky { 108684a5fefSHans Petter Selasky return *(const volatile uint16_t *)addr; 109684a5fefSHans Petter Selasky } 110684a5fefSHans Petter Selasky 111684a5fefSHans Petter Selasky #undef ioread32 112684a5fefSHans Petter Selasky static inline uint32_t 113684a5fefSHans Petter Selasky ioread32(const volatile void *addr) 114684a5fefSHans Petter Selasky { 115684a5fefSHans Petter Selasky return *(const volatile uint32_t *)addr; 116684a5fefSHans Petter Selasky } 117684a5fefSHans Petter Selasky 1188d59ecb2SHans Petter Selasky #undef ioread32be 1198d59ecb2SHans Petter Selasky static inline uint32_t 1208d59ecb2SHans Petter Selasky ioread32be(const volatile void *addr) 1218d59ecb2SHans Petter Selasky { 1228d59ecb2SHans Petter Selasky return be32toh(*(const volatile uint32_t *)addr); 1238d59ecb2SHans Petter Selasky } 1248d59ecb2SHans Petter Selasky 125684a5fefSHans Petter Selasky #undef iowrite8 126684a5fefSHans Petter Selasky static inline void 127684a5fefSHans Petter Selasky iowrite8(uint8_t v, volatile void *addr) 128684a5fefSHans Petter Selasky { 129684a5fefSHans Petter Selasky *(volatile uint8_t *)addr = v; 130684a5fefSHans Petter Selasky } 131684a5fefSHans Petter Selasky 132684a5fefSHans Petter Selasky #undef iowrite16 133684a5fefSHans Petter Selasky static inline void 134684a5fefSHans Petter Selasky iowrite16(uint16_t v, volatile void *addr) 135684a5fefSHans Petter Selasky { 136684a5fefSHans Petter Selasky *(volatile uint16_t *)addr = v; 137684a5fefSHans Petter Selasky } 138684a5fefSHans Petter Selasky 139684a5fefSHans Petter Selasky #undef iowrite32 140684a5fefSHans Petter Selasky static inline void 141684a5fefSHans Petter Selasky iowrite32(uint32_t v, volatile void *addr) 142684a5fefSHans Petter Selasky { 143684a5fefSHans Petter Selasky *(volatile uint32_t *)addr = v; 144684a5fefSHans Petter Selasky } 145684a5fefSHans Petter Selasky 1468d59ecb2SHans Petter Selasky #undef iowrite32be 1478d59ecb2SHans Petter Selasky static inline void 1488d59ecb2SHans Petter Selasky iowrite32be(uint32_t v, volatile void *addr) 1498d59ecb2SHans Petter Selasky { 1508d59ecb2SHans Petter Selasky *(volatile uint32_t *)addr = htobe32(v); 1518d59ecb2SHans Petter Selasky } 1528d59ecb2SHans Petter Selasky 15386845417SHans Petter Selasky #undef readb 15486845417SHans Petter Selasky static inline uint8_t 15586845417SHans Petter Selasky readb(const volatile void *addr) 15686845417SHans Petter Selasky { 15786845417SHans Petter Selasky return *(const volatile uint8_t *)addr; 15886845417SHans Petter Selasky } 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 { 16486845417SHans Petter Selasky return *(const volatile uint16_t *)addr; 16586845417SHans Petter Selasky } 16686845417SHans Petter Selasky 16786845417SHans Petter Selasky #undef readl 16886845417SHans Petter Selasky static inline uint32_t 16986845417SHans Petter Selasky readl(const volatile void *addr) 17086845417SHans Petter Selasky { 17186845417SHans Petter Selasky return *(const volatile uint32_t *)addr; 17286845417SHans Petter Selasky } 17386845417SHans Petter Selasky 17486845417SHans Petter Selasky #if defined(__i386__) || defined(__amd64__) 175*94a201beSHans Petter Selasky static inline void 176*94a201beSHans Petter Selasky _outb(u_char data, u_int port) 177*94a201beSHans Petter Selasky { 178*94a201beSHans Petter Selasky __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); 179*94a201beSHans Petter Selasky } 180*94a201beSHans Petter Selasky #endif 181*94a201beSHans Petter Selasky 182*94a201beSHans Petter Selasky #if defined(__i386__) || defined(__amd64__) 1838d59ecb2SHans Petter Selasky void *_ioremap_attr(vm_paddr_t phys_addr, unsigned long size, int attr); 18486845417SHans Petter Selasky #else 18586845417SHans Petter Selasky #define _ioremap_attr(...) NULL 18686845417SHans Petter Selasky #endif 18786845417SHans Petter Selasky 1888d59ecb2SHans Petter Selasky #define ioremap_nocache(addr, size) \ 1898d59ecb2SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE) 1908d59ecb2SHans Petter Selasky #define ioremap_wc(addr, size) \ 1918d59ecb2SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_COMBINING) 192684a5fefSHans Petter Selasky #define ioremap_wb(addr, size) \ 193684a5fefSHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK) 194f2dbb750SHans Petter Selasky #define ioremap_wt(addr, size) \ 195f2dbb750SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_THROUGH) 19686845417SHans Petter Selasky #define ioremap(addr, size) \ 19786845417SHans Petter Selasky _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE) 1988d59ecb2SHans Petter Selasky void iounmap(void *addr); 1998d59ecb2SHans Petter Selasky 2008d59ecb2SHans Petter Selasky #define memset_io(a, b, c) memset((a), (b), (c)) 2018d59ecb2SHans Petter Selasky #define memcpy_fromio(a, b, c) memcpy((a), (b), (c)) 2028d59ecb2SHans Petter Selasky #define memcpy_toio(a, b, c) memcpy((a), (b), (c)) 2038d59ecb2SHans Petter Selasky 2048d59ecb2SHans Petter Selasky static inline void 2058d59ecb2SHans Petter Selasky __iowrite64_copy(void *to, void *from, size_t count) 2068d59ecb2SHans Petter Selasky { 2078d59ecb2SHans Petter Selasky #ifdef __LP64__ 2088d59ecb2SHans Petter Selasky uint64_t *src; 2098d59ecb2SHans Petter Selasky uint64_t *dst; 2108d59ecb2SHans Petter Selasky int i; 2118d59ecb2SHans Petter Selasky 2128d59ecb2SHans Petter Selasky for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 2138d59ecb2SHans Petter Selasky __raw_writeq(*src, dst); 2148d59ecb2SHans Petter Selasky #else 2158d59ecb2SHans Petter Selasky uint32_t *src; 2168d59ecb2SHans Petter Selasky uint32_t *dst; 2178d59ecb2SHans Petter Selasky int i; 2188d59ecb2SHans Petter Selasky 2198d59ecb2SHans Petter Selasky count *= 2; 2208d59ecb2SHans Petter Selasky for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 2218d59ecb2SHans Petter Selasky __raw_writel(*src, dst); 2228d59ecb2SHans Petter Selasky #endif 2238d59ecb2SHans Petter Selasky } 2248d59ecb2SHans Petter Selasky 225684a5fefSHans Petter Selasky enum { 226684a5fefSHans Petter Selasky MEMREMAP_WB = 1 << 0, 227684a5fefSHans Petter Selasky MEMREMAP_WT = 1 << 1, 228684a5fefSHans Petter Selasky MEMREMAP_WC = 1 << 2, 229684a5fefSHans Petter Selasky }; 230684a5fefSHans Petter Selasky 231684a5fefSHans Petter Selasky static inline void * 232684a5fefSHans Petter Selasky memremap(resource_size_t offset, size_t size, unsigned long flags) 233684a5fefSHans Petter Selasky { 234684a5fefSHans Petter Selasky void *addr = NULL; 235684a5fefSHans Petter Selasky 236684a5fefSHans Petter Selasky if ((flags & MEMREMAP_WB) && 237684a5fefSHans Petter Selasky (addr = ioremap_wb(offset, size)) != NULL) 238684a5fefSHans Petter Selasky goto done; 239684a5fefSHans Petter Selasky if ((flags & MEMREMAP_WT) && 240f2dbb750SHans Petter Selasky (addr = ioremap_wt(offset, size)) != NULL) 241684a5fefSHans Petter Selasky goto done; 242684a5fefSHans Petter Selasky if ((flags & MEMREMAP_WC) && 243684a5fefSHans Petter Selasky (addr = ioremap_wc(offset, size)) != NULL) 244684a5fefSHans Petter Selasky goto done; 245684a5fefSHans Petter Selasky done: 246684a5fefSHans Petter Selasky return (addr); 247684a5fefSHans Petter Selasky } 248684a5fefSHans Petter Selasky 249684a5fefSHans Petter Selasky static inline void 250684a5fefSHans Petter Selasky memunmap(void *addr) 251684a5fefSHans Petter Selasky { 252684a5fefSHans Petter Selasky /* XXX May need to check if this is RAM */ 253684a5fefSHans Petter Selasky iounmap(addr); 254684a5fefSHans Petter Selasky } 2558d59ecb2SHans Petter Selasky 2568d59ecb2SHans Petter Selasky #endif /* _LINUX_IO_H_ */ 257