1 /* -*- linux-c -*- ------------------------------------------------------- * 2 * 3 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright 2007 rPath, Inc. - All Rights Reserved 5 * 6 * This file is part of the Linux kernel, and is made available under 7 * the terms of the GNU General Public License version 2. 8 * 9 * ----------------------------------------------------------------------- */ 10 11 /* 12 * arch/i386/boot/boot.h 13 * 14 * Header file for the real-mode kernel code 15 */ 16 17 #ifndef BOOT_BOOT_H 18 #define BOOT_BOOT_H 19 20 #define STACK_SIZE 512 /* Minimum number of bytes for stack */ 21 22 #ifndef __ASSEMBLY__ 23 24 #include <stdarg.h> 25 #include <linux/types.h> 26 #include <linux/edd.h> 27 #include <asm/boot.h> 28 #include <asm/setup.h> 29 30 /* Useful macros */ 31 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) 32 33 extern struct setup_header hdr; 34 extern struct boot_params boot_params; 35 36 /* Basic port I/O */ 37 static inline void outb(u8 v, u16 port) 38 { 39 asm volatile("outb %0,%1" : : "a" (v), "dN" (port)); 40 } 41 static inline u8 inb(u16 port) 42 { 43 u8 v; 44 asm volatile("inb %1,%0" : "=a" (v) : "dN" (port)); 45 return v; 46 } 47 48 static inline void outw(u16 v, u16 port) 49 { 50 asm volatile("outw %0,%1" : : "a" (v), "dN" (port)); 51 } 52 static inline u16 inw(u16 port) 53 { 54 u16 v; 55 asm volatile("inw %1,%0" : "=a" (v) : "dN" (port)); 56 return v; 57 } 58 59 static inline void outl(u32 v, u16 port) 60 { 61 asm volatile("outl %0,%1" : : "a" (v), "dN" (port)); 62 } 63 static inline u32 inl(u32 port) 64 { 65 u32 v; 66 asm volatile("inl %1,%0" : "=a" (v) : "dN" (port)); 67 return v; 68 } 69 70 static inline void io_delay(void) 71 { 72 const u16 DELAY_PORT = 0x80; 73 asm volatile("outb %%al,%0" : : "dN" (DELAY_PORT)); 74 } 75 76 /* These functions are used to reference data in other segments. */ 77 78 static inline u16 ds(void) 79 { 80 u16 seg; 81 asm("movw %%ds,%0" : "=rm" (seg)); 82 return seg; 83 } 84 85 static inline void set_fs(u16 seg) 86 { 87 asm volatile("movw %0,%%fs" : : "rm" (seg)); 88 } 89 static inline u16 fs(void) 90 { 91 u16 seg; 92 asm volatile("movw %%fs,%0" : "=rm" (seg)); 93 return seg; 94 } 95 96 static inline void set_gs(u16 seg) 97 { 98 asm volatile("movw %0,%%gs" : : "rm" (seg)); 99 } 100 static inline u16 gs(void) 101 { 102 u16 seg; 103 asm volatile("movw %%gs,%0" : "=rm" (seg)); 104 return seg; 105 } 106 107 typedef unsigned int addr_t; 108 109 static inline u8 rdfs8(addr_t addr) 110 { 111 u8 v; 112 asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr)); 113 return v; 114 } 115 static inline u16 rdfs16(addr_t addr) 116 { 117 u16 v; 118 asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr)); 119 return v; 120 } 121 static inline u32 rdfs32(addr_t addr) 122 { 123 u32 v; 124 asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr)); 125 return v; 126 } 127 128 static inline void wrfs8(u8 v, addr_t addr) 129 { 130 asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "qi" (v)); 131 } 132 static inline void wrfs16(u16 v, addr_t addr) 133 { 134 asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "ri" (v)); 135 } 136 static inline void wrfs32(u32 v, addr_t addr) 137 { 138 asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "ri" (v)); 139 } 140 141 static inline u8 rdgs8(addr_t addr) 142 { 143 u8 v; 144 asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr)); 145 return v; 146 } 147 static inline u16 rdgs16(addr_t addr) 148 { 149 u16 v; 150 asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr)); 151 return v; 152 } 153 static inline u32 rdgs32(addr_t addr) 154 { 155 u32 v; 156 asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr)); 157 return v; 158 } 159 160 static inline void wrgs8(u8 v, addr_t addr) 161 { 162 asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "qi" (v)); 163 } 164 static inline void wrgs16(u16 v, addr_t addr) 165 { 166 asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "ri" (v)); 167 } 168 static inline void wrgs32(u32 v, addr_t addr) 169 { 170 asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "ri" (v)); 171 } 172 173 /* Note: these only return true/false, not a signed return value! */ 174 static inline int memcmp(const void *s1, const void *s2, size_t len) 175 { 176 u8 diff; 177 asm("repe; cmpsb; setnz %0" 178 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); 179 return diff; 180 } 181 182 static inline int memcmp_fs(const void *s1, addr_t s2, size_t len) 183 { 184 u8 diff; 185 asm volatile("fs; repe; cmpsb; setnz %0" 186 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); 187 return diff; 188 } 189 static inline int memcmp_gs(const void *s1, addr_t s2, size_t len) 190 { 191 u8 diff; 192 asm volatile("gs; repe; cmpsb; setnz %0" 193 : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); 194 return diff; 195 } 196 197 static inline int isdigit(int ch) 198 { 199 return (ch >= '0') && (ch <= '9'); 200 } 201 202 /* Heap -- available for dynamic lists. */ 203 extern char _end[]; 204 extern char *HEAP; 205 extern char *heap_end; 206 #define RESET_HEAP() ((void *)( HEAP = _end )) 207 static inline char *__get_heap(size_t s, size_t a, size_t n) 208 { 209 char *tmp; 210 211 HEAP = (char *)(((size_t)HEAP+(a-1)) & ~(a-1)); 212 tmp = HEAP; 213 HEAP += s*n; 214 return tmp; 215 } 216 #define GET_HEAP(type, n) \ 217 ((type *)__get_heap(sizeof(type),__alignof__(type),(n))) 218 219 static inline bool heap_free(size_t n) 220 { 221 return (int)(heap_end-HEAP) >= (int)n; 222 } 223 224 /* copy.S */ 225 226 void copy_to_fs(addr_t dst, void *src, size_t len); 227 void *copy_from_fs(void *dst, addr_t src, size_t len); 228 void copy_to_gs(addr_t dst, void *src, size_t len); 229 void *copy_from_gs(void *dst, addr_t src, size_t len); 230 void *memcpy(void *dst, void *src, size_t len); 231 void *memset(void *dst, int c, size_t len); 232 233 #define memcpy(d,s,l) __builtin_memcpy(d,s,l) 234 #define memset(d,c,l) __builtin_memset(d,c,l) 235 236 /* a20.c */ 237 int enable_a20(void); 238 239 /* apm.c */ 240 int query_apm_bios(void); 241 242 /* cmdline.c */ 243 int cmdline_find_option(const char *option, char *buffer, int bufsize); 244 int cmdline_find_option_bool(const char *option); 245 246 /* cpu.c, cpucheck.c */ 247 int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr); 248 int validate_cpu(void); 249 250 /* edd.c */ 251 void query_edd(void); 252 253 /* header.S */ 254 void __attribute__((noreturn)) die(void); 255 256 /* mca.c */ 257 int query_mca(void); 258 259 /* memory.c */ 260 int detect_memory(void); 261 262 /* pm.c */ 263 void __attribute__((noreturn)) go_to_protected_mode(void); 264 265 /* pmjump.S */ 266 void __attribute__((noreturn)) 267 protected_mode_jump(u32 entrypoint, u32 bootparams); 268 269 /* printf.c */ 270 int sprintf(char *buf, const char *fmt, ...); 271 int vsprintf(char *buf, const char *fmt, va_list args); 272 int printf(const char *fmt, ...); 273 274 /* string.c */ 275 int strcmp(const char *str1, const char *str2); 276 size_t strnlen(const char *s, size_t maxlen); 277 unsigned int atou(const char *s); 278 279 /* tty.c */ 280 void puts(const char *); 281 void putchar(int); 282 int getchar(void); 283 void kbd_flush(void); 284 int getchar_timeout(void); 285 286 /* video.c */ 287 void set_video(void); 288 289 /* video-vesa.c */ 290 void vesa_store_edid(void); 291 292 /* voyager.c */ 293 int query_voyager(void); 294 295 #endif /* __ASSEMBLY__ */ 296 297 #endif /* BOOT_BOOT_H */ 298