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 panicking = 0; // printing a panic message
  19 volatile int panicked = 0; // spinning forever at end of a panic
  20 
  21 // lock to avoid interleaving concurrent printf's.
  22 static struct {
  23   struct spinlock lock;
  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[20];
  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;
  68   char *s;
  69 
  70   if(panicking == 0)
  71     acquire(&pr.lock);
  72 
  73   va_start(ap, fmt);
  74   for(i = 0; (cx = fmt[i] & 0xff) != 0; i++){
  75     if(cx != '%'){
  76       consputc(cx);
  77       continue;
  78     }
  79     i++;
  80     c0 = fmt[i+0] & 0xff;
  81     c1 = c2 = 0;
  82     if(c0) c1 = fmt[i+1] & 0xff;
  83     if(c1) c2 = fmt[i+2] & 0xff;
  84     if(c0 == 'd'){
  85       printint(va_arg(ap, int), 10, 1);
  86     } else if(c0 == 'l' && c1 == 'd'){
  87       printint(va_arg(ap, uint64), 10, 1);
  88       i += 1;
  89     } else if(c0 == 'l' && c1 == 'l' && c2 == 'd'){
  90       printint(va_arg(ap, uint64), 10, 1);
  91       i += 2;
  92     } else if(c0 == 'u'){
  93       printint(va_arg(ap, uint32), 10, 0);
  94     } else if(c0 == 'l' && c1 == 'u'){
  95       printint(va_arg(ap, uint64), 10, 0);
  96       i += 1;
  97     } else if(c0 == 'l' && c1 == 'l' && c2 == 'u'){
  98       printint(va_arg(ap, uint64), 10, 0);
  99       i += 2;
 100     } else if(c0 == 'x'){
 101       printint(va_arg(ap, uint32), 16, 0);
 102     } else if(c0 == 'l' && c1 == 'x'){
 103       printint(va_arg(ap, uint64), 16, 0);
 104       i += 1;
 105     } else if(c0 == 'l' && c1 == 'l' && c2 == 'x'){
 106       printint(va_arg(ap, uint64), 16, 0);
 107       i += 2;
 108     } else if(c0 == 'p'){
 109       printptr(va_arg(ap, uint64));
 110     } else if(c0 == 'c'){
 111       consputc(va_arg(ap, uint));
 112     } else if(c0 == 's'){
 113       if((s = va_arg(ap, char*)) == 0)
 114         s = "(null)";
 115       for(; *s; s++)
 116         consputc(*s);
 117     } else if(c0 == '%'){
 118       consputc('%');
 119     } else if(c0 == 0){
 120       break;
 121     } else {
 122       // Print unknown % sequence to draw attention.
 123       consputc('%');
 124       consputc(c0);
 125     }
 126 
 127   }
 128   va_end(ap);
 129 
 130   if(panicking == 0)
 131     release(&pr.lock);
 132 
 133   return 0;
 134 }
 135 
 136 void
 137 panic(char *s)
 138 {
 139   panicking = 1;
 140   printf("panic: ");
 141   printf("%s\n", s);
 142   panicked = 1; // freeze uart output from other CPUs
 143   for(;;)
 144     ;
 145 }
 146 
 147 void
 148 printfinit(void)
 149 {
 150   initlock(&pr.lock, "pr");
 151 }

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