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