133965Sjdp/*- 278828Sobrien * Copyright (c) 2010 Isilon Systems, Inc. 3218822Sdim * Copyright (c) 2010 iX Systems, Inc. 433965Sjdp * Copyright (c) 2010 Panasas, Inc. 533965Sjdp * Copyright (c) 2013-2015 Mellanox Technologies, Ltd. 633965Sjdp * All rights reserved. 733965Sjdp * 833965Sjdp * Redistribution and use in source and binary forms, with or without 933965Sjdp * modification, are permitted provided that the following conditions 1033965Sjdp * are met: 1133965Sjdp * 1. Redistributions of source code must retain the above copyright 1233965Sjdp * notice unmodified, this list of conditions, and the following 1333965Sjdp * disclaimer. 1433965Sjdp * 2. Redistributions in binary form must reproduce the above copyright 1533965Sjdp * notice, this list of conditions and the following disclaimer in the 1633965Sjdp * documentation and/or other materials provided with the distribution. 1733965Sjdp * 1833965Sjdp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1933965Sjdp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20218822Sdim * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21218822Sdim * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2233965Sjdp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23130561Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24218822Sdim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25218822Sdim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26218822Sdim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27218822Sdim * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2833965Sjdp * 29218822Sdim * $FreeBSD: releng/11.0/sys/compat/linuxkpi/common/include/linux/io.h 300594 2016-05-24 09:23:04Z kevlo $ 3033965Sjdp */ 3133965Sjdp#ifndef _LINUX_IO_H_ 3233965Sjdp#define _LINUX_IO_H_ 3333965Sjdp 3433965Sjdp#include <machine/vm.h> 3533965Sjdp#include <sys/endian.h> 3633965Sjdp#include <sys/types.h> 3760484Sobrien 3833965Sjdp#include <linux/compiler.h> 3933965Sjdp 4033965Sjdpstatic inline uint32_t 4133965Sjdp__raw_readl(const volatile void *addr) 4233965Sjdp{ 4333965Sjdp return *(const volatile uint32_t *)addr; 4433965Sjdp} 4533965Sjdp 46104834Sobrienstatic inline void 47104834Sobrien__raw_writel(uint32_t b, volatile void *addr) 48104834Sobrien{ 4933965Sjdp *(volatile uint32_t *)addr = b; 5060484Sobrien} 5177298Sobrien 5260484Sobrienstatic inline uint64_t 5360484Sobrien__raw_readq(const volatile void *addr) 5460484Sobrien{ 5560484Sobrien return *(const volatile uint64_t *)addr; 5660484Sobrien} 5733965Sjdp 5833965Sjdpstatic inline void 5933965Sjdp__raw_writeq(uint64_t b, volatile void *addr) 6033965Sjdp{ 6133965Sjdp *(volatile uint64_t *)addr = b; 6233965Sjdp} 6333965Sjdp 6433965Sjdp/* 6533965Sjdp * XXX This is all x86 specific. It should be bus space access. 6633965Sjdp */ 6733965Sjdp#define mmiowb() barrier() 6833965Sjdp 6933965Sjdp#undef writel 7033965Sjdpstatic inline void 7138889Sjdpwritel(uint32_t b, void *addr) 7238889Sjdp{ 7338889Sjdp *(volatile uint32_t *)addr = b; 7438889Sjdp} 7560484Sobrien 7660484Sobrien#undef writeq 7760484Sobrienstatic inline void 7838889Sjdpwriteq(uint64_t b, void *addr) 7938889Sjdp{ 8089857Sobrien *(volatile uint64_t *)addr = b; 8133965Sjdp} 8233965Sjdp 8333965Sjdp#undef writeb 8489857Sobrienstatic inline void 8533965Sjdpwriteb(uint8_t b, void *addr) 8633965Sjdp{ 8733965Sjdp *(volatile uint8_t *)addr = b; 8833965Sjdp} 89130561Sobrien 9033965Sjdp#undef writew 9133965Sjdpstatic inline void 9233965Sjdpwritew(uint16_t b, void *addr) 9377298Sobrien{ 9433965Sjdp *(volatile uint16_t *)addr = b; 9577298Sobrien} 96130561Sobrien 9733965Sjdp#undef ioread8 9833965Sjdpstatic inline uint8_t 9960484Sobrienioread8(const volatile void *addr) 10033965Sjdp{ 10133965Sjdp return *(const volatile uint8_t *)addr; 10233965Sjdp} 10338889Sjdp 10433965Sjdp#undef ioread16 10533965Sjdpstatic inline uint16_t 10633965Sjdpioread16(const volatile void *addr) 10760484Sobrien{ 10860484Sobrien return *(const volatile uint16_t *)addr; 10960484Sobrien} 11033965Sjdp 11160484Sobrien#undef ioread32 11233965Sjdpstatic inline uint32_t 11333965Sjdpioread32(const volatile void *addr) 11433965Sjdp{ 11560484Sobrien return *(const volatile uint32_t *)addr; 116130561Sobrien} 11733965Sjdp 11833965Sjdp#undef ioread32be 11933965Sjdpstatic inline uint32_t 12033965Sjdpioread32be(const volatile void *addr) 12133965Sjdp{ 12233965Sjdp return be32toh(*(const volatile uint32_t *)addr); 12333965Sjdp} 12433965Sjdp 12533965Sjdp#undef iowrite8 12633965Sjdpstatic inline void 12733965Sjdpiowrite8(uint8_t v, volatile void *addr) 12833965Sjdp{ 12933965Sjdp *(volatile uint8_t *)addr = v; 13033965Sjdp} 131130561Sobrien 13233965Sjdp#undef iowrite16 13360484Sobrienstatic inline void 13460484Sobrieniowrite16(uint16_t v, volatile void *addr) 13560484Sobrien{ 13660484Sobrien *(volatile uint16_t *)addr = v; 13760484Sobrien} 13860484Sobrien 13960484Sobrien#undef iowrite32 14060484Sobrienstatic inline void 14160484Sobrieniowrite32(uint32_t v, volatile void *addr) 14260484Sobrien{ 14360484Sobrien *(volatile uint32_t *)addr = v; 14460484Sobrien} 14560484Sobrien 14633965Sjdp#undef iowrite32be 14733965Sjdpstatic inline void 14833965Sjdpiowrite32be(uint32_t v, volatile void *addr) 14933965Sjdp{ 15033965Sjdp *(volatile uint32_t *)addr = htobe32(v); 151130561Sobrien} 15233965Sjdp 15333965Sjdp#undef readb 154130561Sobrienstatic inline uint8_t 15533965Sjdpreadb(const volatile void *addr) 15633965Sjdp{ 157130561Sobrien return *(const volatile uint8_t *)addr; 15833965Sjdp} 15989857Sobrien 16089857Sobrien#undef readw 16189857Sobrienstatic inline uint16_t 16289857Sobrienreadw(const volatile void *addr) 163130561Sobrien{ 16489857Sobrien return *(const volatile uint16_t *)addr; 16589857Sobrien} 16633965Sjdp 16733965Sjdp#undef readl 16833965Sjdpstatic inline uint32_t 169130561Sobrienreadl(const volatile void *addr) 17033965Sjdp{ 17160484Sobrien return *(const volatile uint32_t *)addr; 17233965Sjdp} 17333965Sjdp 17433965Sjdp#if defined(__i386__) || defined(__amd64__) 17533965Sjdpstatic inline void 17633965Sjdp_outb(u_char data, u_int port) 17733965Sjdp{ 178130561Sobrien __asm __volatile("outb %0, %w1" : : "a" (data), "Nd" (port)); 17933965Sjdp} 18033965Sjdp#endif 18160484Sobrien 18238889Sjdp#if defined(__i386__) || defined(__amd64__) 18338889Sjdpvoid *_ioremap_attr(vm_paddr_t phys_addr, unsigned long size, int attr); 18438889Sjdp#else 18538889Sjdp#define _ioremap_attr(...) NULL 18660484Sobrien#endif 18738889Sjdp 18838889Sjdp#define ioremap_nocache(addr, size) \ 18960484Sobrien _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE) 190130561Sobrien#define ioremap_wc(addr, size) \ 19160484Sobrien _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_COMBINING) 19260484Sobrien#define ioremap_wb(addr, size) \ 193130561Sobrien _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK) 19433965Sjdp#define ioremap_wt(addr, size) \ 195130561Sobrien _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_THROUGH) 19633965Sjdp#define ioremap(addr, size) \ 19733965Sjdp _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE) 19833965Sjdpvoid iounmap(void *addr); 19933965Sjdp 20033965Sjdp#define memset_io(a, b, c) memset((a), (b), (c)) 20133965Sjdp#define memcpy_fromio(a, b, c) memcpy((a), (b), (c)) 20233965Sjdp#define memcpy_toio(a, b, c) memcpy((a), (b), (c)) 20360484Sobrien 20433965Sjdpstatic inline void 20533965Sjdp__iowrite32_copy(void *to, void *from, size_t count) 20633965Sjdp{ 20733965Sjdp uint32_t *src; 20833965Sjdp uint32_t *dst; 20933965Sjdp int i; 21033965Sjdp 21133965Sjdp for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 212130561Sobrien __raw_writel(*src, dst); 213130561Sobrien} 21477298Sobrien 21577298Sobrienstatic inline void 21677298Sobrien__iowrite64_copy(void *to, void *from, size_t count) 21777298Sobrien{ 21877298Sobrien#ifdef __LP64__ 21977298Sobrien uint64_t *src; 22077298Sobrien uint64_t *dst; 22160484Sobrien int i; 22277298Sobrien 22360484Sobrien for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 22477298Sobrien __raw_writeq(*src, dst); 22577298Sobrien#else 22660484Sobrien __iowrite32_copy(to, from, count * 2); 22777298Sobrien#endif 22860484Sobrien} 22977298Sobrien 23033965Sjdpenum { 23133965Sjdp MEMREMAP_WB = 1 << 0, 232130561Sobrien MEMREMAP_WT = 1 << 1, 23333965Sjdp MEMREMAP_WC = 1 << 2, 23433965Sjdp}; 23533965Sjdp 23633965Sjdpstatic inline void * 23733965Sjdpmemremap(resource_size_t offset, size_t size, unsigned long flags) 23833965Sjdp{ 23933965Sjdp void *addr = NULL; 24033965Sjdp 24133965Sjdp if ((flags & MEMREMAP_WB) && 24260484Sobrien (addr = ioremap_wb(offset, size)) != NULL) 24360484Sobrien goto done; 24460484Sobrien if ((flags & MEMREMAP_WT) && 24560484Sobrien (addr = ioremap_wt(offset, size)) != NULL) 24660484Sobrien goto done; 24760484Sobrien if ((flags & MEMREMAP_WC) && 24860484Sobrien (addr = ioremap_wc(offset, size)) != NULL) 24960484Sobrien goto done; 25060484Sobriendone: 25133965Sjdp return (addr); 25260484Sobrien} 25333965Sjdp 25433965Sjdpstatic inline void 25560484Sobrienmemunmap(void *addr) 25660484Sobrien{ 25760484Sobrien /* XXX May need to check if this is RAM */ 25833965Sjdp iounmap(addr); 25977298Sobrien} 26033965Sjdp 26133965Sjdp#endif /* _LINUX_IO_H_ */ 26233965Sjdp