portio.hpp
00001 #if !defined(__SYSTEM_L4_X86_PORTIO_HPP__)
00002 #define __SYSTEM_L4_X86_PORTIO_HPP__
00003
00004
00005
00006
00007 #include <l4/vmm/api/l4util.h>
00008
00009 #if L4VMM_ARCH_HAS_IOSPACE
00010
00011
00012
00013
00014 #include <stdint.h>
00015
00016
00017
00018
00019 #include <l4/util/port_io.h>
00020
00021
00022
00023
00024
00025 #if defined(l4util_in8) || defined(l4util_in16) || defined(l4util_in32) || \
00026 defined(l4util_out8) || defined(l4util_out16) || defined(l4util_out32) || \
00027 defined(l4util_ins8) || defined(l4util_ins16) || defined(l4util_ins32) || \
00028 defined(l4util_outs8) || defined(l4util_outs16) || defined(l4util_outs32)
00029 #error someone included the compat header(s). fix this.
00030 #endif
00031
00032
00033
00034
00035 namespace detail
00036 {
00037 #define L4VMM_OUTS(bits, instruction) \
00038 inline void l4vmm_outs ## bits(const l4_port_t port, const l4_umword_t src, \
00039 const l4_umword_t num) \
00040 { \
00041 l4_umword_t dummy; \
00042 asm volatile ("rep " #instruction \
00043 : "=S"(dummy), "=c"(dummy) \
00044 : "d"(port), "S"(src), "c"(num)); \
00045 }
00046
00047 L4VMM_OUTS(8, outsb)
00048 L4VMM_OUTS(16, outsw)
00049 L4VMM_OUTS(32, outsl)
00050
00051 #undef L4VMM_OUTS
00052 }
00053
00054
00055
00056
00057 template <typename>
00058 struct portio
00059 {};
00060
00061 template <>
00062 struct portio<uint8_t>
00063 {
00064 static inline uint8_t in(const l4_port_t port)
00065 {
00066 return l4util_in8(port);
00067 }
00068
00069 static inline int out(const l4_port_t port, const uint8_t value)
00070 {
00071 l4util_out8(value, port);
00072 return 0;
00073 }
00074
00075 static inline void ins(const l4_port_t port, void *dst, const l4_umword_t num)
00076 {
00077 l4util_ins8(port, reinterpret_cast<l4_umword_t>(dst), num);
00078 }
00079
00080 static inline void outs(const l4_port_t port, const void *src, const l4_umword_t num)
00081 {
00082 detail::l4vmm_outs8(port, reinterpret_cast<l4_umword_t>(src), num);
00083 }
00084 };
00085
00086 template <>
00087 struct portio<uint16_t>
00088 {
00089 static inline uint16_t in(const l4_port_t port)
00090 {
00091 return l4util_in16(port);
00092 }
00093
00094 static inline int out(const l4_port_t port, const uint16_t value)
00095 {
00096 l4util_out16(value, port);
00097 return 0;
00098 }
00099
00100 static inline void ins(const l4_port_t port, void *dst, const l4_umword_t num)
00101 {
00102 l4util_ins16(port, reinterpret_cast<l4_umword_t>(dst), num);
00103 }
00104
00105 static inline void outs(const l4_port_t port, const void *src, const l4_umword_t num)
00106 {
00107 detail::l4vmm_outs16(port, reinterpret_cast<l4_umword_t>(src), num);
00108 }
00109 };
00110
00111 template <>
00112 struct portio<uint32_t>
00113 {
00114 static inline uint32_t in(const l4_port_t port)
00115 {
00116 return l4util_in32(port);
00117 }
00118
00119 static inline int out(const l4_port_t port, const uint32_t value)
00120 {
00121 l4util_out32(value, port);
00122 return 0;
00123 }
00124
00125 static inline void ins(const l4_port_t port, void *dst, const l4_umword_t num)
00126 {
00127 l4util_ins32(port, reinterpret_cast<l4_umword_t>(dst), num);
00128 }
00129
00130 static inline void outs(const l4_port_t port, const void *src, const l4_umword_t num)
00131 {
00132 detail::l4vmm_outs32(port, reinterpret_cast<l4_umword_t>(src), num);
00133 }
00134 };
00135
00136 #endif
00137
00138 #endif
00139
00140
00141