The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kernel/utility.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* This file contains a collection of miscellaneous procedures:
    2  *   panic:         abort MINIX due to a fatal error
    3  *   kprintf:       diagnostic output for the kernel 
    4  *
    5  * Changes:
    6  *   Dec 10, 2004   kernel printing to circular buffer  (Jorrit N. Herder)
    7  * 
    8  * This file contains the routines that take care of kernel messages, i.e.,
    9  * diagnostic output within the kernel. Kernel messages are not directly
   10  * displayed on the console, because this must be done by the output driver. 
   11  * Instead, the kernel accumulates characters in a buffer and notifies the
   12  * output driver when a new message is ready. 
   13  */
   14 
   15 #include <minix/com.h>
   16 #include "kernel.h"
   17 #include <stdarg.h>
   18 #include <unistd.h>
   19 #include <stddef.h>
   20 #include <stdlib.h>
   21 #include <signal.h>
   22 #include "proc.h"
   23 
   24 #define END_OF_KMESS    -1
   25 FORWARD _PROTOTYPE(void kputc, (int c));
   26 FORWARD _PROTOTYPE( void ser_putc, (char c));
   27 
   28 /*===========================================================================*
   29  *                              panic                                        *
   30  *===========================================================================*/
   31 PUBLIC void panic(mess,nr)
   32 _CONST char *mess;
   33 int nr;
   34 {
   35 /* The system has run aground of a fatal kernel error. Terminate execution. */
   36   static int panicking = 0;
   37   if (panicking ++) return;             /* prevent recursive panics */
   38 
   39   if (mess != NULL) {
   40         kprintf("\nKernel panic: %s", mess);
   41         if (nr != NO_NUM) kprintf(" %d", nr);
   42         kprintf("\n",NO_NUM);
   43   }
   44 
   45   /* Abort MINIX. */
   46   prepare_shutdown(RBT_PANIC);
   47 }
   48 
   49 /*===========================================================================*
   50  *                              kprintf                                      *
   51  *===========================================================================*/
   52 PUBLIC void kprintf(const char *fmt, ...)       /* format to be printed */
   53 {
   54   int c;                                        /* next character in fmt */
   55   int d;
   56   unsigned long u;                              /* hold number argument */
   57   int base;                                     /* base of number arg */
   58   int negative;                                 /* print minus sign */
   59   static char x2c[] = "0123456789ABCDEF";       /* nr conversion table */
   60   char ascii[8 * sizeof(long) / 3 + 2];         /* string for ascii number */
   61   char *s;                                      /* string to be printed */
   62   va_list argp;                                 /* optional arguments */
   63   
   64   va_start(argp, fmt);                          /* init variable arguments */
   65 
   66   while((c=*fmt++) != 0) {
   67 
   68       if (c == '%') {                           /* expect format '%key' */
   69           negative = 0;                         /* (re)initialize */
   70           s = NULL;                             /* (re)initialize */
   71           switch(c = *fmt++) {                  /* determine what to do */
   72 
   73           /* Known keys are %d, %u, %x, %s, and %%. This is easily extended 
   74            * with number types like %b and %o by providing a different base.
   75            * Number type keys don't set a string to 's', but use the general
   76            * conversion after the switch statement.
   77            */ 
   78           case 'd':                             /* output decimal */
   79               d = va_arg(argp, signed int);
   80               if (d < 0) { negative = 1; u = -d; }  else { u = d; }
   81               base = 10;
   82               break;
   83           case 'u':                             /* output unsigned long */
   84               u = va_arg(argp, unsigned long);
   85               base = 10;
   86               break;
   87           case 'x':                             /* output hexadecimal */
   88               u = va_arg(argp, unsigned long);
   89               base = 0x10;
   90               break;
   91           case 's':                             /* output string */
   92               s = va_arg(argp, char *);
   93               if (s == NULL) s = "(null)";
   94               break;
   95           case '%':                             /* output percent */
   96               s = "%";                           
   97               break;                    
   98 
   99           /* Unrecognized key. */
  100           default:                              /* echo back %key */
  101               s = "%?";                         
  102               s[1] = c;                         /* set unknown key */
  103           }
  104 
  105           /* Assume a number if no string is set. Convert to ascii. */
  106           if (s == NULL) {
  107               s = ascii + sizeof(ascii)-1;
  108               *s = 0;                   
  109               do {  *--s = x2c[(u % base)]; }   /* work backwards */
  110               while ((u /= base) > 0); 
  111           }
  112 
  113           /* This is where the actual output for format "%key" is done. */
  114           if (negative) kputc('-');             /* print sign if negative */
  115           while(*s != 0) { kputc(*s++); }       /* print string/ number */
  116       }
  117       else {
  118           kputc(c);                             /* print and continue */
  119       }
  120   }
  121   kputc(END_OF_KMESS);                          /* terminate output */
  122   va_end(argp);                                 /* end variable arguments */
  123 }
  124 
  125 /*===========================================================================*
  126  *                              kputc                                        *
  127  *===========================================================================*/
  128 PRIVATE void kputc(c)
  129 int c;                                  /* character to append */
  130 {
  131 /* Accumulate a single character for a kernel message. Send a notification
  132  * to the output driver if an END_OF_KMESS is encountered. 
  133  */
  134   if (c != END_OF_KMESS) {
  135       if (do_serial_debug)
  136         ser_putc(c);
  137       kmess.km_buf[kmess.km_next] = c;  /* put normal char in buffer */
  138       if (kmess.km_size < KMESS_BUF_SIZE)
  139           kmess.km_size += 1;           
  140       kmess.km_next = (kmess.km_next + 1) % KMESS_BUF_SIZE;
  141   } else {
  142       int p, outprocs[] = OUTPUT_PROCS_ARRAY;
  143       for(p = 0; outprocs[p] != NONE; p++) {
  144          send_sig(outprocs[p], SIGKMESS);
  145       }
  146   }
  147 }
  148 
  149 #define COM1_BASE       0x3F8
  150 #define COM1_THR        (COM1_BASE + 0)
  151 #define   LSR_THRE      0x20
  152 #define COM1_LSR        (COM1_BASE + 5)
  153 
  154 PRIVATE void ser_putc(char c)
  155 {
  156         int i;
  157         int lsr, thr;
  158 
  159         return;
  160 
  161         lsr= COM1_LSR;
  162         thr= COM1_THR;
  163         for (i= 0; i<100000; i++)
  164         {
  165                 if (inb(lsr) & LSR_THRE)
  166                         break;
  167         }
  168         outb(thr, c);
  169 }

Cache object: fc5f53230629ba6ab6047fa691ef0407


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.