io.h revision 299364
1219820Sjeff/*- 2219820Sjeff * Copyright (c) 2010 Isilon Systems, Inc. 3219820Sjeff * Copyright (c) 2010 iX Systems, Inc. 4219820Sjeff * Copyright (c) 2010 Panasas, Inc. 5290706Shselasky * Copyright (c) 2013-2015 Mellanox Technologies, Ltd. 6219820Sjeff * All rights reserved. 7219820Sjeff * 8219820Sjeff * Redistribution and use in source and binary forms, with or without 9219820Sjeff * modification, are permitted provided that the following conditions 10219820Sjeff * are met: 11219820Sjeff * 1. Redistributions of source code must retain the above copyright 12219820Sjeff * notice unmodified, this list of conditions, and the following 13219820Sjeff * disclaimer. 14219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright 15219820Sjeff * notice, this list of conditions and the following disclaimer in the 16219820Sjeff * documentation and/or other materials provided with the distribution. 17219820Sjeff * 18219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28289644Shselasky * 29289644Shselasky * $FreeBSD: head/sys/compat/linuxkpi/common/include/linux/io.h 299364 2016-05-10 12:04:57Z hselasky $ 30219820Sjeff */ 31219820Sjeff#ifndef _LINUX_IO_H_ 32219820Sjeff#define _LINUX_IO_H_ 33219820Sjeff 34219820Sjeff#include <machine/vm.h> 35277396Shselasky#include <sys/endian.h> 36290335Shselasky#include <sys/types.h> 37219820Sjeff 38299364Shselasky#include <linux/compiler.h> 39299364Shselasky 40219820Sjeffstatic inline uint32_t 41219820Sjeff__raw_readl(const volatile void *addr) 42219820Sjeff{ 43219820Sjeff return *(const volatile uint32_t *)addr; 44219820Sjeff} 45219820Sjeff 46219820Sjeffstatic inline void 47219820Sjeff__raw_writel(uint32_t b, volatile void *addr) 48219820Sjeff{ 49219820Sjeff *(volatile uint32_t *)addr = b; 50219820Sjeff} 51219820Sjeff 52219820Sjeffstatic inline uint64_t 53219820Sjeff__raw_readq(const volatile void *addr) 54219820Sjeff{ 55219820Sjeff return *(const volatile uint64_t *)addr; 56219820Sjeff} 57219820Sjeff 58219820Sjeffstatic inline void 59219820Sjeff__raw_writeq(uint64_t b, volatile void *addr) 60219820Sjeff{ 61219820Sjeff *(volatile uint64_t *)addr = b; 62219820Sjeff} 63219820Sjeff 64219820Sjeff/* 65219820Sjeff * XXX This is all x86 specific. It should be bus space access. 66219820Sjeff */ 67299364Shselasky#define mmiowb() barrier() 68219820Sjeff 69219820Sjeff#undef writel 70219820Sjeffstatic inline void 71219820Sjeffwritel(uint32_t b, void *addr) 72219820Sjeff{ 73219820Sjeff *(volatile uint32_t *)addr = b; 74219820Sjeff} 75219820Sjeff 76219820Sjeff#undef writeq 77219820Sjeffstatic inline void 78219820Sjeffwriteq(uint64_t b, void *addr) 79219820Sjeff{ 80219820Sjeff *(volatile uint64_t *)addr = b; 81219820Sjeff} 82219820Sjeff 83219820Sjeff#undef writeb 84219820Sjeffstatic inline void 85219820Sjeffwriteb(uint8_t b, void *addr) 86219820Sjeff{ 87219820Sjeff *(volatile uint8_t *)addr = b; 88219820Sjeff} 89219820Sjeff 90219820Sjeff#undef writew 91219820Sjeffstatic inline void 92219820Sjeffwritew(uint16_t b, void *addr) 93219820Sjeff{ 94219820Sjeff *(volatile uint16_t *)addr = b; 95219820Sjeff} 96219820Sjeff 97299364Shselasky#undef ioread8 98299364Shselaskystatic inline uint8_t 99299364Shselaskyioread8(const volatile void *addr) 100299364Shselasky{ 101299364Shselasky return *(const volatile uint8_t *)addr; 102299364Shselasky} 103299364Shselasky 104299364Shselasky#undef ioread16 105299364Shselaskystatic inline uint16_t 106299364Shselaskyioread16(const volatile void *addr) 107299364Shselasky{ 108299364Shselasky return *(const volatile uint16_t *)addr; 109299364Shselasky} 110299364Shselasky 111299364Shselasky#undef ioread32 112299364Shselaskystatic inline uint32_t 113299364Shselaskyioread32(const volatile void *addr) 114299364Shselasky{ 115299364Shselasky return *(const volatile uint32_t *)addr; 116299364Shselasky} 117299364Shselasky 118277396Shselasky#undef ioread32be 119277396Shselaskystatic inline uint32_t 120277396Shselaskyioread32be(const volatile void *addr) 121277396Shselasky{ 122277396Shselasky return be32toh(*(const volatile uint32_t *)addr); 123277396Shselasky} 124277396Shselasky 125299364Shselasky#undef iowrite8 126299364Shselaskystatic inline void 127299364Shselaskyiowrite8(uint8_t v, volatile void *addr) 128299364Shselasky{ 129299364Shselasky *(volatile uint8_t *)addr = v; 130299364Shselasky} 131299364Shselasky 132299364Shselasky#undef iowrite16 133299364Shselaskystatic inline void 134299364Shselaskyiowrite16(uint16_t v, volatile void *addr) 135299364Shselasky{ 136299364Shselasky *(volatile uint16_t *)addr = v; 137299364Shselasky} 138299364Shselasky 139299364Shselasky#undef iowrite32 140299364Shselaskystatic inline void 141299364Shselaskyiowrite32(uint32_t v, volatile void *addr) 142299364Shselasky{ 143299364Shselasky *(volatile uint32_t *)addr = v; 144299364Shselasky} 145299364Shselasky 146277396Shselasky#undef iowrite32be 147277396Shselaskystatic inline void 148277396Shselaskyiowrite32be(uint32_t v, volatile void *addr) 149277396Shselasky{ 150277396Shselasky *(volatile uint32_t *)addr = htobe32(v); 151277396Shselasky} 152277396Shselasky 153290706Shselasky#undef readb 154290706Shselaskystatic inline uint8_t 155290706Shselaskyreadb(const volatile void *addr) 156290706Shselasky{ 157290706Shselasky return *(const volatile uint8_t *)addr; 158290706Shselasky} 159290706Shselasky 160290706Shselasky#undef readw 161290706Shselaskystatic inline uint16_t 162290706Shselaskyreadw(const volatile void *addr) 163290706Shselasky{ 164290706Shselasky return *(const volatile uint16_t *)addr; 165290706Shselasky} 166290706Shselasky 167290706Shselasky#undef readl 168290706Shselaskystatic inline uint32_t 169290706Shselaskyreadl(const volatile void *addr) 170290706Shselasky{ 171290706Shselasky return *(const volatile uint32_t *)addr; 172290706Shselasky} 173290706Shselasky 174290706Shselasky#if defined(__i386__) || defined(__amd64__) 175219820Sjeffvoid *_ioremap_attr(vm_paddr_t phys_addr, unsigned long size, int attr); 176290706Shselasky#else 177290706Shselasky#define _ioremap_attr(...) NULL 178290706Shselasky#endif 179290706Shselasky 180219820Sjeff#define ioremap_nocache(addr, size) \ 181233547Sjhb _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE) 182219820Sjeff#define ioremap_wc(addr, size) \ 183219820Sjeff _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_COMBINING) 184299364Shselasky#define ioremap_wb(addr, size) \ 185299364Shselasky _ioremap_attr((addr), (size), VM_MEMATTR_WRITE_BACK) 186290706Shselasky#define ioremap(addr, size) \ 187290706Shselasky _ioremap_attr((addr), (size), VM_MEMATTR_UNCACHEABLE) 188219820Sjeffvoid iounmap(void *addr); 189219820Sjeff 190219820Sjeff#define memset_io(a, b, c) memset((a), (b), (c)) 191219820Sjeff#define memcpy_fromio(a, b, c) memcpy((a), (b), (c)) 192219820Sjeff#define memcpy_toio(a, b, c) memcpy((a), (b), (c)) 193219820Sjeff 194219820Sjeffstatic inline void 195219820Sjeff__iowrite64_copy(void *to, void *from, size_t count) 196219820Sjeff{ 197219820Sjeff#ifdef __LP64__ 198219820Sjeff uint64_t *src; 199219820Sjeff uint64_t *dst; 200219820Sjeff int i; 201219820Sjeff 202219820Sjeff for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 203219820Sjeff __raw_writeq(*src, dst); 204219820Sjeff#else 205219820Sjeff uint32_t *src; 206219820Sjeff uint32_t *dst; 207219820Sjeff int i; 208219820Sjeff 209219820Sjeff count *= 2; 210219820Sjeff for (i = 0, src = from, dst = to; i < count; i++, src++, dst++) 211219820Sjeff __raw_writel(*src, dst); 212219820Sjeff#endif 213219820Sjeff} 214219820Sjeff 215299364Shselaskyenum { 216299364Shselasky MEMREMAP_WB = 1 << 0, 217299364Shselasky MEMREMAP_WT = 1 << 1, 218299364Shselasky MEMREMAP_WC = 1 << 2, 219299364Shselasky}; 220219820Sjeff 221299364Shselaskystatic inline void * 222299364Shselaskymemremap(resource_size_t offset, size_t size, unsigned long flags) 223299364Shselasky{ 224299364Shselasky void *addr = NULL; 225299364Shselasky 226299364Shselasky if ((flags & MEMREMAP_WB) && 227299364Shselasky (addr = ioremap_wb(offset, size)) != NULL) 228299364Shselasky goto done; 229299364Shselasky if ((flags & MEMREMAP_WT) && 230299364Shselasky (addr = ioremap_nocache(offset, size)) != NULL) 231299364Shselasky goto done; 232299364Shselasky if ((flags & MEMREMAP_WC) && 233299364Shselasky (addr = ioremap_wc(offset, size)) != NULL) 234299364Shselasky goto done; 235299364Shselaskydone: 236299364Shselasky return (addr); 237299364Shselasky} 238299364Shselasky 239299364Shselaskystatic inline void 240299364Shselaskymemunmap(void *addr) 241299364Shselasky{ 242299364Shselasky /* XXX May need to check if this is RAM */ 243299364Shselasky iounmap(addr); 244299364Shselasky} 245299364Shselasky 246219820Sjeff#endif /* _LINUX_IO_H_ */ 247