Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.20 550 lines 9.9 kB view raw
1/* 2 * Misc. bootloader code (almost) all platforms can use 3 * 4 * Author: Johnnie Peters <jpeters@mvista.com> 5 * Editor: Tom Rini <trini@mvista.com> 6 * 7 * Derived from arch/ppc/boot/prep/misc.c 8 * 9 * 2000-2001 (c) MontaVista, Software, Inc. This file is licensed under 10 * the terms of the GNU General Public License version 2. This program 11 * is licensed "as is" without any warranty of any kind, whether express 12 * or implied. 13 */ 14 15#include <stdarg.h> /* for va_ bits */ 16#include <linux/string.h> 17#include <linux/zlib.h> 18#include "nonstdio.h" 19 20/* If we're on a PReP, assume we have a keyboard controller 21 * Also note, if we're not PReP, we assume you are a serial 22 * console - Tom */ 23#if defined(CONFIG_PPC_PREP) && defined(CONFIG_VGA_CONSOLE) 24extern void cursor(int x, int y); 25extern void scroll(void); 26extern char *vidmem; 27extern int lines, cols; 28extern int orig_x, orig_y; 29extern int keyb_present; 30extern int CRT_tstc(void); 31extern int CRT_getc(void); 32#else 33int cursor(int x, int y) {return 0;} 34void scroll(void) {} 35char vidmem[1]; 36#define lines 0 37#define cols 0 38int orig_x = 0; 39int orig_y = 0; 40#define keyb_present 0 41int CRT_tstc(void) {return 0;} 42int CRT_getc(void) {return 0;} 43#endif 44 45extern char *avail_ram; 46extern char *end_avail; 47extern char _end[]; 48 49void puts(const char *); 50void putc(const char c); 51void puthex(unsigned long val); 52void gunzip(void *, int, unsigned char *, int *); 53static int _cvt(unsigned long val, char *buf, long radix, char *digits); 54 55void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap); 56unsigned char *ISA_io = NULL; 57 58#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ 59 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ 60 || defined(CONFIG_SERIAL_MPSC_CONSOLE) 61extern unsigned long com_port; 62 63extern int serial_tstc(unsigned long com_port); 64extern unsigned char serial_getc(unsigned long com_port); 65extern void serial_putc(unsigned long com_port, unsigned char c); 66#endif 67 68void pause(void) 69{ 70 puts("pause\n"); 71} 72 73void exit(void) 74{ 75 puts("exit\n"); 76 while(1); 77} 78 79int tstc(void) 80{ 81#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ 82 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ 83 || defined(CONFIG_SERIAL_MPSC_CONSOLE) 84 if(keyb_present) 85 return (CRT_tstc() || serial_tstc(com_port)); 86 else 87 return (serial_tstc(com_port)); 88#else 89 return CRT_tstc(); 90#endif 91} 92 93int getc(void) 94{ 95 while (1) { 96#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ 97 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ 98 || defined(CONFIG_SERIAL_MPSC_CONSOLE) 99 if (serial_tstc(com_port)) 100 return (serial_getc(com_port)); 101#endif /* serial console */ 102 if (keyb_present) 103 if(CRT_tstc()) 104 return (CRT_getc()); 105 } 106} 107 108void 109putc(const char c) 110{ 111 int x,y; 112 113#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ 114 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ 115 || defined(CONFIG_SERIAL_MPSC_CONSOLE) 116 serial_putc(com_port, c); 117 if ( c == '\n' ) 118 serial_putc(com_port, '\r'); 119#endif /* serial console */ 120 121 x = orig_x; 122 y = orig_y; 123 124 if ( c == '\n' ) { 125 x = 0; 126 if ( ++y >= lines ) { 127 scroll(); 128 y--; 129 } 130 } else if (c == '\r') { 131 x = 0; 132 } else if (c == '\b') { 133 if (x > 0) { 134 x--; 135 } 136 } else { 137 vidmem [ ( x + cols * y ) * 2 ] = c; 138 if ( ++x >= cols ) { 139 x = 0; 140 if ( ++y >= lines ) { 141 scroll(); 142 y--; 143 } 144 } 145 } 146 147 cursor(x, y); 148 149 orig_x = x; 150 orig_y = y; 151} 152 153void puts(const char *s) 154{ 155 int x,y; 156 char c; 157 158 x = orig_x; 159 y = orig_y; 160 161 while ( ( c = *s++ ) != '\0' ) { 162#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \ 163 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \ 164 || defined(CONFIG_SERIAL_MPSC_CONSOLE) 165 serial_putc(com_port, c); 166 if ( c == '\n' ) serial_putc(com_port, '\r'); 167#endif /* serial console */ 168 169 if ( c == '\n' ) { 170 x = 0; 171 if ( ++y >= lines ) { 172 scroll(); 173 y--; 174 } 175 } else if (c == '\b') { 176 if (x > 0) { 177 x--; 178 } 179 } else { 180 vidmem [ ( x + cols * y ) * 2 ] = c; 181 if ( ++x >= cols ) { 182 x = 0; 183 if ( ++y >= lines ) { 184 scroll(); 185 y--; 186 } 187 } 188 } 189 } 190 191 cursor(x, y); 192 193 orig_x = x; 194 orig_y = y; 195} 196 197void error(char *x) 198{ 199 puts("\n\n"); 200 puts(x); 201 puts("\n\n -- System halted"); 202 203 while(1); /* Halt */ 204} 205 206static void *zalloc(unsigned size) 207{ 208 void *p = avail_ram; 209 210 size = (size + 7) & -8; 211 avail_ram += size; 212 if (avail_ram > end_avail) { 213 puts("oops... out of memory\n"); 214 pause(); 215 } 216 return p; 217} 218 219#define HEAD_CRC 2 220#define EXTRA_FIELD 4 221#define ORIG_NAME 8 222#define COMMENT 0x10 223#define RESERVED 0xe0 224 225void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) 226{ 227 z_stream s; 228 int r, i, flags; 229 230 /* skip header */ 231 i = 10; 232 flags = src[3]; 233 if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { 234 puts("bad gzipped data\n"); 235 exit(); 236 } 237 if ((flags & EXTRA_FIELD) != 0) 238 i = 12 + src[10] + (src[11] << 8); 239 if ((flags & ORIG_NAME) != 0) 240 while (src[i++] != 0) 241 ; 242 if ((flags & COMMENT) != 0) 243 while (src[i++] != 0) 244 ; 245 if ((flags & HEAD_CRC) != 0) 246 i += 2; 247 if (i >= *lenp) { 248 puts("gunzip: ran out of data in header\n"); 249 exit(); 250 } 251 252 /* Initialize ourself. */ 253 s.workspace = zalloc(zlib_inflate_workspacesize()); 254 r = zlib_inflateInit2(&s, -MAX_WBITS); 255 if (r != Z_OK) { 256 puts("zlib_inflateInit2 returned "); puthex(r); puts("\n"); 257 exit(); 258 } 259 s.next_in = src + i; 260 s.avail_in = *lenp - i; 261 s.next_out = dst; 262 s.avail_out = dstlen; 263 r = zlib_inflate(&s, Z_FINISH); 264 if (r != Z_OK && r != Z_STREAM_END) { 265 puts("inflate returned "); puthex(r); puts("\n"); 266 exit(); 267 } 268 *lenp = s.next_out - (unsigned char *) dst; 269 zlib_inflateEnd(&s); 270} 271 272void 273puthex(unsigned long val) 274{ 275 276 unsigned char buf[10]; 277 int i; 278 for (i = 7; i >= 0; i--) 279 { 280 buf[i] = "0123456789ABCDEF"[val & 0x0F]; 281 val >>= 4; 282 } 283 buf[8] = '\0'; 284 puts(buf); 285} 286 287#define FALSE 0 288#define TRUE 1 289 290void 291_printk(char const *fmt, ...) 292{ 293 va_list ap; 294 295 va_start(ap, fmt); 296 _vprintk(putc, fmt, ap); 297 va_end(ap); 298 return; 299} 300 301#define is_digit(c) ((c >= '0') && (c <= '9')) 302 303void 304_vprintk(void(*putc)(const char), const char *fmt0, va_list ap) 305{ 306 char c, sign, *cp = 0; 307 int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right; 308 char buf[32]; 309 long val; 310 while ((c = *fmt0++)) 311 { 312 if (c == '%') 313 { 314 c = *fmt0++; 315 left_prec = right_prec = pad_on_right = 0; 316 if (c == '-') 317 { 318 c = *fmt0++; 319 pad_on_right++; 320 } 321 if (c == '0') 322 { 323 zero_fill = TRUE; 324 c = *fmt0++; 325 } else 326 { 327 zero_fill = FALSE; 328 } 329 while (is_digit(c)) 330 { 331 left_prec = (left_prec * 10) + (c - '0'); 332 c = *fmt0++; 333 } 334 if (c == '.') 335 { 336 c = *fmt0++; 337 zero_fill++; 338 while (is_digit(c)) 339 { 340 right_prec = (right_prec * 10) + (c - '0'); 341 c = *fmt0++; 342 } 343 } else 344 { 345 right_prec = left_prec; 346 } 347 sign = '\0'; 348 switch (c) 349 { 350 case 'd': 351 case 'x': 352 case 'X': 353 val = va_arg(ap, long); 354 switch (c) 355 { 356 case 'd': 357 if (val < 0) 358 { 359 sign = '-'; 360 val = -val; 361 } 362 length = _cvt(val, buf, 10, "0123456789"); 363 break; 364 case 'x': 365 length = _cvt(val, buf, 16, "0123456789abcdef"); 366 break; 367 case 'X': 368 length = _cvt(val, buf, 16, "0123456789ABCDEF"); 369 break; 370 } 371 cp = buf; 372 break; 373 case 's': 374 cp = va_arg(ap, char *); 375 length = strlen(cp); 376 break; 377 case 'c': 378 c = va_arg(ap, long /*char*/); 379 (*putc)(c); 380 continue; 381 default: 382 (*putc)('?'); 383 } 384 pad = left_prec - length; 385 if (sign != '\0') 386 { 387 pad--; 388 } 389 if (zero_fill) 390 { 391 c = '0'; 392 if (sign != '\0') 393 { 394 (*putc)(sign); 395 sign = '\0'; 396 } 397 } else 398 { 399 c = ' '; 400 } 401 if (!pad_on_right) 402 { 403 while (pad-- > 0) 404 { 405 (*putc)(c); 406 } 407 } 408 if (sign != '\0') 409 { 410 (*putc)(sign); 411 } 412 while (length-- > 0) 413 { 414 (*putc)(c = *cp++); 415 if (c == '\n') 416 { 417 (*putc)('\r'); 418 } 419 } 420 if (pad_on_right) 421 { 422 while (pad-- > 0) 423 { 424 (*putc)(c); 425 } 426 } 427 } else 428 { 429 (*putc)(c); 430 if (c == '\n') 431 { 432 (*putc)('\r'); 433 } 434 } 435 } 436} 437 438int 439_cvt(unsigned long val, char *buf, long radix, char *digits) 440{ 441 char temp[80]; 442 char *cp = temp; 443 int length = 0; 444 if (val == 0) 445 { /* Special case */ 446 *cp++ = '0'; 447 } else 448 while (val) 449 { 450 *cp++ = digits[val % radix]; 451 val /= radix; 452 } 453 while (cp != temp) 454 { 455 *buf++ = *--cp; 456 length++; 457 } 458 *buf = '\0'; 459 return (length); 460} 461 462void 463_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base) 464{ 465 int i, c; 466 if ((unsigned int)s > (unsigned int)p) 467 { 468 s = (unsigned int)s - (unsigned int)p; 469 } 470 while (s > 0) 471 { 472 if (base) 473 { 474 _printk("%06X: ", (int)p - (int)base); 475 } else 476 { 477 _printk("%06X: ", p); 478 } 479 for (i = 0; i < 16; i++) 480 { 481 if (i < s) 482 { 483 _printk("%02X", p[i] & 0xFF); 484 } else 485 { 486 _printk(" "); 487 } 488 if ((i % 2) == 1) _printk(" "); 489 if ((i % 8) == 7) _printk(" "); 490 } 491 _printk(" |"); 492 for (i = 0; i < 16; i++) 493 { 494 if (i < s) 495 { 496 c = p[i] & 0xFF; 497 if ((c < 0x20) || (c >= 0x7F)) c = '.'; 498 } else 499 { 500 c = ' '; 501 } 502 _printk("%c", c); 503 } 504 _printk("|\n"); 505 s -= 16; 506 p += 16; 507 } 508} 509 510void 511_dump_buf(unsigned char *p, int s) 512{ 513 _printk("\n"); 514 _dump_buf_with_offset(p, s, 0); 515} 516 517/* Very simple inb/outb routines. We declare ISA_io to be 0 above, and 518 * then modify it on platforms which need to. We do it like this 519 * because on some platforms we give inb/outb an exact location, and 520 * on others it's an offset from a given location. -- Tom 521 */ 522 523void ISA_init(unsigned long base) 524{ 525 ISA_io = (unsigned char *)base; 526} 527 528void 529outb(int port, unsigned char val) 530{ 531 /* Ensure I/O operations complete */ 532 __asm__ volatile("eieio"); 533 ISA_io[port] = val; 534} 535 536unsigned char 537inb(int port) 538{ 539 /* Ensure I/O operations complete */ 540 __asm__ volatile("eieio"); 541 return (ISA_io[port]); 542} 543 544/* 545 * Local variables: 546 * c-indent-level: 8 547 * c-basic-offset: 8 548 * tab-width: 8 549 * End: 550 */