Added: new boot.S, serial out for Xeon Phi
[barrelfish] / kernel / printf.c
1 /**
2  * \file
3  * \brief Implementations of printf and friends
4  */
5
6 /*
7  * Copyright (c) 2007, 2008, 2010, 2011, 2012, 2013 ETH Zurich.
8  * All rights reserved.
9  *
10  * This file is distributed under the terms in the attached LICENSE file.
11  * If you do not find this file, copies can be found by writing to:
12  * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
13  */
14
15 /*      $NetBSD: subr_prf.c,v 1.109 2007/09/26 07:40:36 he Exp $        */
16 /*-
17  * Copyright (c) 1986, 1988, 1991, 1993
18  *      The Regents of the University of California.  All rights reserved.
19  * (c) UNIX System Laboratories, Inc.
20  * All or some portions of this file are derived from material licensed
21  * to the University of California by American Telephone and Telegraph
22  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
23  * the permission of UNIX System Laboratories, Inc.
24  *
25  * Redistribution and use in source and binary forms, with or without
26  * modification, are permitted provided that the following conditions
27  * are met:
28  * 1. Redistributions of source code must retain the above copyright
29  *    notice, this list of conditions and the following disclaimer.
30  * 2. Redistributions in binary form must reproduce the above copyright
31  *    notice, this list of conditions and the following disclaimer in the
32  *    documentation and/or other materials provided with the distribution.
33  * 3. Neither the name of the University nor the names of its contributors
34  *    may be used to endorse or promote products derived from this software
35  *    without specific prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
38  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
41  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  *
49  *      @(#)subr_prf.c  8.4 (Berkeley) 5/4/95
50  */
51
52 #include <kernel.h>
53 #include <stddef.h>
54 #include <stdarg.h>
55 #include <stdio.h>
56 #include <string.h>
57 #include <kputchar.h>
58 #include <sys/types.h>
59
60 #define TOCONS          (1 << 0)
61 #define TOLOG           (1 << 1)
62 #define TOBUFONLY       (1 << 2)
63
64 #define KPRINTF_BUFSIZE         (sizeof(quad_t) * __CHAR_BIT__ / 3 + 2)
65
66 static const char hexdigits[] = "0123456789abcdef";
67 static const char HEXDIGITS[] = "0123456789ABCDEF";
68
69 #define KPRINTF_MUTEX_ENTER()  kprintf_begin()
70 #define KPRINTF_MUTEX_EXIT()   kprintf_end()
71
72 #ifdef putchar
73 #undef putchar
74 #endif
75
76 int
77 putchar(int c)
78 {
79     kprintf_begin();
80     kputchar(c);
81     kprintf_end();
82     return c;
83 }
84
85
86 static int kprintf(char * CT(bufsize) OPT sbuf, size_t bufsize,
87                    const char * NTS fmt0, va_list ap, int oflags);
88
89 /*
90  * printf_nolog: Like printf(), but does not send message to the log.
91  */
92
93 int
94 printf_nolog(const char *fmt, ...)
95 {
96     va_list ap;
97
98     KPRINTF_MUTEX_ENTER();
99
100     va_start(ap, fmt);
101     int retval = kprintf(NULL, 0, fmt, ap, TOCONS);
102     va_end(ap);
103
104     KPRINTF_MUTEX_EXIT();
105
106     return retval;
107 }
108
109 /*
110  * normal kernel printf functions: printf, vprintf, snprintf, vsnprintf
111  */
112
113 /*
114  * printf: print a message to the console and the log
115  */
116 int
117 printf(const char *fmt, ...)
118 {
119     va_list ap;
120
121     KPRINTF_MUTEX_ENTER();
122
123     va_start(ap, fmt);
124     int retval = kprintf(NULL, 0, fmt, ap, TOCONS /*| TOLOG*/);
125     va_end(ap);
126
127     KPRINTF_MUTEX_EXIT();
128
129     return retval;
130 }
131
132 /*
133  * vprintf: print a message to the console and the log [already have
134  *      va_alist]
135  */
136
137 int
138 vprintf(const char *fmt, va_list ap)
139 {
140     KPRINTF_MUTEX_ENTER();
141
142     int retval = kprintf(NULL, 0, fmt, ap, TOCONS /*| TOLOG*/);
143
144     KPRINTF_MUTEX_EXIT();
145
146     return retval;
147 }
148
149 /*
150  * snprintf: print a message to a buffer
151  */
152 int
153 snprintf(char *bf, size_t size, const char *fmt, ...)
154 {
155     int retval;
156     va_list ap;
157
158     if (size < 1)
159         return (-1);
160
161     va_start(ap, fmt);
162     retval = kprintf(bf, size, fmt, ap, TOBUFONLY);
163     va_end(ap);
164     if (retval < size) {
165         bf[retval] = '\0'; /* null terminate */
166     }
167     return (retval);
168 }
169
170 /*
171  * vsnprintf: print a message to a buffer [already have va_alist]
172  */
173 int
174 vsnprintf(char *bf, size_t size, const char *fmt, va_list ap)
175 {
176     int retval;
177
178     if (size < 1)
179         return (-1);
180
181     retval = kprintf(bf, size, fmt, ap, TOBUFONLY);
182     if (retval < size) {
183         bf[retval] = '\0'; /* null terminate */
184     }
185     return (retval);
186 }
187
188 /*
189  * kprintf: scaled down version of printf(3).
190  *
191  * this version based on vfprintf() from libc which was derived from
192  * software contributed to Berkeley by Chris Torek.
193  *
194  * NOTE: The kprintf mutex must be held if we're going TOBUF or TOCONS!
195  */
196
197 /* XXX: legacy types needed by kprintf. don't use these for new code */
198 typedef signed long long    quad_t;
199 typedef unsigned long long  u_quad_t;
200
201 /*
202  * macros for converting digits to letters and vice versa
203  */
204 #define to_digit(c)     ((c) - '0')
205 #define is_digit(c)     ((unsigned)to_digit(c) <= 9)
206 #define to_char(n)      ((n) + '0')
207
208 /*
209  * flags used during conversion.
210  */
211 #define ALT             0x001   /* alternate form */
212 #define HEXPREFIX       0x002   /* add 0x or 0X prefix */
213 #define LADJUST         0x004   /* left adjustment */
214 #define LONGDBL         0x008   /* long double; unimplemented */
215 #define LONGINT         0x010   /* long integer */
216 #define QUADINT         0x020   /* quad integer */
217 #define SHORTINT        0x040   /* short integer */
218 #define MAXINT          0x080   /* intmax_t */
219 #define PTRINT          0x100   /* intptr_t */
220 #define SIZEINT         0x200   /* size_t */
221 #define ZEROPAD         0x400   /* zero (as opposed to blank) pad */
222 #define FPT             0x800   /* Floating point number */
223
224 /*
225  * To extend shorts properly, we need both signed and unsigned
226  * argument extraction methods.
227  */
228 #define SARG()                                          \
229   (flags&MAXINT ? va_arg(ap, intmax_t) :                \
230    flags&PTRINT ? va_arg(ap, intptr_t) :                \
231    flags&SIZEINT ? va_arg(ap, ssize_t) : /* XXX */      \
232    flags&QUADINT ? va_arg(ap, quad_t) :                 \
233    flags&LONGINT ? va_arg(ap, long) :                   \
234    flags&SHORTINT ? (long)(short)va_arg(ap, int) :      \
235    (long)va_arg(ap, int))
236 #define UARG()                                          \
237   (flags&MAXINT ? va_arg(ap, uintmax_t) :               \
238    flags&PTRINT ? va_arg(ap, uintptr_t) :               \
239    flags&SIZEINT ? va_arg(ap, size_t) :                 \
240    flags&QUADINT ? va_arg(ap, u_quad_t) :               \
241    flags&LONGINT ? va_arg(ap, u_long) :                 \
242    flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) :  \
243    (u_long)va_arg(ap, u_int))
244
245 #define KPRINTF_PUTCHAR(C) {                            \
246     if (oflags == TOBUFONLY) {                          \
247         if (sbuf == tailp) {                            \
248             ret += 1;           /* indicate error */    \
249             goto overflow;                              \
250         } else {                                        \
251             *sbuf++ = (C);                              \
252         }                                               \
253     } else {                                            \
254         kputchar((C));                                  \
255     }                                                   \
256   }
257
258 /*
259  * Guts of kernel printf.  Note, we already expect to be in a mutex!
260  */
261 static int
262 kprintf(char *sbuf_in, size_t bufsize, const char *fmt0, va_list ap, int oflags)
263 { TRUSTEDBLOCK
264     char *sbuf = sbuf_in;       /* XXX: make deputy happy */
265     const char *fmt;            /* format string */
266     int ch;                     /* character from fmt */
267     int n;                      /* handy integer (short term usage) */
268     char * TRUSTED cp;          /* handy char pointer (short term usage) */
269     int flags;                  /* flags as above */
270     int ret;                    /* return value accumulator */
271     int width;                  /* width from format (%8d), or 0 */
272     int prec;                   /* precision from format (%.3d), or -1 */
273     char sign;                  /* sign prefix (' ', '+', '-', or \0) */
274
275     u_quad_t _uquad;            /* integer arguments %[diouxX] */
276     enum { OCT, DEC, HEX } base;        /* base for [diouxX] conversion */
277     int dprec;                  /* a copy of prec if [diouxX], 0 otherwise */
278     int realsz;                 /* field size expanded by dprec */
279     int size;                   /* size of converted field or string */
280     const char *xdigs;          /* digits for [xX] conversion */
281     char bf[KPRINTF_BUFSIZE];   /* space for %c, %[diouxX] */
282     char *tailp;                /* tail pointer for snprintf */
283
284     tailp = NULL;               /* XXX: shutup gcc */
285
286 /*
287  * XXX: somehow this does not work on k1om
288  */
289 #ifndef __k1om__
290     if (oflags == TOBUFONLY)
291         tailp = &sbuf[bufsize];
292 #endif
293     n = 0;                      /* XXX: shutup gcc */
294     cp = NULL;                  /* XXX: shutup gcc */
295     size = 0;                   /* XXX: shutup gcc */
296
297     fmt = fmt0;
298     ret = 0;
299
300     xdigs = NULL;               /* XXX: shut up gcc warning */
301
302     /*
303      * Scan the format for conversions (`%' character).
304      */
305     for (;;) {
306         while (*fmt != '%' && *fmt) {
307             ret++;
308             KPRINTF_PUTCHAR(*fmt++);
309         }
310         if (*fmt == 0)
311             goto done;
312
313         fmt++;                  /* skip over '%' */
314
315         flags = 0;
316         dprec = 0;
317         width = 0;
318         prec = -1;
319         sign = '\0';
320
321       rflag:
322         ch = *fmt++;
323       reswitch:
324         switch (ch) {
325         case ' ':
326             /*
327              * ``If the space and + flags both appear, the space
328              * flag will be ignored.''
329              *        -- ANSI X3J11
330              */
331             if (!sign)
332                 sign = ' ';
333             goto rflag;
334         case '#':
335             flags |= ALT;
336             goto rflag;
337         case '*':
338             /*
339              * ``A negative field width argument is taken as a
340              * - flag followed by a positive field width.''
341              *        -- ANSI X3J11
342              * They don't exclude field widths read from args.
343              */
344             if ((width = va_arg(ap, int)) >= 0)
345                  goto rflag;
346             width = -width;
347             /* FALLTHROUGH */
348         case '-':
349             flags |= LADJUST;
350             goto rflag;
351         case '+':
352             sign = '+';
353             goto rflag;
354         case '.':
355             if ((ch = *fmt++) == '*') {
356                 n = va_arg(ap, int);
357                 prec = n < 0 ? -1 : n;
358                 goto rflag;
359             }
360             n = 0;
361             while (is_digit(ch)) {
362                 n = 10 * n + to_digit(ch);
363                 ch = *fmt++;
364             }
365             prec = n < 0 ? -1 : n;
366             goto reswitch;
367         case '0':
368             /*
369              * ``Note that 0 is taken as a flag, not as the
370              * beginning of a field width.''
371              *        -- ANSI X3J11
372              */
373             flags |= ZEROPAD;
374             goto rflag;
375         case '1':
376         case '2':
377         case '3':
378         case '4':
379         case '5':
380         case '6':
381         case '7':
382         case '8':
383         case '9':
384             n = 0;
385             do {
386                 n = 10 * n + to_digit(ch);
387                 ch = *fmt++;
388             } while (is_digit(ch));
389             width = n;
390             goto reswitch;
391         case 'h':
392             flags |= SHORTINT;
393             goto rflag;
394         case 'j':
395             flags |= MAXINT;
396             goto rflag;
397         case 'l':
398             if (*fmt == 'l') {
399                 fmt++;
400                 flags |= QUADINT;
401             } else {
402                 flags |= LONGINT;
403             }
404             goto rflag;
405         case 'q':
406             flags |= QUADINT;
407             goto rflag;
408         case 't':
409             flags |= PTRINT;
410             goto rflag;
411         case 'z':
412             flags |= SIZEINT;
413             goto rflag;
414         case 'c':
415             *(cp = bf) = va_arg(ap, int);
416             size = 1;
417             sign = '\0';
418             break;
419         case 'D':
420             flags |= LONGINT;
421          /*FALLTHROUGH*/ case 'd':
422         case 'i':
423             _uquad = SARG();
424             if ((quad_t) _uquad < 0) {
425                 _uquad = -_uquad;
426                 sign = '-';
427             }
428             base = DEC;
429             goto number;
430         case 'n':
431             if (flags & MAXINT)
432                 *va_arg(ap, intmax_t *) = ret;
433             else if (flags & PTRINT)
434                 *va_arg(ap, intptr_t *) = ret;
435             else if (flags & SIZEINT)
436                 *va_arg(ap, ssize_t *) = ret;
437             else if (flags & QUADINT)
438                 *va_arg(ap, quad_t *) = ret;
439             else if (flags & LONGINT)
440                 *va_arg(ap, long *) = ret;
441             else if (flags & SHORTINT)
442                 *va_arg(ap, short *) = ret;
443             else
444                 *va_arg(ap, int *) = ret;
445             continue;           /* no output */
446         case 'O':
447             flags |= LONGINT;
448          /*FALLTHROUGH*/ case 'o':
449             _uquad = UARG();
450             base = OCT;
451             goto nosign;
452         case 'p':
453             /*
454              * ``The argument shall be a pointer to void.  The
455              * value of the pointer is converted to a sequence
456              * of printable characters, in an implementation-
457              * defined manner.''
458              *        -- ANSI X3J11
459              */
460             /* NOSTRICT */
461             _uquad = (u_long) va_arg(ap, void *);
462             base = HEX;
463             xdigs = hexdigits;
464             flags |= HEXPREFIX;
465             ch = 'x';
466             goto nosign;
467         case 's':
468             cp = va_arg(ap, char *);
469             if (cp == NULL)
470                 /*XXXUNCONST*/ cp = "(null)";
471             if (prec >= 0) {
472                 /*
473                  * can't use strlen; can only look for the
474                  * NUL in the first `prec' characters, and
475                  * strlen() will go further.
476                  */
477                 const char *p = memchr(cp, 0, prec);
478
479                 if (p != NULL) {
480                     size = TC(p) - cp;
481                     if (size > prec)
482                         size = prec;
483                 } else
484                     size = prec;
485             } else
486                 size = strlen(cp);
487             sign = '\0';
488             break;
489         case 'U':
490             flags |= LONGINT;
491          /*FALLTHROUGH*/ case 'u':
492             _uquad = UARG();
493             base = DEC;
494             goto nosign;
495         case 'X':
496             xdigs = HEXDIGITS;
497             goto hex;
498         case 'x':
499             xdigs = hexdigits;
500           hex:_uquad = UARG();
501             base = HEX;
502             /* leading 0x/X only if non-zero */
503             if (flags & ALT && _uquad != 0)
504                 flags |= HEXPREFIX;
505
506             /* unsigned conversions */
507           nosign:sign = '\0';
508             /*
509              * ``... diouXx conversions ... if a precision is
510              * specified, the 0 flag will be ignored.''
511              *        -- ANSI X3J11
512              */
513           number:if ((dprec = prec) >= 0)
514                 flags &= ~ZEROPAD;
515
516             /*
517              * ``The result of converting a zero value with an
518              * explicit precision of zero is no characters.''
519              *        -- ANSI X3J11
520              */
521             cp = bf + KPRINTF_BUFSIZE;
522             if (_uquad != 0 || prec != 0) {
523                 /*
524                  * Unsigned mod is hard, and unsigned mod
525                  * by a constant is easier than that by
526                  * a variable; hence this switch.
527                  */
528                 switch (base) {
529                 case OCT:
530                     do {
531                         *--cp = to_char(_uquad & 7);
532                         _uquad >>= 3;
533                     } while (_uquad);
534                     /* handle octal leading 0 */
535                     if (flags & ALT && *cp != '0')
536                         *--cp = '0';
537                     break;
538
539                 case DEC:
540                     /* many numbers are 1 digit */
541                     while (_uquad >= 10) {
542                         *--cp = to_char(_uquad % 10);
543                         _uquad /= 10;
544                     }
545                     *--cp = to_char(_uquad);
546                     break;
547
548                 case HEX:
549                     do {
550                         *--cp = xdigs[_uquad & 15];
551                         _uquad >>= 4;
552                     } while (_uquad);
553                     break;
554
555                 default:
556                      /*XXXUNCONST*/ cp = "bug in kprintf: bad base";
557                     size = strlen(cp);
558                     goto skipsize;
559                 }
560             }
561             size = TC(bf) + KPRINTF_BUFSIZE - cp;
562           skipsize:
563             break;
564         default:               /* "%?" prints ?, unless ? is NUL */
565             if (ch == '\0')
566                 goto done;
567             /* pretend it was %c with argument ch */
568             cp = bf;
569             *cp = ch;
570             size = 1;
571             sign = '\0';
572             break;
573         }
574
575         /*
576          * All reasonable formats wind up here.  At this point, `cp'
577          * points to a string which (if not flags&LADJUST) should be
578          * padded out to `width' places.  If flags&ZEROPAD, it should
579          * first be prefixed by any sign or other prefix; otherwise,
580          * it should be blank padded before the prefix is emitted.
581          * After any left-hand padding and prefixing, emit zeroes
582          * required by a decimal [diouxX] precision, then print the
583          * string proper, then emit zeroes required by any leftover
584          * floating precision; finally, if LADJUST, pad with blanks.
585          *
586          * Compute actual size, so we know how much to pad.
587          * size excludes decimal prec; realsz includes it.
588          */
589         realsz = dprec > size ? dprec : size;
590         if (sign)
591             realsz++;
592         else if (flags & HEXPREFIX)
593             realsz += 2;
594
595         /* adjust ret */
596         ret += width > realsz ? width : realsz;
597
598         /* right-adjusting blank padding */
599         if ((flags & (LADJUST | ZEROPAD)) == 0) {
600             n = width - realsz;
601             while (n-- > 0)
602                 KPRINTF_PUTCHAR(' ');
603         }
604
605         /* prefix */
606         if (sign) {
607             KPRINTF_PUTCHAR(sign);
608         } else if (flags & HEXPREFIX) {
609             KPRINTF_PUTCHAR('0');
610             KPRINTF_PUTCHAR(ch);
611         }
612
613         /* right-adjusting zero padding */
614         if ((flags & (LADJUST | ZEROPAD)) == ZEROPAD) {
615             n = width - realsz;
616             while (n-- > 0)
617                 KPRINTF_PUTCHAR('0');
618         }
619
620         /* leading zeroes from decimal precision */
621         n = dprec - size;
622         while (n-- > 0)
623             KPRINTF_PUTCHAR('0');
624
625         /* the string or number proper */
626         while (size--)
627             KPRINTF_PUTCHAR(*cp++);
628         /* left-adjusting padding (always blank) */
629         if (flags & LADJUST) {
630             n = width - realsz;
631             while (n-- > 0)
632                 KPRINTF_PUTCHAR(' ');
633         }
634     }
635
636   done:
637     /*    (*v_flush)(); */
638   overflow:
639     return (ret);
640     /* NOTREACHED */
641 }