Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / arch / x86 / include / ipxe / x86_io.h
diff --git a/qemu/roms/ipxe/src/arch/x86/include/ipxe/x86_io.h b/qemu/roms/ipxe/src/arch/x86/include/ipxe/x86_io.h
new file mode 100644 (file)
index 0000000..9e68f4e
--- /dev/null
@@ -0,0 +1,162 @@
+#ifndef _IPXE_X86_IO_H
+#define _IPXE_X86_IO_H
+
+/** @file
+ *
+ * iPXE I/O API for x86
+ *
+ * x86 uses direct pointer dereferences for accesses to memory-mapped
+ * I/O space, and the inX/outX instructions for accesses to
+ * port-mapped I/O space.
+ *
+ * 64-bit atomic accesses (readq() and writeq()) use MMX instructions
+ * under i386, and will crash original Pentium and earlier CPUs.
+ * Fortunately, no hardware that requires atomic 64-bit accesses will
+ * physically fit into a machine with such an old CPU anyway.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#ifdef IOAPI_X86
+#define IOAPI_PREFIX_x86
+#else
+#define IOAPI_PREFIX_x86 __x86_
+#endif
+
+/*
+ * Memory space mappings
+ *
+ */
+
+/** Page shift */
+#define PAGE_SHIFT 12
+
+/*
+ * Physical<->Bus and Bus<->I/O address mappings
+ *
+ */
+
+static inline __always_inline unsigned long
+IOAPI_INLINE ( x86, phys_to_bus ) ( unsigned long phys_addr ) {
+       return phys_addr;
+}
+
+static inline __always_inline unsigned long
+IOAPI_INLINE ( x86, bus_to_phys ) ( unsigned long bus_addr ) {
+       return bus_addr;
+}
+
+static inline __always_inline void *
+IOAPI_INLINE ( x86, ioremap ) ( unsigned long bus_addr, size_t len __unused ) {
+       return ( bus_addr ? phys_to_virt ( bus_addr ) : NULL );
+}
+
+static inline __always_inline void
+IOAPI_INLINE ( x86, iounmap ) ( volatile const void *io_addr __unused ) {
+       /* Nothing to do */
+}
+
+static inline __always_inline unsigned long
+IOAPI_INLINE ( x86, io_to_bus ) ( volatile const void *io_addr ) {
+       return virt_to_phys ( io_addr );
+}
+
+/*
+ * MMIO reads and writes up to native word size
+ *
+ */
+
+#define X86_READX( _api_func, _type )                                        \
+static inline __always_inline _type                                          \
+IOAPI_INLINE ( x86, _api_func ) ( volatile _type *io_addr ) {                \
+       return *io_addr;                                                      \
+}
+X86_READX ( readb, uint8_t );
+X86_READX ( readw, uint16_t );
+X86_READX ( readl, uint32_t );
+#ifdef __x86_64__
+X86_READX ( readq, uint64_t );
+#endif
+
+#define X86_WRITEX( _api_func, _type )                                       \
+static inline __always_inline void                                           \
+IOAPI_INLINE ( x86, _api_func ) ( _type data,                                \
+                                 volatile _type *io_addr ) {                 \
+       *io_addr = data;                                                      \
+}
+X86_WRITEX ( writeb, uint8_t );
+X86_WRITEX ( writew, uint16_t );
+X86_WRITEX ( writel, uint32_t );
+#ifdef __x86_64__
+X86_WRITEX ( writeq, uint64_t );
+#endif
+
+/*
+ * PIO reads and writes up to 32 bits
+ *
+ */
+
+#define X86_INX( _insn_suffix, _type, _reg_prefix )                          \
+static inline __always_inline _type                                          \
+IOAPI_INLINE ( x86, in ## _insn_suffix ) ( volatile _type *io_addr ) {       \
+       _type data;                                                           \
+       __asm__ __volatile__ ( "in" #_insn_suffix " %w1, %" _reg_prefix "0"   \
+                              : "=a" ( data ) : "Nd" ( io_addr ) );          \
+       return data;                                                          \
+}                                                                            \
+static inline __always_inline void                                           \
+IOAPI_INLINE ( x86, ins ## _insn_suffix ) ( volatile _type *io_addr,         \
+                                           _type *data,                      \
+                                           unsigned int count ) {            \
+       unsigned int discard_D;                                               \
+       __asm__ __volatile__ ( "rep ins" #_insn_suffix                        \
+                              : "=D" ( discard_D )                           \
+                              : "d" ( io_addr ), "c" ( count ),              \
+                                "0" ( data ) );                              \
+}
+X86_INX ( b, uint8_t, "b" );
+X86_INX ( w, uint16_t, "w" );
+X86_INX ( l, uint32_t, "k" );
+
+#define X86_OUTX( _insn_suffix, _type, _reg_prefix )                         \
+static inline __always_inline void                                           \
+IOAPI_INLINE ( x86, out ## _insn_suffix ) ( _type data,                              \
+                                           volatile _type *io_addr ) {       \
+       __asm__ __volatile__ ( "out" #_insn_suffix " %" _reg_prefix "0, %w1"  \
+                              : : "a" ( data ), "Nd" ( io_addr ) );          \
+}                                                                            \
+static inline __always_inline void                                           \
+IOAPI_INLINE ( x86, outs ## _insn_suffix ) ( volatile _type *io_addr,        \
+                                            const _type *data,               \
+                                            unsigned int count ) {           \
+       unsigned int discard_S;                                               \
+       __asm__ __volatile__ ( "rep outs" #_insn_suffix                       \
+                              : "=S" ( discard_S )                           \
+                              : "d" ( io_addr ), "c" ( count ),              \
+                                "0" ( data ) );                              \
+}
+X86_OUTX ( b, uint8_t, "b" );
+X86_OUTX ( w, uint16_t, "w" );
+X86_OUTX ( l, uint32_t, "k" );
+
+/*
+ * Slow down I/O
+ *
+ */
+
+static inline __always_inline void
+IOAPI_INLINE ( x86, iodelay ) ( void ) {
+       __asm__ __volatile__ ( "outb %al, $0x80" );
+}
+
+/*
+ * Memory barrier
+ *
+ */
+
+static inline __always_inline void
+IOAPI_INLINE ( x86, mb ) ( void ) {
+       __asm__ __volatile__ ( "lock; addl $0, 0(%%esp)" : : : "memory" );
+}
+
+#endif /* _IPXE_X86_IO_H */