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/ddb/db_output.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 /*
    2  * Mach Operating System
    3  * Copyright (c) 1991,1990 Carnegie Mellon University
    4  * All Rights Reserved.
    5  *
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  *
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  *
   16  * Carnegie Mellon requests users of this software to return to
   17  *
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  *
   23  * any improvements or extensions that they make and grant Carnegie the
   24  * rights to redistribute these changes.
   25  *
   26  * $FreeBSD: src/sys/ddb/db_output.c,v 1.26 1999/08/28 00:41:09 peter Exp $
   27  */
   28 
   29 /*
   30  *      Author: David B. Golub, Carnegie Mellon University
   31  *      Date:   7/90
   32  */
   33 
   34 /*
   35  * Printf and character output for debugger.
   36  */
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/cons.h>
   41 #include <sys/ctype.h>
   42 #include <sys/thread2.h>
   43 #include <sys/spinlock2.h>
   44 
   45 #include <machine/stdarg.h>
   46 
   47 #include <ddb/ddb.h>
   48 #include <ddb/db_output.h>
   49 
   50 /*
   51  *      Character output - tracks position in line.
   52  *      To do this correctly, we should know how wide
   53  *      the output device is - then we could zero
   54  *      the line position when the output device wraps
   55  *      around to the start of the next line.
   56  *
   57  *      Instead, we count the number of spaces printed
   58  *      since the last printing character so that we
   59  *      don't print trailing spaces.  This avoids most
   60  *      of the wraparounds.
   61  */
   62 static int      db_output_position = 0;         /* output column */
   63 static int      db_last_non_space = 0;          /* last non-space character */
   64 db_expr_t       db_tab_stop_width = 8;          /* how wide are tab stops? */
   65 #define NEXT_TAB(i) \
   66         ((((i) + db_tab_stop_width) / db_tab_stop_width) * db_tab_stop_width)
   67 db_expr_t       db_max_width = 79;              /* output line width */
   68 
   69 static void db_putchar (int c, void *arg);
   70 
   71 /*
   72  * Force pending whitespace.
   73  */
   74 void
   75 db_force_whitespace(void)
   76 {
   77         int last_print, next_tab;
   78 
   79         last_print = db_last_non_space;
   80         while (last_print < db_output_position) {
   81             next_tab = NEXT_TAB(last_print);
   82             if (next_tab <= db_output_position) {
   83                 while (last_print < next_tab) { /* DON'T send a tab!!! */
   84                         cnputc(' ');
   85                         last_print++;
   86                 }
   87             }
   88             else {
   89                 cnputc(' ');
   90                 last_print++;
   91             }
   92         }
   93         db_last_non_space = db_output_position;
   94 }
   95 
   96 /*
   97  * Output character.  Buffer whitespace.
   98  *
   99  * Parameters:
  100  *     arg:     character to output
  101  */
  102 static void
  103 db_putchar(int c, void *arg)
  104 {
  105         /*
  106          * If not in the debugger, output data to both the console and
  107          * the message buffer.
  108          */
  109         if (!db_active) {
  110                 if (c == '\r' || c == '\n' || c == '\t' ||
  111                     isprint(c)) {
  112                         kprintf("%c", c);
  113                 } else {
  114                         kprintf("?");
  115                 }
  116                 if (!db_active)
  117                         return;
  118                 if (c == '\r' || c == '\n')
  119                         db_check_interrupt();
  120                 return;
  121         }
  122 
  123         crit_enter_hard();
  124 
  125         if (c > ' ' && c <= '~') {
  126             /*
  127              * Printing character.
  128              * If we have spaces to print, print them first.
  129              * Use tabs if possible.
  130              */
  131             db_force_whitespace();
  132             cnputc(c);
  133             db_output_position++;
  134             db_last_non_space = db_output_position;
  135         }
  136         else if (c == '\n') {
  137             /* Newline */
  138             cnputc(c);
  139             db_output_position = 0;
  140             db_last_non_space = 0;
  141             db_check_interrupt();
  142         }
  143         else if (c == '\r') {
  144             /* Return */
  145             cnputc(c);
  146             db_output_position = 0;
  147             db_last_non_space = 0;
  148             db_check_interrupt();
  149         }
  150         else if (c == '\t') {
  151             /* assume tabs every 8 positions */
  152             db_output_position = NEXT_TAB(db_output_position);
  153         }
  154         else if (c == ' ') {
  155             /* space */
  156             db_output_position++;
  157         }
  158         else if (c == '\007') {
  159             /* bell */
  160             cnputc(c);
  161         }
  162         /* other characters are assumed non-printing */
  163         crit_exit_hard();
  164 }
  165 
  166 /*
  167  * Return output position
  168  */
  169 int
  170 db_print_position(void)
  171 {
  172         return (db_output_position);
  173 }
  174 
  175 /*
  176  * Printing
  177  *
  178  * NOTE: We bypass subr_prf's cons_spin here by using our own putchar
  179  *       function.
  180  */
  181 void
  182 db_printf(const char *fmt, ...)
  183 {
  184         __va_list listp;
  185 
  186         __va_start(listp, fmt);
  187         kvcprintf (fmt, db_putchar, NULL, db_radix, listp);
  188         __va_end(listp);
  189 /*      DELAY(100000);*/
  190 }
  191 
  192 void
  193 db_vprintf(const char *fmt, __va_list va)
  194 {
  195         kvcprintf (fmt, db_putchar, NULL, db_radix, va);
  196 /*      DELAY(100000);*/
  197 }
  198 
  199 int db_indent;
  200 
  201 void
  202 db_iprintf(const char *fmt,...)
  203 {
  204         int i;
  205         __va_list listp;
  206 
  207         for (i = db_indent; i >= 8; i -= 8)
  208                 db_printf("\t");
  209         while (--i >= 0)
  210                 db_printf(" ");
  211         __va_start(listp, fmt);
  212         kvcprintf (fmt, db_putchar, NULL, db_radix, listp);
  213         __va_end(listp);
  214 }
  215 
  216 /*
  217  * End line if too long.
  218  */
  219 void
  220 db_end_line(int field_width)
  221 {
  222         if (db_output_position + field_width > db_max_width)
  223             db_printf("\n");
  224 }
  225 
  226 /*
  227  * Simple pager
  228  */
  229 int
  230 db_more(int *nl)
  231 {
  232         ++*nl;
  233         if (*nl == 20) {
  234                 int c;
  235 
  236                 db_printf("--More--");
  237                 c = cngetc();
  238                 db_printf("\r");
  239                 /*
  240                  * A whole screenfull or just one line?
  241                  */
  242                 switch (c) {
  243                 case '\n':              /* just one line */
  244                         *nl = 19;
  245                         break;
  246                 case ' ':
  247                         *nl = 0;        /* another screenfull */
  248                         break;
  249                 default:                /* exit */
  250                         db_printf("\n");
  251                         return(-1);
  252                 }
  253         }
  254         return(0);
  255 }
  256 
  257 /*
  258  * Replacement for old '%z' kprintf format.
  259  */
  260 void
  261 db_format_hex(char *buf, size_t bufsiz, quad_t val, int altflag)
  262 {
  263         /* Only use alternate form if val is nonzero. */
  264         const char *fmt = (altflag && val) ? "-%#qx" : "-%qx";
  265 
  266         if (val < 0)
  267                 val = -val;
  268         else
  269                 ++fmt;
  270 
  271         ksnprintf(buf, bufsiz, fmt, val);
  272 }
  273 
  274 /* #define TEMPORARY_DEBUGGING */
  275 #ifdef TEMPORARY_DEBUGGING
  276 
  277 /*
  278  * Temporary Debugging, only turned on manually by kernel hackers trying
  279  * to debug extremely low level code.  Adjust PCHAR_ as required.
  280  */
  281 static void PCHAR_(int, void * __unused);
  282 
  283 void
  284 kprintf0(const char *fmt, ...)
  285 {
  286         __va_list ap;
  287 
  288         __va_start(ap, fmt);
  289         kvcprintf(fmt, PCHAR_, NULL, 10, ap);
  290         __va_end(ap);
  291 }
  292 
  293 static void
  294 PCHAR_(int c, void *dummy __unused)
  295 {
  296         const int COMC_TXWAIT = 0x40000;
  297         const int COMPORT = 0x2f8;              /* 0x3f8 COM1, 0x2f8 COM2 */
  298         const int LSR_TXRDY = 0x20;
  299         const int BAUD = 9600;
  300         const int com_lsr = 5;
  301         const int com_data = 0;
  302         int wait;
  303         static int setbaud;
  304 
  305         if (setbaud == 0) {
  306                 setbaud = 1;
  307                 outb(COMPORT+3, 0x83);    /* DLAB + 8N1 */
  308                 outb(COMPORT+0, (115200 / BAUD) & 0xFF);
  309                 outb(COMPORT+1, (115200 / BAUD) >> 8);
  310                 outb(COMPORT+3, 0x03);    /* 8N1 */
  311                 outb(COMPORT+4, 0x03);    /* RTS+DTR */
  312                 outb(COMPORT+2, 0x01);    /* FIFO_ENABLE */
  313         }
  314 
  315         for (wait = COMC_TXWAIT; wait > 0; wait--) {
  316                 if (inb(COMPORT + com_lsr) & LSR_TXRDY) {
  317                         outb(COMPORT + com_data, (u_char)c);
  318                         break;
  319                 }
  320         }
  321 }
  322 
  323 #endif

Cache object: 2950533111f3d7609470d0a73fb1fbe1


[ 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.