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(int xx, int base, int sign)
  30 {
  31   char buf[16];
  32   int i;
  33   uint 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. only understands %d, %x, %p, %s.
  63 void
  64 printf(char *fmt, ...)
  65 {
  66   va_list ap;
  67   int i, c, locking;
  68   char *s;
  69 
  70   locking = pr.locking;
  71   if(locking)
  72     acquire(&pr.lock);
  73 
  74   if (fmt == 0)
  75     panic("null fmt");
  76 
  77   va_start(ap, fmt);
  78   for(i = 0; (c = fmt[i] & 0xff) != 0; i++){
  79     if(c != '%'){
  80       consputc(c);
  81       continue;
  82     }
  83     c = fmt[++i] & 0xff;
  84     if(c == 0)
  85       break;
  86     switch(c){
  87     case 'd':
  88       printint(va_arg(ap, int), 10, 1);
  89       break;
  90     case 'x':
  91       printint(va_arg(ap, int), 16, 1);
  92       break;
  93     case 'p':
  94       printptr(va_arg(ap, uint64));
  95       break;
  96     case 's':
  97       if((s = va_arg(ap, char*)) == 0)
  98         s = "(null)";
  99       for(; *s; s++)
 100         consputc(*s);
 101       break;
 102     case '%':
 103       consputc('%');
 104       break;
 105     default:
 106       // Print unknown % sequence to draw attention.
 107       consputc('%');
 108       consputc(c);
 109       break;
 110     }
 111   }
 112   va_end(ap);
 113 
 114   if(locking)
 115     release(&pr.lock);
 116 }
 117 
 118 void
 119 panic(char *s)
 120 {
 121   pr.locking = 0;
 122   printf("panic: ");
 123   printf(s);
 124   printf("\n");
 125   panicked = 1; // freeze uart output from other CPUs
 126   for(;;)
 127     ;
 128 }
 129 
 130 void
 131 printfinit(void)
 132 {
 133   initlock(&pr.lock, "pr");
 134   pr.locking = 1;
 135 }

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