root/kernel/printf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. printint
  2. printptr
  3. printf
  4. panic
  5. printfinit

   1 //
   2 // formatted console output -- printf, panic.
   3 //
   4 
   5 #include <stdarg.h>
   6 
   7 #include "types.h"
   8 #include "param.h"
   9 #include "spinlock.h"
  10 #include "sleeplock.h"
  11 #include "fs.h"
  12 #include "file.h"
  13 #include "memlayout.h"
  14 #include "riscv.h"
  15 #include "defs.h"
  16 #include "proc.h"
  17 
  18 volatile int panicked = 0;
  19 
  20 // lock to avoid interleaving concurrent printf's.
  21 static struct {
  22   struct spinlock lock;
  23   int locking;
  24 } pr;
  25 
  26 static char digits[] = "0123456789abcdef";
  27 
  28 static void
  29 printint(long long xx, int base, int sign)
  30 {
  31   char buf[16];
  32   int i;
  33   unsigned long long x;
  34 
  35   if(sign && (sign = (xx < 0)))
  36     x = -xx;
  37   else
  38     x = xx;
  39 
  40   i = 0;
  41   do {
  42     buf[i++] = digits[x % base];
  43   } while((x /= base) != 0);
  44 
  45   if(sign)
  46     buf[i++] = '-';
  47 
  48   while(--i >= 0)
  49     consputc(buf[i]);
  50 }
  51 
  52 static void
  53 printptr(uint64 x)
  54 {
  55   int i;
  56   consputc('0');
  57   consputc('x');
  58   for (i = 0; i < (sizeof(uint64) * 2); i++, x <<= 4)
  59     consputc(digits[x >> (sizeof(uint64) * 8 - 4)]);
  60 }
  61 
  62 // Print to the console.
  63 int
  64 printf(char *fmt, ...)
  65 {
  66   va_list ap;
  67   int i, cx, c0, c1, c2, locking;
  68   char *s;
  69 
  70   locking = pr.locking;
  71   if(locking)
  72     acquire(&pr.lock);
  73 
  74   va_start(ap, fmt);
  75   for(i = 0; (cx = fmt[i] & 0xff) != 0; i++){
  76     if(cx != '%'){
  77       consputc(cx);
  78       continue;
  79     }
  80     i++;
  81     c0 = fmt[i+0] & 0xff;
  82     c1 = c2 = 0;
  83     if(c0) c1 = fmt[i+1] & 0xff;
  84     if(c1) c2 = fmt[i+2] & 0xff;
  85     if(c0 == 'd'){
  86       printint(va_arg(ap, int), 10, 1);
  87     } else if(c0 == 'l' && c1 == 'd'){
  88       printint(va_arg(ap, uint64), 10, 1);
  89       i += 1;
  90     } else if(c0 == 'l' && c1 == 'l' && c2 == 'd'){
  91       printint(va_arg(ap, uint64), 10, 1);
  92       i += 2;
  93     } else if(c0 == 'u'){
  94       printint(va_arg(ap, int), 10, 0);
  95     } else if(c0 == 'l' && c1 == 'u'){
  96       printint(va_arg(ap, uint64), 10, 0);
  97       i += 1;
  98     } else if(c0 == 'l' && c1 == 'l' && c2 == 'u'){
  99       printint(va_arg(ap, uint64), 10, 0);
 100       i += 2;
 101     } else if(c0 == 'x'){
 102       printint(va_arg(ap, int), 16, 0);
 103     } else if(c0 == 'l' && c1 == 'x'){
 104       printint(va_arg(ap, uint64), 16, 0);
 105       i += 1;
 106     } else if(c0 == 'l' && c1 == 'l' && c2 == 'x'){
 107       printint(va_arg(ap, uint64), 16, 0);
 108       i += 2;
 109     } else if(c0 == 'p'){
 110       printptr(va_arg(ap, uint64));
 111     } else if(c0 == 's'){
 112       if((s = va_arg(ap, char*)) == 0)
 113         s = "(null)";
 114       for(; *s; s++)
 115         consputc(*s);
 116     } else if(c0 == '%'){
 117       consputc('%');
 118     } else if(c0 == 0){
 119       break;
 120     } else {
 121       // Print unknown % sequence to draw attention.
 122       consputc('%');
 123       consputc(c0);
 124     }
 125 
 126 #if 0
 127     switch(c){
 128     case 'd':
 129       printint(va_arg(ap, int), 10, 1);
 130       break;
 131     case 'x':
 132       printint(va_arg(ap, int), 16, 1);
 133       break;
 134     case 'p':
 135       printptr(va_arg(ap, uint64));
 136       break;
 137     case 's':
 138       if((s = va_arg(ap, char*)) == 0)
 139         s = "(null)";
 140       for(; *s; s++)
 141         consputc(*s);
 142       break;
 143     case '%':
 144       consputc('%');
 145       break;
 146     default:
 147       // Print unknown % sequence to draw attention.
 148       consputc('%');
 149       consputc(c);
 150       break;
 151     }
 152 #endif
 153   }
 154   va_end(ap);
 155 
 156   if(locking)
 157     release(&pr.lock);
 158 
 159   return 0;
 160 }
 161 
 162 void
 163 panic(char *s)
 164 {
 165   pr.locking = 0;
 166   printf("panic: ");
 167   printf("%s\n", s);
 168   panicked = 1; // freeze uart output from other CPUs
 169   for(;;)
 170     ;
 171 }
 172 
 173 void
 174 printfinit(void)
 175 {
 176   initlock(&pr.lock, "pr");
 177   pr.locking = 1;
 178 }

/* [<][>][^][v][top][bottom][index][help] */