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