1 /* $OpenBSD: pio.h,v 1.5 2015/04/25 21:31:24 guenther Exp $ */ 2 /* $NetBSD: pio.h,v 1.2 2003/02/27 11:22:46 fvdl Exp $ */ 3 4 /*- 5 * Copyright (c) 1998 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Charles M. Hannum. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifndef _MACHINE_PIO_H_ 34 #define _MACHINE_PIO_H_ 35 36 /* 37 * Functions to provide access to x86 programmed I/O instructions. 38 * 39 * The in[bwl]() and out[bwl]() functions are split into two varieties: one to 40 * use a small, constant, 8-bit port number, and another to use a large or 41 * variable port number. The former can be compiled as a smaller instruction. 42 */ 43 44 45 #ifdef __OPTIMIZE__ 46 47 #define __use_immediate_port(port) \ 48 (__builtin_constant_p((port)) && (port) < 0x100) 49 50 #else 51 52 #define __use_immediate_port(port) 0 53 54 #endif 55 56 57 #define inb(port) \ 58 (/* CONSTCOND */ __use_immediate_port(port) ? __inbc(port) : __inb(port)) 59 60 static __inline u_int8_t 61 __inbc(unsigned port) 62 { 63 u_int8_t data; 64 __asm volatile("inb %w1,%0" : "=a" (data) : "id" (port)); 65 return data; 66 } 67 68 static __inline u_int8_t 69 __inb(unsigned port) 70 { 71 u_int8_t data; 72 __asm volatile("inb %w1,%0" : "=a" (data) : "d" (port)); 73 return data; 74 } 75 76 static __inline void 77 insb(unsigned port, void *addr, int cnt) 78 { 79 void *dummy1; 80 int dummy2; 81 __asm volatile("repne\n\tinsb" : 82 "=D" (dummy1), "=c" (dummy2) : 83 "d" (port), "0" (addr), "1" (cnt) : 84 "memory"); 85 } 86 87 #define inw(port) \ 88 (/* CONSTCOND */ __use_immediate_port(port) ? __inwc(port) : __inw(port)) 89 90 static __inline u_int16_t 91 __inwc(unsigned port) 92 { 93 u_int16_t data; 94 __asm volatile("inw %w1,%0" : "=a" (data) : "id" (port)); 95 return data; 96 } 97 98 static __inline u_int16_t 99 __inw(unsigned port) 100 { 101 u_int16_t data; 102 __asm volatile("inw %w1,%0" : "=a" (data) : "d" (port)); 103 return data; 104 } 105 106 static __inline void 107 insw(unsigned port, void *addr, int cnt) 108 { 109 void *dummy1; 110 int dummy2; 111 __asm volatile("repne\n\tinsw" : 112 "=D" (dummy1), "=c" (dummy2) : 113 "d" (port), "0" (addr), "1" (cnt) : 114 "memory"); 115 } 116 117 #define inl(port) \ 118 (/* CONSTCOND */ __use_immediate_port(port) ? __inlc(port) : __inl(port)) 119 120 static __inline u_int32_t 121 __inlc(unsigned port) 122 { 123 u_int32_t data; 124 __asm volatile("inl %w1,%0" : "=a" (data) : "id" (port)); 125 return data; 126 } 127 128 static __inline u_int32_t 129 __inl(unsigned port) 130 { 131 u_int32_t data; 132 __asm volatile("inl %w1,%0" : "=a" (data) : "d" (port)); 133 return data; 134 } 135 136 static __inline void 137 insl(unsigned port, void *addr, int cnt) 138 { 139 void *dummy1; 140 int dummy2; 141 __asm volatile("repne\n\tinsl" : 142 "=D" (dummy1), "=c" (dummy2) : 143 "d" (port), "0" (addr), "1" (cnt) : 144 "memory"); 145 } 146 147 #define outb(port, data) \ 148 (/* CONSTCOND */__use_immediate_port(port) ? __outbc(port, data) : \ 149 __outb(port, data)) 150 151 static __inline void 152 __outbc(unsigned port, u_int8_t data) 153 { 154 __asm volatile("outb %0,%w1" : : "a" (data), "id" (port)); 155 } 156 157 static __inline void 158 __outb(unsigned port, u_int8_t data) 159 { 160 __asm volatile("outb %0,%w1" : : "a" (data), "d" (port)); 161 } 162 163 static __inline void 164 outsb(unsigned port, const void *addr, int cnt) 165 { 166 void *dummy1; 167 int dummy2; 168 __asm volatile("repne\n\toutsb" : 169 "=S" (dummy1), "=c" (dummy2) : 170 "d" (port), "0" (addr), "1" (cnt)); 171 } 172 173 #define outw(port, data) \ 174 (/* CONSTCOND */ __use_immediate_port(port) ? __outwc(port, data) : \ 175 __outw(port, data)) 176 177 static __inline void 178 __outwc(unsigned port, u_int16_t data) 179 { 180 __asm volatile("outw %0,%w1" : : "a" (data), "id" (port)); 181 } 182 183 static __inline void 184 __outw(unsigned port, u_int16_t data) 185 { 186 __asm volatile("outw %0,%w1" : : "a" (data), "d" (port)); 187 } 188 189 static __inline void 190 outsw(unsigned port, const void *addr, int cnt) 191 { 192 void *dummy1; 193 int dummy2; 194 __asm volatile("repne\n\toutsw" : 195 "=S" (dummy1), "=c" (dummy2) : 196 "d" (port), "0" (addr), "1" (cnt)); 197 } 198 199 #define outl(port, data) \ 200 (/* CONSTCOND */ __use_immediate_port(port) ? __outlc(port, data) : \ 201 __outl(port, data)) 202 203 static __inline void 204 __outlc(unsigned port, u_int32_t data) 205 { 206 __asm volatile("outl %0,%w1" : : "a" (data), "id" (port)); 207 } 208 209 static __inline void 210 __outl(unsigned port, u_int32_t data) 211 { 212 __asm volatile("outl %0,%w1" : : "a" (data), "d" (port)); 213 } 214 215 static __inline void 216 outsl(unsigned port, const void *addr, int cnt) 217 { 218 void *dummy1; 219 int dummy2; 220 __asm volatile("repne\n\toutsl" : 221 "=S" (dummy1), "=c" (dummy2) : 222 "d" (port), "0" (addr), "1" (cnt)); 223 } 224 225 #endif /* _MACHINE_PIO_H_ */ 226