misc-common.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:10k
- /*
- * arch/ppc/boot/common/misc-common.c
- *
- * Misc. bootloader code (almost) all platforms can use
- *
- * Author: Johnnie Peters <jpeters@mvista.com>
- * Editor: Tom Rini <trini@mvista.com>
- *
- * Derived from arch/ppc/boot/prep/misc.c
- *
- * Copyright 2000-2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- #include <stdarg.h> /* for va_ bits */
- #include <linux/config.h>
- #include "zlib.h"
- #include "nonstdio.h"
- /* If we're on a ALL_PPC, assume we have a keyboard controller
- * Also note, if we're not ALL_PPC, we assume you are a serial
- * console - Tom */
- #if defined(CONFIG_ALL_PPC) && defined(CONFIG_VGA_CONSOLE)
- extern void cursor(int x, int y);
- extern void scroll(void);
- extern char *vidmem;
- extern int lines, cols;
- extern int orig_x, orig_y;
- extern int keyb_present;
- extern int CRT_tstc(void);
- extern int CRT_getc(void);
- #else
- int cursor(int x, int y) {return 0;}
- void scroll(void) {}
- char vidmem[1];
- #define lines 0
- #define cols 0
- int orig_x = 0;
- int orig_y = 0;
- #define keyb_present 0
- int CRT_tstc(void) {return 0;}
- int CRT_getc(void) {return 0;}
- #endif
- extern char *avail_ram;
- extern char *end_avail;
- extern char _end[];
- void puts(const char *);
- void putc(const char c);
- void puthex(unsigned long val);
- void _bcopy(char *src, char *dst, int len);
- void gunzip(void *, int, unsigned char *, int *);
- static int _cvt(unsigned long val, char *buf, long radix, char *digits);
- void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap);
- unsigned char *ISA_io = NULL;
- #if defined(CONFIG_SERIAL_CONSOLE)
- extern unsigned long com_port;
- extern int serial_tstc(unsigned long com_port);
- extern unsigned char serial_getc(unsigned long com_port);
- extern void serial_putc(unsigned long com_port, unsigned char c);
- #endif
- void pause(void)
- {
- puts("pausen");
- }
- void exit(void)
- {
- puts("exitn");
- while(1);
- }
- int tstc(void)
- {
- #if defined(CONFIG_SERIAL_CONSOLE)
- if(keyb_present)
- return (CRT_tstc() || serial_tstc(com_port));
- else
- return (serial_tstc(com_port));
- #else
- return CRT_tstc();
- #endif
- }
- int getc(void)
- {
- while (1) {
- #if defined(CONFIG_SERIAL_CONSOLE)
- if (serial_tstc(com_port))
- return (serial_getc(com_port));
- #endif /* CONFIG_SERIAL_CONSOLE */
- if (keyb_present)
- if(CRT_tstc())
- return (CRT_getc());
- }
- }
- void
- putc(const char c)
- {
- int x,y;
- #if defined(CONFIG_SERIAL_CONSOLE)
- serial_putc(com_port, c);
- if ( c == 'n' )
- serial_putc(com_port, 'r');
- #endif /* CONFIG_SERIAL_CONSOLE */
- x = orig_x;
- y = orig_y;
- if ( c == 'n' ) {
- x = 0;
- if ( ++y >= lines ) {
- scroll();
- y--;
- }
- } else if (c == 'r') {
- x = 0;
- } else if (c == 'b') {
- if (x > 0) {
- x--;
- }
- } else {
- vidmem [ ( x + cols * y ) * 2 ] = c;
- if ( ++x >= cols ) {
- x = 0;
- if ( ++y >= lines ) {
- scroll();
- y--;
- }
- }
- }
- cursor(x, y);
- orig_x = x;
- orig_y = y;
- }
- void puts(const char *s)
- {
- int x,y;
- char c;
- x = orig_x;
- y = orig_y;
- while ( ( c = *s++ ) != ' ' ) {
- #if defined(CONFIG_SERIAL_CONSOLE)
- serial_putc(com_port, c);
- if ( c == 'n' ) serial_putc(com_port, 'r');
- #endif /* CONFIG_SERIAL_CONSOLE */
- if ( c == 'n' ) {
- x = 0;
- if ( ++y >= lines ) {
- scroll();
- y--;
- }
- } else if (c == 'b') {
- if (x > 0) {
- x--;
- }
- } else {
- vidmem [ ( x + cols * y ) * 2 ] = c;
- if ( ++x >= cols ) {
- x = 0;
- if ( ++y >= lines ) {
- scroll();
- y--;
- }
- }
- }
- }
- cursor(x, y);
- orig_x = x;
- orig_y = y;
- }
- void error(char *x)
- {
- puts("nn");
- puts(x);
- puts("nn -- System halted");
- while(1); /* Halt */
- }
- void *zalloc(void *x, unsigned items, unsigned size)
- {
- void *p = avail_ram;
-
- size *= items;
- size = (size + 7) & -8;
- avail_ram += size;
- if (avail_ram > end_avail) {
- puts("oops... out of memoryn");
- pause();
- }
- return p;
- }
- void zfree(void *x, void *addr, unsigned nb)
- {
- }
- #define HEAD_CRC 2
- #define EXTRA_FIELD 4
- #define ORIG_NAME 8
- #define COMMENT 0x10
- #define RESERVED 0xe0
- #define DEFLATED 8
- void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
- {
- z_stream s;
- int r, i, flags;
-
- /* skip header */
- i = 10;
- flags = src[3];
- if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
- puts("bad gzipped datan");
- exit();
- }
- if ((flags & EXTRA_FIELD) != 0)
- i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
- i += 2;
- if (i >= *lenp) {
- puts("gunzip: ran out of data in headern");
- exit();
- }
-
- s.zalloc = zalloc;
- s.zfree = zfree;
- r = inflateInit2(&s, -MAX_WBITS);
- if (r != Z_OK) {
- puts("inflateInit2 returned "); puthex(r); puts("n");
- exit();
- }
- s.next_in = src + i;
- s.avail_in = *lenp - i;
- s.next_out = dst;
- s.avail_out = dstlen;
- r = inflate(&s, Z_FINISH);
- if (r != Z_OK && r != Z_STREAM_END) {
- puts("inflate returned "); puthex(r); puts("n");
- exit();
- }
- *lenp = s.next_out - (unsigned char *) dst;
- inflateEnd(&s);
- }
- void
- puthex(unsigned long val)
- {
- unsigned char buf[10];
- int i;
- for (i = 7; i >= 0; i--)
- {
- buf[i] = "0123456789ABCDEF"[val & 0x0F];
- val >>= 4;
- }
- buf[8] = ' ';
- puts(buf);
- }
- #define FALSE 0
- #define TRUE 1
- void
- _printk(char const *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- _vprintk(putc, fmt, ap);
- va_end(ap);
- return;
- }
- #define is_digit(c) ((c >= '0') && (c <= '9'))
- void
- _vprintk(void(*putc)(const char), const char *fmt0, va_list ap)
- {
- char c, sign, *cp = 0;
- int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right;
- char buf[32];
- long val;
- while ((c = *fmt0++))
- {
- if (c == '%')
- {
- c = *fmt0++;
- left_prec = right_prec = pad_on_right = 0;
- if (c == '-')
- {
- c = *fmt0++;
- pad_on_right++;
- }
- if (c == '0')
- {
- zero_fill = TRUE;
- c = *fmt0++;
- } else
- {
- zero_fill = FALSE;
- }
- while (is_digit(c))
- {
- left_prec = (left_prec * 10) + (c - '0');
- c = *fmt0++;
- }
- if (c == '.')
- {
- c = *fmt0++;
- zero_fill++;
- while (is_digit(c))
- {
- right_prec = (right_prec * 10) + (c - '0');
- c = *fmt0++;
- }
- } else
- {
- right_prec = left_prec;
- }
- sign = ' ';
- switch (c)
- {
- case 'd':
- case 'x':
- case 'X':
- val = va_arg(ap, long);
- switch (c)
- {
- case 'd':
- if (val < 0)
- {
- sign = '-';
- val = -val;
- }
- length = _cvt(val, buf, 10, "0123456789");
- break;
- case 'x':
- length = _cvt(val, buf, 16, "0123456789abcdef");
- break;
- case 'X':
- length = _cvt(val, buf, 16, "0123456789ABCDEF");
- break;
- }
- cp = buf;
- break;
- case 's':
- cp = va_arg(ap, char *);
- length = strlen(cp);
- break;
- case 'c':
- c = va_arg(ap, long /*char*/);
- (*putc)(c);
- continue;
- default:
- (*putc)('?');
- }
- pad = left_prec - length;
- if (sign != ' ')
- {
- pad--;
- }
- if (zero_fill)
- {
- c = '0';
- if (sign != ' ')
- {
- (*putc)(sign);
- sign = ' ';
- }
- } else
- {
- c = ' ';
- }
- if (!pad_on_right)
- {
- while (pad-- > 0)
- {
- (*putc)(c);
- }
- }
- if (sign != ' ')
- {
- (*putc)(sign);
- }
- while (length-- > 0)
- {
- (*putc)(c = *cp++);
- if (c == 'n')
- {
- (*putc)('r');
- }
- }
- if (pad_on_right)
- {
- while (pad-- > 0)
- {
- (*putc)(c);
- }
- }
- } else
- {
- (*putc)(c);
- if (c == 'n')
- {
- (*putc)('r');
- }
- }
- }
- }
- int
- _cvt(unsigned long val, char *buf, long radix, char *digits)
- {
- char temp[80];
- char *cp = temp;
- int length = 0;
- if (val == 0)
- { /* Special case */
- *cp++ = '0';
- } else
- while (val)
- {
- *cp++ = digits[val % radix];
- val /= radix;
- }
- while (cp != temp)
- {
- *buf++ = *--cp;
- length++;
- }
- *buf = ' ';
- return (length);
- }
- void
- _dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
- {
- int i, c;
- if ((unsigned int)s > (unsigned int)p)
- {
- s = (unsigned int)s - (unsigned int)p;
- }
- while (s > 0)
- {
- if (base)
- {
- _printk("%06X: ", (int)p - (int)base);
- } else
- {
- _printk("%06X: ", p);
- }
- for (i = 0; i < 16; i++)
- {
- if (i < s)
- {
- _printk("%02X", p[i] & 0xFF);
- } else
- {
- _printk(" ");
- }
- if ((i % 2) == 1) _printk(" ");
- if ((i % 8) == 7) _printk(" ");
- }
- _printk(" |");
- for (i = 0; i < 16; i++)
- {
- if (i < s)
- {
- c = p[i] & 0xFF;
- if ((c < 0x20) || (c >= 0x7F)) c = '.';
- } else
- {
- c = ' ';
- }
- _printk("%c", c);
- }
- _printk("|n");
- s -= 16;
- p += 16;
- }
- }
- void
- _dump_buf(unsigned char *p, int s)
- {
- _printk("n");
- _dump_buf_with_offset(p, s, 0);
- }
- /* Very simple inb/outb routines. We declare ISA_io to be 0 above, and
- * then modify it on platforms which need to. We do it like this
- * because on some platforms we give inb/outb an exact location, and
- * on others it's an offset from a given location. -- Tom
- */
- void
- outb(int port, unsigned char val)
- {
- /* Ensure I/O operations complete */
- __asm__ volatile("eieio");
- ISA_io[port] = val;
- }
- unsigned char
- inb(int port)
- {
- /* Ensure I/O operations complete */
- __asm__ volatile("eieio");
- return (ISA_io[port]);
- }
- /*
- * Local variables:
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */