2008-10-22 22:26:29 -07:00
# ifndef _ASM_X86_IO_64_H
# define _ASM_X86_IO_64_H
2005-04-16 15:20:36 -07:00
/*
* 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 >
*/
2008-01-30 13:30:05 +01:00
extern void native_io_delay ( void ) ;
2005-04-16 15:20:36 -07:00
2008-01-30 13:30:05 +01:00
extern int io_delay_type ;
extern void io_delay_init ( void ) ;
2008-01-30 13:31:10 +01:00
# if defined(CONFIG_PARAVIRT)
# include <asm/paravirt.h>
# else
2008-01-30 13:30:05 +01:00
static inline void slow_down_io ( void )
{
native_io_delay ( ) ;
2005-04-16 15:20:36 -07:00
# ifdef REALLY_SLOW_IO
2008-01-30 13:30:05 +01:00
native_io_delay ( ) ;
native_io_delay ( ) ;
native_io_delay ( ) ;
2005-04-16 15:20:36 -07:00
# endif
2008-01-30 13:30:05 +01:00
}
2008-01-30 13:31:10 +01:00
# endif
2005-04-16 15:20:36 -07:00
/*
* Talk about misusing macros . .
*/
2008-03-23 01:02:23 -07:00
# define __OUT1(s, x) \
2005-09-12 18:49:24 +02:00
static inline void out # # s ( unsigned x value , unsigned short port ) {
2005-04-16 15:20:36 -07:00
2008-03-23 01:02:23 -07:00
# define __OUT2(s, s1, s2) \
asm volatile ( " out " # s " % " s1 " 0,% " s2 " 1 "
2008-01-30 13:31:10 +01:00
# ifndef REALLY_SLOW_IO
# define REALLY_SLOW_IO
# define UNSET_REALLY_SLOW_IO
# endif
2005-04-16 15:20:36 -07:00
2008-03-23 01:02:23 -07:00
# define __OUT(s, s1, x) \
__OUT1 ( s , x ) __OUT2 ( s , s1 , " w " ) : : " a " ( value ) , " Nd " ( port ) ) ; \
} \
__OUT1 ( s # # _p , x ) __OUT2 ( s , s1 , " w " ) : : " a " ( value ) , " Nd " ( port ) ) ; \
slow_down_io ( ) ; \
}
2005-04-16 15:20:36 -07:00
2008-03-23 01:02:23 -07:00
# define __IN1(s) \
static inline RETURN_TYPE in # # s ( unsigned short port ) \
{ \
RETURN_TYPE _v ;
2005-04-16 15:20:36 -07:00
2008-03-23 01:02:23 -07:00
# define __IN2(s, s1, s2) \
asm volatile ( " in " # s " % " s2 " 1,% " s1 " 0 "
2008-01-30 13:31:10 +01:00
2008-03-23 01:02:23 -07:00
# define __IN(s, s1, i...) \
__IN1 ( s ) __IN2 ( s , s1 , " w " ) : " =a " ( _v ) : " Nd " ( port ) , # # i ) ; \
return _v ; \
} \
__IN1 ( s # # _p ) __IN2 ( s , s1 , " w " ) : " =a " ( _v ) : " Nd " ( port ) , # # i ) ; \
slow_down_io ( ) ; \
return _v ; }
2005-04-16 15:20:36 -07:00
2008-01-30 13:31:10 +01:00
# ifdef UNSET_REALLY_SLOW_IO
# undef REALLY_SLOW_IO
# endif
2005-04-16 15:20:36 -07:00
2008-03-23 01:02:23 -07:00
# define __INS(s) \
static inline void ins # # s ( unsigned short port , void * addr , \
unsigned long count ) \
{ \
asm volatile ( " rep ; ins " # s \
: " =D " ( addr ) , " =c " ( count ) \
: " d " ( port ) , " 0 " ( addr ) , " 1 " ( count ) ) ; \
}
2005-04-16 15:20:36 -07:00
2008-03-23 01:02:23 -07:00
# define __OUTS(s) \
static inline void outs # # s ( unsigned short port , const void * addr , \
unsigned long count ) \
{ \
asm volatile ( " rep ; outs " # s \
: " =S " ( addr ) , " =c " ( count ) \
: " d " ( port ) , " 0 " ( addr ) , " 1 " ( count ) ) ; \
}
2005-04-16 15:20:36 -07:00
# define RETURN_TYPE unsigned char
2008-03-23 01:02:23 -07:00
__IN ( b , " " )
2005-04-16 15:20:36 -07:00
# undef RETURN_TYPE
# define RETURN_TYPE unsigned short
2008-03-23 01:02:23 -07:00
__IN ( w , " " )
2005-04-16 15:20:36 -07:00
# undef RETURN_TYPE
# define RETURN_TYPE unsigned int
2008-03-23 01:02:23 -07:00
__IN ( l , " " )
2005-04-16 15:20:36 -07:00
# undef RETURN_TYPE
2008-03-23 01:02:23 -07:00
__OUT ( b , " b " , char )
__OUT ( w , " w " , short )
__OUT ( l , , int )
2005-04-16 15:20:36 -07:00
__INS ( b )
__INS ( w )
__INS ( l )
__OUTS ( b )
__OUTS ( w )
__OUTS ( l )
# define IO_SPACE_LIMIT 0xffff
2007-02-13 13:26:23 +01:00
# if defined(__KERNEL__) && defined(__x86_64__)
2005-04-16 15:20:36 -07:00
# include <linux/vmalloc.h>
# ifndef __i386__
/*
* Change virtual addresses to physical addresses and vv .
* These are pretty trivial
*/
2008-03-23 01:02:23 -07:00
static inline unsigned long virt_to_phys ( volatile void * address )
2005-04-16 15:20:36 -07:00
{
return __pa ( address ) ;
}
2008-03-23 01:02:23 -07:00
static inline void * phys_to_virt ( unsigned long address )
2005-04-16 15:20:36 -07:00
{
return __va ( address ) ;
}
# endif
/*
* Change " struct page " to physical address .
*/
# define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
# include <asm-generic/iomap.h>
/*
* This one maps high address device memory and turns off caching for that area .
* it ' s useful if some control registers are in such an area and write combining
* or read caching is not desirable :
*/
2008-03-24 11:22:39 -07:00
extern void __iomem * ioremap_nocache ( resource_size_t offset , unsigned long size ) ;
extern void __iomem * ioremap_cache ( resource_size_t offset , unsigned long size ) ;
2008-07-23 21:27:05 -07:00
extern void __iomem * ioremap_prot ( resource_size_t offset , unsigned long size ,
unsigned long prot_val ) ;
2008-01-30 13:33:40 +01:00
/*
* The default ioremap ( ) behavior is non - cached :
*/
2008-03-24 11:22:39 -07:00
static inline void __iomem * ioremap ( resource_size_t offset , unsigned long size )
2008-01-30 13:33:40 +01:00
{
2008-01-30 13:34:09 +01:00
return ioremap_nocache ( offset , size ) ;
2008-01-30 13:33:40 +01:00
}
2005-04-16 15:20:36 -07:00
extern void iounmap ( volatile void __iomem * addr ) ;
2008-01-30 13:33:40 +01:00
serial: convert early_uart to earlycon for 8250
Beacuse SERIAL_PORT_DFNS is removed from include/asm-i386/serial.h and
include/asm-x86_64/serial.h. the serial8250_ports need to be probed late in
serial initializing stage. the console_init=>serial8250_console_init=>
register_console=>serial8250_console_setup will return -ENDEV, and console
ttyS0 can not be enabled at that time. need to wait till uart_add_one_port in
drivers/serial/serial_core.c to call register_console to get console ttyS0.
that is too late.
Make early_uart to use early_param, so uart console can be used earlier. Make
it to be bootconsole with CON_BOOT flag, so can use console handover feature.
and it will switch to corresponding normal serial console automatically.
new command line will be:
console=uart8250,io,0x3f8,9600n8
console=uart8250,mmio,0xff5e0000,115200n8
or
earlycon=uart8250,io,0x3f8,9600n8
earlycon=uart8250,mmio,0xff5e0000,115200n8
it will print in very early stage:
Early serial console at I/O port 0x3f8 (options '9600n8')
console [uart0] enabled
later for console it will print:
console handover: boot [uart0] -> real [ttyS0]
Signed-off-by: <yinghai.lu@sun.com>
Cc: Andi Kleen <ak@suse.de>
Cc: Bjorn Helgaas <bjorn.helgaas@hp.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Gerd Hoffmann <kraxel@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-15 23:37:59 -07:00
extern void __iomem * fix_ioremap ( unsigned idx , unsigned long phys ) ;
2005-04-16 15:20:36 -07:00
/*
* ISA I / O bus memory addresses are 1 : 1 with the physical address .
*/
# define isa_virt_to_bus virt_to_phys
# define isa_page_to_bus page_to_phys
# define isa_bus_to_virt phys_to_virt
/*
* However PCI ones are not necessarily 1 : 1 and therefore these interfaces
* are forbidden in portable PCI drivers .
*
* Allow them on x86 for legacy drivers , though .
*/
# define virt_to_bus virt_to_phys
# define bus_to_virt phys_to_virt
2008-03-23 01:02:23 -07:00
void __memcpy_fromio ( void * , unsigned long , unsigned ) ;
void __memcpy_toio ( unsigned long , const void * , unsigned ) ;
2005-04-16 15:20:36 -07:00
2008-03-23 01:02:23 -07:00
static inline void memcpy_fromio ( void * to , const volatile void __iomem * from ,
unsigned len )
2005-04-16 15:20:36 -07:00
{
2008-03-23 01:02:23 -07:00
__memcpy_fromio ( to , ( unsigned long ) from , len ) ;
2005-04-16 15:20:36 -07:00
}
2008-03-23 01:02:23 -07:00
static inline void memcpy_toio ( volatile void __iomem * to , const void * from ,
unsigned len )
2005-04-16 15:20:36 -07:00
{
2008-03-23 01:02:23 -07:00
__memcpy_toio ( ( unsigned long ) to , from , len ) ;
2005-04-16 15:20:36 -07:00
}
void memset_io ( volatile void __iomem * a , int b , size_t c ) ;
/*
* 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))
2008-03-23 01:02:23 -07:00
# define flush_write_buffers()
2005-04-16 15:20:36 -07:00
/*
* Convert a virtual cached pointer to an uncached pointer
*/
# define xlate_dev_kmem_ptr(p) p
# endif /* __KERNEL__ */
2008-10-22 22:26:29 -07:00
# endif /* _ASM_X86_IO_64_H */