[BACK]Return to debug.c CVS log [TXT][DIR] Up to [local] / prex / sys / kern

Annotation of prex/sys/kern/debug.c, Revision 1.1.1.1

1.1       nbrk        1: /*-
                      2:  * Copyright (c) 2005-2008, Kohsuke Ohtani
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. Neither the name of the author nor the names of any co-contributors
                     14:  *    may be used to endorse or promote products derived from this software
                     15:  *    without specific prior written permission.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     18:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     19:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     20:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     21:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     22:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     23:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     24:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     25:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     26:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     27:  * SUCH DAMAGE.
                     28:  */
                     29:
                     30: /*
                     31:  * debug.c - kernel debug services
                     32:  */
                     33:
                     34: #include <kernel.h>
                     35: #include <task.h>
                     36: #include <thread.h>
                     37: #include <vm.h>
                     38: #include <irq.h>
                     39:
                     40: #ifdef DEBUG
                     41:
                     42: /*
                     43:  * diag_print() is provided by architecture dependent layer.
                     44:  */
                     45: typedef void (*prtfn_t)(char *);
                     46: static prtfn_t print_func = &diag_print;
                     47:
                     48: static char    dbg_msg[DBGMSG_SIZE];
                     49:
                     50: /*
                     51:  * dmesg support
                     52:  */
                     53: static char    log_buf[LOGBUF_SIZE];
                     54: static u_long  log_head;
                     55: static u_long  log_tail;
                     56: static u_long  log_len;
                     57:
                     58: #define LOGINDEX(x)    ((x) & (LOGBUF_SIZE - 1))
                     59:
                     60: /*
                     61:  * Print out the specified string.
                     62:  *
                     63:  * An actual output is displayed via the platform
                     64:  * specific device by diag_print() routine in kernel.
                     65:  * As an alternate option, the device driver can
                     66:  * replace the print routine by using debug_attach().
                     67:  */
                     68: void
                     69: printf(const char *fmt, ...)
                     70: {
                     71:        va_list args;
                     72:        int i;
                     73:        char c;
                     74:
                     75:        irq_lock();
                     76:        va_start(args, fmt);
                     77:
                     78:        vsprintf(dbg_msg, fmt, args);
                     79:
                     80:        /* Print out */
                     81:        (*print_func)(dbg_msg);
                     82:
                     83:        /*
                     84:         * Record to log buffer
                     85:         */
                     86:        for (i = 0; i < DBGMSG_SIZE; i++) {
                     87:                c = dbg_msg[i];
                     88:                if (c == '\0')
                     89:                        break;
                     90:                log_buf[LOGINDEX(log_tail)] = c;
                     91:                log_tail++;
                     92:                if (log_len < LOGBUF_SIZE)
                     93:                        log_len++;
                     94:                else
                     95:                        log_head = log_tail - LOGBUF_SIZE;
                     96:        }
                     97:        va_end(args);
                     98:        irq_unlock();
                     99: }
                    100:
                    101: /*
                    102:  * Kernel assertion.
                    103:  *
                    104:  * assert() is called only when the expression is false in
                    105:  * ASSERT() macro. ASSERT() macro is compiled only when
                    106:  * the debug option is enabled.
                    107:  */
                    108: void
                    109: assert(const char *file, int line, const char *exp)
                    110: {
                    111:
                    112:        irq_lock();
                    113:        printf("\nAssertion failed: %s line:%d '%s'\n", file, line, exp);
                    114:        BREAKPOINT();
                    115:        for (;;)
                    116:                machine_idle();
                    117:        /* NOTREACHED */
                    118: }
                    119:
                    120: /*
                    121:  * Kernel panic.
                    122:  *
                    123:  * panic() is called for a fatal kernel error. It shows
                    124:  * specified message, and stops CPU.
                    125:  */
                    126: void
                    127: panic(const char *msg)
                    128: {
                    129:
                    130:        irq_lock();
                    131:        printf("\nKernel panic: %s\n", msg);
                    132:        irq_unlock();
                    133:        BREAKPOINT();
                    134:        for (;;)
                    135:                machine_idle();
                    136:        /* NOTREACHED */
                    137: }
                    138:
                    139: /*
                    140:  * Copy log to user buffer.
                    141:  */
                    142: int
                    143: debug_getlog(char *buf)
                    144: {
                    145:        u_long i, len, index;
                    146:        int err = 0;
                    147:        char c;
                    148:
                    149:        irq_lock();
                    150:        index = log_head;
                    151:        len = log_len;
                    152:        if (len >= LOGBUF_SIZE) {
                    153:                /*
                    154:                 * Overrun found. Discard broken message.
                    155:                 */
                    156:                while (len > 0 && log_buf[LOGINDEX(index)] != '\n') {
                    157:                        index++;
                    158:                        len--;
                    159:                }
                    160:        }
                    161:        for (i = 0; i < LOGBUF_SIZE; i++) {
                    162:                if (i < len)
                    163:                        c = log_buf[LOGINDEX(index)];
                    164:                else
                    165:                        c = '\0';
                    166:                if (umem_copyout(&c, buf, 1)) {
                    167:                        err = EFAULT;
                    168:                        break;
                    169:                }
                    170:                index++;
                    171:                buf++;
                    172:        }
                    173:        irq_unlock();
                    174:        return err;
                    175: }
                    176:
                    177: /*
                    178:  * Dump system information.
                    179:  *
                    180:  * A keyboard driver may call this routine if a user
                    181:  * presses a predefined "dump" key.  Since interrupt is
                    182:  * locked in this routine, there is no need to lock the
                    183:  * interrupt/scheduler in each dump function.
                    184:  */
                    185: int
                    186: debug_dump(int item)
                    187: {
                    188:        int err = 0;
                    189:
                    190:        irq_lock();
                    191:        switch (item) {
                    192:        case DUMP_THREAD:
                    193:                thread_dump();
                    194:                break;
                    195:        case DUMP_TASK:
                    196:                task_dump();
                    197:                break;
                    198:        case DUMP_VM:
                    199:                vm_dump();
                    200:                break;
                    201:        default:
                    202:                err = ENOSYS;
                    203:                break;
                    204:        }
                    205:        irq_unlock();
                    206:        return err;
                    207: }
                    208:
                    209: /*
                    210:  * Attach to a print handler.
                    211:  * A device driver can hook the function to display message.
                    212:  */
                    213: void
                    214: debug_attach(void (*fn)(char *))
                    215: {
                    216:        ASSERT(fn);
                    217:
                    218:        print_func = fn;
                    219: }
                    220:
                    221: #endif /* !DEBUG */

CVSweb