Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Created by: Jason Wessel <jason.wessel@windriver.com>
0003  *
0004  * Copyright (c) 2009 Wind River Systems, Inc.  All Rights Reserved.
0005  *
0006  * This file is licensed under the terms of the GNU General Public
0007  * License version 2. This program is licensed "as is" without any
0008  * warranty of any kind, whether express or implied.
0009  */
0010 
0011 #include <linux/kgdb.h>
0012 #include <linux/kdb.h>
0013 #include <linux/kdebug.h>
0014 #include <linux/export.h>
0015 #include <linux/hardirq.h>
0016 #include "kdb_private.h"
0017 #include "../debug_core.h"
0018 
0019 /*
0020  * KDB interface to KGDB internals
0021  */
0022 get_char_func kdb_poll_funcs[] = {
0023     dbg_io_get_char,
0024     NULL,
0025     NULL,
0026     NULL,
0027     NULL,
0028     NULL,
0029 };
0030 EXPORT_SYMBOL_GPL(kdb_poll_funcs);
0031 
0032 int kdb_poll_idx = 1;
0033 EXPORT_SYMBOL_GPL(kdb_poll_idx);
0034 
0035 static struct kgdb_state *kdb_ks;
0036 
0037 int kdb_common_init_state(struct kgdb_state *ks)
0038 {
0039     kdb_initial_cpu = atomic_read(&kgdb_active);
0040     kdb_current_task = kgdb_info[ks->cpu].task;
0041     kdb_current_regs = kgdb_info[ks->cpu].debuggerinfo;
0042     return 0;
0043 }
0044 
0045 int kdb_common_deinit_state(void)
0046 {
0047     kdb_initial_cpu = -1;
0048     kdb_current_task = NULL;
0049     kdb_current_regs = NULL;
0050     return 0;
0051 }
0052 
0053 int kdb_stub(struct kgdb_state *ks)
0054 {
0055     int error = 0;
0056     kdb_bp_t *bp;
0057     unsigned long addr = kgdb_arch_pc(ks->ex_vector, ks->linux_regs);
0058     kdb_reason_t reason = KDB_REASON_OOPS;
0059     kdb_dbtrap_t db_result = KDB_DB_NOBPT;
0060     int i;
0061 
0062     kdb_ks = ks;
0063     if (KDB_STATE(REENTRY)) {
0064         reason = KDB_REASON_SWITCH;
0065         KDB_STATE_CLEAR(REENTRY);
0066         addr = instruction_pointer(ks->linux_regs);
0067     }
0068     ks->pass_exception = 0;
0069     if (atomic_read(&kgdb_setting_breakpoint))
0070         reason = KDB_REASON_KEYBOARD;
0071 
0072     if (ks->err_code == KDB_REASON_SYSTEM_NMI && ks->signo == SIGTRAP)
0073         reason = KDB_REASON_SYSTEM_NMI;
0074 
0075     else if (in_nmi())
0076         reason = KDB_REASON_NMI;
0077 
0078     for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) {
0079         if ((bp->bp_enabled) && (bp->bp_addr == addr)) {
0080             reason = KDB_REASON_BREAK;
0081             db_result = KDB_DB_BPT;
0082             if (addr != instruction_pointer(ks->linux_regs))
0083                 kgdb_arch_set_pc(ks->linux_regs, addr);
0084             break;
0085         }
0086     }
0087     if (reason == KDB_REASON_BREAK || reason == KDB_REASON_SWITCH) {
0088         for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) {
0089             if (bp->bp_free)
0090                 continue;
0091             if (bp->bp_addr == addr) {
0092                 bp->bp_delay = 1;
0093                 bp->bp_delayed = 1;
0094     /*
0095      * SSBPT is set when the kernel debugger must single step a
0096      * task in order to re-establish an instruction breakpoint
0097      * which uses the instruction replacement mechanism.  It is
0098      * cleared by any action that removes the need to single-step
0099      * the breakpoint.
0100      */
0101                 reason = KDB_REASON_BREAK;
0102                 db_result = KDB_DB_BPT;
0103                 KDB_STATE_SET(SSBPT);
0104                 break;
0105             }
0106         }
0107     }
0108 
0109     if (reason != KDB_REASON_BREAK && ks->ex_vector == 0 &&
0110         ks->signo == SIGTRAP) {
0111         reason = KDB_REASON_SSTEP;
0112         db_result = KDB_DB_BPT;
0113     }
0114     /* Set initial kdb state variables */
0115     KDB_STATE_CLEAR(KGDB_TRANS);
0116     kdb_common_init_state(ks);
0117     /* Remove any breakpoints as needed by kdb and clear single step */
0118     kdb_bp_remove();
0119     KDB_STATE_CLEAR(DOING_SS);
0120     KDB_STATE_SET(PAGER);
0121     if (ks->err_code == DIE_OOPS || reason == KDB_REASON_OOPS) {
0122         ks->pass_exception = 1;
0123         KDB_FLAG_SET(CATASTROPHIC);
0124     }
0125     /* set CATASTROPHIC if the system contains unresponsive processors */
0126     for_each_online_cpu(i)
0127         if (!kgdb_info[i].enter_kgdb)
0128             KDB_FLAG_SET(CATASTROPHIC);
0129     if (KDB_STATE(SSBPT) && reason == KDB_REASON_SSTEP) {
0130         KDB_STATE_CLEAR(SSBPT);
0131         KDB_STATE_CLEAR(DOING_SS);
0132     } else {
0133         /* Start kdb main loop */
0134         error = kdb_main_loop(KDB_REASON_ENTER, reason,
0135                       ks->err_code, db_result, ks->linux_regs);
0136     }
0137     /*
0138      * Upon exit from the kdb main loop setup break points and restart
0139      * the system based on the requested continue state
0140      */
0141     kdb_common_deinit_state();
0142     KDB_STATE_CLEAR(PAGER);
0143     if (error == KDB_CMD_KGDB) {
0144         if (KDB_STATE(DOING_KGDB))
0145             KDB_STATE_CLEAR(DOING_KGDB);
0146         return DBG_PASS_EVENT;
0147     }
0148     kdb_bp_install(ks->linux_regs);
0149     /* Set the exit state to a single step or a continue */
0150     if (KDB_STATE(DOING_SS))
0151         gdbstub_state(ks, "s");
0152     else
0153         gdbstub_state(ks, "c");
0154 
0155     KDB_FLAG_CLEAR(CATASTROPHIC);
0156 
0157     /* Invoke arch specific exception handling prior to system resume */
0158     kgdb_info[ks->cpu].ret_state = gdbstub_state(ks, "e");
0159     if (ks->pass_exception)
0160         kgdb_info[ks->cpu].ret_state = 1;
0161     if (error == KDB_CMD_CPU) {
0162         KDB_STATE_SET(REENTRY);
0163         /*
0164          * Force clear the single step bit because kdb emulates this
0165          * differently vs the gdbstub
0166          */
0167         kgdb_single_step = 0;
0168         return DBG_SWITCH_CPU_EVENT;
0169     }
0170     return kgdb_info[ks->cpu].ret_state;
0171 }
0172 
0173 void kdb_gdb_state_pass(char *buf)
0174 {
0175     gdbstub_state(kdb_ks, buf);
0176 }