root/arch/i386/i386/db_interface.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kdbprinttrap
  2. kdb_trap
  3. db_sysregs_cmd
  4. db_cpuid2apic
  5. db_cpuinfo_cmd
  6. db_startproc_cmd
  7. db_stopproc_cmd
  8. db_ddbproc_cmd
  9. db_machine_init
  10. Debugger

    1 /*      $OpenBSD: db_interface.c,v 1.23 2006/11/29 22:40:13 miod Exp $  */
    2 /*      $NetBSD: db_interface.c,v 1.22 1996/05/03 19:42:00 christos Exp $       */
    3 
    4 /*
    5  * Mach Operating System
    6  * Copyright (c) 1991,1990 Carnegie Mellon University
    7  * All Rights Reserved.
    8  *
    9  * Permission to use, copy, modify and distribute this software and its
   10  * documentation is hereby granted, provided that both the copyright
   11  * notice and this permission notice appear in all copies of the
   12  * software, derivative works or modified versions, and any portions
   13  * thereof, and that both notices appear in supporting documentation.
   14  *
   15  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   16  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   17  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   18  *
   19  * Carnegie Mellon requests users of this software to return to
   20  *
   21  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   22  *  School of Computer Science
   23  *  Carnegie Mellon University
   24  *  Pittsburgh PA 15213-3890
   25  *
   26  * any improvements or extensions that they make and grant Carnegie Mellon
   27  * the rights to redistribute these changes.
   28  *
   29  *      db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
   30  */
   31 
   32 /*
   33  * Interface to new debugger.
   34  */
   35 #include <sys/param.h>
   36 #include <sys/proc.h>
   37 #include <sys/reboot.h>
   38 #include <sys/systm.h>
   39 #include <sys/mutex.h>
   40 
   41 #include <uvm/uvm_extern.h>
   42 
   43 #include <dev/cons.h>
   44 
   45 #include <machine/db_machdep.h>
   46 
   47 #include <ddb/db_sym.h>
   48 #include <ddb/db_command.h>
   49 #include <ddb/db_extern.h>
   50 #include <ddb/db_access.h>
   51 #include <ddb/db_output.h>
   52 #include <ddb/db_var.h>
   53 
   54 #include "acpi.h"
   55 #if NACPI > 0
   56 #include <dev/acpi/acpidebug.h>
   57 #endif /* NACPI > 0 */
   58 
   59 extern label_t  *db_recover;
   60 extern char *trap_type[];
   61 extern int trap_types;
   62 extern boolean_t db_cmd_loop_done;
   63 
   64 #ifdef MULTIPROCESSOR
   65 extern volatile int ddb_state;
   66 boolean_t        db_switch_cpu;
   67 long             db_switch_to_cpu;
   68 #endif
   69 
   70 db_regs_t       ddb_regs;
   71 int     db_active = 0;
   72 
   73 void kdbprinttrap(int, int);
   74 void db_sysregs_cmd(db_expr_t, int, db_expr_t, char *);
   75 #ifdef MULTIPROCESSOR
   76 void db_cpuinfo_cmd(db_expr_t, int, db_expr_t, char *);
   77 void db_startproc_cmd(db_expr_t, int, db_expr_t, char *);
   78 void db_stopproc_cmd(db_expr_t, int, db_expr_t, char *);
   79 void db_ddbproc_cmd(db_expr_t, int, db_expr_t, char *);
   80 int db_cpuid2apic(int);
   81 #endif /* MULTIPROCESSOR */
   82 
   83 /*
   84  * Print trap reason.
   85  */
   86 void
   87 kdbprinttrap(int type, int code)
   88 {
   89         db_printf("kernel: ");
   90         if (type >= trap_types || type < 0)
   91                 db_printf("type %d", type);
   92         else
   93                 db_printf("%s", trap_type[type]);
   94         db_printf(" trap, code=%x\n", code);
   95 }
   96 
   97 /*
   98  *  kdb_trap - field a TRACE or BPT trap
   99  */
  100 int
  101 kdb_trap(int type, int code, db_regs_t *regs)
  102 {
  103         int s;
  104 
  105         switch (type) {
  106         case T_BPTFLT:  /* breakpoint */
  107         case T_TRCTRAP: /* single_step */
  108         case T_NMI:     /* NMI */
  109         case -1:        /* keyboard interrupt */
  110                 break;
  111         default:
  112                 if (!db_panic)
  113                         return (0);
  114 
  115                 kdbprinttrap(type, code);
  116                 if (db_recover != 0) {
  117                         db_error("Faulted in DDB; continuing...\n");
  118                         /*NOTREACHED*/
  119                 }
  120         }
  121 
  122 #ifdef MULTIPROCESSOR
  123         mtx_enter(&ddb_mp_mutex);
  124         if (ddb_state == DDB_STATE_EXITING)
  125                 ddb_state = DDB_STATE_NOT_RUNNING;
  126         mtx_leave(&ddb_mp_mutex);
  127         while (db_enter_ddb()) {
  128 #endif /* MULTIPROCESSOR */
  129 
  130         /* XXX Should switch to kdb`s own stack here. */
  131 
  132         ddb_regs = *regs;
  133         if (KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
  134                 /*
  135                  * Kernel mode - esp and ss not saved
  136                  */
  137                 ddb_regs.tf_esp = (int)&regs->tf_esp;   /* kernel stack pointer */
  138                 __asm__("movw %%ss,%w0" : "=r" (ddb_regs.tf_ss));
  139         }
  140 
  141         s = splhigh();
  142         db_active++;
  143         cnpollc(TRUE);
  144         db_trap(type, code);
  145         cnpollc(FALSE);
  146         db_active--;
  147         splx(s);
  148 
  149         regs->tf_fs     = ddb_regs.tf_fs & 0xffff;
  150         regs->tf_gs     = ddb_regs.tf_gs & 0xffff;
  151         regs->tf_es     = ddb_regs.tf_es & 0xffff;
  152         regs->tf_ds     = ddb_regs.tf_ds & 0xffff;
  153         regs->tf_edi    = ddb_regs.tf_edi;
  154         regs->tf_esi    = ddb_regs.tf_esi;
  155         regs->tf_ebp    = ddb_regs.tf_ebp;
  156         regs->tf_ebx    = ddb_regs.tf_ebx;
  157         regs->tf_edx    = ddb_regs.tf_edx;
  158         regs->tf_ecx    = ddb_regs.tf_ecx;
  159         regs->tf_eax    = ddb_regs.tf_eax;
  160         regs->tf_eip    = ddb_regs.tf_eip;
  161         regs->tf_cs     = ddb_regs.tf_cs & 0xffff;
  162         regs->tf_eflags = ddb_regs.tf_eflags;
  163         if (!KERNELMODE(regs->tf_cs, regs->tf_eflags)) {
  164                 /* ring transit - saved esp and ss valid */
  165                 regs->tf_esp    = ddb_regs.tf_esp;
  166                 regs->tf_ss     = ddb_regs.tf_ss & 0xffff;
  167         }
  168 
  169 
  170 #ifdef MULTIPROCESSOR
  171                 if (!db_switch_cpu)
  172                         ddb_state = DDB_STATE_EXITING;
  173         }
  174 #endif /* MULTIPROCESSOR */
  175         return (1);
  176 }
  177 
  178 void
  179 db_sysregs_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  180 {
  181         int64_t idtr, gdtr;
  182         uint32_t cr;
  183         uint16_t ldtr, tr;
  184 
  185         __asm__ __volatile__("sidt %0" : "=m" (idtr));
  186         db_printf("idtr:   0x%08x/%04x\n",
  187             (unsigned int)(idtr >> 16), idtr & 0xffff);
  188 
  189         __asm__ __volatile__("sgdt %0" : "=m" (gdtr));
  190         db_printf("gdtr:   0x%08x/%04x\n",
  191             (unsigned int)(gdtr >> 16), gdtr & 0xffff);
  192 
  193         __asm__ __volatile__("sldt %0" : "=g" (ldtr));
  194         db_printf("ldtr:   0x%04x\n", ldtr);
  195 
  196         __asm__ __volatile__("str %0" : "=g" (tr));
  197         db_printf("tr:     0x%04x\n", tr);
  198 
  199         __asm__ __volatile__("movl %%cr0,%0" : "=r" (cr));
  200         db_printf("cr0:    0x%08x\n", cr);
  201 
  202         __asm__ __volatile__("movl %%cr2,%0" : "=r" (cr));
  203         db_printf("cr2:    0x%08x\n", cr);
  204 
  205         __asm__ __volatile__("movl %%cr3,%0" : "=r" (cr));
  206         db_printf("cr3:    0x%08x\n", cr);
  207 
  208         __asm__ __volatile__("movl %%cr4,%0" : "=r" (cr));
  209         db_printf("cr4:    0x%08x\n", cr);
  210 }
  211 
  212 #ifdef MULTIPROCESSOR
  213 int
  214 db_cpuid2apic(int id)
  215 {
  216         int apic;
  217 
  218         for (apic = 0; apic < I386_MAXPROCS; apic++) {
  219                 if (cpu_info[apic] != NULL &&
  220                     cpu_info[apic]->ci_dev.dv_unit == id)
  221                         return (apic);
  222         }
  223         return (-1);
  224 }
  225 
  226 void
  227 db_cpuinfo_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  228 {
  229         int i;
  230 
  231         for (i = 0; i < I386_MAXPROCS; i++) {
  232                 if (cpu_info[i] != NULL) {
  233                         db_printf("%c%4d: ", (i == cpu_number()) ? '*' : ' ',
  234                             cpu_info[i]->ci_dev.dv_unit);
  235                         switch(cpu_info[i]->ci_ddb_paused) {
  236                         case CI_DDB_RUNNING:
  237                                 db_printf("running\n");
  238                                 break;
  239                         case CI_DDB_SHOULDSTOP:
  240                                 db_printf("stopping\n");
  241                                 break;
  242                         case CI_DDB_STOPPED:
  243                                 db_printf("stopped\n");
  244                                 break;
  245                         case CI_DDB_ENTERDDB:
  246                                 db_printf("entering ddb\n");
  247                                 break;
  248                         case CI_DDB_INDDB:
  249                                 db_printf("ddb\n");
  250                                 break;
  251                         default:
  252                                 db_printf("? (%d)\n",
  253                                     cpu_info[i]->ci_ddb_paused);
  254                                 break;
  255                         }
  256                 }
  257         }
  258 }
  259 
  260 void
  261 db_startproc_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  262 {
  263         int apic;
  264 
  265         if (have_addr) {
  266                 apic = db_cpuid2apic(addr);
  267                 if (apic >= 0 && apic < I386_MAXPROCS &&
  268                     cpu_info[apic] != NULL && apic != cpu_number())
  269                         db_startcpu(apic);
  270                 else
  271                         db_printf("Invalid cpu %d\n", (int)addr);
  272         } else {
  273                 for (apic = 0; apic < I386_MAXPROCS; apic++) {
  274                         if (cpu_info[apic] != NULL && apic != cpu_number()) {
  275                                 db_startcpu(apic);
  276                         }
  277                 }
  278         }
  279 }
  280 
  281 void
  282 db_stopproc_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  283 {
  284         int apic;
  285 
  286         if (have_addr) {
  287                 apic = db_cpuid2apic(addr);
  288                 if (apic >= 0 && apic < I386_MAXPROCS &&
  289                     cpu_info[apic] != NULL && apic != cpu_number())
  290                         db_stopcpu(apic);
  291                 else
  292                         db_printf("Invalid cpu %d\n", (int)addr);
  293         } else {
  294                 for (apic = 0; apic < I386_MAXPROCS; apic++) {
  295                         if (cpu_info[apic] != NULL && apic != cpu_number()) {
  296                                 db_stopcpu(apic);
  297                         }
  298                 }
  299         }
  300 }
  301 
  302 void
  303 db_ddbproc_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
  304 {
  305         int apic;
  306 
  307         if (have_addr) {
  308                 apic = db_cpuid2apic(addr);
  309                 if (apic >= 0 && apic < I386_MAXPROCS &&
  310                     cpu_info[apic] != NULL && apic != cpu_number()) {
  311                         db_stopcpu(apic);
  312                         db_switch_to_cpu = apic;
  313                         db_switch_cpu = 1;
  314                         db_cmd_loop_done = 1;
  315                 } else {
  316                         db_printf("Invalid cpu %d\n", (int)addr);
  317                 }
  318         } else {
  319                 db_printf("CPU not specified\n");
  320         }
  321 }
  322 #endif /* MULTIPROCESSOR */
  323 
  324 #if NACPI > 0
  325 struct db_command db_acpi_cmds[] = {
  326         { "disasm",     db_acpi_disasm,         CS_OWN, NULL },
  327         { "showval",    db_acpi_showval,        CS_OWN, NULL },
  328         { "tree",       db_acpi_tree,           0,      NULL },
  329         { "trace",      db_acpi_trace,          0,      NULL },
  330         { NULL,         NULL,                   0,      NULL }
  331 };
  332 #endif /* NACPI > 0 */
  333 
  334 struct db_command db_machine_command_table[] = {
  335         { "sysregs",    db_sysregs_cmd,         0,      0 },
  336 #ifdef MULTIPROCESSOR
  337         { "cpuinfo",    db_cpuinfo_cmd,         0,      0 },
  338         { "startcpu",   db_startproc_cmd,       0,      0 },
  339         { "stopcpu",    db_stopproc_cmd,        0,      0 },
  340         { "ddbcpu",     db_ddbproc_cmd,         0,      0 },
  341 #endif /* MULTIPROCESSOR */
  342 #if NACPI > 0
  343         { "acpi",       NULL,                   0,      db_acpi_cmds },
  344 #endif /* NACPI > 0 */
  345         { (char *)0, }
  346 };
  347 
  348 void
  349 db_machine_init(void)
  350 {
  351 #ifdef MULTIPROCESSOR
  352         int i;
  353 #endif /* MULTIPROCESSOR */
  354 
  355         db_machine_commands_install(db_machine_command_table);
  356 #ifdef MULTIPROCESSOR
  357         for (i = 0; i < I386_MAXPROCS; i++) {
  358                 if (cpu_info[i] != NULL)
  359                         cpu_info[i]->ci_ddb_paused = CI_DDB_RUNNING;
  360         }
  361 #endif /* MULTIPROCESSOR */
  362 }
  363 
  364 void
  365 Debugger(void)
  366 {
  367         __asm__("int $3");
  368 }

/* [<][>][^][v][top][bottom][index][help] */