2008-10-22 22:26:29 -07:00
# ifndef _ASM_X86_IO_32_H
# define _ASM_X86_IO_32_H
2005-04-16 15:20:36 -07:00
# include <linux/string.h>
# include <linux/compiler.h>
/*
* This file contains the definitions for the x86 IO instructions
* inb / inw / inl / outb / outw / outl and the " string versions " of the same
* ( insb / insw / insl / outsb / outsw / outsl ) . You can also use " pausing "
* versions of the single - IO instructions ( inb_p / inw_p / . . ) .
*
* This file is not meant to be obfuscating : it ' s just complicated
* to ( a ) handle it all in a way that makes gcc able to optimize it
* as well as possible and ( b ) trying to avoid writing the same thing
* over and over again with slight variations and possibly making a
* mistake somewhere .
*/
/*
* Thanks to James van Artsdalen for a better timing - fix than
* the two short jumps : using outb ' s to a nonexistent port seems
* to guarantee better timings even on fast machines .
*
* On the other hand , I ' d like to be sure of a non - existent port :
* I feel a bit unsafe about using 0x80 ( should be safe , though )
*
* Linus
*/
/*
* Bit simplified and optimized by Jan Hubicka
* Support of BIGMEM added by Gerhard Wichert , Siemens AG , July 1999.
*
* isa_memset_io , isa_memcpy_fromio , isa_memcpy_toio added ,
* isa_read [ wl ] and isa_write [ wl ] fixed
* - Arnaldo Carvalho de Melo < acme @ conectiva . com . br >
*/
# define XQUAD_PORTIO_BASE 0xfe400000
# define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */
# ifdef __KERNEL__
# include <asm-generic/iomap.h>
# include <linux/vmalloc.h>
/*
* Convert a virtual cached pointer to an uncached pointer
*/
# define xlate_dev_kmem_ptr(p) p
2007-10-17 18:04:39 +02:00
static inline void
memset_io ( volatile void __iomem * addr , unsigned char val , int count )
2005-04-16 15:20:36 -07:00
{
2007-10-17 18:04:39 +02:00
memset ( ( void __force * ) addr , val , count ) ;
2005-04-16 15:20:36 -07:00
}
2007-10-17 18:04:39 +02:00
static inline void
memcpy_fromio ( void * dst , const volatile void __iomem * src , int count )
2005-04-16 15:20:36 -07:00
{
2007-10-17 18:04:39 +02:00
__memcpy ( dst , ( const void __force * ) src , count ) ;
2005-04-16 15:20:36 -07:00
}
2007-10-17 18:04:39 +02:00
static inline void
memcpy_toio ( volatile void __iomem * dst , const void * src , int count )
2005-04-16 15:20:36 -07:00
{
2007-10-17 18:04:39 +02:00
__memcpy ( ( void __force * ) dst , src , count ) ;
2005-04-16 15:20:36 -07:00
}
/*
* ISA space is ' always mapped ' on a typical x86 system , no need to
* explicitly ioremap ( ) it . The fact that the ISA IO space is mapped
* to PAGE_OFFSET is pure coincidence - it does not mean ISA values
* are physical addresses . The following constant pointer can be
* used as the IO - area pointer ( it can be iounmapped as well , so the
* analogy with PCI is quite large ) :
*/
# define __ISA_IO_base ((char __iomem *)(PAGE_OFFSET))
/*
* Cache management
*
* This needed for two cases
* 1. Out of order aware processors
* 2. Accidentally out of order processors ( PPro errata # 51 )
*/
2008-03-23 01:02:22 -07:00
2005-04-16 15:20:36 -07:00
# if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
static inline void flush_write_buffers ( void )
{
2008-03-23 01:02:22 -07:00
asm volatile ( " lock; addl $0,0(%%esp) " : : : " memory " ) ;
2005-04-16 15:20:36 -07:00
}
# else
2007-10-16 23:29:42 -07:00
# define flush_write_buffers() do { } while (0)
2005-04-16 15:20:36 -07:00
# endif
# endif /* __KERNEL__ */
2008-01-30 13:30:05 +01:00
extern void native_io_delay ( void ) ;
2007-05-02 19:27:10 +02:00
2008-01-30 13:30:05 +01:00
extern int io_delay_type ;
extern void io_delay_init ( void ) ;
2006-12-07 02:14:07 +01:00
# if defined(CONFIG_PARAVIRT)
# include <asm/paravirt.h>
2005-04-16 15:20:36 -07:00
# else
2006-12-07 02:14:07 +01:00
2008-03-23 01:02:22 -07:00
static inline void slow_down_io ( void )
{
2007-05-02 19:27:10 +02:00
native_io_delay ( ) ;
2005-04-16 15:20:36 -07:00
# ifdef REALLY_SLOW_IO
2007-05-02 19:27:10 +02:00
native_io_delay ( ) ;
native_io_delay ( ) ;
native_io_delay ( ) ;
2005-04-16 15:20:36 -07:00
# endif
}
2006-12-07 02:14:07 +01:00
# endif
2008-03-23 01:02:22 -07:00
# define __BUILDIO(bwl, bw, type) \
static inline void out # # bwl ( unsigned type value , int port ) \
{ \
out # # bwl # # _local ( value , port ) ; \
} \
\
static inline unsigned type in # # bwl ( int port ) \
{ \
return in # # bwl # # _local ( port ) ; \
2005-04-16 15:20:36 -07:00
}
2008-03-23 01:02:22 -07:00
# define BUILDIO(bwl, bw, type) \
static inline void out # # bwl # # _local ( unsigned type value , int port ) \
{ \
asm volatile ( " out " # bwl " % " # bw " 0, %w1 " \
: : " a " ( value ) , " Nd " ( port ) ) ; \
} \
\
static inline unsigned type in # # bwl # # _local ( int port ) \
{ \
unsigned type value ; \
asm volatile ( " in " # bwl " %w1, % " # bw " 0 " \
: " =a " ( value ) : " Nd " ( port ) ) ; \
return value ; \
} \
\
static inline void out # # bwl # # _local_p ( unsigned type value , int port ) \
{ \
out # # bwl # # _local ( value , port ) ; \
slow_down_io ( ) ; \
} \
\
static inline unsigned type in # # bwl # # _local_p ( int port ) \
{ \
unsigned type value = in # # bwl # # _local ( port ) ; \
slow_down_io ( ) ; \
return value ; \
} \
\
__BUILDIO ( bwl , bw , type ) \
\
static inline void out # # bwl # # _p ( unsigned type value , int port ) \
{ \
out # # bwl ( value , port ) ; \
slow_down_io ( ) ; \
} \
\
static inline unsigned type in # # bwl # # _p ( int port ) \
{ \
unsigned type value = in # # bwl ( port ) ; \
slow_down_io ( ) ; \
return value ; \
} \
\
static inline void outs # # bwl ( int port , const void * addr , unsigned long count ) \
{ \
asm volatile ( " rep; outs " # bwl \
: " +S " ( addr ) , " +c " ( count ) : " d " ( port ) ) ; \
} \
\
static inline void ins # # bwl ( int port , void * addr , unsigned long count ) \
{ \
asm volatile ( " rep; ins " # bwl \
: " +D " ( addr ) , " +c " ( count ) : " d " ( port ) ) ; \
2005-04-16 15:20:36 -07:00
}
2008-03-23 01:02:22 -07:00
BUILDIO ( b , b , char )
BUILDIO ( w , w , short )
BUILDIO ( l , , int )
2005-04-16 15:20:36 -07:00
2008-10-22 22:26:29 -07:00
# endif /* _ASM_X86_IO_32_H */