openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

io.h.new (5791B)


      1 /*	$OpenBSD: pio.h,v 1.5 1997/11/10 23:40:45 niklas Exp $	*/
      2 /*	$NetBSD: pio.h,v 1.13 1996/03/08 20:15:23 cgd Exp $	*/
      3 
      4 /*
      5  * Copyright (c) 1993, 1995 Charles M. Hannum.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *      This product includes software developed by Charles M. Hannum.
     18  * 4. The name of the author may not be used to endorse or promote products
     19  *    derived from this software without specific prior written permission
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #ifndef _I386_PIO_H_
     34 #define _I386_PIO_H_
     35 
     36 /*
     37  * Functions to provide access to i386 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 #include "blt/types.h"
     45 
     46 #define __SLOW_DOWN_IO asm volatile ("jmp 1f \n 1: jmp 1f \n 1:")
     47 #define SLOW_DOWN_IO __SLOW_DOWN_IO
     48 
     49 #define outb_p(a,b)  { outb(a,b) ; SLOW_DOWN_IO; }
     50 #define inb_p(a,b)   { inb(a,b)  ; SLOW_DOWN_IO; }
     51 #define outw_p(a,b)  { outw(a,b) ; SLOW_DOWN_IO; }
     52 #define inw_p(a,b)   { inw(a,b)  ; SLOW_DOWN_IO; }
     53 
     54 #ifdef __OPTIMIZE__
     55 
     56 #define	__use_immediate_port(port) \
     57 	(__builtin_constant_p((port)) && (port) < 0x100)
     58 
     59 #else
     60 
     61 #define	__use_immediate_port(port)	0
     62 
     63 #endif
     64 
     65 
     66 #define	inb(port) \
     67 	(__use_immediate_port(port) ? __inbc(port) : __inb(port))
     68 
     69 static inline uint8
     70 __inbc(int port)
     71 {
     72 	uint8 data;
     73 	__asm __volatile("inb %1,%0" : "=a" (data) : "id" (port));
     74 	return data;
     75 }
     76 
     77 static inline uint8
     78 __inb(int port)
     79 {
     80 	uint8 data;
     81 	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
     82 	return data;
     83 }
     84 
     85 static inline void
     86 insb(int port, void *addr, int cnt)
     87 {
     88 	__asm __volatile("cld\n\trepne\n\tinsb"			:
     89 								:
     90 			 "d" (port), "D" (addr), "c" (cnt)	:
     91 			 "%edi", "%ecx", "memory");
     92 }
     93 
     94 #define	inw(port) \
     95 	(__use_immediate_port(port) ? __inwc(port) : __inw(port))
     96 
     97 static inline uint16
     98 __inwc(int port)
     99 {
    100 	uint16 data;
    101 	__asm __volatile("inw %1,%0" : "=a" (data) : "id" (port));
    102 	return data;
    103 }
    104 
    105 static inline uint16
    106 __inw(int port)
    107 {
    108 	uint16 data;
    109 	__asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
    110 	return data;
    111 }
    112 
    113 static inline void
    114 insw(int port, void *addr, int cnt)
    115 {
    116 	__asm __volatile("cld\n\trepne\n\tinsw"			:
    117 								:
    118 			 "d" (port), "D" (addr), "c" (cnt)	:
    119 			 "%edi", "%ecx", "memory");
    120 }
    121 
    122 #define	inl(port) \
    123 	(__use_immediate_port(port) ? __inlc(port) : __inl(port))
    124 
    125 static inline uint32
    126 __inlc(int port)
    127 {
    128 	uint32 data;
    129 	__asm __volatile("inl %1,%0" : "=a" (data) : "id" (port));
    130 	return data;
    131 }
    132 
    133 static inline uint32
    134 __inl(int port)
    135 {
    136 	uint32 data;
    137 	__asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
    138 	return data;
    139 }
    140 
    141 static inline void
    142 insl(int port, void *addr, int cnt)
    143 {
    144 	__asm __volatile("cld\n\trepne\n\tinsl"			:
    145 								:
    146 			 "d" (port), "D" (addr), "c" (cnt)	:
    147 			 "%edi", "%ecx", "memory");
    148 }
    149 
    150 #define	outb(port, data) \
    151 	(__use_immediate_port(port) ? __outbc(port, data) : __outb(port, data))
    152 
    153 static inline void
    154 __outbc(int port, uint8 data)
    155 {
    156 	__asm __volatile("outb %0,%1" : : "a" (data), "id" (port));
    157 }
    158 
    159 static inline void
    160 __outb(int port, uint8 data)
    161 {
    162 	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
    163 }
    164 
    165 static inline void
    166 outsb(int port, const void *addr, int cnt)
    167 {
    168 	__asm __volatile("cld\n\trepne\n\toutsb"		:
    169 								:
    170 			 "d" (port), "S" (addr), "c" (cnt)	:
    171 			 "%esi", "%ecx");
    172 }
    173 
    174 #define	outw(port, data) \
    175 	(__use_immediate_port(port) ? __outwc(port, data) : __outw(port, data))
    176 
    177 static inline void
    178 __outwc(int port, uint16 data)
    179 {
    180 	__asm __volatile("outw %0,%1" : : "a" (data), "id" (port));
    181 }
    182 
    183 static inline void
    184 __outw(int port, uint16 data)
    185 {
    186 	__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
    187 }
    188 
    189 static inline void
    190 outsw(int port, const void *addr, int cnt)
    191 {
    192 	__asm __volatile("cld\n\trepne\n\toutsw"		:
    193 								:
    194 			 "d" (port), "S" (addr), "c" (cnt)	:
    195 			 "%esi", "%ecx");
    196 }
    197 
    198 #define	outl(port, data) \
    199 	(__use_immediate_port(port) ? __outlc(port, data) : __outl(port, data))
    200 
    201 static inline void
    202 __outlc(int port, uint32 data)
    203 {
    204 	__asm __volatile("outl %0,%1" : : "a" (data), "id" (port));
    205 }
    206 
    207 static inline void
    208 __outl(int port, uint32 data)
    209 {
    210 	__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
    211 }
    212 
    213 static inline void
    214 outsl(int port, const void *addr, int cnt)
    215 {
    216 	__asm __volatile("cld\n\trepne\n\toutsl"		:
    217 								:
    218 			 "d" (port), "S" (addr), "c" (cnt)	:
    219 			 "%esi", "%ecx");
    220 }
    221 
    222 #endif /* _I386_PIO_H_ */