247 lines
5.4 KiB
C
247 lines
5.4 KiB
C
/* $NetBSD: db_machdep.c,v 1.11 1998/06/07 20:19:13 ragge Exp $ */
|
|
|
|
/*
|
|
* Mach Operating System
|
|
* Copyright (c) 1991,1990 Carnegie Mellon University
|
|
* All Rights Reserved.
|
|
*
|
|
* Permission to use, copy, modify and distribute this software and its
|
|
* documentation is hereby granted, provided that both the copyright
|
|
* notice and this permission notice appear in all copies of the
|
|
* software, derivative works or modified versions, and any portions
|
|
* thereof, and that both notices appear in supporting documentation.
|
|
*
|
|
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
|
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
|
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
|
*
|
|
* Carnegie Mellon requests users of this software to return to
|
|
*
|
|
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
|
* School of Computer Science
|
|
* Carnegie Mellon University
|
|
* Pittsburgh PA 15213-3890
|
|
*
|
|
* any improvements or extensions that they make and grant Carnegie the
|
|
* rights to redistribute these changes.
|
|
*
|
|
* db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
|
|
*/
|
|
|
|
/*
|
|
* Interface to new debugger.
|
|
* Taken from i386 port and modified for vax.
|
|
*/
|
|
#include <sys/param.h>
|
|
#include <sys/proc.h>
|
|
#include <sys/reboot.h>
|
|
#include <sys/systm.h> /* just for boothowto --eichin */
|
|
|
|
#include <vm/vm.h>
|
|
|
|
#include <dev/cons.h>
|
|
|
|
#include <machine/db_machdep.h>
|
|
#include <machine/trap.h>
|
|
#include <machine/frame.h>
|
|
#include <machine/cpu.h>
|
|
#include <machine/../vax/gencons.h>
|
|
|
|
#include <ddb/db_sym.h>
|
|
#include <ddb/db_command.h>
|
|
#include <ddb/db_output.h>
|
|
#include <ddb/db_extern.h>
|
|
#include <ddb/db_access.h>
|
|
#include <ddb/db_interface.h>
|
|
#include <ddb/db_variables.h>
|
|
|
|
extern label_t *db_recover;
|
|
|
|
void kdbprinttrap __P((int, int));
|
|
|
|
int db_active = 0;
|
|
|
|
extern int qdpolling;
|
|
/*
|
|
* DDB is called by either <ESC> - D on keyboard, via a TRACE or
|
|
* BPT trap or from kernel, normally as a result of a panic.
|
|
* If it is the result of a panic, set the ddb register frame to
|
|
* contain the registers when panic was called. (easy to debug).
|
|
*/
|
|
void
|
|
kdb_trap(frame)
|
|
struct trapframe *frame;
|
|
{
|
|
int s;
|
|
|
|
switch (frame->trap) {
|
|
case T_BPTFLT: /* breakpoint */
|
|
case T_TRCTRAP: /* single_step */
|
|
break;
|
|
|
|
case T_KDBTRAP:
|
|
if (panicstr) {
|
|
struct callsframe *pf, *df;
|
|
|
|
df = (void *)frame->fp; /* start of debug's calls */
|
|
pf = (void *)df->ca_fp; /* start of panic's calls */
|
|
bcopy(&pf->ca_argno, &ddb_regs.r0, sizeof(int) * 12);
|
|
ddb_regs.fp = pf->ca_fp;
|
|
ddb_regs.pc = pf->ca_pc;
|
|
ddb_regs.ap = pf->ca_ap;
|
|
ddb_regs.sp = (unsigned)pf;
|
|
ddb_regs.psl = frame->psl & ~0xffe0;
|
|
ddb_regs.psl = pf->ca_maskpsw & 0xffe0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if ((boothowto & RB_KDB) == 0)
|
|
return;
|
|
|
|
kdbprinttrap(frame->trap, frame->code);
|
|
if (db_recover != 0) {
|
|
db_error("Faulted in DDB; continuing...\n");
|
|
/*NOTREACHED*/
|
|
}
|
|
}
|
|
|
|
if (!panicstr)
|
|
bcopy(frame, &ddb_regs, sizeof(struct trapframe));
|
|
|
|
/* XXX Should switch to interrupt stack here, if needed. */
|
|
|
|
s = splddb();
|
|
db_active++;
|
|
cnpollc(TRUE);
|
|
db_trap(frame->trap, frame->code);
|
|
cnpollc(FALSE);
|
|
db_active--;
|
|
splx(s);
|
|
|
|
if (!panicstr)
|
|
bcopy(&ddb_regs, frame, sizeof(struct trapframe));
|
|
frame->sp = mfpr(PR_USP);
|
|
|
|
return;
|
|
}
|
|
|
|
extern char *traptypes[];
|
|
extern int no_traps;
|
|
|
|
/*
|
|
* Print trap reason.
|
|
*/
|
|
void
|
|
kdbprinttrap(type, code)
|
|
int type, code;
|
|
{
|
|
db_printf("kernel: ");
|
|
if (type >= no_traps || type < 0)
|
|
db_printf("type %d", type);
|
|
else
|
|
db_printf("%s", traptypes[type]);
|
|
db_printf(" trap, code=%x\n", code);
|
|
}
|
|
|
|
/*
|
|
* Read bytes from kernel address space for debugger.
|
|
*/
|
|
void
|
|
db_read_bytes(addr, size, data)
|
|
vm_offset_t addr;
|
|
register size_t size;
|
|
register char *data;
|
|
{
|
|
register char *src;
|
|
|
|
src = (char *)addr;
|
|
while (--size >= 0)
|
|
*data++ = *src++;
|
|
}
|
|
|
|
/*
|
|
* Write bytes to kernel address space for debugger.
|
|
*/
|
|
void
|
|
db_write_bytes(addr, size, data)
|
|
vm_offset_t addr;
|
|
register size_t size;
|
|
register char *data;
|
|
{
|
|
register char *dst;
|
|
|
|
dst = (char *)addr;
|
|
for (;size;size--)
|
|
*dst++ = *data++;
|
|
}
|
|
|
|
void
|
|
Debugger()
|
|
{
|
|
mtpr(0xf, PR_SIRR); /* beg for debugger */
|
|
}
|
|
|
|
/*
|
|
* Machine register set.
|
|
*/
|
|
struct db_variable db_regs[] = {
|
|
{"r0", &ddb_regs.r0, FCN_NULL},
|
|
{"r1", &ddb_regs.r1, FCN_NULL},
|
|
{"r2", &ddb_regs.r2, FCN_NULL},
|
|
{"r3", &ddb_regs.r3, FCN_NULL},
|
|
{"r4", &ddb_regs.r4, FCN_NULL},
|
|
{"r5", &ddb_regs.r5, FCN_NULL},
|
|
{"r6", &ddb_regs.r6, FCN_NULL},
|
|
{"r7", &ddb_regs.r7, FCN_NULL},
|
|
{"r8", &ddb_regs.r8, FCN_NULL},
|
|
{"r9", &ddb_regs.r9, FCN_NULL},
|
|
{"r10", &ddb_regs.r10, FCN_NULL},
|
|
{"r11", &ddb_regs.r11, FCN_NULL},
|
|
{"ap", &ddb_regs.ap, FCN_NULL},
|
|
{"fp", &ddb_regs.fp, FCN_NULL},
|
|
{"sp", &ddb_regs.sp, FCN_NULL},
|
|
{"pc", &ddb_regs.pc, FCN_NULL},
|
|
{"psl", &ddb_regs.psl, FCN_NULL},
|
|
};
|
|
struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
|
|
|
|
void
|
|
db_stack_trace_cmd(addr, have_addr, count, modif)
|
|
db_expr_t addr;
|
|
boolean_t have_addr;
|
|
db_expr_t count;
|
|
char *modif;
|
|
{
|
|
printf("db_stack_trace_cmd - addr %lx, have_addr %x, count %lx, modif %x\n",addr, have_addr, count, (int)modif);
|
|
}
|
|
|
|
static int ddbescape = 0;
|
|
|
|
int
|
|
kdbrint(tkn)
|
|
int tkn;
|
|
{
|
|
|
|
if (ddbescape && ((tkn & 0x7f) == 'D')) {
|
|
mtpr(0xf, PR_SIRR);
|
|
ddbescape = 0;
|
|
return 1;
|
|
}
|
|
|
|
if ((ddbescape == 0) && ((tkn & 0x7f) == 27)) {
|
|
ddbescape = 1;
|
|
return 1;
|
|
}
|
|
|
|
if (ddbescape) {
|
|
ddbescape = 0;
|
|
return 2;
|
|
}
|
|
|
|
ddbescape = 0;
|
|
return 0;
|
|
}
|
|
|
|
|