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