3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/hal/x86/portio.c
6 * PURPOSE: Port I/O functions
7 * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
12 #include <ddk/ntddk.h>
15 /* FUNCTIONS ****************************************************************/
18 * This file contains the definitions for the x86 IO instructions
19 * inb/inw/inl/outb/outw/outl and the "string versions" of the same
20 * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
21 * versions of the single-IO instructions (inb_p/inw_p/..).
23 * This file is not meant to be obfuscating: it's just complicated
24 * to (a) handle it all in a way that makes gcc able to optimize it
25 * as well as possible and (b) trying to avoid writing the same thing
26 * over and over again with slight variations and possibly making a
31 * Thanks to James van Artsdalen for a better timing-fix than
32 * the two short jumps: using outb's to a nonexistent port seems
33 * to guarantee better timings even on fast machines.
35 * On the other hand, I'd like to be sure of a non-existent port:
36 * I feel a bit unsafe about using 0x80 (should be safe, though)
41 #ifdef SLOW_IO_BY_JUMPING
42 #define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
44 #define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
48 #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
50 #define SLOW_DOWN_IO __SLOW_DOWN_IO
54 READ_PORT_BUFFER_UCHAR (PUCHAR Port,
58 __asm__ __volatile__ ("cld ; rep ; insb\n\t"
59 : "=D" (Buffer), "=c" (Count)
60 : "d" (Port),"0" (Buffer),"1" (Count));
64 READ_PORT_BUFFER_USHORT (PUSHORT Port,
68 __asm__ __volatile__ ("cld ; rep ; insw"
69 : "=D" (Buffer), "=c" (Count)
70 : "d" (Port),"0" (Buffer),"1" (Count));
74 READ_PORT_BUFFER_ULONG (PULONG Port,
78 __asm__ __volatile__ ("cld ; rep ; insl"
79 : "=D" (Buffer), "=c" (Count)
80 : "d" (Port),"0" (Buffer),"1" (Count));
84 READ_PORT_UCHAR (PUCHAR Port)
88 __asm__("inb %w1, %0\n\t"
96 READ_PORT_USHORT (PUSHORT Port)
100 __asm__("inw %w1, %0\n\t"
108 READ_PORT_ULONG (PULONG Port)
112 __asm__("inl %w1, %0\n\t"
120 WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
124 __asm__ __volatile__ ("cld ; rep ; outsb"
125 : "=S" (Buffer), "=c" (Count)
126 : "d" (Port),"0" (Buffer),"1" (Count));
130 WRITE_PORT_BUFFER_USHORT (PUSHORT Port,
134 __asm__ __volatile__ ("cld ; rep ; outsw"
135 : "=S" (Buffer), "=c" (Count)
136 : "d" (Port),"0" (Buffer),"1" (Count));
140 WRITE_PORT_BUFFER_ULONG (PULONG Port,
144 __asm__ __volatile__ ("cld ; rep ; outsl"
145 : "=S" (Buffer), "=c" (Count)
146 : "d" (Port),"0" (Buffer),"1" (Count));
150 WRITE_PORT_UCHAR (PUCHAR Port,
153 __asm__("outb %0, %w1\n\t"
161 WRITE_PORT_USHORT (PUSHORT Port,
164 __asm__("outw %0, %w1\n\t"
172 WRITE_PORT_ULONG (PULONG Port,
175 __asm__("outl %0, %w1\n\t"