2007-07-11 23:18:39 +04:00
/* -*- linux-c -*- ------------------------------------------------------- *
*
* Copyright ( C ) 1991 , 1992 Linus Torvalds
* Copyright 2007 rPath , Inc . - All Rights Reserved
2009-04-02 05:08:28 +04:00
* Copyright 2009 Intel Corporation ; author H . Peter Anvin
2007-07-11 23:18:39 +04:00
*
* This file is part of the Linux kernel , and is made available under
* the terms of the GNU General Public License version 2.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* Header file for the real - mode kernel code
*/
# ifndef BOOT_BOOT_H
# define BOOT_BOOT_H
2017-04-19 18:20:15 +03:00
# define STACK_SIZE 1024 /* Minimum number of bytes for stack */
2007-10-26 03:11:33 +04:00
2007-07-11 23:18:39 +04:00
# ifndef __ASSEMBLY__
# include <stdarg.h>
# include <linux/types.h>
# include <linux/edd.h>
2007-10-24 00:37:25 +04:00
# include <asm/setup.h>
2016-06-08 22:38:45 +03:00
# include <asm/asm.h>
2008-08-14 00:14:22 +04:00
# include "bitops.h"
2010-08-03 08:03:46 +04:00
# include "ctype.h"
2013-10-11 04:18:13 +04:00
# include "cpuflags.h"
2008-08-13 12:07:05 +04:00
2007-07-11 23:18:39 +04:00
/* Useful macros */
# define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
2008-08-18 11:06:01 +04:00
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
2007-07-11 23:18:39 +04:00
extern struct setup_header hdr ;
extern struct boot_params boot_params ;
2010-07-11 12:06:57 +04:00
# define cpu_relax() asm volatile("rep; nop")
2007-07-11 23:18:39 +04:00
/* Basic port I/O */
static inline void outb ( u8 v , u16 port )
{
asm volatile ( " outb %0,%1 " : : " a " ( v ) , " dN " ( port ) ) ;
}
static inline u8 inb ( u16 port )
{
u8 v ;
asm volatile ( " inb %1,%0 " : " =a " ( v ) : " dN " ( port ) ) ;
return v ;
}
static inline void outw ( u16 v , u16 port )
{
asm volatile ( " outw %0,%1 " : : " a " ( v ) , " dN " ( port ) ) ;
}
static inline u16 inw ( u16 port )
{
u16 v ;
asm volatile ( " inw %1,%0 " : " =a " ( v ) : " dN " ( port ) ) ;
return v ;
}
static inline void outl ( u32 v , u16 port )
{
2007-07-15 03:47:13 +04:00
asm volatile ( " outl %0,%1 " : : " a " ( v ) , " dN " ( port ) ) ;
2007-07-11 23:18:39 +04:00
}
2012-01-31 20:48:28 +04:00
static inline u32 inl ( u16 port )
2007-07-11 23:18:39 +04:00
{
u32 v ;
asm volatile ( " inl %1,%0 " : " =a " ( v ) : " dN " ( port ) ) ;
return v ;
}
static inline void io_delay ( void )
{
const u16 DELAY_PORT = 0x80 ;
asm volatile ( " outb %%al,%0 " : : " dN " ( DELAY_PORT ) ) ;
}
/* These functions are used to reference data in other segments. */
static inline u16 ds ( void )
{
u16 seg ;
asm ( " movw %%ds,%0 " : " =rm " ( seg ) ) ;
return seg ;
}
static inline void set_fs ( u16 seg )
{
asm volatile ( " movw %0,%%fs " : : " rm " ( seg ) ) ;
}
static inline u16 fs ( void )
{
u16 seg ;
2007-08-23 03:28:01 +04:00
asm volatile ( " movw %%fs,%0 " : " =rm " ( seg ) ) ;
2007-07-11 23:18:39 +04:00
return seg ;
}
static inline void set_gs ( u16 seg )
{
asm volatile ( " movw %0,%%gs " : : " rm " ( seg ) ) ;
}
static inline u16 gs ( void )
{
u16 seg ;
2007-08-23 03:28:01 +04:00
asm volatile ( " movw %%gs,%0 " : " =rm " ( seg ) ) ;
2007-07-11 23:18:39 +04:00
return seg ;
}
typedef unsigned int addr_t ;
static inline u8 rdfs8 ( addr_t addr )
{
u8 v ;
2008-01-30 15:33:02 +03:00
asm volatile ( " movb %%fs:%1,%0 " : " =q " ( v ) : " m " ( * ( u8 * ) addr ) ) ;
2007-07-11 23:18:39 +04:00
return v ;
}
static inline u16 rdfs16 ( addr_t addr )
{
u16 v ;
2007-08-23 03:28:01 +04:00
asm volatile ( " movw %%fs:%1,%0 " : " =r " ( v ) : " m " ( * ( u16 * ) addr ) ) ;
2007-07-11 23:18:39 +04:00
return v ;
}
static inline u32 rdfs32 ( addr_t addr )
{
u32 v ;
2007-08-23 03:28:01 +04:00
asm volatile ( " movl %%fs:%1,%0 " : " =r " ( v ) : " m " ( * ( u32 * ) addr ) ) ;
2007-07-11 23:18:39 +04:00
return v ;
}
static inline void wrfs8 ( u8 v , addr_t addr )
{
2008-01-30 15:33:02 +03:00
asm volatile ( " movb %1,%%fs:%0 " : " +m " ( * ( u8 * ) addr ) : " qi " ( v ) ) ;
2007-07-11 23:18:39 +04:00
}
static inline void wrfs16 ( u16 v , addr_t addr )
{
2008-01-30 15:33:02 +03:00
asm volatile ( " movw %1,%%fs:%0 " : " +m " ( * ( u16 * ) addr ) : " ri " ( v ) ) ;
2007-07-11 23:18:39 +04:00
}
static inline void wrfs32 ( u32 v , addr_t addr )
{
2008-01-30 15:33:02 +03:00
asm volatile ( " movl %1,%%fs:%0 " : " +m " ( * ( u32 * ) addr ) : " ri " ( v ) ) ;
2007-07-11 23:18:39 +04:00
}
static inline u8 rdgs8 ( addr_t addr )
{
u8 v ;
2008-01-30 15:33:02 +03:00
asm volatile ( " movb %%gs:%1,%0 " : " =q " ( v ) : " m " ( * ( u8 * ) addr ) ) ;
2007-07-11 23:18:39 +04:00
return v ;
}
static inline u16 rdgs16 ( addr_t addr )
{
u16 v ;
2007-08-23 03:28:01 +04:00
asm volatile ( " movw %%gs:%1,%0 " : " =r " ( v ) : " m " ( * ( u16 * ) addr ) ) ;
2007-07-11 23:18:39 +04:00
return v ;
}
static inline u32 rdgs32 ( addr_t addr )
{
u32 v ;
2007-08-23 03:28:01 +04:00
asm volatile ( " movl %%gs:%1,%0 " : " =r " ( v ) : " m " ( * ( u32 * ) addr ) ) ;
2007-07-11 23:18:39 +04:00
return v ;
}
static inline void wrgs8 ( u8 v , addr_t addr )
{
2008-01-30 15:33:02 +03:00
asm volatile ( " movb %1,%%gs:%0 " : " +m " ( * ( u8 * ) addr ) : " qi " ( v ) ) ;
2007-07-11 23:18:39 +04:00
}
static inline void wrgs16 ( u16 v , addr_t addr )
{
2008-01-30 15:33:02 +03:00
asm volatile ( " movw %1,%%gs:%0 " : " +m " ( * ( u16 * ) addr ) : " ri " ( v ) ) ;
2007-07-11 23:18:39 +04:00
}
static inline void wrgs32 ( u32 v , addr_t addr )
{
2008-01-30 15:33:02 +03:00
asm volatile ( " movl %1,%%gs:%0 " : " +m " ( * ( u32 * ) addr ) : " ri " ( v ) ) ;
2007-07-11 23:18:39 +04:00
}
/* Note: these only return true/false, not a signed return value! */
2016-06-08 22:38:38 +03:00
static inline bool memcmp_fs ( const void * s1 , addr_t s2 , size_t len )
2007-07-11 23:18:39 +04:00
{
2016-06-08 22:38:38 +03:00
bool diff ;
2016-06-08 22:38:45 +03:00
asm volatile ( " fs; repe; cmpsb " CC_SET ( nz )
: CC_OUT ( nz ) ( diff ) , " +D " ( s1 ) , " +S " ( s2 ) , " +c " ( len ) ) ;
2007-07-11 23:18:39 +04:00
return diff ;
}
2016-06-08 22:38:38 +03:00
static inline bool memcmp_gs ( const void * s1 , addr_t s2 , size_t len )
2007-07-11 23:18:39 +04:00
{
2016-06-08 22:38:38 +03:00
bool diff ;
2016-06-08 22:38:45 +03:00
asm volatile ( " gs; repe; cmpsb " CC_SET ( nz )
: CC_OUT ( nz ) ( diff ) , " +D " ( s1 ) , " +S " ( s2 ) , " +c " ( len ) ) ;
2007-07-11 23:18:39 +04:00
return diff ;
}
/* Heap -- available for dynamic lists. */
extern char _end [ ] ;
extern char * HEAP ;
extern char * heap_end ;
# define RESET_HEAP() ((void *)( HEAP = _end ))
static inline char * __get_heap ( size_t s , size_t a , size_t n )
{
char * tmp ;
HEAP = ( char * ) ( ( ( size_t ) HEAP + ( a - 1 ) ) & ~ ( a - 1 ) ) ;
tmp = HEAP ;
HEAP + = s * n ;
return tmp ;
}
# define GET_HEAP(type, n) \
( ( type * ) __get_heap ( sizeof ( type ) , __alignof__ ( type ) , ( n ) ) )
2007-10-26 03:09:38 +04:00
static inline bool heap_free ( size_t n )
2007-07-11 23:18:39 +04:00
{
2007-10-26 03:09:38 +04:00
return ( int ) ( heap_end - HEAP ) > = ( int ) n ;
2007-07-11 23:18:39 +04:00
}
/* copy.S */
void copy_to_fs ( addr_t dst , void * src , size_t len ) ;
void * copy_from_fs ( void * dst , addr_t src , size_t len ) ;
void copy_to_gs ( addr_t dst , void * src , size_t len ) ;
void * copy_from_gs ( void * dst , addr_t src , size_t len ) ;
/* a20.c */
int enable_a20 ( void ) ;
/* apm.c */
int query_apm_bios ( void ) ;
2009-04-02 05:08:28 +04:00
/* bioscall.c */
struct biosregs {
union {
struct {
u32 edi ;
u32 esi ;
u32 ebp ;
u32 _esp ;
u32 ebx ;
u32 edx ;
u32 ecx ;
u32 eax ;
u32 _fsgs ;
u32 _dses ;
u32 eflags ;
} ;
struct {
u16 di , hdi ;
u16 si , hsi ;
u16 bp , hbp ;
u16 _sp , _hsp ;
u16 bx , hbx ;
u16 dx , hdx ;
u16 cx , hcx ;
u16 ax , hax ;
u16 gs , fs ;
u16 es , ds ;
u16 flags , hflags ;
} ;
struct {
u8 dil , dih , edi2 , edi3 ;
u8 sil , sih , esi2 , esi3 ;
u8 bpl , bph , ebp2 , ebp3 ;
u8 _spl , _sph , _esp2 , _esp3 ;
u8 bl , bh , ebx2 , ebx3 ;
u8 dl , dh , edx2 , edx3 ;
u8 cl , ch , ecx2 , ecx3 ;
u8 al , ah , eax2 , eax3 ;
} ;
} ;
} ;
void intcall ( u8 int_no , const struct biosregs * ireg , struct biosregs * oreg ) ;
2007-07-11 23:18:39 +04:00
/* cmdline.c */
2013-01-25 00:19:59 +04:00
int __cmdline_find_option ( unsigned long cmdline_ptr , const char * option , char * buffer , int bufsize ) ;
int __cmdline_find_option_bool ( unsigned long cmdline_ptr , const char * option ) ;
2010-08-02 13:17:31 +04:00
static inline int cmdline_find_option ( const char * option , char * buffer , int bufsize )
{
2013-01-25 00:19:59 +04:00
unsigned long cmd_line_ptr = boot_params . hdr . cmd_line_ptr ;
2013-01-25 00:19:58 +04:00
if ( cmd_line_ptr > = 0x100000 )
return - 1 ; /* inaccessible */
return __cmdline_find_option ( cmd_line_ptr , option , buffer , bufsize ) ;
2010-08-02 13:17:31 +04:00
}
static inline int cmdline_find_option_bool ( const char * option )
{
2013-01-25 00:19:59 +04:00
unsigned long cmd_line_ptr = boot_params . hdr . cmd_line_ptr ;
2013-01-25 00:19:58 +04:00
if ( cmd_line_ptr > = 0x100000 )
return - 1 ; /* inaccessible */
return __cmdline_find_option_bool ( cmd_line_ptr , option ) ;
2010-08-02 13:17:31 +04:00
}
2007-07-11 23:18:39 +04:00
/* cpu.c, cpucheck.c */
int check_cpu ( int * cpu_level_ptr , int * req_level_ptr , u32 * * err_flags_ptr ) ;
2016-07-08 03:19:14 +03:00
int check_knl_erratum ( void ) ;
2007-07-11 23:18:39 +04:00
int validate_cpu ( void ) ;
2010-08-02 13:17:31 +04:00
/* early_serial_console.c */
extern int early_serial_base ;
void console_init ( void ) ;
2007-07-11 23:18:39 +04:00
/* edd.c */
void query_edd ( void ) ;
/* header.S */
void __attribute__ ( ( noreturn ) ) die ( void ) ;
/* memory.c */
int detect_memory ( void ) ;
/* pm.c */
void __attribute__ ( ( noreturn ) ) go_to_protected_mode ( void ) ;
/* pmjump.S */
void __attribute__ ( ( noreturn ) )
protected_mode_jump ( u32 entrypoint , u32 bootparams ) ;
/* printf.c */
int sprintf ( char * buf , const char * fmt , . . . ) ;
int vsprintf ( char * buf , const char * fmt , va_list args ) ;
int printf ( const char * fmt , . . . ) ;
2009-04-02 05:08:28 +04:00
/* regs.c */
void initregs ( struct biosregs * regs ) ;
2007-07-11 23:18:39 +04:00
/* string.c */
int strcmp ( const char * str1 , const char * str2 ) ;
2010-07-11 12:06:57 +04:00
int strncmp ( const char * cs , const char * ct , size_t count ) ;
2007-07-11 23:18:39 +04:00
size_t strnlen ( const char * s , size_t maxlen ) ;
unsigned int atou ( const char * s ) ;
2010-07-11 12:06:57 +04:00
unsigned long long simple_strtoull ( const char * cp , char * * endp , unsigned int base ) ;
2013-08-13 22:13:00 +04:00
size_t strlen ( const char * s ) ;
2017-01-12 02:20:01 +03:00
char * strchr ( const char * s , int c ) ;
2007-07-11 23:18:39 +04:00
/* tty.c */
void puts ( const char * ) ;
void putchar ( int ) ;
int getchar ( void ) ;
void kbd_flush ( void ) ;
int getchar_timeout ( void ) ;
/* video.c */
void set_video ( void ) ;
2008-04-11 01:28:10 +04:00
/* video-mode.c */
int set_mode ( u16 mode ) ;
int mode_defined ( u16 mode ) ;
void probe_cards ( int unsafe ) ;
2007-07-11 23:18:39 +04:00
/* video-vesa.c */
void vesa_store_edid ( void ) ;
# endif /* __ASSEMBLY__ */
# endif /* BOOT_BOOT_H */