2 * Misc. bootloader code (almost) all platforms can use
4 * Author: Johnnie Peters <jpeters@mvista.com>
5 * Editor: Tom Rini <trini@mvista.com>
7 * Derived from arch/ppc/boot/prep/misc.c
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
15 #include <stdarg.h> /* for va_ bits */
16 #include <linux/string.h>
17 #include <linux/zlib.h>
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
23 #if defined(CONFIG_PPC_PREP) && defined(CONFIG_VGA_CONSOLE)
24 extern void cursor(int x, int y);
25 extern void scroll(void);
27 extern int lines, cols;
28 extern int orig_x, orig_y;
29 extern int keyb_present;
30 extern int CRT_tstc(void);
31 extern int CRT_getc(void);
33 int cursor(int x, int y) {return 0;}
40 #define keyb_present 0
41 int CRT_tstc(void) {return 0;}
42 int CRT_getc(void) {return 0;}
45 extern char *avail_ram;
46 extern char *end_avail;
49 void puts(const char *);
50 void putc(const char c);
51 void puthex(unsigned long val);
52 void gunzip(void *, int, unsigned char *, int *);
53 static int _cvt(unsigned long val, char *buf, long radix, char *digits);
55 void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap);
56 unsigned char *ISA_io = NULL;
58 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
59 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
60 || defined(CONFIG_SERIAL_MPSC_CONSOLE)
61 extern unsigned long com_port;
63 extern int serial_tstc(unsigned long com_port);
64 extern unsigned char serial_getc(unsigned long com_port);
65 extern void serial_putc(unsigned long com_port, unsigned char c);
81 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
82 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
83 || defined(CONFIG_SERIAL_MPSC_CONSOLE)
85 return (CRT_tstc() || serial_tstc(com_port));
87 return (serial_tstc(com_port));
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 */
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);
118 serial_putc(com_port, '\r');
119 #endif /* serial console */
126 if ( ++y >= lines ) {
130 } else if (c == '\r') {
132 } else if (c == '\b') {
137 vidmem [ ( x + cols * y ) * 2 ] = c;
140 if ( ++y >= lines ) {
153 void puts(const char *s)
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 */
171 if ( ++y >= lines ) {
175 } else if (c == '\b') {
180 vidmem [ ( x + cols * y ) * 2 ] = c;
183 if ( ++y >= lines ) {
201 puts("\n\n -- System halted");
206 static void *zalloc(unsigned size)
210 size = (size + 7) & -8;
212 if (avail_ram > end_avail) {
213 puts("oops... out of memory\n");
220 #define EXTRA_FIELD 4
223 #define RESERVED 0xe0
225 void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
233 if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
234 puts("bad gzipped data\n");
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)
242 if ((flags & COMMENT) != 0)
243 while (src[i++] != 0)
245 if ((flags & HEAD_CRC) != 0)
248 puts("gunzip: ran out of data in header\n");
252 /* Initialize ourself. */
253 s.workspace = zalloc(zlib_inflate_workspacesize());
254 r = zlib_inflateInit2(&s, -MAX_WBITS);
256 puts("zlib_inflateInit2 returned "); puthex(r); puts("\n");
260 s.avail_in = *lenp - i;
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");
268 *lenp = s.next_out - (unsigned char *) dst;
273 puthex(unsigned long val)
276 unsigned char buf[10];
278 for (i = 7; i >= 0; i--)
280 buf[i] = "0123456789ABCDEF"[val & 0x0F];
291 _printk(char const *fmt, ...)
296 _vprintk(putc, fmt, ap);
301 #define is_digit(c) ((c >= '0') && (c <= '9'))
304 _vprintk(void(*putc)(const char), const char *fmt0, va_list ap)
306 char c, sign, *cp = 0;
307 int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right;
310 while ((c = *fmt0++))
315 left_prec = right_prec = pad_on_right = 0;
331 left_prec = (left_prec * 10) + (c - '0');
340 right_prec = (right_prec * 10) + (c - '0');
345 right_prec = left_prec;
353 val = va_arg(ap, long);
362 length = _cvt(val, buf, 10, "0123456789");
365 length = _cvt(val, buf, 16, "0123456789abcdef");
368 length = _cvt(val, buf, 16, "0123456789ABCDEF");
374 cp = va_arg(ap, char *);
378 c = va_arg(ap, long /*char*/);
384 pad = left_prec - length;
439 _cvt(unsigned long val, char *buf, long radix, char *digits)
450 *cp++ = digits[val % radix];
463 _dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
466 if ((unsigned int)s > (unsigned int)p)
468 s = (unsigned int)s - (unsigned int)p;
474 _printk("%06X: ", (int)p - (int)base);
477 _printk("%06X: ", p);
479 for (i = 0; i < 16; i++)
483 _printk("%02X", p[i] & 0xFF);
488 if ((i % 2) == 1) _printk(" ");
489 if ((i % 8) == 7) _printk(" ");
492 for (i = 0; i < 16; i++)
497 if ((c < 0x20) || (c >= 0x7F)) c = '.';
511 _dump_buf(unsigned char *p, int s)
514 _dump_buf_with_offset(p, s, 0);
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
523 void ISA_init(unsigned long base)
525 ISA_io = (unsigned char *)base;
529 outb(int port, unsigned char val)
531 /* Ensure I/O operations complete */
532 __asm__ volatile("eieio");
539 /* Ensure I/O operations complete */
540 __asm__ volatile("eieio");
541 return (ISA_io[port]);