linux-old/arch/ppc/boot/common/misc-common.c
<<
>>
Prefs
   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 "zlib.h"
  20#include "nonstdio.h"
  21
  22/* If we're on a ALL_PPC, assume we have a keyboard controller
  23 * Also note, if we're not ALL_PPC, we assume you are a serial
  24 * console - Tom */
  25#if defined(CONFIG_ALL_PPC) && defined(CONFIG_VGA_CONSOLE)
  26extern void cursor(int x, int y);
  27extern void scroll(void);
  28extern char *vidmem;
  29extern int lines, cols;
  30extern int orig_x, orig_y;
  31extern int keyb_present;
  32extern int CRT_tstc(void);
  33extern int CRT_getc(void);
  34#else
  35int cursor(int x, int y) {return 0;}
  36void scroll(void) {}
  37char vidmem[1];
  38#define lines 0
  39#define cols 0
  40int orig_x = 0;
  41int orig_y = 0;
  42#define keyb_present 0
  43int CRT_tstc(void) {return 0;}
  44int CRT_getc(void) {return 0;}
  45#endif
  46
  47extern char *avail_ram;
  48extern char *end_avail;
  49extern char _end[];
  50
  51void puts(const char *);
  52void putc(const char c);
  53void puthex(unsigned long val);
  54void _bcopy(char *src, char *dst, int len);
  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_CONSOLE)
  62extern unsigned long com_port;
  63
  64extern int serial_tstc(unsigned long com_port);
  65extern unsigned char serial_getc(unsigned long com_port);
  66extern void serial_putc(unsigned long com_port, unsigned char c);
  67#endif
  68
  69void pause(void)
  70{
  71        puts("pause\n");
  72}
  73
  74void exit(void)
  75{
  76        puts("exit\n");
  77        while(1);
  78}
  79
  80int tstc(void)
  81{
  82#if defined(CONFIG_SERIAL_CONSOLE)
  83        if(keyb_present)
  84                return (CRT_tstc() || serial_tstc(com_port));
  85        else
  86                return (serial_tstc(com_port));
  87#else
  88        return CRT_tstc();
  89#endif
  90}
  91
  92int getc(void)
  93{
  94        while (1) {
  95#if defined(CONFIG_SERIAL_CONSOLE)
  96                if (serial_tstc(com_port))
  97                        return (serial_getc(com_port));
  98#endif /* CONFIG_SERIAL_CONSOLE */
  99                if (keyb_present)
 100                        if(CRT_tstc())
 101                                return (CRT_getc());
 102        }
 103}
 104
 105void
 106putc(const char c)
 107{
 108        int x,y;
 109
 110#if defined(CONFIG_SERIAL_CONSOLE)
 111        serial_putc(com_port, c);
 112        if ( c == '\n' )
 113                serial_putc(com_port, '\r');
 114#endif /* CONFIG_SERIAL_CONSOLE */
 115
 116        x = orig_x;
 117        y = orig_y;
 118
 119        if ( c == '\n' ) {
 120                x = 0;
 121                if ( ++y >= lines ) {
 122                        scroll();
 123                        y--;
 124                }
 125        } else if (c == '\r') {
 126                x = 0;
 127        } else if (c == '\b') {
 128                if (x > 0) {
 129                        x--;
 130                }
 131        } else {
 132                vidmem [ ( x + cols * y ) * 2 ] = c;
 133                if ( ++x >= cols ) {
 134                        x = 0;
 135                        if ( ++y >= lines ) {
 136                                scroll();
 137                                y--;
 138                        }
 139                }
 140        }
 141
 142        cursor(x, y);
 143
 144        orig_x = x;
 145        orig_y = y;
 146}
 147
 148void puts(const char *s)
 149{
 150        int x,y;
 151        char c;
 152
 153        x = orig_x;
 154        y = orig_y;
 155
 156        while ( ( c = *s++ ) != '\0' ) {
 157#if defined(CONFIG_SERIAL_CONSOLE)
 158                serial_putc(com_port, c);
 159                if ( c == '\n' ) serial_putc(com_port, '\r');
 160#endif /* CONFIG_SERIAL_CONSOLE */
 161
 162                if ( c == '\n' ) {
 163                        x = 0;
 164                        if ( ++y >= lines ) {
 165                                scroll();
 166                                y--;
 167                        }
 168                } else if (c == '\b') {
 169                  if (x > 0) {
 170                    x--;
 171                  }
 172                } else {
 173                        vidmem [ ( x + cols * y ) * 2 ] = c;
 174                        if ( ++x >= cols ) {
 175                                x = 0;
 176                                if ( ++y >= lines ) {
 177                                        scroll();
 178                                        y--;
 179                                }
 180                        }
 181                }
 182        }
 183
 184        cursor(x, y);
 185
 186        orig_x = x;
 187        orig_y = y;
 188}
 189
 190void error(char *x)
 191{
 192        puts("\n\n");
 193        puts(x);
 194        puts("\n\n -- System halted");
 195
 196        while(1);       /* Halt */
 197}
 198
 199void *zalloc(void *x, unsigned items, unsigned size)
 200{
 201        void *p = avail_ram;
 202
 203        size *= items;
 204        size = (size + 7) & -8;
 205        avail_ram += size;
 206        if (avail_ram > end_avail) {
 207                puts("oops... out of memory\n");
 208                pause();
 209        }
 210        return p;
 211}
 212
 213void zfree(void *x, void *addr, unsigned nb)
 214{
 215}
 216
 217#define HEAD_CRC        2
 218#define EXTRA_FIELD     4
 219#define ORIG_NAME       8
 220#define COMMENT         0x10
 221#define RESERVED        0xe0
 222
 223#define DEFLATED        8
 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] != 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        s.zalloc = zalloc;
 253        s.zfree = zfree;
 254        r = inflateInit2(&s, -MAX_WBITS);
 255        if (r != Z_OK) {
 256                puts("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 = 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        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
 524outb(int port, unsigned char val)
 525{
 526        /* Ensure I/O operations complete */
 527        __asm__ volatile("eieio");
 528        ISA_io[port] = val;
 529}
 530
 531unsigned char
 532inb(int port)
 533{
 534        /* Ensure I/O operations complete */
 535        __asm__ volatile("eieio");
 536        return (ISA_io[port]);
 537}
 538
 539/*
 540 * Local variables:
 541 *  c-indent-level: 8
 542 *  c-basic-offset: 8
 543 *  tab-width: 8
 544 * End:
 545 */
 546
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.