add port io functions to sys/io.h
authorRich Felker <dalias@aerifal.cx>
Mon, 19 Nov 2012 00:31:58 +0000 (19:31 -0500)
committerRich Felker <dalias@aerifal.cx>
Mon, 19 Nov 2012 00:31:58 +0000 (19:31 -0500)
based on proposal by Isaac Dunham. nonexistance of bits/io.h will
cause inclusion of sys/io.h to produce an error on archs that are not
supposed to have it. this is probably the desired behavior, but the
error message may be a bit unusual.

arch/i386/bits/io.h [new file with mode: 0644]
arch/x86_64/bits/io.h [new file with mode: 0644]
include/sys/io.h
src/linux/ioperm.c
src/linux/iopl.c

diff --git a/arch/i386/bits/io.h b/arch/i386/bits/io.h
new file mode 100644 (file)
index 0000000..d26ea57
--- /dev/null
@@ -0,0 +1,80 @@
+int iopl(int);
+int ioperm(unsigned long, unsigned long, int);
+
+static __inline void outb(unsigned char __val, unsigned short __port)
+{
+       __asm__ volatile ("outb %0,%1" : : "a" (__val), "dN" (__port));
+}
+
+static __inline void outw(unsigned short __val, unsigned short __port)
+{
+       __asm__ volatile ("outw %0,%1" : : "a" (__val), "dN" (__port));
+}
+
+static __inline void outl(unsigned int __val, unsigned short __port)
+{
+       __asm__ volatile ("outl %0,%1" : : "a" (__val), "dN" (__port));
+}
+
+static __inline unsigned char inb(unsigned short __port)
+{
+       unsigned char __val;
+       __asm__ volatile ("inb %1,%0" : "=a" (__val) : "dN" (__port));
+       return __val;
+}
+
+static __inline unsigned short inw(unsigned short __port)
+{
+       unsigned short __val;
+       __asm__ volatile ("inw %1,%0" : "=a" (__val) : "dN" (__port));
+       return __val;
+}
+
+static __inline unsigned int inl(unsigned short __port)
+{
+       unsigned int __val;
+       __asm__ volatile ("inl %1,%0" : "=a" (__val) : "dN" (__port));
+       return __val;
+}
+
+static __inline void outsb(unsigned short __port, const void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; outsb"
+                     : "+S" (__buf), "+c" (__n)
+                     : "d" (__port));
+}
+
+static __inline void outsw(unsigned short __port, const void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; outsw"
+                     : "+S" (__buf), "+c" (__n)
+                     : "d" (__port));
+}
+
+static __inline void outsl(unsigned short __port, const void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; outsl"
+                     : "+S" (__buf), "+c"(__n)
+                     : "d" (__port));
+}
+
+static __inline void insb(unsigned short __port, void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; insb"
+                     : "+D" (__buf), "+c" (__n)
+                     : "d" (__port));
+}
+
+static __inline void insw(unsigned short __port, void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; insw"
+                     : "+D" (__buf), "+c" (__n)
+                     : "d" (__port));
+}
+
+static __inline void insl(unsigned short __port, void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; insl"
+                     : "+D" (__buf), "+c" (__n)
+                     : "d" (__port));
+}
diff --git a/arch/x86_64/bits/io.h b/arch/x86_64/bits/io.h
new file mode 100644 (file)
index 0000000..d26ea57
--- /dev/null
@@ -0,0 +1,80 @@
+int iopl(int);
+int ioperm(unsigned long, unsigned long, int);
+
+static __inline void outb(unsigned char __val, unsigned short __port)
+{
+       __asm__ volatile ("outb %0,%1" : : "a" (__val), "dN" (__port));
+}
+
+static __inline void outw(unsigned short __val, unsigned short __port)
+{
+       __asm__ volatile ("outw %0,%1" : : "a" (__val), "dN" (__port));
+}
+
+static __inline void outl(unsigned int __val, unsigned short __port)
+{
+       __asm__ volatile ("outl %0,%1" : : "a" (__val), "dN" (__port));
+}
+
+static __inline unsigned char inb(unsigned short __port)
+{
+       unsigned char __val;
+       __asm__ volatile ("inb %1,%0" : "=a" (__val) : "dN" (__port));
+       return __val;
+}
+
+static __inline unsigned short inw(unsigned short __port)
+{
+       unsigned short __val;
+       __asm__ volatile ("inw %1,%0" : "=a" (__val) : "dN" (__port));
+       return __val;
+}
+
+static __inline unsigned int inl(unsigned short __port)
+{
+       unsigned int __val;
+       __asm__ volatile ("inl %1,%0" : "=a" (__val) : "dN" (__port));
+       return __val;
+}
+
+static __inline void outsb(unsigned short __port, const void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; outsb"
+                     : "+S" (__buf), "+c" (__n)
+                     : "d" (__port));
+}
+
+static __inline void outsw(unsigned short __port, const void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; outsw"
+                     : "+S" (__buf), "+c" (__n)
+                     : "d" (__port));
+}
+
+static __inline void outsl(unsigned short __port, const void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; outsl"
+                     : "+S" (__buf), "+c"(__n)
+                     : "d" (__port));
+}
+
+static __inline void insb(unsigned short __port, void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; insb"
+                     : "+D" (__buf), "+c" (__n)
+                     : "d" (__port));
+}
+
+static __inline void insw(unsigned short __port, void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; insw"
+                     : "+D" (__buf), "+c" (__n)
+                     : "d" (__port));
+}
+
+static __inline void insl(unsigned short __port, void *__buf, unsigned long __n)
+{
+       __asm__ volatile ("cld; rep; insl"
+                     : "+D" (__buf), "+c" (__n)
+                     : "d" (__port));
+}
index a6ba467..ce5423e 100644 (file)
@@ -4,8 +4,9 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-int ioperm(unsigned long, unsigned long, int);
-int iopl(int);
+#include <features.h>
+
+#include <bits/io.h>
 
 #ifdef __cplusplus
 }
 
 #ifdef __cplusplus
 }
index 6d7c37d..08c6d8b 100644 (file)
@@ -1,7 +1,8 @@
-#include <sys/io.h>
 #include "syscall.h"
 
 #ifdef SYS_ioperm
 #include "syscall.h"
 
 #ifdef SYS_ioperm
+#include <sys/io.h>
+
 int ioperm(unsigned long from, unsigned long num, int turn_on)
 {
        return syscall(SYS_ioperm, from, num, turn_on);
 int ioperm(unsigned long from, unsigned long num, int turn_on)
 {
        return syscall(SYS_ioperm, from, num, turn_on);
index 5a626e1..835d3d4 100644 (file)
@@ -1,7 +1,8 @@
-#include <sys/io.h>
 #include "syscall.h"
 
 #ifdef SYS_iopl
 #include "syscall.h"
 
 #ifdef SYS_iopl
+#include <sys/io.h>
+
 int iopl(int level)
 {
        return syscall(SYS_iopl, level);
 int iopl(int level)
 {
        return syscall(SYS_iopl, level);