]>
git.proxmox.com Git - mirror_ubuntu-kernels.git/blob - arch/ppc64/boot/start.c
2 * Copyright (C) Paul Mackerras 1997.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
10 #include <linux/types.h>
11 #include <linux/string.h>
12 #include <linux/ctype.h>
14 #include <asm/div64.h>
24 void *finddevice(const char *name
);
25 int getprop(void *phandle
, const char *name
, void *buf
, int buflen
);
26 void chrpboot(int a1
, int a2
, void *prom
); /* in main.c */
28 void printk(char *fmt
, ...);
31 start(int a1
, int a2
, void *promptr
)
33 prom
= (int (*)(void *)) promptr
;
34 chosen_handle
= finddevice("/chosen");
35 if (chosen_handle
== (void *) -1)
37 if (getprop(chosen_handle
, "stdout", &stdout
, sizeof(stdout
)) != 4)
40 if (getprop(chosen_handle
, "stdin", &stdin
, sizeof(stdin
)) != 4)
43 chrpboot(a1
, a2
, promptr
);
49 write(void *handle
, void *ptr
, int nb
)
61 args
.service
= "write";
64 args
.ihandle
= handle
;
73 read(void *handle
, void *ptr
, int nb
)
85 args
.service
= "read";
88 args
.ihandle
= handle
;
104 args
.service
= "exit";
116 args
.service
= "enter";
121 finddevice(const char *name
)
131 args
.service
= "finddevice";
135 args
.phandle
= (void *) -1;
141 claim(unsigned long virt
, unsigned long size
, unsigned long align
)
153 args
.service
= "claim";
164 getprop(void *phandle
, const char *name
, void *buf
, int buflen
)
177 args
.service
= "getprop";
180 args
.phandle
= phandle
;
183 args
.buflen
= buflen
;
196 return write(f
, &ch
, 1) == 1? c
: -1;
202 return putc(c
, stdout
);
206 fputs(char *str
, void *f
)
210 return write(f
, str
, n
) == n
? 0: -1;
219 switch (read(stdin
, &ch
, 1)) {
223 printk("read(stdin) returned -1\r\n");
229 static char line
[256];
230 static char *lineptr
;
242 if (c
== -1 || c
== 4)
244 if (c
== '\r' || c
== '\n') {
252 if (lineptr
> line
) {
260 while (lineptr
> line
) {
268 if (lineptr
>= &line
[sizeof(line
) - 1])
276 lineleft
= lineptr
- line
;
287 /* String functions lifted from lib/vsprintf.c and lib/ctype.c */
288 unsigned char _ctype
[] = {
289 _C
,_C
,_C
,_C
,_C
,_C
,_C
,_C
, /* 0-7 */
290 _C
,_C
|_S
,_C
|_S
,_C
|_S
,_C
|_S
,_C
|_S
,_C
,_C
, /* 8-15 */
291 _C
,_C
,_C
,_C
,_C
,_C
,_C
,_C
, /* 16-23 */
292 _C
,_C
,_C
,_C
,_C
,_C
,_C
,_C
, /* 24-31 */
293 _S
|_SP
,_P
,_P
,_P
,_P
,_P
,_P
,_P
, /* 32-39 */
294 _P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
, /* 40-47 */
295 _D
,_D
,_D
,_D
,_D
,_D
,_D
,_D
, /* 48-55 */
296 _D
,_D
,_P
,_P
,_P
,_P
,_P
,_P
, /* 56-63 */
297 _P
,_U
|_X
,_U
|_X
,_U
|_X
,_U
|_X
,_U
|_X
,_U
|_X
,_U
, /* 64-71 */
298 _U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
, /* 72-79 */
299 _U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
, /* 80-87 */
300 _U
,_U
,_U
,_P
,_P
,_P
,_P
,_P
, /* 88-95 */
301 _P
,_L
|_X
,_L
|_X
,_L
|_X
,_L
|_X
,_L
|_X
,_L
|_X
,_L
, /* 96-103 */
302 _L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
, /* 104-111 */
303 _L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
, /* 112-119 */
304 _L
,_L
,_L
,_P
,_P
,_P
,_P
,_C
, /* 120-127 */
305 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
306 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
307 _S
|_SP
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
, /* 160-175 */
308 _P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
,_P
, /* 176-191 */
309 _U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
,_U
, /* 192-207 */
310 _U
,_U
,_U
,_U
,_U
,_U
,_U
,_P
,_U
,_U
,_U
,_U
,_U
,_U
,_U
,_L
, /* 208-223 */
311 _L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
, /* 224-239 */
312 _L
,_L
,_L
,_L
,_L
,_L
,_L
,_P
,_L
,_L
,_L
,_L
,_L
,_L
,_L
,_L
}; /* 240-255 */
314 size_t strnlen(const char * s
, size_t count
)
318 for (sc
= s
; count
-- && *sc
!= '\0'; ++sc
)
323 unsigned long simple_strtoul(const char *cp
,char **endp
,unsigned int base
)
325 unsigned long result
= 0,value
;
332 if ((*cp
== 'x') && isxdigit(cp
[1])) {
338 while (isxdigit(*cp
) &&
339 (value
= isdigit(*cp
) ? *cp
-'0' : toupper(*cp
)-'A'+10) < base
) {
340 result
= result
*base
+ value
;
348 long simple_strtol(const char *cp
,char **endp
,unsigned int base
)
351 return -simple_strtoul(cp
+1,endp
,base
);
352 return simple_strtoul(cp
,endp
,base
);
355 static int skip_atoi(const char **s
)
360 i
= i
*10 + *((*s
)++) - '0';
364 #define ZEROPAD 1 /* pad with zero */
365 #define SIGN 2 /* unsigned/signed long */
366 #define PLUS 4 /* show plus */
367 #define SPACE 8 /* space if plus */
368 #define LEFT 16 /* left justified */
369 #define SPECIAL 32 /* 0x */
370 #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
372 static char * number(char * str
, long long num
, int base
, int size
, int precision
, int type
)
375 const char *digits
="0123456789abcdefghijklmnopqrstuvwxyz";
379 digits
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
382 if (base
< 2 || base
> 36)
384 c
= (type
& ZEROPAD
) ? '0' : ' ';
391 } else if (type
& PLUS
) {
394 } else if (type
& SPACE
) {
399 if (type
& SPECIAL
) {
408 else while (num
!= 0)
409 tmp
[i
++] = digits
[do_div(num
,base
)];
413 if (!(type
&(ZEROPAD
+LEFT
)))
418 if (type
& SPECIAL
) {
429 while (i
< precision
--)
438 /* Forward decl. needed for IP address printing stuff... */
439 int sprintf(char * buf
, const char *fmt
, ...);
441 int vsprintf(char *buf
, const char *fmt
, va_list args
)
444 unsigned long long num
;
449 int flags
; /* flags to number() */
451 int field_width
; /* width of output field */
452 int precision
; /* min. # of digits for integers; max
453 number of chars for from string */
454 int qualifier
; /* 'h', 'l', or 'L' for integer fields */
455 /* 'z' support added 23/7/1999 S.H. */
456 /* 'z' changed to 'Z' --davidm 1/25/99 */
459 for (str
=buf
; *fmt
; ++fmt
) {
468 ++fmt
; /* this also skips first '%' */
470 case '-': flags
|= LEFT
; goto repeat
;
471 case '+': flags
|= PLUS
; goto repeat
;
472 case ' ': flags
|= SPACE
; goto repeat
;
473 case '#': flags
|= SPECIAL
; goto repeat
;
474 case '0': flags
|= ZEROPAD
; goto repeat
;
477 /* get field width */
480 field_width
= skip_atoi(&fmt
);
481 else if (*fmt
== '*') {
483 /* it's the next argument */
484 field_width
= va_arg(args
, int);
485 if (field_width
< 0) {
486 field_width
= -field_width
;
491 /* get the precision */
496 precision
= skip_atoi(&fmt
);
497 else if (*fmt
== '*') {
499 /* it's the next argument */
500 precision
= va_arg(args
, int);
506 /* get the conversion qualifier */
508 if (*fmt
== 'h' || *fmt
== 'l' || *fmt
== 'L' || *fmt
=='Z') {
519 while (--field_width
> 0)
521 *str
++ = (unsigned char) va_arg(args
, int);
522 while (--field_width
> 0)
527 s
= va_arg(args
, char *);
531 len
= strnlen(s
, precision
);
534 while (len
< field_width
--)
536 for (i
= 0; i
< len
; ++i
)
538 while (len
< field_width
--)
543 if (field_width
== -1) {
544 field_width
= 2*sizeof(void *);
548 (unsigned long) va_arg(args
, void *), 16,
549 field_width
, precision
, flags
);
554 if (qualifier
== 'l') {
555 long * ip
= va_arg(args
, long *);
557 } else if (qualifier
== 'Z') {
558 size_t * ip
= va_arg(args
, size_t *);
561 int * ip
= va_arg(args
, int *);
570 /* integer number formats - set up the flags and "break" */
595 if (qualifier
== 'L')
596 num
= va_arg(args
, long long);
597 else if (qualifier
== 'l') {
598 num
= va_arg(args
, unsigned long);
600 num
= (signed long) num
;
601 } else if (qualifier
== 'Z') {
602 num
= va_arg(args
, size_t);
603 } else if (qualifier
== 'h') {
604 num
= (unsigned short) va_arg(args
, int);
606 num
= (signed short) num
;
608 num
= va_arg(args
, unsigned int);
610 num
= (signed int) num
;
612 str
= number(str
, num
, base
, field_width
, precision
, flags
);
618 int sprintf(char * buf
, const char *fmt
, ...)
624 i
=vsprintf(buf
,fmt
,args
);
629 static char sprint_buf
[1024];
632 printk(char *fmt
, ...)
638 n
= vsprintf(sprint_buf
, fmt
, args
);
640 write(stdout
, sprint_buf
, n
);
644 printf(char *fmt
, ...)
650 n
= vsprintf(sprint_buf
, fmt
, args
);
652 write(stdout
, sprint_buf
, n
);