initial commit with v2.6.9
[linux-2.6.9-moxart.git] / arch / ppc / boot / common / misc-common.c
blob7acd03b31730dbbafc38dd8c9b21d11a1bbcef00
1 /*
2 * arch/ppc/boot/common/misc-common.c
4 * Misc. bootloader code (almost) all platforms can use
6 * Author: Johnnie Peters <jpeters@mvista.com>
7 * Editor: Tom Rini <trini@mvista.com>
9 * Derived from arch/ppc/boot/prep/misc.c
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.
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"
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)
27 extern void cursor(int x, int y);
28 extern void scroll(void);
29 extern char *vidmem;
30 extern int lines, cols;
31 extern int orig_x, orig_y;
32 extern int keyb_present;
33 extern int CRT_tstc(void);
34 extern int CRT_getc(void);
35 #else
36 int cursor(int x, int y) {return 0;}
37 void scroll(void) {}
38 char vidmem[1];
39 #define lines 0
40 #define cols 0
41 int orig_x = 0;
42 int orig_y = 0;
43 #define keyb_present 0
44 int CRT_tstc(void) {return 0;}
45 int CRT_getc(void) {return 0;}
46 #endif
48 extern char *avail_ram;
49 extern char *end_avail;
50 extern char _end[];
52 void puts(const char *);
53 void putc(const char c);
54 void puthex(unsigned long val);
55 void _bcopy(char *src, char *dst, int len);
56 void gunzip(void *, int, unsigned char *, int *);
57 static int _cvt(unsigned long val, char *buf, long radix, char *digits);
59 void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap);
60 unsigned char *ISA_io = NULL;
62 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
63 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE)
64 extern unsigned long com_port;
66 extern int serial_tstc(unsigned long com_port);
67 extern unsigned char serial_getc(unsigned long com_port);
68 extern void serial_putc(unsigned long com_port, unsigned char c);
69 #endif
71 void pause(void)
73 puts("pause\n");
76 void exit(void)
78 puts("exit\n");
79 while(1);
82 int tstc(void)
84 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
85 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE)
86 if(keyb_present)
87 return (CRT_tstc() || serial_tstc(com_port));
88 else
89 return (serial_tstc(com_port));
90 #else
91 return CRT_tstc();
92 #endif
95 int getc(void)
97 while (1) {
98 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
99 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE)
100 if (serial_tstc(com_port))
101 return (serial_getc(com_port));
102 #endif /* serial console */
103 if (keyb_present)
104 if(CRT_tstc())
105 return (CRT_getc());
109 void
110 putc(const char c)
112 int x,y;
114 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
115 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE)
116 serial_putc(com_port, c);
117 if ( c == '\n' )
118 serial_putc(com_port, '\r');
119 #endif /* serial console */
121 x = orig_x;
122 y = orig_y;
124 if ( c == '\n' ) {
125 x = 0;
126 if ( ++y >= lines ) {
127 scroll();
128 y--;
130 } else if (c == '\r') {
131 x = 0;
132 } else if (c == '\b') {
133 if (x > 0) {
134 x--;
136 } else {
137 vidmem [ ( x + cols * y ) * 2 ] = c;
138 if ( ++x >= cols ) {
139 x = 0;
140 if ( ++y >= lines ) {
141 scroll();
142 y--;
147 cursor(x, y);
149 orig_x = x;
150 orig_y = y;
153 void puts(const char *s)
155 int x,y;
156 char c;
158 x = orig_x;
159 y = orig_y;
161 while ( ( c = *s++ ) != '\0' ) {
162 #if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
163 || defined(CONFIG_SERIAL_MPC52xx_CONSOLE)
164 serial_putc(com_port, c);
165 if ( c == '\n' ) serial_putc(com_port, '\r');
166 #endif /* serial console */
168 if ( c == '\n' ) {
169 x = 0;
170 if ( ++y >= lines ) {
171 scroll();
172 y--;
174 } else if (c == '\b') {
175 if (x > 0) {
176 x--;
178 } else {
179 vidmem [ ( x + cols * y ) * 2 ] = c;
180 if ( ++x >= cols ) {
181 x = 0;
182 if ( ++y >= lines ) {
183 scroll();
184 y--;
190 cursor(x, y);
192 orig_x = x;
193 orig_y = y;
196 void error(char *x)
198 puts("\n\n");
199 puts(x);
200 puts("\n\n -- System halted");
202 while(1); /* Halt */
205 static void *zalloc(unsigned size)
207 void *p = avail_ram;
209 size = (size + 7) & -8;
210 avail_ram += size;
211 if (avail_ram > end_avail) {
212 puts("oops... out of memory\n");
213 pause();
215 return p;
218 #define HEAD_CRC 2
219 #define EXTRA_FIELD 4
220 #define ORIG_NAME 8
221 #define COMMENT 0x10
222 #define RESERVED 0xe0
224 void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
226 z_stream s;
227 int r, i, flags;
229 /* skip header */
230 i = 10;
231 flags = src[3];
232 if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
233 puts("bad gzipped data\n");
234 exit();
236 if ((flags & EXTRA_FIELD) != 0)
237 i = 12 + src[10] + (src[11] << 8);
238 if ((flags & ORIG_NAME) != 0)
239 while (src[i++] != 0)
241 if ((flags & COMMENT) != 0)
242 while (src[i++] != 0)
244 if ((flags & HEAD_CRC) != 0)
245 i += 2;
246 if (i >= *lenp) {
247 puts("gunzip: ran out of data in header\n");
248 exit();
251 /* Initialize ourself. */
252 s.workspace = zalloc(zlib_inflate_workspacesize());
253 r = zlib_inflateInit2(&s, -MAX_WBITS);
254 if (r != Z_OK) {
255 puts("zlib_inflateInit2 returned "); puthex(r); puts("\n");
256 exit();
258 s.next_in = src + i;
259 s.avail_in = *lenp - i;
260 s.next_out = dst;
261 s.avail_out = dstlen;
262 r = zlib_inflate(&s, Z_FINISH);
263 if (r != Z_OK && r != Z_STREAM_END) {
264 puts("inflate returned "); puthex(r); puts("\n");
265 exit();
267 *lenp = s.next_out - (unsigned char *) dst;
268 zlib_inflateEnd(&s);
271 void
272 puthex(unsigned long val)
275 unsigned char buf[10];
276 int i;
277 for (i = 7; i >= 0; i--)
279 buf[i] = "0123456789ABCDEF"[val & 0x0F];
280 val >>= 4;
282 buf[8] = '\0';
283 puts(buf);
286 #define FALSE 0
287 #define TRUE 1
289 void
290 _printk(char const *fmt, ...)
292 va_list ap;
294 va_start(ap, fmt);
295 _vprintk(putc, fmt, ap);
296 va_end(ap);
297 return;
300 #define is_digit(c) ((c >= '0') && (c <= '9'))
302 void
303 _vprintk(void(*putc)(const char), const char *fmt0, va_list ap)
305 char c, sign, *cp = 0;
306 int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right;
307 char buf[32];
308 long val;
309 while ((c = *fmt0++))
311 if (c == '%')
313 c = *fmt0++;
314 left_prec = right_prec = pad_on_right = 0;
315 if (c == '-')
317 c = *fmt0++;
318 pad_on_right++;
320 if (c == '0')
322 zero_fill = TRUE;
323 c = *fmt0++;
324 } else
326 zero_fill = FALSE;
328 while (is_digit(c))
330 left_prec = (left_prec * 10) + (c - '0');
331 c = *fmt0++;
333 if (c == '.')
335 c = *fmt0++;
336 zero_fill++;
337 while (is_digit(c))
339 right_prec = (right_prec * 10) + (c - '0');
340 c = *fmt0++;
342 } else
344 right_prec = left_prec;
346 sign = '\0';
347 switch (c)
349 case 'd':
350 case 'x':
351 case 'X':
352 val = va_arg(ap, long);
353 switch (c)
355 case 'd':
356 if (val < 0)
358 sign = '-';
359 val = -val;
361 length = _cvt(val, buf, 10, "0123456789");
362 break;
363 case 'x':
364 length = _cvt(val, buf, 16, "0123456789abcdef");
365 break;
366 case 'X':
367 length = _cvt(val, buf, 16, "0123456789ABCDEF");
368 break;
370 cp = buf;
371 break;
372 case 's':
373 cp = va_arg(ap, char *);
374 length = strlen(cp);
375 break;
376 case 'c':
377 c = va_arg(ap, long /*char*/);
378 (*putc)(c);
379 continue;
380 default:
381 (*putc)('?');
383 pad = left_prec - length;
384 if (sign != '\0')
386 pad--;
388 if (zero_fill)
390 c = '0';
391 if (sign != '\0')
393 (*putc)(sign);
394 sign = '\0';
396 } else
398 c = ' ';
400 if (!pad_on_right)
402 while (pad-- > 0)
404 (*putc)(c);
407 if (sign != '\0')
409 (*putc)(sign);
411 while (length-- > 0)
413 (*putc)(c = *cp++);
414 if (c == '\n')
416 (*putc)('\r');
419 if (pad_on_right)
421 while (pad-- > 0)
423 (*putc)(c);
426 } else
428 (*putc)(c);
429 if (c == '\n')
431 (*putc)('\r');
438 _cvt(unsigned long val, char *buf, long radix, char *digits)
440 char temp[80];
441 char *cp = temp;
442 int length = 0;
443 if (val == 0)
444 { /* Special case */
445 *cp++ = '0';
446 } else
447 while (val)
449 *cp++ = digits[val % radix];
450 val /= radix;
452 while (cp != temp)
454 *buf++ = *--cp;
455 length++;
457 *buf = '\0';
458 return (length);
461 void
462 _dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
464 int i, c;
465 if ((unsigned int)s > (unsigned int)p)
467 s = (unsigned int)s - (unsigned int)p;
469 while (s > 0)
471 if (base)
473 _printk("%06X: ", (int)p - (int)base);
474 } else
476 _printk("%06X: ", p);
478 for (i = 0; i < 16; i++)
480 if (i < s)
482 _printk("%02X", p[i] & 0xFF);
483 } else
485 _printk(" ");
487 if ((i % 2) == 1) _printk(" ");
488 if ((i % 8) == 7) _printk(" ");
490 _printk(" |");
491 for (i = 0; i < 16; i++)
493 if (i < s)
495 c = p[i] & 0xFF;
496 if ((c < 0x20) || (c >= 0x7F)) c = '.';
497 } else
499 c = ' ';
501 _printk("%c", c);
503 _printk("|\n");
504 s -= 16;
505 p += 16;
509 void
510 _dump_buf(unsigned char *p, int s)
512 _printk("\n");
513 _dump_buf_with_offset(p, s, 0);
516 /* Very simple inb/outb routines. We declare ISA_io to be 0 above, and
517 * then modify it on platforms which need to. We do it like this
518 * because on some platforms we give inb/outb an exact location, and
519 * on others it's an offset from a given location. -- Tom
522 void ISA_init(unsigned long base)
524 ISA_io = (unsigned char *)base;
527 void
528 outb(int port, unsigned char val)
530 /* Ensure I/O operations complete */
531 __asm__ volatile("eieio");
532 ISA_io[port] = val;
535 unsigned char
536 inb(int port)
538 /* Ensure I/O operations complete */
539 __asm__ volatile("eieio");
540 return (ISA_io[port]);
544 * Local variables:
545 * c-indent-level: 8
546 * c-basic-offset: 8
547 * tab-width: 8
548 * End: