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

Annotation of prex-old/sys/kern/debug.c, Revision 1.1.1.1.2.1

1.1       nbrk        1: /*-
1.1.1.1.2.1! nbrk        2:  * Copyright (c) 2005-2008, Kohsuke Ohtani
1.1       nbrk        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:
1.1.1.1.2.1! nbrk       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;
1.1       nbrk       47:
1.1.1.1.2.1! nbrk       48: static char    dbg_msg[DBGMSG_SIZE];
1.1       nbrk       49:
                     50: /*
1.1.1.1.2.1! nbrk       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.
1.1       nbrk       62:  *
1.1.1.1.2.1! nbrk       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().
1.1       nbrk       67:  */
                     68: void
1.1.1.1.2.1! nbrk       69: printf(const char *fmt, ...)
1.1       nbrk       70: {
                     71:        va_list args;
1.1.1.1.2.1! nbrk       72:        int i;
        !            73:        char c;
1.1       nbrk       74:
                     75:        irq_lock();
                     76:        va_start(args, fmt);
1.1.1.1.2.1! nbrk       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:        }
1.1       nbrk       97:        va_end(args);
                     98:        irq_unlock();
                     99: }
                    100:
                    101: /*
                    102:  * Kernel assertion.
                    103:  *
1.1.1.1.2.1! nbrk      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.
1.1       nbrk      107:  */
                    108: void
                    109: assert(const char *file, int line, const char *exp)
                    110: {
1.1.1.1.2.1! nbrk      111:
1.1       nbrk      112:        irq_lock();
1.1.1.1.2.1! nbrk      113:        printf("\nAssertion failed: %s line:%d '%s'\n", file, line, exp);
1.1       nbrk      114:        BREAKPOINT();
                    115:        for (;;)
                    116:                machine_idle();
                    117:        /* NOTREACHED */
                    118: }
                    119:
                    120: /*
                    121:  * Kernel panic.
                    122:  *
1.1.1.1.2.1! nbrk      123:  * panic() is called for a fatal kernel error. It shows
        !           124:  * specified message, and stops CPU.
1.1       nbrk      125:  */
                    126: void
1.1.1.1.2.1! nbrk      127: panic(const char *msg)
1.1       nbrk      128: {
                    129:
                    130:        irq_lock();
1.1.1.1.2.1! nbrk      131:        printf("\nKernel panic: %s\n", msg);
1.1       nbrk      132:        irq_unlock();
                    133:        BREAKPOINT();
                    134:        for (;;)
                    135:                machine_idle();
                    136:        /* NOTREACHED */
                    137: }
                    138:
                    139: /*
1.1.1.1.2.1! nbrk      140:  * Copy log to user buffer.
1.1       nbrk      141:  */
                    142: int
1.1.1.1.2.1! nbrk      143: debug_getlog(char *buf)
1.1       nbrk      144: {
1.1.1.1.2.1! nbrk      145:        u_long i, len, index;
        !           146:        int err = 0;
1.1       nbrk      147:        char c;
                    148:
1.1.1.1.2.1! nbrk      149:        irq_lock();
        !           150:        index = log_head;
1.1       nbrk      151:        len = log_len;
1.1.1.1.2.1! nbrk      152:        if (len >= LOGBUF_SIZE) {
        !           153:                /*
        !           154:                 * Overrun found. Discard broken message.
        !           155:                 */
        !           156:                while (len > 0 && log_buf[LOGINDEX(index)] != '\n') {
1.1       nbrk      157:                        index++;
                    158:                        len--;
                    159:                }
                    160:        }
1.1.1.1.2.1! nbrk      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:                }
1.1       nbrk      170:                index++;
1.1.1.1.2.1! nbrk      171:                buf++;
1.1       nbrk      172:        }
1.1.1.1.2.1! nbrk      173:        irq_unlock();
        !           174:        return err;
1.1       nbrk      175: }
                    176:
                    177: /*
                    178:  * Dump system information.
                    179:  *
1.1.1.1.2.1! nbrk      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.
1.1       nbrk      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:
1.1.1.1.2.1! nbrk      202:                err = ENOSYS;
1.1       nbrk      203:                break;
                    204:        }
                    205:        irq_unlock();
                    206:        return err;
                    207: }
                    208:
                    209: /*
1.1.1.1.2.1! nbrk      210:  * Attach to a print handler.
1.1       nbrk      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:
1.1.1.1.2.1! nbrk      218:        print_func = fn;
1.1       nbrk      219: }
                    220:
                    221: #endif /* !DEBUG */

CVSweb