summaryrefslogtreecommitdiff
path: root/sys/arch/mvme88k/ddb
diff options
context:
space:
mode:
authorSteve Murphree <smurph@cvs.openbsd.org>2001-12-22 08:31:06 +0000
committerSteve Murphree <smurph@cvs.openbsd.org>2001-12-22 08:31:06 +0000
commit87380d574c2af338617f92def75a97a172f2ec25 (patch)
treee2780ec83a78305e17168990da932274cab1642a /sys/arch/mvme88k/ddb
parent832a91320a5723dc06b1cf25dfea92a78db07fa1 (diff)
mc88110 support in ddb. Bring in bit definitions.
We can support hardware sstep for mc88110 and software sstep for mc88100.
Diffstat (limited to 'sys/arch/mvme88k/ddb')
-rw-r--r--sys/arch/mvme88k/ddb/db_disasm.c862
-rw-r--r--sys/arch/mvme88k/ddb/db_interface.c238
-rw-r--r--sys/arch/mvme88k/ddb/db_sstep.c93
-rw-r--r--sys/arch/mvme88k/ddb/db_trace.c1613
4 files changed, 1467 insertions, 1339 deletions
diff --git a/sys/arch/mvme88k/ddb/db_disasm.c b/sys/arch/mvme88k/ddb/db_disasm.c
index 27beebfc477..0375e55c78a 100644
--- a/sys/arch/mvme88k/ddb/db_disasm.c
+++ b/sys/arch/mvme88k/ddb/db_disasm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_disasm.c,v 1.8 2001/12/16 23:49:46 miod Exp $ */
+/* $OpenBSD: db_disasm.c,v 1.9 2001/12/22 08:31:04 smurph Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1991 Carnegie Mellon University
@@ -30,6 +30,7 @@
* m88k disassembler for use in ddb
*/
+#include <sys/param.h> /* cputyp and friends */
#include <sys/types.h>
#include <machine/db_machdep.h>
@@ -47,7 +48,7 @@ static char *condname[6] = {
"gt0 ", "eq0 ", "ge0 ", "lt0 ", "ne0 ", "le0 "
};
-static char *ctrlreg[64] = {
+static char *m88100_ctrlreg[64] = {
"cr0(PID) ",
"cr1(PSR) ",
"cr2(EPSR) ",
@@ -83,6 +84,62 @@ static char *ctrlreg[64] = {
"fcr63(FPCR)"
};
+static char *m88110_ctrlreg[64] = {
+ "cr0(PID) ",
+ "cr1(PSR) ",
+ "cr2(EPSR) ",
+ 0,
+ "cr4(EXIP) ",
+ "cr5(ENIP) ",
+ 0,
+ "cr7(VBR) ",
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ "cr14(RES1) ",
+ "cr15(RES2) ",
+ "cr16(SR0) ",
+ "cr17(SR1) ",
+ "cr18(SR2) ",
+ "cr19(SR3) ",
+ "cr20(SR4) ",
+ "fcr0(FPECR)",
+ 0,
+ 0,
+ 0,
+ "cr25(ICMD) ",
+ "cr26(ICTL) ",
+ "cr27(ISAR) ",
+ "cr28(ISAP) ",
+ "cr29(IUAP) ",
+ "cr30(IIR) ",
+ "cr31(IBP) ",
+ "cr32(IPPU) ",
+ "cr33(IPPL) ",
+ "cr34(ISR) ",
+ "cr35(ILAR) ",
+ "cr36(IPAR) ",
+ 0,0,0,
+ "cr40(DCMD) ",
+ "cr41(DCTL) ",
+ "cr42(DSAR) ",
+ "cr43(DSAP) ",
+ "cr44(DUAP) ",
+ "cr45(DIR) ",
+ "cr46(DBP) ",
+ "cr47(DPPU) ",
+ "cr48(DPPL) ",
+ "cr49(DSR) ",
+ "cr50(DLAR) ",
+ "cr51(DPAR) ",
+ 0,0,0,0,0,0,0,0,0,0,
+ "fcr62(FPSR)",
+ "fcr63(FPCR)"
+};
+
#define printval(x) \
do { \
if ((x) < 0) \
@@ -107,26 +164,26 @@ void bitman __P((int, char *, long));
void immem __P((int, char *, long));
void nimmem __P((int, char *, long));
void lognim __P((int, char *, long));
-void onimmed __P((int, char *, long));
+void onimmed __P((int, char *, long));
-/* Handlers immediate integer arithmetic instructions */
+/* Handlers immediate integer arithmetic instructions */
void
oimmed(int inst, char *opcode, long iadr)
{
- register int Linst = inst & 0177777;
- register int Hinst = inst >> 16;
- register int H6inst = Hinst >> 10;
- register int rs1 = Hinst & 037;
- register int rd = ( Hinst >> 5 ) & 037;
-
- if (( H6inst > 017 ) && ( H6inst < 030 ) && ( H6inst & 01) == 1 )
- db_printf("\t%s.u",opcode);
- else {
- db_printf("\t%s",opcode);
- db_printf(" ");
- }
- db_printf("\t\tr%-3d,r%-3d,", rd, rs1);
- printval(Linst);
+ register int Linst = inst & 0177777;
+ register int Hinst = inst >> 16;
+ register int H6inst = Hinst >> 10;
+ register int rs1 = Hinst & 037;
+ register int rd = ( Hinst >> 5 ) & 037;
+
+ if (( H6inst > 017 ) && ( H6inst < 030 ) && ( H6inst & 01) == 1 )
+ db_printf("\t%s.u",opcode);
+ else {
+ db_printf("\t%s",opcode);
+ db_printf(" ");
+ }
+ db_printf("\t\tr%-3d,r%-3d,", rd, rs1);
+ printval(Linst);
}
@@ -134,72 +191,74 @@ oimmed(int inst, char *opcode, long iadr)
void
ctrlregs(int inst, char *opcode, long iadr)
{
- register int L6inst = (inst >> 11) & 037;
- register int creg = (inst >> 5) & 077;
- register int rd = (inst >> 21) & 037;
- register int rs1 = (inst >> 16) & 037;
-
- db_printf("\t%s",opcode);
-
- if ( L6inst == 010 || L6inst == 011 )
- db_printf("\t\tr%-3d,%s", rd, ctrlreg[creg]);
- else if ( L6inst == 020 || L6inst == 021 )
- db_printf("\t\tr%-3d,%s", rs1, ctrlreg[creg]);
- else
- db_printf("\t\tr%-3d,r%-3d,%s", rd, rs1, ctrlreg[creg]);
+ register int L6inst = (inst >> 11) & 037;
+ register int creg = (inst >> 5) & 077;
+ register int rd = (inst >> 21) & 037;
+ register int rs1 = (inst >> 16) & 037;
+
+ db_printf("\t%s",opcode);
+
+ if ( L6inst == 010 || L6inst == 011 )
+ db_printf("\t\tr%-3d,%s", rd,
+ cputyp == CPU_88100 ? m88100_ctrlreg[creg] : m88110_ctrlreg[creg]);
+ else if ( L6inst == 020 || L6inst == 021 )
+ db_printf("\t\tr%-3d,%s", rs1,
+ cputyp == CPU_88100 ? m88100_ctrlreg[creg] : m88110_ctrlreg[creg]);
+ else
+ db_printf("\t\tr%-3d,r%-3d,%s", rd, rs1,
+ cputyp == CPU_88100 ? m88100_ctrlreg[creg] : m88110_ctrlreg[creg]);
}
void
printsod(int t)
{
- if ( t == 0 )
- db_printf("s");
- else
- db_printf("d");
+ if ( t == 0 )
+ db_printf("s");
+ else
+ db_printf("d");
}
/* Handles floating point instructions */
void
sindou(int inst, char *opcode, long iadr)
{
- register int rs2 = inst & 037;
- register int td = ( inst >> 5 ) & 03;
- register int t2 = ( inst >> 7 ) & 03;
- register int t1 = ( inst >> 9 ) & 03;
- register int rs1 = ( inst >> 16 ) & 037;
- register int rd = ( inst >> 21 ) & 037;
- register int checkbits = ( inst >> 11 ) & 037;
-
- db_printf("\t%s.",opcode);
- printsod(td);
- if (( checkbits > 010 && checkbits < 014 ) || ( checkbits == 04 )) {
- printsod(t2);
- db_printf(" ");
- if ( checkbits == 012 || checkbits == 013 )
- db_printf("\t\tr%-3d,r%-3d", rd, rs2);
- else
- db_printf("\t\tr%-3d,r%-3d", rd, rs2);
- }
- else{
- printsod(t1);printsod(t2);
- db_printf("\t\tr%-3d,r%-3d,r%-3d", rd, rs1, rs2);
- }
+ register int rs2 = inst & 037;
+ register int td = ( inst >> 5 ) & 03;
+ register int t2 = ( inst >> 7 ) & 03;
+ register int t1 = ( inst >> 9 ) & 03;
+ register int rs1 = ( inst >> 16 ) & 037;
+ register int rd = ( inst >> 21 ) & 037;
+ register int checkbits = ( inst >> 11 ) & 037;
+
+ db_printf("\t%s.",opcode);
+ printsod(td);
+ if (( checkbits > 010 && checkbits < 014 ) || ( checkbits == 04 )) {
+ printsod(t2);
+ db_printf(" ");
+ if ( checkbits == 012 || checkbits == 013 )
+ db_printf("\t\tr%-3d,r%-3d", rd, rs2);
+ else
+ db_printf("\t\tr%-3d,r%-3d", rd, rs2);
+ } else {
+ printsod(t1);printsod(t2);
+ db_printf("\t\tr%-3d,r%-3d,r%-3d", rd, rs1, rs2);
+ }
}
void
jump(int inst, char *opcode, long iadr)
{
- register int rs2 = inst & 037;
- register int Nbit = ( inst >> 10 ) & 01;
-
- db_printf("\t%s",opcode);
- if ( Nbit == 1 )
- db_printf(".n");
- else
- db_printf(" ");
- db_printf("\t\tr%-3d",rs2);
+ register int rs2 = inst & 037;
+ register int Nbit = ( inst >> 10 ) & 01;
+
+ db_printf("\t%s",opcode);
+ if ( Nbit == 1 )
+ db_printf(".n");
+ else
+ db_printf(" ");
+ db_printf("\t\tr%-3d",rs2);
}
@@ -207,53 +266,50 @@ jump(int inst, char *opcode, long iadr)
void
instset(int inst, char *opcode, long iadr)
{
- register int rs2 = inst & 037;
- register int rs1 = ( inst >> 16 ) & 037;
- register int rd = ( inst >> 21 ) & 037;
- register int checkbits = ( inst >> 10 ) & 077;
- register int H6inst = ( inst >> 26 ) & 077;
-
- db_printf("\t%s",opcode);
- if ( H6inst == 076 ) {
- db_printf("\t\tr%-3d,",rs1);
- printval(inst & 0177777);
- }
- else if (( checkbits == 072 ) || ( checkbits == 073 ))
- db_printf("\t\tr%-3d,r%-3d", rd, rs2);
- else if ( checkbits == 076 )
- db_printf("\t\tr%-3d,r%-3d",rs1,rs2);
+ register int rs2 = inst & 037;
+ register int rs1 = ( inst >> 16 ) & 037;
+ register int rd = ( inst >> 21 ) & 037;
+ register int checkbits = ( inst >> 10 ) & 077;
+ register int H6inst = ( inst >> 26 ) & 077;
+
+ db_printf("\t%s",opcode);
+ if ( H6inst == 076 ) {
+ db_printf("\t\tr%-3d,",rs1);
+ printval(inst & 0177777);
+ } else if (( checkbits == 072 ) || ( checkbits == 073 ))
+ db_printf("\t\tr%-3d,r%-3d", rd, rs2);
+ else if ( checkbits == 076 )
+ db_printf("\t\tr%-3d,r%-3d",rs1,rs2);
}
void
symofset(int disp, int bit, int iadr)
{
- long addr;
-
- if ( disp & (1 << (bit-1)) ) {
- /* negative value */
- addr = iadr + ((disp << 2) | (~0 << bit));
- }
- else {
- addr = iadr + (disp << 2);
- }
- db_printsym(addr,DB_STGY_PROC);
- return;
+ long addr;
+
+ if ( disp & (1 << (bit-1)) ) {
+ /* negative value */
+ addr = iadr + ((disp << 2) | (~0 << bit));
+ } else {
+ addr = iadr + (disp << 2);
+ }
+ db_printsym(addr,DB_STGY_PROC);
+ return;
}
void
obranch(int inst, char *opcode, long iadr)
{
- int cond = ( inst >> 26 ) & 01;
- int disp = inst &0377777777;
-
- if ( cond == 0 ) {
- db_printf("\t%s\t\t",opcode);
- symofset(disp, 26, iadr);
- }
- else {
- db_printf("\t%s.n\t\t",opcode);
- symofset(disp, 26, iadr);
- }
+ int cond = ( inst >> 26 ) & 01;
+ int disp = inst &0377777777;
+
+ if ( cond == 0 ) {
+ db_printf("\t%s\t\t",opcode);
+ symofset(disp, 26, iadr);
+ } else {
+ db_printf("\t%s.n\t\t",opcode);
+ symofset(disp, 26, iadr);
+ }
}
@@ -261,61 +317,59 @@ obranch(int inst, char *opcode, long iadr)
void
brcond(int inst, char *opcode, long iadr)
{
- int cond = ( inst >> 26 ) & 1;
- int match = ( inst >> 21 ) & 037;
- int rs = ( inst >> 16 ) & 037;
- int disp = ( inst & 0177777 );
-
- if ( cond == 0 )
- db_printf("\t%s\t\t", opcode);
- else
- db_printf("\t%s.n\t\t", opcode);
- if ( ( ( inst >> 27 ) & 03 ) == 1 )
- switch (match) {
- case 1 : db_printf("%s,", condname[0]); break;
- case 2 : db_printf("%s,", condname[1]); break;
- case 3 : db_printf("%s,", condname[2]); break;
- case 12: db_printf("%s,", condname[3]); break;
- case 13: db_printf("%s,", condname[4]); break;
- case 14: db_printf("%s,", condname[5]); break;
- default: printval(match);
- db_printf(",");
- }
- else {
- printval(match);
- db_printf(",");
- }
-
- db_printf("r%-3d,", rs);
- symofset(disp, 16, iadr);
+ int cond = ( inst >> 26 ) & 1;
+ int match = ( inst >> 21 ) & 037;
+ int rs = ( inst >> 16 ) & 037;
+ int disp = ( inst & 0177777 );
+
+ if ( cond == 0 )
+ db_printf("\t%s\t\t", opcode);
+ else
+ db_printf("\t%s.n\t\t", opcode);
+ if ( ( ( inst >> 27 ) & 03 ) == 1 )
+ switch (match) {
+ case 1 : db_printf("%s,", condname[0]); break;
+ case 2 : db_printf("%s,", condname[1]); break;
+ case 3 : db_printf("%s,", condname[2]); break;
+ case 12: db_printf("%s,", condname[3]); break;
+ case 13: db_printf("%s,", condname[4]); break;
+ case 14: db_printf("%s,", condname[5]); break;
+ default: printval(match);
+ db_printf(",");
+ } else {
+ printval(match);
+ db_printf(",");
+ }
+
+ db_printf("r%-3d,", rs);
+ symofset(disp, 16, iadr);
}
void
otrap(int inst, char *opcode, long iadr)
{
- int vecno = inst & 0777;
- int match = ( inst >> 21 ) & 037;
- int rs = ( inst >> 16 ) & 037;
-
- db_printf("\t%s\t",opcode);
- if ( ( ( inst >> 12 ) & 017 ) == 0xe )
- switch (match) {
- case 1 : db_printf("%s,", condname[0]);break;
- case 2 : db_printf("%s,", condname[1]);break;
- case 3 : db_printf("%s,", condname[2]);break;
- case 12: db_printf("%s,", condname[3]);break;
- case 13: db_printf("%s,", condname[4]);break;
- case 14: db_printf("%s,", condname[5]);break;
- default: printval(match);
- db_printf(",");
- }
- else {
- printval(match);
- db_printf(",");
- }
- db_printf("\tr%-3d,", rs);
- printval(vecno);
+ int vecno = inst & 0777;
+ int match = ( inst >> 21 ) & 037;
+ int rs = ( inst >> 16 ) & 037;
+
+ db_printf("\t%s\t",opcode);
+ if ( ( ( inst >> 12 ) & 017 ) == 0xe )
+ switch (match) {
+ case 1 : db_printf("%s,", condname[0]);break;
+ case 2 : db_printf("%s,", condname[1]);break;
+ case 3 : db_printf("%s,", condname[2]);break;
+ case 12: db_printf("%s,", condname[3]);break;
+ case 13: db_printf("%s,", condname[4]);break;
+ case 14: db_printf("%s,", condname[5]);break;
+ default: printval(match);
+ db_printf(",");
+ } else {
+ printval(match);
+ db_printf(",");
+ }
+ db_printf("\tr%-3d,", rs);
+ printval(vecno);
}
@@ -323,24 +377,22 @@ otrap(int inst, char *opcode, long iadr)
void
obit(int inst, char *opcode, long iadr)
{
- int rs = ( inst >> 16 ) & 037;
- int rd = ( inst >> 21 ) & 037;
- int width = ( inst >> 5 ) & 037;
- int offset = ( inst & 037 );
-
- db_printf("\t%s\t\tr%-3d,r%-3d,", opcode, rd, rs);
- if ( ( ( inst >> 10 ) & 077 ) == 052 ) {
- db_printf("<");
- printval(offset);
- db_printf(">");
- }
- else
- {
- printval(width);
- db_printf("<");
- printval(offset);
- db_printf(">");
- }
+ int rs = ( inst >> 16 ) & 037;
+ int rd = ( inst >> 21 ) & 037;
+ int width = ( inst >> 5 ) & 037;
+ int offset = ( inst & 037 );
+
+ db_printf("\t%s\t\tr%-3d,r%-3d,", opcode, rd, rs);
+ if ( ( ( inst >> 10 ) & 077 ) == 052 ) {
+ db_printf("<");
+ printval(offset);
+ db_printf(">");
+ } else {
+ printval(width);
+ db_printf("<");
+ printval(offset);
+ db_printf(">");
+ }
}
@@ -348,12 +400,12 @@ obit(int inst, char *opcode, long iadr)
void
bitman(int inst, char *opcode, long iadr)
{
-
- int rs1 = ( inst >> 16 ) & 037;
- int rd = ( inst >> 21 ) & 037;
- int rs2 = inst & 037;
-
- db_printf("\t%s\t\tr%-3d,r%-3d,r%-3d", opcode, rd, rs1, rs2);
+
+ int rs1 = ( inst >> 16 ) & 037;
+ int rd = ( inst >> 21 ) & 037;
+ int rs2 = inst & 037;
+
+ db_printf("\t%s\t\tr%-3d,r%-3d,r%-3d", opcode, rd, rs1, rs2);
}
@@ -361,30 +413,29 @@ bitman(int inst, char *opcode, long iadr)
void
immem(int inst, char *opcode, long iadr)
{
- register int immed = inst & 0xFFFF;
- register int rd = (inst >> 21) & 037;
- register int rs = (inst >> 16) & 037;
- register int st_lda = (inst >> 28) & 03;
- register int aryno = (inst >> 26) & 03;
- char c = ' ';
-
- if (!st_lda) {
- if ((aryno == 0) || (aryno == 01))
- opcode = "xmem";
- else
- opcode = "ld";
- if (aryno == 0)
- aryno = 03;
- if (!(aryno == 01))
- c = 'u';
- }
- else
- if (st_lda == 01)
- opcode = "ld";
-
- db_printf("\t%s%s%c\t\tr%-3d,r%-3d,", opcode, instwidth[aryno],
- c, rd, rs);
- printval(immed);
+ register int immed = inst & 0xFFFF;
+ register int rd = (inst >> 21) & 037;
+ register int rs = (inst >> 16) & 037;
+ register int st_lda = (inst >> 28) & 03;
+ register int aryno = (inst >> 26) & 03;
+ char c = ' ';
+
+ if (!st_lda) {
+ if ((aryno == 0) || (aryno == 01))
+ opcode = "xmem";
+ else
+ opcode = "ld";
+ if (aryno == 0)
+ aryno = 03;
+ if (!(aryno == 01))
+ c = 'u';
+ } else
+ if (st_lda == 01)
+ opcode = "ld";
+
+ db_printf("\t%s%s%c\t\tr%-3d,r%-3d,", opcode, instwidth[aryno],
+ c, rd, rs);
+ printval(immed);
}
@@ -392,59 +443,57 @@ immem(int inst, char *opcode, long iadr)
void
nimmem(int inst, char *opcode, long iadr)
{
- register int scaled = (inst >> 9) & 01;
- register int rd = (inst >> 21) & 037;
- register int rs1 = (inst >> 16) & 037;
- register int rs2 = inst & 037;
- register int st_lda = (inst >> 12) & 03;
- register int aryno = (inst >> 10) & 03;
- register int user_bit = 0;
- int signed_fg = 1;
- char *user = " ";
- char c = ' ';
-
- if (!st_lda) {
- if ((aryno == 0) || (aryno == 01))
- opcode = "xmem";
- else
- opcode = "ld";
- if (aryno == 0)
- aryno = 03;
- if (!(aryno == 01)) {
- c = 'u';
- signed_fg = 0;
- }
- }
- else
- if (st_lda == 01)
- opcode = "ld";
-
- if (!(st_lda == 03)) {
- user_bit = (inst >> 8) & 01;
- if (user_bit)
- user = ".usr";
- }
-
- if (user_bit && signed_fg && (aryno == 01)) {
- if (st_lda)
- db_printf("\t%s%s\tr%-3d,r%-3d", opcode,
- user, rd, rs1);
- else
- db_printf("\t%s%s\tr%-3d,r%-3d", opcode,
- user, rd, rs1);
- }
- else
- if (user_bit && signed_fg)
- db_printf("\t%s%s%s\tr%-3d,r%-3d", opcode,
- instwidth[aryno], user, rd, rs1);
- else
- db_printf("\t%s%s%c%s\tr%-3d,r%-3d", opcode,
- instwidth[aryno], c, user, rd, rs1);
-
- if (scaled)
- db_printf("[r%-3d]", rs2);
- else
- db_printf(",r%-3d", rs2);
+ register int scaled = (inst >> 9) & 01;
+ register int rd = (inst >> 21) & 037;
+ register int rs1 = (inst >> 16) & 037;
+ register int rs2 = inst & 037;
+ register int st_lda = (inst >> 12) & 03;
+ register int aryno = (inst >> 10) & 03;
+ register int user_bit = 0;
+ int signed_fg = 1;
+ char *user = " ";
+ char c = ' ';
+
+ if (!st_lda) {
+ if ((aryno == 0) || (aryno == 01))
+ opcode = "xmem";
+ else
+ opcode = "ld";
+ if (aryno == 0)
+ aryno = 03;
+ if (!(aryno == 01)) {
+ c = 'u';
+ signed_fg = 0;
+ }
+ } else
+ if (st_lda == 01)
+ opcode = "ld";
+
+ if (!(st_lda == 03)) {
+ user_bit = (inst >> 8) & 01;
+ if (user_bit)
+ user = ".usr";
+ }
+
+ if (user_bit && signed_fg && (aryno == 01)) {
+ if (st_lda)
+ db_printf("\t%s%s\tr%-3d,r%-3d", opcode,
+ user, rd, rs1);
+ else
+ db_printf("\t%s%s\tr%-3d,r%-3d", opcode,
+ user, rd, rs1);
+ } else
+ if (user_bit && signed_fg)
+ db_printf("\t%s%s%s\tr%-3d,r%-3d", opcode,
+ instwidth[aryno], user, rd, rs1);
+ else
+ db_printf("\t%s%s%c%s\tr%-3d,r%-3d", opcode,
+ instwidth[aryno], c, user, rd, rs1);
+
+ if (scaled)
+ db_printf("[r%-3d]", rs2);
+ else
+ db_printf(",r%-3d", rs2);
}
@@ -452,16 +501,16 @@ nimmem(int inst, char *opcode, long iadr)
void
lognim(int inst, char *opcode, long iadr)
{
- register int rd = (inst >> 21) & 037;
- register int rs1 = (inst >> 16) & 037;
- register int rs2 = inst & 037;
- register int complemt = (inst >> 10) & 01;
- char *c = " ";
-
- if (complemt)
- c = ".c";
-
- db_printf("\t%s%s\t\tr%-3d,r%-3d,r%-3d", opcode, c, rd, rs1, rs2);
+ register int rd = (inst >> 21) & 037;
+ register int rs1 = (inst >> 16) & 037;
+ register int rs2 = inst & 037;
+ register int complemt = (inst >> 10) & 01;
+ char *c = " ";
+
+ if (complemt)
+ c = ".c";
+
+ db_printf("\t%s%s\t\tr%-3d,r%-3d,r%-3d", opcode, c, rd, rs1, rs2);
}
@@ -469,137 +518,136 @@ lognim(int inst, char *opcode, long iadr)
void
onimmed(int inst, char *opcode, long iadr)
{
- register int rd = (inst >> 21) & 037;
- register int rs1 = (inst >> 16) & 037;
- register int rs2 = inst & 037;
- register int carry = (inst >> 8) & 03;
- register int nochar = (inst >> 10) & 07;
- register int nodecode = (inst >> 11) & 01;
- char *tab, *c ;
-
- if (nochar > 02)
- tab = "\t\t";
- else
- tab = "\t";
-
- if (!nodecode) {
- if (carry == 01)
- c = ".co ";
- else
- if (carry == 02)
- c = ".ci ";
- else
- if (carry == 03)
- c = ".cio";
+ register int rd = (inst >> 21) & 037;
+ register int rs1 = (inst >> 16) & 037;
+ register int rs2 = inst & 037;
+ register int carry = (inst >> 8) & 03;
+ register int nochar = (inst >> 10) & 07;
+ register int nodecode = (inst >> 11) & 01;
+ char *tab, *c ;
+
+ if (nochar > 02)
+ tab = "\t\t";
else
- c = " ";
- }
- else
- c = " ";
-
- db_printf("\t%s%s%sr%-3d,r%-3d,r%-3d", opcode, c,
- tab, rd, rs1, rs2);
+ tab = "\t";
+
+ if (!nodecode) {
+ if (carry == 01)
+ c = ".co ";
+ else
+ if (carry == 02)
+ c = ".ci ";
+ else
+ if (carry == 03)
+ c = ".cio";
+ else
+ c = " ";
+ } else
+ c = " ";
+
+ db_printf("\t%s%s%sr%-3d,r%-3d,r%-3d", opcode, c,
+ tab, rd, rs1, rs2);
}
static struct opdesc {
- unsigned mask, match;
- void (*opfun) __P((int, char *, long));
- char *farg;
+ unsigned mask, match;
+ void (*opfun) __P((int, char *, long));
+ char *farg;
} opdecode[] = {
- /* ORDER IS IMPORTANT BELOW */
-
- { 0xF0000000U, 0x00000000U, immem, 0, },
- { 0xF0000000U, 0x10000000U, immem, 0, },
- { 0xF0000000U, 0x20000000U, immem, "st" },
- { 0xF0000000U, 0x30000000U, immem, "lda" },
-
- { 0xF8000000U, 0x40000000U, oimmed, "and" },
- { 0xF8000000U, 0x48000000U, oimmed, "mask" },
- { 0xF8000000U, 0x50000000U, oimmed, "xor" },
- { 0xF8000000U, 0x58000000U, oimmed, "or" },
- { 0xFC000000U, 0x60000000U, oimmed, "addu" },
- { 0xFC000000U, 0x64000000U, oimmed, "subu" },
- { 0xFC000000U, 0x68000000U, oimmed, "divu" },
- { 0xFC000000U, 0x6C000000U, oimmed, "mul" },
- { 0xFC000000U, 0x70000000U, oimmed, "add" },
- { 0xFC000000U, 0x74000000U, oimmed, "sub" },
- { 0xFC000000U, 0x78000000U, oimmed, "div" },
- { 0xFC000000U, 0x7C000000U, oimmed, "cmp" },
-
- { 0xFC00F800U, 0x80004000U, ctrlregs, "ldcr" },
- { 0xFC00F800U, 0x80004800U, ctrlregs, "fldcr" },
- { 0xFC00F800U, 0x80008000U, ctrlregs, "stcr" },
- { 0xFC00F800U, 0x80008800U, ctrlregs, "fstcr" },
- { 0xFC00F800U, 0x8000C000U, ctrlregs, "xcr" },
- { 0xFC00F800U, 0x8000C800U, ctrlregs, "fxcr" },
-
- { 0xFC00F800U, 0x84000000U, sindou, "fmul" },
- { 0xFC1FFF80U, 0x84002000U, sindou, "flt" },
- { 0xFC00F800U, 0x84002800U, sindou, "fadd" },
- { 0xFC00F800U, 0x84003000U, sindou, "fsub" },
- { 0xFC00F860U, 0x84003800U, sindou, "fcmp" },
- { 0xFC1FFE60U, 0x84004800U, sindou, "int" },
- { 0xFC1FFE60U, 0x84005000U, sindou, "nint" },
- { 0xFC1FFE60U, 0x84005800U, sindou, "trnc" },
- { 0xFC00F800U, 0x84007000U, sindou, "fdiv" },
-
- { 0xF8000000U, 0xC0000000U, obranch, "br" },
- { 0xF8000000U, 0xC8000000U, obranch, "bsr" },
-
- { 0xF8000000U, 0xD0000000U, brcond, "bb0" },
- { 0xF8000000U, 0xD8000000U, brcond, "bb1" },
- { 0xF8000000U, 0xE8000000U, brcond, "bcnd" },
-
- { 0xFC00FC00U, 0xF0008000U, obit, "clr" },
- { 0xFC00FC00U, 0xF0008800U, obit, "set" },
- { 0xFC00FC00U, 0xF0009000U, obit, "ext" },
- { 0xFC00FC00U, 0xF0009800U, obit, "extu" },
- { 0xFC00FC00U, 0xF000A000U, obit, "mak" },
- { 0xFC00FC00U, 0xF000A800U, obit, "rot" },
-
- { 0xFC00FE00U, 0xF000D000U, otrap, "tb0" },
- { 0xFC00FE00U, 0xF000D800U, otrap, "tb1" },
- { 0xFC00FE00U, 0xF000E800U, otrap, "tcnd" },
-
- { 0xFC00F2E0U, 0xF4000000U, nimmem, 0, },
- { 0xFC00F2E0U, 0xF4000200U, nimmem, 0, },
- { 0xFC00F2E0U, 0xF4001000U, nimmem, 0, },
- { 0xFC00F2E0U, 0xF4001200U, nimmem, 0, },
- { 0xFC00F2E0U, 0xF4002000U, nimmem, "st" },
- { 0xFC00F2E0U, 0xF4002200U, nimmem, "st" },
- { 0xFC00F2E0U, 0xF4003000U, nimmem, "lda" },
- { 0xFC00F2E0U, 0xF4003200U, nimmem, "lda" },
-
- { 0xFC00FBE0U, 0xF4004000U, lognim, "and" },
- { 0xFC00FBE0U, 0xF4005000U, lognim, "xor" },
- { 0xFC00FBE0U, 0xF4005800U, lognim, "or" },
-
- { 0xFC00FCE0U, 0xF4006000U, onimmed, "addu" },
- { 0xFC00FCE0U, 0xF4006400U, onimmed, "subu" },
- { 0xFC00FCE0U, 0xF4006800U, onimmed, "divu" },
- { 0xFC00FCE0U, 0xF4006C00U, onimmed, "mul" },
- { 0xFC00FCE0U, 0xF4007000U, onimmed, "add" },
- { 0xFC00FCE0U, 0xF4007400U, onimmed, "sub" },
- { 0xFC00FCE0U, 0xF4007800U, onimmed, "div" },
- { 0xFC00FCE0U, 0xF4007C00U, onimmed, "cmp" },
-
- { 0xFC00FFE0U, 0xF4008000U, bitman, "clr" },
- { 0xFC00FFE0U, 0xF4008800U, bitman, "set" },
- { 0xFC00FFE0U, 0xF4009000U, bitman, "ext" },
- { 0xFC00FFE0U, 0xF4009800U, bitman, "extu" },
- { 0xFC00FFE0U, 0xF400A000U, bitman, "mak" },
- { 0xFC00FFE0U, 0xF400A800U, bitman, "rot" },
-
- { 0xFC00FBE0U, 0xF400C000U, jump, "jmp" },
- { 0xFC00FBE0U, 0xF400C800U, jump, "jsr" },
-
- { 0xFC00FFE0U, 0xF400E800U, instset, "ff1" },
- { 0xFC00FFE0U, 0xF400EC00U, instset, "ff0" },
- { 0xFC00FFE0U, 0xF400F800U, instset, "tbnd" },
- { 0xFC00FFE0U, 0xF400FC00U, instset, "rte" },
- { 0xFC000000U, 0xF8000000U, instset, "tbnd" },
- { 0,0,0,0 }
+ /* ORDER IS IMPORTANT BELOW */
+
+ { 0xF0000000U, 0x00000000U, immem, 0,},
+ { 0xF0000000U, 0x10000000U, immem, 0,},
+ { 0xF0000000U, 0x20000000U, immem, "st"},
+ { 0xF0000000U, 0x30000000U, immem, "lda"},
+
+ { 0xF8000000U, 0x40000000U, oimmed, "and"},
+ { 0xF8000000U, 0x48000000U, oimmed, "mask"},
+ { 0xF8000000U, 0x50000000U, oimmed, "xor"},
+ { 0xF8000000U, 0x58000000U, oimmed, "or"},
+ { 0xFC000000U, 0x60000000U, oimmed, "addu"},
+ { 0xFC000000U, 0x64000000U, oimmed, "subu"},
+ { 0xFC000000U, 0x68000000U, oimmed, "divu"},
+ { 0xFC000000U, 0x6C000000U, oimmed, "mul"},
+ { 0xFC000000U, 0x70000000U, oimmed, "add"},
+ { 0xFC000000U, 0x74000000U, oimmed, "sub"},
+ { 0xFC000000U, 0x78000000U, oimmed, "div"},
+ { 0xFC000000U, 0x7C000000U, oimmed, "cmp"},
+
+ { 0xFC00F800U, 0x80004000U, ctrlregs, "ldcr"},
+ { 0xFC00F800U, 0x80004800U, ctrlregs, "fldcr"},
+ { 0xFC00F800U, 0x80008000U, ctrlregs, "stcr"},
+ { 0xFC00F800U, 0x80008800U, ctrlregs, "fstcr"},
+ { 0xFC00F800U, 0x8000C000U, ctrlregs, "xcr"},
+ { 0xFC00F800U, 0x8000C800U, ctrlregs, "fxcr"},
+
+ { 0xFC00F800U, 0x84000000U, sindou, "fmul"},
+ { 0xFC1FFF80U, 0x84002000U, sindou, "flt"},
+ { 0xFC00F800U, 0x84002800U, sindou, "fadd"},
+ { 0xFC00F800U, 0x84003000U, sindou, "fsub"},
+ { 0xFC00F860U, 0x84003800U, sindou, "fcmp"},
+ { 0xFC1FFE60U, 0x84004800U, sindou, "int"},
+ { 0xFC1FFE60U, 0x84005000U, sindou, "nint"},
+ { 0xFC1FFE60U, 0x84005800U, sindou, "trnc"},
+ { 0xFC00F800U, 0x84007000U, sindou, "fdiv"},
+
+ { 0xF8000000U, 0xC0000000U, obranch, "br"},
+ { 0xF8000000U, 0xC8000000U, obranch, "bsr"},
+
+ { 0xF8000000U, 0xD0000000U, brcond, "bb0"},
+ { 0xF8000000U, 0xD8000000U, brcond, "bb1"},
+ { 0xF8000000U, 0xE8000000U, brcond, "bcnd"},
+
+ { 0xFC00FC00U, 0xF0008000U, obit, "clr"},
+ { 0xFC00FC00U, 0xF0008800U, obit, "set"},
+ { 0xFC00FC00U, 0xF0009000U, obit, "ext"},
+ { 0xFC00FC00U, 0xF0009800U, obit, "extu"},
+ { 0xFC00FC00U, 0xF000A000U, obit, "mak"},
+ { 0xFC00FC00U, 0xF000A800U, obit, "rot"},
+
+ { 0xFC00FE00U, 0xF000D000U, otrap, "tb0"},
+ { 0xFC00FE00U, 0xF000D800U, otrap, "tb1"},
+ { 0xFC00FE00U, 0xF000E800U, otrap, "tcnd"},
+
+ { 0xFC00F2E0U, 0xF4000000U, nimmem, 0,},
+ { 0xFC00F2E0U, 0xF4000200U, nimmem, 0,},
+ { 0xFC00F2E0U, 0xF4001000U, nimmem, 0,},
+ { 0xFC00F2E0U, 0xF4001200U, nimmem, 0,},
+ { 0xFC00F2E0U, 0xF4002000U, nimmem, "st"},
+ { 0xFC00F2E0U, 0xF4002200U, nimmem, "st"},
+ { 0xFC00F2E0U, 0xF4003000U, nimmem, "lda"},
+ { 0xFC00F2E0U, 0xF4003200U, nimmem, "lda"},
+
+ { 0xFC00FBE0U, 0xF4004000U, lognim, "and"},
+ { 0xFC00FBE0U, 0xF4005000U, lognim, "xor"},
+ { 0xFC00FBE0U, 0xF4005800U, lognim, "or"},
+
+ { 0xFC00FCE0U, 0xF4006000U, onimmed, "addu"},
+ { 0xFC00FCE0U, 0xF4006400U, onimmed, "subu"},
+ { 0xFC00FCE0U, 0xF4006800U, onimmed, "divu"},
+ { 0xFC00FCE0U, 0xF4006C00U, onimmed, "mul"},
+ { 0xFC00FCE0U, 0xF4007000U, onimmed, "add"},
+ { 0xFC00FCE0U, 0xF4007400U, onimmed, "sub"},
+ { 0xFC00FCE0U, 0xF4007800U, onimmed, "div"},
+ { 0xFC00FCE0U, 0xF4007C00U, onimmed, "cmp"},
+
+ { 0xFC00FFE0U, 0xF4008000U, bitman, "clr"},
+ { 0xFC00FFE0U, 0xF4008800U, bitman, "set"},
+ { 0xFC00FFE0U, 0xF4009000U, bitman, "ext"},
+ { 0xFC00FFE0U, 0xF4009800U, bitman, "extu"},
+ { 0xFC00FFE0U, 0xF400A000U, bitman, "mak"},
+ { 0xFC00FFE0U, 0xF400A800U, bitman, "rot"},
+
+ { 0xFC00FBE0U, 0xF400C000U, jump, "jmp"},
+ { 0xFC00FBE0U, 0xF400C800U, jump, "jsr"},
+
+ { 0xFC00FFE0U, 0xF400E800U, instset, "ff1"},
+ { 0xFC00FFE0U, 0xF400EC00U, instset, "ff0"},
+ { 0xFC00FFE0U, 0xF400F800U, instset, "tbnd"},
+ { 0xFC00FFE0U, 0xF400FC00U, instset, "rte"},
+ { 0xFC000000U, 0xF8000000U, instset, "tbnd"},
+ { 0,0,0,0}
};
static char *badop = "\t???";
@@ -607,31 +655,29 @@ static char *badop = "\t???";
int
m88k_print_instruction(unsigned iadr, long inst)
{
- register struct opdesc *p;
-
- /* this messes up "orb" instructions ever so slightly, */
- /* but keeps us in sync between routines... */
- if (inst == 0) {
- db_printf ("\t.word 0");
- }
- else
- {
- for (p = opdecode; p->mask; p++)
- if ((inst & p->mask) == p->match) {
- (*p->opfun) (inst, p->farg, iadr);
- break;
+ register struct opdesc *p;
+
+ /* this messes up "orb" instructions ever so slightly, */
+ /* but keeps us in sync between routines... */
+ if (inst == 0) {
+ db_printf ("\t.word 0");
+ } else {
+ for (p = opdecode; p->mask; p++)
+ if ((inst & p->mask) == p->match) {
+ (*p->opfun) (inst, p->farg, iadr);
+ break;
+ }
+ if (!p->mask)
+ db_printf (badop);
}
- if (!p->mask)
- db_printf (badop);
- }
- return iadr+4;
+ return iadr+4;
}
db_addr_t
db_disasm(db_addr_t loc, boolean_t altfmt)
{
- m88k_print_instruction(loc, db_get_value(loc, 4, FALSE));
- db_printf ("\n");
- return loc+4;
+ m88k_print_instruction(loc, db_get_value(loc, 4, FALSE));
+ db_printf ("\n");
+ return loc+4;
}
diff --git a/sys/arch/mvme88k/ddb/db_interface.c b/sys/arch/mvme88k/ddb/db_interface.c
index c6e3d68653d..c58a5fca844 100644
--- a/sys/arch/mvme88k/ddb/db_interface.c
+++ b/sys/arch/mvme88k/ddb/db_interface.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_interface.c,v 1.22 2001/12/22 07:35:43 smurph Exp $ */
+/* $OpenBSD: db_interface.c,v 1.23 2001/12/22 08:31:04 smurph Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1991 Carnegie Mellon University
@@ -37,10 +37,11 @@
#include <uvm/uvm_extern.h>
-#include <machine/m8820x.h> /* CMMU defs */
-#include <machine/trap.h> /* current_thread() */
-#include <machine/db_machdep.h> /* local ddb stuff */
-#include <machine/bugio.h> /* bug routines */
+#include <machine/asm_macro.h> /* flush_pipeline() */
+#include <machine/m8820x.h> /* CMMU defs */
+#include <machine/trap.h> /* current_thread() */
+#include <machine/db_machdep.h> /* local ddb stuff */
+#include <machine/bugio.h> /* bug routines */
#include <machine/locore.h>
#include <machine/mmu.h>
#include <machine/cpu_number.h>
@@ -70,6 +71,7 @@ char *db_task_name __P((void));
int m88k_dmx_print __P((unsigned, unsigned, unsigned, unsigned));
void m88k_db_pause __P((unsigned));
void m88k_db_print_frame __P((db_expr_t, int, db_expr_t, char *));
+void m88k_db_registers __P((db_expr_t, int, db_expr_t, char *));
void m88k_db_where __P((db_expr_t, int, db_expr_t, char *));
void m88k_db_frame_search __P((db_expr_t, int, db_expr_t, char *));
void m88k_db_iflush __P((db_expr_t, int, db_expr_t, char *));
@@ -125,29 +127,29 @@ m88k_dmx_print(t, d, a, no)
unsigned t, d, a, no;
{
static unsigned addr_mod[16] = {
- 0, 3, 2, 2, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 3, 2, 2, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
};
static char *mode[16] = {
- "?", ".b", ".b", ".h", ".b", "?", "?", "?",
- ".b", ".h", "?" , "?" , "?" , "?", "?", ""
+ "?", ".b", ".b", ".h", ".b", "?", "?", "?",
+ ".b", ".h", "?" , "?" , "?" , "?", "?", ""
};
static unsigned mask[16] = {
- 0, 0xff, 0xff00, 0xffff,
- 0xff0000, 0, 0, 0,
- 0xff000000U, 0xffff0000U, 0, 0,
- 0, 0, 0, 0xffffffffU
+ 0, 0xff, 0xff00, 0xffff,
+ 0xff0000, 0, 0, 0,
+ 0xff000000U, 0xffff0000U, 0, 0,
+ 0, 0, 0, 0xffffffffU
};
static unsigned shift[16] = {
- 0, 0, 8, 0, 16, 0, 0, 0,
- 24, 16, 0, 0, 0, 0, 0, 0
+ 0, 0, 8, 0, 16, 0, 0, 0,
+ 24, 16, 0, 0, 0, 0, 0, 0
};
int reg = REG(t);
if (XMEM(t)) {
db_printf("xmem%s%s r%d(0x%x) <-> mem(0x%x),",
- XMEM_MODE(t), DAS(t), reg,
- (((t)>>2 & 0xf) == 0xf) ? d : (d & 0xff), a);
+ XMEM_MODE(t), DAS(t), reg,
+ (((t)>>2 & 0xf) == 0xf) ? d : (d & 0xff), a);
return 1;
} else {
if (MODE(t) == 0xf) {
@@ -155,30 +157,30 @@ m88k_dmx_print(t, d, a, no)
if (STORE(t)) {
if (DOUB(t) && no == 2)
db_printf("st.d%s -> mem(0x%x) (** restart sxip **)",
- DAS(t), a);
+ DAS(t), a);
else
db_printf("st%s (0x%x) -> mem(0x%x)",
- DAS(t), d, a);
+ DAS(t), d, a);
} else {
/* load */
if (DOUB(t) && no == 2)
db_printf("ld.d%s r%d <- mem(0x%x), r%d <- mem(0x%x)",
- DAS(t), reg, a, reg+1, a+4);
+ DAS(t), reg, a, reg+1, a+4);
else
db_printf("ld%s r%d <- mem(0x%x)",
- DAS(t), reg, a);
+ DAS(t), reg, a);
}
} else {
/* fractional word - check if load or store */
a += addr_mod[MODE(t)];
if (STORE(t))
db_printf("st%s%s (0x%x) -> mem(0x%x)",
- mode[MODE(t)], DAS(t),
- (d & mask[MODE(t)]) >> shift[MODE(t)], a);
+ mode[MODE(t)], DAS(t),
+ (d & mask[MODE(t)]) >> shift[MODE(t)], a);
else
db_printf("ld%s%s%s r%d <- mem(0x%x)",
- mode[MODE(t)], SIGN(t) ? "" : "u",
- DAS(t), reg, a);
+ mode[MODE(t)], SIGN(t) ? "" : "u",
+ DAS(t), reg, a);
}
}
return 0;
@@ -243,46 +245,55 @@ m88k_db_print_frame(addr, have_addr, count, modif)
#define R(i) s->r[i]
#define IPMASK(x) ((x) & ~(3))
db_printf("R00-05: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- R(0), R(1), R(2), R(3), R(4), R(5));
+ R(0), R(1), R(2), R(3), R(4), R(5));
db_printf("R06-11: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- R(6), R(7), R(8), R(9), R(10), R(11));
+ R(6), R(7), R(8), R(9), R(10), R(11));
db_printf("R12-17: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- R(12), R(13), R(14), R(15), R(16), R(17));
+ R(12), R(13), R(14), R(15), R(16), R(17));
db_printf("R18-23: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- R(18), R(19), R(20), R(21), R(22), R(23));
+ R(18), R(19), R(20), R(21), R(22), R(23));
db_printf("R24-29: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
- R(24), R(25), R(26), R(27), R(28), R(29));
+ R(24), R(25), R(26), R(27), R(28), R(29));
db_printf("R30-31: 0x%08x 0x%08x\n", R(30), R(31));
- db_printf("sxip: 0x%08x ", s->sxip & ~3);
+ db_printf("%sxip: 0x%08x ", cputyp == CPU_88110 ? "e" : "s", s->sxip & ~3);
db_find_xtrn_sym_and_offset((db_addr_t)IPMASK(s->sxip),
- &name, &offset);
+ &name, &offset);
if (name != 0 && (unsigned)offset <= db_maxoff)
db_printf("%s+0x%08x", name, (unsigned)offset);
db_printf("\n");
if (s->snip != s->sxip + 4) {
- db_printf("snip: 0x%08x ", s->snip);
+ db_printf("%snip: 0x%08x ", cputyp == CPU_88110 ? "e" : "s", s->snip);
db_find_xtrn_sym_and_offset((db_addr_t)IPMASK(s->snip),
- &name, &offset);
+ &name, &offset);
if (name != 0 && (unsigned)offset <= db_maxoff)
db_printf("%s+0x%08x", name, (unsigned)offset);
db_printf("\n");
}
- if (s->sfip != s->snip + 4) {
- db_printf("sfip: 0x%08x ", s->sfip);
- db_find_xtrn_sym_and_offset((db_addr_t)IPMASK(s->sfip),
- &name, &offset);
- if (name != 0 && (unsigned)offset <= db_maxoff)
- db_printf("%s+0x%08x", name, (unsigned)offset);
- db_printf("\n");
+ if (cputyp != CPU_88110) {
+ if (s->sfip != s->snip + 4) {
+ db_printf("sfip: 0x%08x ", s->sfip);
+ db_find_xtrn_sym_and_offset((db_addr_t)IPMASK(s->sfip),
+ &name, &offset);
+ if (name != 0 && (unsigned)offset <= db_maxoff)
+ db_printf("%s+0x%08x", name, (unsigned)offset);
+ db_printf("\n");
+ }
+ } else {
+ db_printf("fpsr: 0x%08x fpcr: 0x%08x fpecr: 0x%08x\n",
+ s->fpsr, s->fpcr, s->fpecr);
+ db_printf("dsap 0x%08x duap 0x%08x dsr 0x%08x dlar 0x%08x dpar 0x%08x\n",
+ s->dsap, s->duap, s->dsr, s->dlar, s->dpar);
+ db_printf("isap 0x%08x iuap 0x%08x isr 0x%08x ilar 0x%08x ipar 0x%08x\n",
+ s->isap, s->iuap, s->isr, s->ilar, s->ipar);
}
- db_printf("vector: 0x%02x interrupt mask: 0x%08x\n",
- s->vector, s->mask);
db_printf("epsr: 0x%08x current process: 0x%x\n",
- s->epsr, curproc);
+ s->epsr, curproc);
+ db_printf("vector: 0x%02x interrupt mask: 0x%08x\n",
+ s->vector, s->mask);
/*
* If the vector indicates trap, instead of an exception or
@@ -292,54 +303,68 @@ m88k_db_print_frame(addr, have_addr, count, modif)
*/
if (!(s->vector <= 10 || (114 <= s->vector && s->vector <= 127))) {
- db_printf("\n\n");
+ db_printf("\n");
return;
}
- if (s->vector == /*data*/3 || s->dmt0 & 1) {
- db_printf("dmt,d,a0: 0x%08x 0x%08x 0x%08x ",
- s->dmt0, s->dmd0, s->dma0);
- db_find_xtrn_sym_and_offset((db_addr_t)s->dma0, &name, &offset);
- if (name != 0 && (unsigned)offset <= db_maxoff)
- db_printf("%s+0x%08x", name, (unsigned)offset);
- db_printf("\n ");
- surpress1 = m88k_dmx_print(s->dmt0|0x01, s->dmd0, s->dma0, 0);
- db_printf("\n");
-
- if ((s->dmt1 & 1) && (!surpress1)) {
- db_printf("dmt,d,a1: 0x%08x 0x%08x 0x%08x ",
- s->dmt1, s->dmd1, s->dma1);
- db_find_xtrn_sym_and_offset((db_addr_t)s->dma1,
- &name, &offset);
+ if (cputyp != CPU_88110) {
+ if (s->vector == /*data*/3 || s->dmt0 & 1) {
+ db_printf("dmt,d,a0: 0x%08x 0x%08x 0x%08x ",
+ s->dmt0, s->dmd0, s->dma0);
+ db_find_xtrn_sym_and_offset((db_addr_t)s->dma0, &name, &offset);
if (name != 0 && (unsigned)offset <= db_maxoff)
db_printf("%s+0x%08x", name, (unsigned)offset);
db_printf("\n ");
- surpress2 = m88k_dmx_print(s->dmt1, s->dmd1, s->dma1, 1);
+ surpress1 = m88k_dmx_print(s->dmt0|0x01, s->dmd0, s->dma0, 0);
db_printf("\n");
- if ((s->dmt2 & 1) && (!surpress2)) {
- db_printf("dmt,d,a2: 0x%08x 0x%08x 0x%08x ",
- s->dmt2, s->dmd2, s->dma2);
- db_find_xtrn_sym_and_offset((db_addr_t)s->dma2,
- &name, &offset);
+ if ((s->dmt1 & 1) && (!surpress1)) {
+ db_printf("dmt,d,a1: 0x%08x 0x%08x 0x%08x ",
+ s->dmt1, s->dmd1, s->dma1);
+ db_find_xtrn_sym_and_offset((db_addr_t)s->dma1,
+ &name, &offset);
if (name != 0 && (unsigned)offset <= db_maxoff)
db_printf("%s+0x%08x", name, (unsigned)offset);
db_printf("\n ");
- m88k_dmx_print(s->dmt2, s->dmd2, s->dma2, 2);
+ surpress2 = m88k_dmx_print(s->dmt1, s->dmd1, s->dma1, 1);
db_printf("\n");
+
+ if ((s->dmt2 & 1) && (!surpress2)) {
+ db_printf("dmt,d,a2: 0x%08x 0x%08x 0x%08x ",
+ s->dmt2, s->dmd2, s->dma2);
+ db_find_xtrn_sym_and_offset((db_addr_t)s->dma2,
+ &name, &offset);
+ if (name != 0 && (unsigned)offset <= db_maxoff)
+ db_printf("%s+0x%08x", name, (unsigned)offset);
+ db_printf("\n ");
+ m88k_dmx_print(s->dmt2, s->dmd2, s->dma2, 2);
+ db_printf("\n");
+ }
}
}
}
if (s->fpecr & 255) { /* floating point error occurred */
db_printf("fpecr: 0x%08x fpsr: 0x%08x fpcr: 0x%08x\n",
- s->fpecr, s->fpsr, s->fpcr);
- db_printf("fcr1-4: 0x%08x 0x%08x 0x%08x 0x%08x\n",
- s->fphs1, s->fpls1, s->fphs2, s->fpls2);
- db_printf("fcr5-8: 0x%08x 0x%08x 0x%08x 0x%08x\n",
- s->fppt, s->fprh, s->fprl, s->fpit);
+ s->fpecr, s->fpsr, s->fpcr);
+ if (cputyp != CPU_88110) {
+ db_printf("fcr1-4: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ s->fphs1, s->fpls1, s->fphs2, s->fpls2);
+ db_printf("fcr5-8: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ s->fppt, s->fprh, s->fprl, s->fpit);
+ }
}
- db_printf("\n\n");
+ db_printf("\n");
+}
+
+void
+m88k_db_registers(addr, have_addr, count, modif)
+ db_expr_t addr;
+ int have_addr;
+ int count;
+ char *modif;
+{
+ m88k_db_print_frame((db_expr_t)DDB_REGS, TRUE, 0, modif);
}
/************************/
@@ -461,10 +486,13 @@ ddb_break_trap(type, eframe)
if (type == T_KDB_BREAK) {
/*
* back up an instruction and retry the instruction
- * at the breakpoint address
+ * at the breakpoint address. mc88110's exip reg
+ * already has the adress of the exception instruction.
*/
+ if (cputyp != CPU_88110) {
eframe->sfip = eframe->snip;
eframe->snip = eframe->sxip;
+ }
}
return 0;
@@ -668,10 +696,10 @@ m88k_db_peek(addr, have_addr, count, modif)
valmask = cmmu_remote_get(0, CMMU_CSSP, 1);
db_printf("dcache valmask 0x%x\n", (unsigned)valmask);
db_printf("dcache tag ports 0x%x 0x%x 0x%x 0x%x\n",
- (unsigned)cmmu_remote_get(0, CMMU_CTP0, 1),
- (unsigned)cmmu_remote_get(0, CMMU_CTP1, 1),
- (unsigned)cmmu_remote_get(0, CMMU_CTP2, 1),
- (unsigned)cmmu_remote_get(0, CMMU_CTP3, 1));
+ (unsigned)cmmu_remote_get(0, CMMU_CTP0, 1),
+ (unsigned)cmmu_remote_get(0, CMMU_CTP1, 1),
+ (unsigned)cmmu_remote_get(0, CMMU_CTP2, 1),
+ (unsigned)cmmu_remote_get(0, CMMU_CTP3, 1));
/* probe icache */
cmmu_remote_set(0, CMMU_SAR, 0, addr);
@@ -679,10 +707,10 @@ m88k_db_peek(addr, have_addr, count, modif)
valmask = cmmu_remote_get(0, CMMU_CSSP, 0);
db_printf("icache valmask 0x%x\n", (unsigned)valmask);
db_printf("icache tag ports 0x%x 0x%x 0x%x 0x%x\n",
- (unsigned)cmmu_remote_get(0, CMMU_CTP0, 0),
- (unsigned)cmmu_remote_get(0, CMMU_CTP1, 0),
- (unsigned)cmmu_remote_get(0, CMMU_CTP2, 0),
- (unsigned)cmmu_remote_get(0, CMMU_CTP3, 0));
+ (unsigned)cmmu_remote_get(0, CMMU_CTP0, 0),
+ (unsigned)cmmu_remote_get(0, CMMU_CTP1, 0),
+ (unsigned)cmmu_remote_get(0, CMMU_CTP2, 0),
+ (unsigned)cmmu_remote_get(0, CMMU_CTP3, 0));
}
@@ -700,9 +728,9 @@ m88k_db_noise(addr, have_addr, count, modif)
/* if off make noisy; if noisy or very noisy turn off */
if (db_noisy) {
db_printf("changing debugger status from %s to quiet\n",
- db_noisy == 1 ? "noisy" :
- db_noisy == 2 ? "very noisy" : "violent");
- db_noisy = 0;
+ db_noisy == 1 ? "noisy" :
+ db_noisy == 2 ? "very noisy" : "violent");
+ db_noisy = 0;
} else {
db_printf("changing debugger status from quiet to noisy\n");
db_noisy = 1;
@@ -712,9 +740,9 @@ m88k_db_noise(addr, have_addr, count, modif)
else {
db_noisy = addr;
db_printf("debugger noise level set to %s\n",
- db_noisy == 0 ? "quiet" :
- (db_noisy == 1 ? "noisy" :
- db_noisy==2 ? "very noisy" : "violent"));
+ db_noisy == 0 ? "quiet" :
+ (db_noisy == 1 ? "noisy" :
+ db_noisy==2 ? "very noisy" : "violent"));
}
}
@@ -805,23 +833,24 @@ m88k_db_prom_cmd(addr, have_addr, count, modif)
struct db_command m88k_cache_cmds[] =
{
- { "iflush", m88k_db_iflush, 0, 0},
- { "dflush", m88k_db_dflush, 0, 0},
- { "peek", m88k_db_peek, 0, 0},
- { (char *) 0,}
+ { "iflush", m88k_db_iflush, 0, 0},
+ { "dflush", m88k_db_dflush, 0, 0},
+ { "peek", m88k_db_peek, 0, 0},
+ { (char *) 0,}
};
struct db_command db_machine_cmds[] =
{
- {"cache", 0, 0, m88k_cache_cmds},
- {"frame", m88k_db_print_frame, 0, 0},
- {"noise", m88k_db_noise, 0, 0},
- {"searchframe", m88k_db_frame_search, 0, 0},
- {"translate", m88k_db_translate, 0, 0},
- {"cmmucfg", m88k_db_cmmucfg, 0, 0},
- {"where", m88k_db_where, 0, 0},
- {"prom", m88k_db_prom_cmd, 0, 0},
- {(char *) 0,}
+ {"cache", 0, 0, m88k_cache_cmds},
+ {"frame", m88k_db_print_frame, 0, 0},
+ {"regs", m88k_db_registers, 0, 0},
+ {"noise", m88k_db_noise, 0, 0},
+ {"searchframe", m88k_db_frame_search, 0, 0},
+ {"translate", m88k_db_translate, 0, 0},
+ {"cmmucfg", m88k_db_cmmucfg, 0, 0},
+ {"where", m88k_db_where, 0, 0},
+ {"prom", m88k_db_prom_cmd, 0, 0},
+ {(char *) 0,}
};
/*
@@ -853,7 +882,7 @@ db_task_name()
/* skip zeros at the end */
while (ptr > limit &&
- (i = db_trace_get_val((vm_offset_t)ptr, &word)) && (word == 0)) {
+ (i = db_trace_get_val((vm_offset_t)ptr, &word)) && (word == 0)) {
ptr -= 4; /* continue looking for a non-null word */
}
@@ -866,10 +895,10 @@ db_task_name()
/* skip looking for null before all the text */
while (ptr > limit &&
- (i = db_trace_get_val(ptr, &word)) && (word != 0)) {
+ (i = db_trace_get_val(ptr, &word)) && (word != 0)) {
ptr -= 4; /* continue looking for a null word */
}
-
+
if (ptr <= limit) {
db_printf("bad name at line %d\n", __LINE__);
return "<couldn't find 2>";
@@ -886,3 +915,4 @@ db_task_name()
}
return (char*)buffer;
}
+
diff --git a/sys/arch/mvme88k/ddb/db_sstep.c b/sys/arch/mvme88k/ddb/db_sstep.c
index b0e17dd0561..788876a16f3 100644
--- a/sys/arch/mvme88k/ddb/db_sstep.c
+++ b/sys/arch/mvme88k/ddb/db_sstep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_sstep.c,v 1.9 2001/12/16 23:49:46 miod Exp $ */
+/* $OpenBSD: db_sstep.c,v 1.10 2001/12/22 08:31:04 smurph Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1991 Carnegie Mellon University
@@ -30,6 +30,7 @@
#include <sys/systm.h>
#include <machine/db_machdep.h>
#include <ddb/db_access.h> /* db_get_value() */
+#include <ddb/db_break.h> /* db_breakpoint_t */
/*
* Support routines for software single step.
@@ -38,8 +39,12 @@
*
*/
-boolean_t inst_delayed __P((unsigned ins));
-db_expr_t getreg_val __P((unsigned regno, db_regs_t *frame));
+boolean_t inst_delayed __P((unsigned int ins));
+
+#ifdef INTERNAL_SSTEP
+db_breakpoint_t db_not_taken_bkpt = 0;
+db_breakpoint_t db_taken_bkpt = 0;
+#endif
/*
* Returns TRUE is the instruction a branch or jump instruction
@@ -47,7 +52,7 @@ db_expr_t getreg_val __P((unsigned regno, db_regs_t *frame));
*/
boolean_t
inst_branch(ins)
- unsigned ins;
+ unsigned int ins;
{
/* check high five bits */
switch (ins >> (32 - 5)) {
@@ -59,7 +64,7 @@ inst_branch(ins)
break;
case 0x1e: /* could be jmp */
if ((ins & 0xfffffbe0U) == 0xf400c000U)
- return TRUE;
+ return TRUE;
}
return FALSE;
@@ -72,7 +77,7 @@ inst_branch(ins)
*/
unsigned
inst_load(ins)
- unsigned ins;
+ unsigned int ins;
{
/* look at the top six bits, for starters */
switch (ins >> (32 - 6)) {
@@ -90,7 +95,7 @@ inst_load(ins)
return 2;
case 0x3d: /* load/store/xmem scaled/unscaled instruction */
- if ((ins & 0xf400c0e0U) == 0xf4000000U) /* is load/xmem */
+ if ((ins & 0xf400c0e0U) == 0xf4000000U) /* is load/xmem */
switch ((ins & 0x0000fce0) >> 5) { /* look at bits 15-5, but mask bits 8-9 */
case 0x0: /* xmem byte */
case 0x1: /* xmem word */
@@ -103,7 +108,7 @@ inst_load(ins)
case 0x4: /* signed double word load */
return 2;
- } /* end switch load/xmem */
+ } /* end switch load/xmem */
break;
} /* end switch 32-6 */
@@ -116,7 +121,7 @@ inst_load(ins)
*/
unsigned
inst_store(ins)
- unsigned ins;
+ unsigned int ins;
{
/* decode top 6 bits again */
switch (ins >> (32 - 6)) {
@@ -156,7 +161,7 @@ inst_store(ins)
*/
boolean_t
inst_delayed(ins)
- unsigned ins;
+ unsigned int ins;
{
/* check the br, bsr, bb0, bb1, bcnd cases */
switch ((ins & 0xfc000000U) >> (32 - 6)) {
@@ -248,8 +253,10 @@ branch_taken(inst, pc, func, func_data)
/* check jmp/jsr case */
/* check bits 5-31, skipping 10 & 11 */
- if ((inst & 0xfffff3e0U) == 0xf400c000U)
- return (*func)(func_data, inst & 0x1f); /* the register value */
+ if ((inst & 0xfffff3e0U) == 0xf400c000U) {
+ return (*func)(func_data, (inst & 0x0000001fU)); /* the register value */
+ }
+
panic("branch_taken");
return 0; /* keeps compiler happy */
@@ -260,17 +267,71 @@ branch_taken(inst, pc, func, func_data)
* Returns the value of the register in the specified
* frame. Only makes sense for general registers.
*/
-db_expr_t
-getreg_val(regno, frame)
- unsigned regno;
+
+register_t
+getreg_val(frame, regno)
db_regs_t *frame;
+ int regno;
{
if (regno == 0)
return 0;
else if (regno < 31)
return frame->r[regno];
else {
- panic("bad register number to getreg_val.");
+ panic("bad register number (%d) to getreg_val.", regno);
return 0;/*to make compiler happy */
}
}
+
+#ifdef INTERNAL_SSTEP
+void
+db_set_single_step(regs)
+ register db_regs_t *regs;
+{
+ if (cputyp == CPU_88110) {
+ ((regs)->epsr |= (PSR_TRACE | PSR_SER));
+ } else {
+ db_addr_t pc = PC_REGS(regs);
+#ifndef SOFTWARE_SSTEP_EMUL
+ db_addr_t brpc;
+ u_int inst;
+
+ /*
+ * User was stopped at pc, e.g. the instruction
+ * at pc was not executed.
+ */
+ inst = db_get_value(pc, sizeof(int), FALSE);
+ if (inst_branch(inst) || inst_call(inst) || inst_return(inst)) {
+ brpc = branch_taken(inst, pc, getreg_val, regs);
+ if (brpc != pc) { /* self-branches are hopeless */
+ db_taken_bkpt = db_set_temp_breakpoint(brpc);
+ }
+#if 0
+ /* XXX this seems like a true bug, no? */
+ pc = next_instr_address(pc, 1);
+#endif
+ }
+#endif /*SOFTWARE_SSTEP_EMUL*/
+ pc = next_instr_address(pc, 0);
+ db_not_taken_bkpt = db_set_temp_breakpoint(pc);
+ }
+}
+
+void
+db_clear_single_step(regs)
+ db_regs_t *regs;
+{
+ if (cputyp == CPU_88110) {
+ ((regs)->epsr &= ~(PSR_TRACE | PSR_SER));
+ } else {
+ if (db_taken_bkpt != 0) {
+ db_delete_temp_breakpoint(db_taken_bkpt);
+ db_taken_bkpt = 0;
+ }
+ if (db_not_taken_bkpt != 0) {
+ db_delete_temp_breakpoint(db_not_taken_bkpt);
+ db_not_taken_bkpt = 0;
+ }
+ }
+}
+#endif
diff --git a/sys/arch/mvme88k/ddb/db_trace.c b/sys/arch/mvme88k/ddb/db_trace.c
index 0b28feca0d7..b8275d7962c 100644
--- a/sys/arch/mvme88k/ddb/db_trace.c
+++ b/sys/arch/mvme88k/ddb/db_trace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: db_trace.c,v 1.11 2001/12/16 23:49:46 miod Exp $ */
+/* $OpenBSD: db_trace.c,v 1.12 2001/12/22 08:31:04 smurph Exp $ */
/*
* Mach Operating System
* Copyright (c) 1993-1991 Carnegie Mellon University
@@ -38,58 +38,58 @@
#include <ddb/db_command.h> /* db_recover */
union instruction {
- unsigned rawbits;
-
- struct {
- unsigned int : 5;
- unsigned int n: 1;
- signed int d26:26;
- } br;
-
- struct {
- unsigned int : 4;
- unsigned int isbb1: 1; /* isbb1==0 means bb0, isbb1==1 means bb1 */
- unsigned int n : 1;
- unsigned int b5 : 5;
- unsigned int s1 : 5;
- signed int d16 :16;
- } bb; /* bcnd too, except "isbb1" makes no sense for bcnd */
-
- struct {
- unsigned int : 6;
- unsigned int b5 : 5;
- unsigned int s1 : 5;
- unsigned int : 7;
- unsigned int vec9 : 9;
- } tb; /* tcnd too */
-
- struct {
- unsigned int :21;
- unsigned int n : 1;
- unsigned int : 5;
- unsigned int s2 : 5;
- } jump; /* jmp, jsr */
-
- struct {
- unsigned int : 6;
- unsigned int d : 5;
- unsigned int s1 : 5;
- unsigned int i16 :16;
- } diatic; /* general reg/reg/i16 instructions */
-
- struct {
- unsigned int : 6;
- unsigned int d : 5;
- unsigned int s1 : 5;
- unsigned int :11;
- unsigned int s2 : 5;
- } triatic; /* general reg/reg/reg instructions */
+ unsigned rawbits;
+
+ struct {
+ unsigned int : 5;
+ unsigned int n: 1;
+ signed int d26:26;
+ } br;
+
+ struct {
+ unsigned int : 4;
+ unsigned int isbb1: 1; /* isbb1==0 means bb0, isbb1==1 means bb1 */
+ unsigned int n : 1;
+ unsigned int b5 : 5;
+ unsigned int s1 : 5;
+ signed int d16 :16;
+ } bb; /* bcnd too, except "isbb1" makes no sense for bcnd */
+
+ struct {
+ unsigned int : 6;
+ unsigned int b5 : 5;
+ unsigned int s1 : 5;
+ unsigned int : 7;
+ unsigned int vec9 : 9;
+ } tb; /* tcnd too */
+
+ struct {
+ unsigned int :21;
+ unsigned int n : 1;
+ unsigned int : 5;
+ unsigned int s2 : 5;
+ } jump; /* jmp, jsr */
+
+ struct {
+ unsigned int : 6;
+ unsigned int d : 5;
+ unsigned int s1 : 5;
+ unsigned int i16 :16;
+ } diatic; /* general reg/reg/i16 instructions */
+
+ struct {
+ unsigned int : 6;
+ unsigned int d : 5;
+ unsigned int s1 : 5;
+ unsigned int :11;
+ unsigned int s2 : 5;
+ } triatic; /* general reg/reg/reg instructions */
};
static inline unsigned br_dest(unsigned addr, union instruction inst)
{
- return addr + inst.br.d26 * 4;
+ return addr + inst.br.d26 * 4;
}
@@ -100,7 +100,7 @@ int frame_is_sane __P((db_regs_t *regs));
char *m88k_exception_name __P((unsigned vector));
unsigned db_trace_get_val __P((vm_offset_t addr, unsigned *ptr));
void db_stack_trace_cmd __P((db_regs_t *addr, int have_addr,
- db_expr_t count, char *modif));
+ db_expr_t count, char *modif));
/*
* Some macros to tell if the given text is the instruction.
@@ -146,41 +146,40 @@ extern int quiet_db_read_bytes;
/* lifted from mips */
static int
-db_setf_regs(
- struct db_variable *vp,
+db_setf_regs(struct db_variable *vp,
db_expr_t *valuep,
int op) /* read/write */
{
- register int *regp = (int *) ((char *) DDB_REGS + (int) (vp->valuep));
+ register int *regp = (int *) ((char *) DDB_REGS + (int) (vp->valuep));
- if (op == DB_VAR_GET)
- *valuep = *regp;
- else if (op == DB_VAR_SET)
- *regp = *valuep;
+ if (op == DB_VAR_GET)
+ *valuep = *regp;
+ else if (op == DB_VAR_SET)
+ *regp = *valuep;
- return (0); /* silence warning */
+ return (0); /* silence warning */
}
#define N(s, x) {s, (long *)&(((db_regs_t *) 0)->x), db_setf_regs}
struct db_variable db_regs[] = {
- N("r1", r[1]), N("r2", r[2]), N("r3", r[3]), N("r4", r[4]),
- N("r5", r[5]), N("r6", r[6]), N("r7", r[7]), N("r8", r[8]),
- N("r9", r[9]), N("r10", r[10]), N("r11", r[11]), N("r12", r[12]),
- N("r13", r[13]), N("r14", r[14]), N("r15", r[15]), N("r16", r[16]),
- N("r17", r[17]), N("r18", r[18]), N("r19", r[19]), N("r20", r[20]),
- N("r21", r[21]), N("r22", r[22]), N("r23", r[23]), N("r24", r[24]),
- N("r25", r[25]), N("r26", r[26]), N("r27", r[27]), N("r28", r[28]),
- N("r29", r[29]), N("r30", r[30]), N("r31", r[31]), N("epsr", epsr),
- N("sxip", sxip), N("snip", snip), N("sfip", sfip), N("ssbr", ssbr),
- N("dmt0", dmt0), N("dmd0", dmd0), N("dma0", dma0), N("dmt1", dmt1),
- N("dmd1", dmd1), N("dma1", dma1), N("dmt2", dmt2), N("dmd2", dmd2),
- N("dma2", dma2), N("fpecr", fpecr),N("fphs1", fphs1),N("fpls1", fpls1),
- N("fphs2", fphs2), N("fpls2", fpls2),N("fppt", fppt), N("fprh", fprh),
- N("fprl", fprl), N("fpit", fpit), N("fpsr", fpsr), N("fpcr", fpcr),
- N("mask", mask), /* interrupt mask */
- N("mode", mode), /* interrupt mode */
- N("exvc", vector), /* exception vector */
+ N("r1", r[1]), N("r2", r[2]), N("r3", r[3]), N("r4", r[4]),
+ N("r5", r[5]), N("r6", r[6]), N("r7", r[7]), N("r8", r[8]),
+ N("r9", r[9]), N("r10", r[10]), N("r11", r[11]), N("r12", r[12]),
+ N("r13", r[13]), N("r14", r[14]), N("r15", r[15]), N("r16", r[16]),
+ N("r17", r[17]), N("r18", r[18]), N("r19", r[19]), N("r20", r[20]),
+ N("r21", r[21]), N("r22", r[22]), N("r23", r[23]), N("r24", r[24]),
+ N("r25", r[25]), N("r26", r[26]), N("r27", r[27]), N("r28", r[28]),
+ N("r29", r[29]), N("r30", r[30]), N("r31", r[31]), N("epsr", epsr),
+ N("sxip", sxip), N("snip", snip), N("sfip", sfip), N("ssbr", ssbr),
+ N("dmt0", dmt0), N("dmd0", dmd0), N("dma0", dma0), N("dmt1", dmt1),
+ N("dmd1", dmd1), N("dma1", dma1), N("dmt2", dmt2), N("dmd2", dmd2),
+ N("dma2", dma2), N("fpecr", fpecr),N("fphs1", fphs1),N("fpls1", fpls1),
+ N("fphs2", fphs2), N("fpls2", fpls2),N("fppt", fppt), N("fprh", fprh),
+ N("fprl", fprl), N("fpit", fpit), N("fpsr", fpsr), N("fpcr", fpcr),
+ N("mask", mask), /* interrupt mask */
+ N("mode", mode), /* interrupt mode */
+ N("exvc", vector), /* exception vector */
};
#undef N
@@ -203,76 +202,76 @@ struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
static unsigned
m88k_instruction_info(unsigned instruction)
{
- static struct { unsigned mask, value, flags; } *ptr, control[] =
- {
- /* runs in the same order as 2nd Ed 88100 manual Table 3-14 */
- { 0xf0000000U, 0x00000000U, /* xmem */ TRASHES | STORE | LOAD },
- { 0xec000000U, 0x00000000U, /* ld.d */ TRASHES | LOAD | DOUBLE },
- { 0xe0000000U, 0x00000000U, /* load */ TRASHES | LOAD },
- { 0xfc000000U, 0x20000000U, /* st.d */ STORE | DOUBLE },
- { 0xf0000000U, 0x20000000U, /* store */ STORE },
- { 0xc0000000U, 0x40000000U, /* arith */ TRASHES },
- { 0xfc004000U, 0x80004000U, /* ld cr */ TRASHES },
- { 0xfc004000U, 0x80000000U, /* st cr */ 0 },
- { 0xfc008060U, 0x84000000U, /* f */ TRASHES },
- { 0xfc008060U, 0x84000020U, /* f.d */ TRASHES | DOUBLE },
- { 0xfc000000U, 0xcc000000U, /* bsr.n */ FLOW_CTRL | DELAYED | BSR },
- { 0xfc000000U, 0xc8000000U, /* bsr */ FLOW_CTRL | BSR },
- { 0xe4000000U, 0xc4000000U, /* br/bb.n */ FLOW_CTRL | DELAYED },
- { 0xe4000000U, 0xc0000000U, /* br/bb */ FLOW_CTRL },
- { 0xfc000000U, 0xec000000U, /* bcnd.n */ FLOW_CTRL | DELAYED },
- { 0xfc000000U, 0xe8000000U, /* bcnd */ FLOW_CTRL },
- { 0xfc00c000U, 0xf0008000U, /* bits */ TRASHES },
- { 0xfc00c000U, 0xf000c000U, /* trap */ 0 },
- { 0xfc00f0e0U, 0xf4002000U, /* st */ 0 },
- { 0xfc00cce0U, 0xf4000000U, /* ld.d */ TRASHES | DOUBLE },
- { 0xfc00c0e0U, 0xf4000000U, /* ld */ TRASHES },
- { 0xfc00c0e0U, 0xf4004000U, /* arith */ TRASHES },
- { 0xfc00c3e0U, 0xf4008000U, /* bits */ TRASHES },
- { 0xfc00ffe0U, 0xf400cc00U, /* jsr.n */ FLOW_CTRL | DELAYED | JSR },
- { 0xfc00ffe0U, 0xf400c800U, /* jsr */ FLOW_CTRL | JSR },
- { 0xfc00ffe0U, 0xf400c400U, /* jmp.n */ FLOW_CTRL | DELAYED },
- { 0xfc00ffe0U, 0xf400c000U, /* jmp */ FLOW_CTRL },
- { 0xfc00fbe0U, 0xf400e800U, /* ff */ TRASHES },
- { 0xfc00ffe0U, 0xf400f800U, /* tbnd */ 0 },
- { 0xfc00ffe0U, 0xf400fc00U, /* rte */ FLOW_CTRL },
- { 0xfc000000U, 0xf8000000U, /* tbnd */ 0 },
- };
- #define ctrl_count (sizeof(control)/sizeof(control[0]))
- for (ptr = &control[0]; ptr < &control[ctrl_count]; ptr++)
- if ((instruction & ptr->mask) == ptr->value)
- return ptr->flags;
- SHOW_INSTRUCTION(0, instruction, "bad m88k_instruction_info");
- return 0;
+ static struct {
+ unsigned mask, value, flags;
+ } *ptr, control[] = {
+ /* runs in the same order as 2nd Ed 88100 manual Table 3-14 */
+ { 0xf0000000U, 0x00000000U, /* xmem */ TRASHES | STORE | LOAD},
+ { 0xec000000U, 0x00000000U, /* ld.d */ TRASHES | LOAD | DOUBLE},
+ { 0xe0000000U, 0x00000000U, /* load */ TRASHES | LOAD},
+ { 0xfc000000U, 0x20000000U, /* st.d */ STORE | DOUBLE},
+ { 0xf0000000U, 0x20000000U, /* store */ STORE},
+ { 0xc0000000U, 0x40000000U, /* arith */ TRASHES},
+ { 0xfc004000U, 0x80004000U, /* ld cr */ TRASHES},
+ { 0xfc004000U, 0x80000000U, /* st cr */ 0},
+ { 0xfc008060U, 0x84000000U, /* f */ TRASHES},
+ { 0xfc008060U, 0x84000020U, /* f.d */ TRASHES | DOUBLE},
+ { 0xfc000000U, 0xcc000000U, /* bsr.n */ FLOW_CTRL | DELAYED | BSR},
+ { 0xfc000000U, 0xc8000000U, /* bsr */ FLOW_CTRL | BSR},
+ { 0xe4000000U, 0xc4000000U, /* br/bb.n */ FLOW_CTRL | DELAYED},
+ { 0xe4000000U, 0xc0000000U, /* br/bb */ FLOW_CTRL},
+ { 0xfc000000U, 0xec000000U, /* bcnd.n */ FLOW_CTRL | DELAYED},
+ { 0xfc000000U, 0xe8000000U, /* bcnd */ FLOW_CTRL},
+ { 0xfc00c000U, 0xf0008000U, /* bits */ TRASHES},
+ { 0xfc00c000U, 0xf000c000U, /* trap */ 0},
+ { 0xfc00f0e0U, 0xf4002000U, /* st */ 0},
+ { 0xfc00cce0U, 0xf4000000U, /* ld.d */ TRASHES | DOUBLE},
+ { 0xfc00c0e0U, 0xf4000000U, /* ld */ TRASHES},
+ { 0xfc00c0e0U, 0xf4004000U, /* arith */ TRASHES},
+ { 0xfc00c3e0U, 0xf4008000U, /* bits */ TRASHES},
+ { 0xfc00ffe0U, 0xf400cc00U, /* jsr.n */ FLOW_CTRL | DELAYED | JSR},
+ { 0xfc00ffe0U, 0xf400c800U, /* jsr */ FLOW_CTRL | JSR},
+ { 0xfc00ffe0U, 0xf400c400U, /* jmp.n */ FLOW_CTRL | DELAYED},
+ { 0xfc00ffe0U, 0xf400c000U, /* jmp */ FLOW_CTRL},
+ { 0xfc00fbe0U, 0xf400e800U, /* ff */ TRASHES},
+ { 0xfc00ffe0U, 0xf400f800U, /* tbnd */ 0},
+ { 0xfc00ffe0U, 0xf400fc00U, /* rte */ FLOW_CTRL},
+ { 0xfc000000U, 0xf8000000U, /* tbnd */ 0},
+ };
+#define ctrl_count (sizeof(control)/sizeof(control[0]))
+ for (ptr = &control[0]; ptr < &control[ctrl_count]; ptr++)
+ if ((instruction & ptr->mask) == ptr->value)
+ return ptr->flags;
+ SHOW_INSTRUCTION(0, instruction, "bad m88k_instruction_info");
+ return 0;
}
static int
hex_value_needs_0x(unsigned value)
{
- int i;
- unsigned last = 0;
- unsigned char c;
- unsigned have_a_hex_digit = 0;
+ int i;
+ unsigned last = 0;
+ unsigned char c;
+ unsigned have_a_hex_digit = 0;
- if (value <= 9)
- return 0;
+ if (value <= 9)
+ return 0;
- for (i = 0; i < 8; i++) {
- c = value & 0xf;
- value >>= 4;
- if (c)
- last = c;
- if (c > 9)
- have_a_hex_digit = 1;
- }
- if (have_a_hex_digit == 0)
- return 1;
- if (last > 9)
- return 1;
- return 0;
+ for (i = 0; i < 8; i++) {
+ c = value & 0xf;
+ value >>= 4;
+ if (c)
+ last = c;
+ if (c > 9)
+ have_a_hex_digit = 1;
+ }
+ if (have_a_hex_digit == 0)
+ return 1;
+ if (last > 9)
+ return 1;
+ return 0;
}
-
/*
* returns
* 1 if regs seems to be a reasonable kernel exception frame.
@@ -283,55 +282,62 @@ hex_value_needs_0x(unsigned value)
int
frame_is_sane(db_regs_t *regs)
{
- /* no good if we can't read the whole frame */
- if (badwordaddr((vm_offset_t)regs) || badwordaddr((vm_offset_t)&regs->mode))
- return 0;
+ /* no good if we can't read the whole frame */
+ if (badwordaddr((vm_offset_t)regs) || badwordaddr((vm_offset_t)&regs->mode)) {
+ db_printf("[WARNING: frame at 0x%x : unreadable]\n", regs);
+ return 0;
+ }
#ifndef DIAGNOSTIC
- /* disabled for now -- see fpu_enable in mvme88k/eh.s */
- /* r0 must be 0 (obviously) */
- if (regs->r[0] != 0)
- return 0;
+ /* disabled for now -- see fpu_enable in luna88k/eh.s */
+ /* r0 must be 0 (obviously) */
+ if (regs->r[0] != 0) {
+ db_printf("[WARNING: frame at 0x%x : r[0] != 0]\n", regs);
+ return 0;
+ }
#endif
- /* stack sanity ... r31 must be nonzero, but must be word aligned */
- if (regs->r[31] == 0 || (regs->r[31] & 3) != 0)
- return 0;
+ /* stack sanity ... r31 must be nonzero, but must be word aligned */
+ if (regs->r[31] == 0 || (regs->r[31] & 3) != 0) {
+ db_printf("[WARNING: frame at 0x%x : r[31] == 0 or not word aligned]\n", regs);
+ return 0;
+ }
- /* sxip is reasonable */
+ if (cputyp != CPU_88110) {
+ /* sxip is reasonable */
#if 0
- if ((regs->sxip & 1) == 1)
- return 0;
+ if ((regs->sxip & 1) == 1)
+ return 0;
#endif
- /* snip is reasonable */
- if ((regs->snip & 3) != 2)
- return 0;
- /* sfip is reasonable */
- if ((regs->sfip & 3) != 2)
- return 0;
+ /* snip is reasonable */
+ if ((regs->snip & 3) != 2)
+ return 0;
+ /* sfip is reasonable */
+ if ((regs->sfip & 3) != 2)
+ return 0;
+ }
- /* epsr sanity */
- if ((regs->epsr & 0x8FFFFFF5U) == 0x800003f0U) /* kernel mode */
- {
- if (regs->epsr & 0x40000000)
- db_printf("[WARNING: byte order in kernel frame at %x "
- "is little-endian!]\n", regs);
- return 1;
- }
- if ((regs->epsr & 0x8FFFFFFFU) == 0x000003f0U) /* user mode */
- {
- if (regs->epsr & 0x40000000)
- db_printf("[WARNING: byte order in user frame at %x "
- "is little-endian!]\n", regs);
- return 2;
- }
- return 0;
+ /* epsr sanity */
+ if ((regs->epsr & PSR_MODE)) { /* kernel mode */
+ if (regs->epsr & PSR_BO)
+ db_printf("[WARNING: byte order in kernel frame at %x "
+ "is little-endian!]\n", regs);
+ return 1;
+ }
+ if (!(regs->epsr & PSR_MODE)) { /* user mode */
+ if (regs->epsr & PSR_BO)
+ db_printf("[WARNING: byte order in user frame at %x "
+ "is little-endian!]\n", regs);
+ return 2;
+ }
+ db_printf("[WARNING: not an exception frame?]\n");
+ return 0;
}
char *
m88k_exception_name(unsigned vector)
{
- switch (vector) {
+ switch (vector) {
default:
case 0: return "Reset";
case 1: return "Interrupt";
@@ -344,6 +350,7 @@ m88k_exception_name(unsigned vector)
case 8: return "Integer Divide Exception";
case 9: return "Integer Overflow Exception";
case 10: return "Error Exception";
+ case 11: return "Non Maskable Interrupt";
case 114: return "FPU precise";
case 115: return "FPU imprecise";
case DDB_ENTRY_BKPT_NO:
@@ -353,7 +360,7 @@ m88k_exception_name(unsigned vector)
case DDB_ENTRY_TRAP_NO:
return "ddb trap";
case 451: return "Syscall";
- }
+ }
}
/*
@@ -363,22 +370,22 @@ m88k_exception_name(unsigned vector)
unsigned
db_trace_get_val(vm_offset_t addr, unsigned *ptr)
{
- label_t db_jmpbuf;
- label_t *prev = db_recover;
- boolean_t old_quiet_db_read_bytes = quiet_db_read_bytes;
+ label_t db_jmpbuf;
+ label_t *prev = db_recover;
+ boolean_t old_quiet_db_read_bytes = quiet_db_read_bytes;
- quiet_db_read_bytes = 1;
+ quiet_db_read_bytes = 1;
- if (setjmp((db_recover = &db_jmpbuf)) != 0) {
- db_recover = prev;
- quiet_db_read_bytes = old_quiet_db_read_bytes;
- return 0;
- } else {
- db_read_bytes(addr, 4, (char*)ptr);
- db_recover = prev;
- quiet_db_read_bytes = old_quiet_db_read_bytes;
- return 1;
- }
+ if (setjmp((db_recover = &db_jmpbuf)) != 0) {
+ db_recover = prev;
+ quiet_db_read_bytes = old_quiet_db_read_bytes;
+ return 0;
+ } else {
+ db_read_bytes(addr, 4, (char*)ptr);
+ db_recover = prev;
+ quiet_db_read_bytes = old_quiet_db_read_bytes;
+ return 1;
+ }
}
@@ -398,18 +405,18 @@ static unsigned saved_reg[32]; /* one value per register */
static void
save_reg(int reg, unsigned value)
{
- #ifdef TRACE_DEBUG
+#ifdef TRACE_DEBUG
if (DEBUGGING_ON) db_printf("save_reg(%d, %x)\n", reg, value);
- #endif
- if (trashed_list & reg_bit(reg)) {
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON) db_printf("<trashed>\n");
- #endif
- return; /* don't save trashed registers */
- }
- saved_reg[(reg%32)] = value;
- global_saved_list |= reg_bit(reg);
- local_saved_list |= reg_bit(reg);
+#endif
+ if (trashed_list & reg_bit(reg)) {
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON) db_printf("<trashed>\n");
+#endif
+ return; /* don't save trashed registers */
+ }
+ saved_reg[(reg%32)] = value;
+ global_saved_list |= reg_bit(reg);
+ local_saved_list |= reg_bit(reg);
}
#define mark_reg_trashed(reg) (trashed_list |= reg_bit(reg))
@@ -428,32 +435,32 @@ save_reg(int reg, unsigned value)
static void
print_args(void)
{
- int reg, last_arg;
-
- /* find the highest argument register saved */
- for (last_arg = LAST_ARG_REG; last_arg >= FIRST_ARG_REG; last_arg--)
- if (have_local_reg(last_arg))
- break;
- if (last_arg < FIRST_ARG_REG)
- return; /* none were saved */
-
- db_printf("(");
-
- /* print each one, up to the highest */
- for (reg = FIRST_ARG_REG; /*nothing */; reg++)
- {
- if (!have_local_reg(reg))
- db_printf("?");
- else {
- unsigned value = saved_reg_value(reg);
- db_printf("%s%x", hex_value_needs_0x(value) ? "0x" : "", value);
+ int reg, last_arg;
+
+ /* find the highest argument register saved */
+ for (last_arg = LAST_ARG_REG; last_arg >= FIRST_ARG_REG; last_arg--)
+ if (have_local_reg(last_arg))
+ break;
+ if (last_arg < FIRST_ARG_REG)
+ return; /* none were saved */
+
+ db_printf("(");
+
+ /* print each one, up to the highest */
+ for (reg = FIRST_ARG_REG; /*nothing */; reg++) {
+ if (!have_local_reg(reg))
+ db_printf("?");
+ else {
+ unsigned value = saved_reg_value(reg);
+ db_printf("%s%x", hex_value_needs_0x(value) ?
+ "0x" : "", value);
+ }
+ if (reg == last_arg)
+ break;
+ else
+ db_printf(", ");
}
- if (reg == last_arg)
- break;
- else
- db_printf(", ");
- }
- db_printf(")");
+ db_printf(")");
}
@@ -485,45 +492,45 @@ print_args(void)
static int
is_jump_source_ok(unsigned return_to, unsigned jump_to)
{
- unsigned flags;
- union instruction instruction;
-
- /*
- * Delayed branches are most common... look two instructions before
- * where we were going to return to to see if it's a delayed branch.
- */
- if (!db_trace_get_val(return_to - 8, &instruction.rawbits))
- return JUMP_SOURCE_IS_BAD;
- flags = m88k_instruction_info(instruction.rawbits);
-
- if ((flags & FLOW_CTRL) && (flags & DELAYED) && (flags & (JSR|BSR))) {
- if (flags & JSR)
- return JUMP_SOURCE_IS_OK; /* have to assume it's correct */
- /* calculate the offset */
- if (br_dest(return_to - 8, instruction) == jump_to)
- return JUMP_SOURCE_IS_OK; /* exactamundo! */
- else
- return JUMP_SOURCE_IS_UNLIKELY; /* seems wrong */
- }
-
- /*
- * Try again, looking for a non-delayed jump one back.
- */
- if (!db_trace_get_val(return_to - 4, &instruction.rawbits))
- return JUMP_SOURCE_IS_BAD;
- flags = m88k_instruction_info(instruction.rawbits);
-
- if ((flags & FLOW_CTRL) && !(flags & DELAYED) && (flags & (JSR|BSR))) {
- if (flags & JSR)
- return JUMP_SOURCE_IS_OK; /* have to assume it's correct */
- /* calculate the offset */
- if (br_dest(return_to - 4, instruction) == jump_to)
- return JUMP_SOURCE_IS_OK; /* exactamundo! */
- else
- return JUMP_SOURCE_IS_UNLIKELY; /* seems wrong */
- }
-
- return JUMP_SOURCE_IS_UNLIKELY;
+ unsigned flags;
+ union instruction instruction;
+
+ /*
+ * Delayed branches are most common... look two instructions before
+ * where we were going to return to to see if it's a delayed branch.
+ */
+ if (!db_trace_get_val(return_to - 8, &instruction.rawbits))
+ return JUMP_SOURCE_IS_BAD;
+ flags = m88k_instruction_info(instruction.rawbits);
+
+ if ((flags & FLOW_CTRL) && (flags & DELAYED) && (flags & (JSR|BSR))) {
+ if (flags & JSR)
+ return JUMP_SOURCE_IS_OK; /* have to assume it's correct */
+ /* calculate the offset */
+ if (br_dest(return_to - 8, instruction) == jump_to)
+ return JUMP_SOURCE_IS_OK; /* exactamundo! */
+ else
+ return JUMP_SOURCE_IS_UNLIKELY; /* seems wrong */
+ }
+
+ /*
+ * Try again, looking for a non-delayed jump one back.
+ */
+ if (!db_trace_get_val(return_to - 4, &instruction.rawbits))
+ return JUMP_SOURCE_IS_BAD;
+ flags = m88k_instruction_info(instruction.rawbits);
+
+ if ((flags & FLOW_CTRL) && !(flags & DELAYED) && (flags & (JSR|BSR))) {
+ if (flags & JSR)
+ return JUMP_SOURCE_IS_OK; /* have to assume it's correct */
+ /* calculate the offset */
+ if (br_dest(return_to - 4, instruction) == jump_to)
+ return JUMP_SOURCE_IS_OK; /* exactamundo! */
+ else
+ return JUMP_SOURCE_IS_UNLIKELY; /* seems wrong */
+ }
+
+ return JUMP_SOURCE_IS_UNLIKELY;
}
static char *note = 0;
@@ -554,455 +561,442 @@ static int next_address_likely_wrong = 0;
static int
stack_decode(unsigned addr, unsigned *stack)
{
- db_sym_t proc;
- unsigned offset_from_proc;
- unsigned instructions_to_search;
- unsigned check_addr;
- unsigned function_addr; /* start of function */
- unsigned r31 = *stack; /* the r31 of the function */
- unsigned inst; /* text of an instruction */
- unsigned ret_addr; /* address to which we return */
- unsigned tried_to_save_r1 = 0;
-
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON)
- db_printf("\n>>>stack_decode(addr=%x, stack=%x)\n",
- addr, *stack);
- #endif
-
- /* get what we hope will be the db_sym_t for the function name */
- proc = db_search_symbol(addr, DB_STGY_PROC, &offset_from_proc);
- if (offset_from_proc == addr) /* i.e. no symbol found */
- proc = DB_SYM_NULL;
-
- /*
- * Somehow, find the start of this function.
- * If we found a symbol above, it'll have the address.
- * Otherwise, we've got to search for it....
- */
- if (proc != DB_SYM_NULL)
- {
- char *names;
- db_symbol_values(proc, &names, &function_addr);
- if (names == 0)
- return 0;
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON) db_printf("name %s address 0x%x\n",
- names, function_addr);
- #endif
- }
- else
- {
- int instructions_to_check = 400;
+ db_sym_t proc;
+ unsigned offset_from_proc;
+ unsigned instructions_to_search;
+ unsigned check_addr;
+ unsigned function_addr; /* start of function */
+ unsigned r31 = *stack; /* the r31 of the function */
+ unsigned inst; /* text of an instruction */
+ unsigned ret_addr; /* address to which we return */
+ unsigned tried_to_save_r1 = 0;
+
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON)
+ db_printf("\n>>>stack_decode(addr=%x, stack=%x)\n",
+ addr, *stack);
+#endif
+
+ /* get what we hope will be the db_sym_t for the function name */
+ proc = db_search_symbol(addr, DB_STGY_PROC, &offset_from_proc);
+ if (offset_from_proc == addr) /* i.e. no symbol found */
+ proc = DB_SYM_NULL;
+
/*
- * hmm - unable to find symbol. Search back
- * looking for a function prolog.
+ * Somehow, find the start of this function.
+ * If we found a symbol above, it'll have the address.
+ * Otherwise, we've got to search for it....
*/
- for (check_addr = addr; instructions_to_check-- > 0; check_addr -= 4)
- {
- if (!db_trace_get_val(check_addr, &inst))
- break;
+ if (proc != DB_SYM_NULL) {
+ char *names;
+ db_symbol_values(proc, &names, &function_addr);
+ if (names == 0)
+ return 0;
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON) db_printf("name %s address 0x%x\n",
+ names, function_addr);
+#endif
+ } else {
+ int instructions_to_check = 400;
+ /*
+ * hmm - unable to find symbol. Search back
+ * looking for a function prolog.
+ */
+ for (check_addr = addr; instructions_to_check-- > 0; check_addr -= 4) {
+ if (!db_trace_get_val(check_addr, &inst))
+ break;
+
+ if (SUBU_R31_R31_IMM(inst)) {
+#if 0
+ /*
+ * If the next instruction is "st r1, r31, ####"
+ * then we can feel safe we have the start of
+ * a function.
+ */
+ if (!db_trace_get_val(check_addr + 4, &inst))
+ continue;
+ if (ST_R1_R31_IMM(instr))
+ break; /* sucess */
+#else
+ /*
+ * Latest GCC optimizer is just too good... the store
+ * of r1 might come much later... so we'll have to
+ * settle for just the "subr r31, r31, ###" to mark
+ * the start....
+ */
+ break;
+#endif
+ }
+ /*
+ * if we come across a [jmp r1] or [jmp.n r1] assume we have hit
+ * the previous functions epilogue and stop our search.
+ * Since we know we would have hit the "subr r31, r31" if it was
+ * right in front of us, we know this doesn't have one so
+ * we just return failure....
+ */
+ if (JMP_R1(inst) || JMPN_R1(inst)) {
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON)
+ db_printf("ran into a [jmp r1] at %x (addr=%x)\n",
+ check_addr, addr);
+#endif
+ return 0;
+ }
+ }
+ if (instructions_to_check < 0) {
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON)
+ db_printf("couldn't find func start (addr=%x)\n", addr);
+#endif
+ return 0; /* bummer, couldn't find it */
+ }
+ function_addr = check_addr;
+ }
- if (SUBU_R31_R31_IMM(inst))
- {
- #if 0
- /*
- * If the next instruction is "st r1, r31, ####"
- * then we can feel safe we have the start of
- * a function.
- */
- if (!db_trace_get_val(check_addr + 4, &inst))
- continue;
- if (ST_R1_R31_IMM(instr))
- break; /* sucess */
- #else
- /*
- * Latest GCC optimizer is just too good... the store
- * of r1 might come much later... so we'll have to
- * settle for just the "subr r31, r31, ###" to mark
- * the start....
- */
- break;
- #endif
- }
- /*
- * if we come across a [jmp r1] or [jmp.n r1] assume we have hit
- * the previous functions epilogue and stop our search.
- * Since we know we would have hit the "subr r31, r31" if it was
- * right in front of us, we know this doesn't have one so
- * we just return failure....
- */
- if (JMP_R1(inst) || JMPN_R1(inst)) {
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON)
- db_printf("ran into a [jmp r1] at %x (addr=%x)\n",
- check_addr, addr);
- #endif
+ /*
+ * We now know the start of the function (function_addr).
+ * If we're stopped right there, or if it's not a
+ * subu r31, r31, ####
+ * then we're done.
+ */
+ if (addr == function_addr) {
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON) db_printf("at start of func\n");
+#endif
return 0;
- }
}
- if (instructions_to_check < 0) {
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON)
- db_printf("couldn't find func start (addr=%x)\n", addr);
- #endif
- return 0; /* bummer, couldn't find it */
- }
- function_addr = check_addr;
- }
-
- /*
- * We now know the start of the function (function_addr).
- * If we're stopped right there, or if it's not a
- * subu r31, r31, ####
- * then we're done.
- */
- if (addr == function_addr) {
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON) db_printf("at start of func\n");
- #endif
- return 0;
- }
- if (!db_trace_get_val(function_addr, &inst)) {
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON) db_printf("couldn't read %x at line %d\n",
- function_addr, __LINE__);
- #endif
- return 0;
- }
- SHOW_INSTRUCTION(function_addr, inst, "start of function: ");
- if (!SUBU_R31_R31_IMM(inst)) {
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON) db_printf("<not subu,r31,r31,imm>\n");
- #endif
- return 0;
- }
-
- /* add the size of this frame to the stack (for the next frame) */
- *stack += IMM16VAL(inst);
-
- /*
- * Search from the beginning of the function (funstart) to where we are
- * in the function (addr) looking to see what kind of registers have
- * been saved on the stack.
- *
- * We'll stop looking before we get to ADDR if we hit a branch.
- */
- clear_local_saved_regs();
- check_addr = function_addr + 4; /* we know the first inst isn't a store */
-
- for (instructions_to_search = (addr - check_addr)/sizeof(long);
- instructions_to_search-- > 0;
- check_addr += 4)
- {
- union instruction instruction;
- unsigned flags;
-
- /* read the instruction */
- if (!db_trace_get_val(check_addr, &instruction.rawbits)) {
- #ifdef TRACE_DEBUG
+ if (!db_trace_get_val(function_addr, &inst)) {
+#ifdef TRACE_DEBUG
if (DEBUGGING_ON) db_printf("couldn't read %x at line %d\n",
- check_addr, __LINE__);
- #endif
- break;
+ function_addr, __LINE__);
+#endif
+ return 0;
+ }
+ SHOW_INSTRUCTION(function_addr, inst, "start of function: ");
+ if (!SUBU_R31_R31_IMM(inst)) {
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON) db_printf("<not subu,r31,r31,imm>\n");
+#endif
+ return 0;
}
- SHOW_INSTRUCTION(check_addr, instruction.rawbits, "prolog: ");
+ /* add the size of this frame to the stack (for the next frame) */
+ *stack += IMM16VAL(inst);
- /* find out the particulars about this instruction */
- flags = m88k_instruction_info(instruction.rawbits);
+ /*
+ * Search from the beginning of the function (funstart) to where we are
+ * in the function (addr) looking to see what kind of registers have
+ * been saved on the stack.
+ *
+ * We'll stop looking before we get to ADDR if we hit a branch.
+ */
+ clear_local_saved_regs();
+ check_addr = function_addr + 4; /* we know the first inst isn't a store */
- /* if a store to something off the stack pointer, note the value */
- if ((flags & STORE) && instruction.diatic.s1 == /*stack pointer*/31)
- {
- unsigned value;
- if (!have_local_reg(instruction.diatic.d)) {
- if (instruction.diatic.d == 1)
- tried_to_save_r1 = r31 + instruction.diatic.i16 ;
- if (db_trace_get_val(r31 + instruction.diatic.i16, &value))
- save_reg(instruction.diatic.d, value);
- }
- if ((flags & DOUBLE) && !have_local_reg(instruction.diatic.d + 1)) {
- if (instruction.diatic.d == 0)
- tried_to_save_r1 = r31+instruction.diatic.i16 +4;
- if (db_trace_get_val(r31+instruction.diatic.i16 +4, &value))
- save_reg(instruction.diatic.d + 1, value);
- }
- }
+ for (instructions_to_search = (addr - check_addr)/sizeof(long);
+ instructions_to_search-- > 0;
+ check_addr += 4) {
+ union instruction instruction;
+ unsigned flags;
- /* if an inst that kills D (and maybe D+1), note that */
- if (flags & TRASHES) {
- mark_reg_trashed(instruction.diatic.d);
- if (flags & DOUBLE)
- mark_reg_trashed(instruction.diatic.d + 1);
+ /* read the instruction */
+ if (!db_trace_get_val(check_addr, &instruction.rawbits)) {
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON) db_printf("couldn't read %x at line %d\n",
+ check_addr, __LINE__);
+#endif
+ break;
+ }
+
+ SHOW_INSTRUCTION(check_addr, instruction.rawbits, "prolog: ");
+
+ /* find out the particulars about this instruction */
+ flags = m88k_instruction_info(instruction.rawbits);
+
+ /* if a store to something off the stack pointer, note the value */
+ if ((flags & STORE) && instruction.diatic.s1 == /*stack pointer*/31) {
+ unsigned value;
+ if (!have_local_reg(instruction.diatic.d)) {
+ if (instruction.diatic.d == 1)
+ tried_to_save_r1 = r31 + instruction.diatic.i16 ;
+ if (db_trace_get_val(r31 + instruction.diatic.i16, &value))
+ save_reg(instruction.diatic.d, value);
+ }
+ if ((flags & DOUBLE) && !have_local_reg(instruction.diatic.d + 1)) {
+ if (instruction.diatic.d == 0)
+ tried_to_save_r1 = r31+instruction.diatic.i16 +4;
+ if (db_trace_get_val(r31+instruction.diatic.i16 +4, &value))
+ save_reg(instruction.diatic.d + 1, value);
+ }
+ }
+
+ /* if an inst that kills D (and maybe D+1), note that */
+ if (flags & TRASHES) {
+ mark_reg_trashed(instruction.diatic.d);
+ if (flags & DOUBLE)
+ mark_reg_trashed(instruction.diatic.d + 1);
+ }
+
+ /* if a flow control instruction, stop now (or next if delayed) */
+ if ((flags & FLOW_CTRL) && instructions_to_search != 0)
+ instructions_to_search = (flags & DELAYED) ? 1 : 0;
}
- /* if a flow control instruction, stop now (or next if delayed) */
- if ((flags & FLOW_CTRL) && instructions_to_search != 0)
- instructions_to_search = (flags & DELAYED) ? 1 : 0;
- }
-
- /*
- * If we didn't save r1 at some point, we're hosed.
- */
- if (!have_local_reg(1)) {
- if (tried_to_save_r1) {
- db_printf(" <return value of next fcn unreadable in %08x>\n",
- tried_to_save_r1);
+ /*
+ * If we didn't save r1 at some point, we're hosed.
+ */
+ if (!have_local_reg(1)) {
+ if (tried_to_save_r1) {
+ db_printf(" <return value of next fcn unreadable in %08x>\n",
+ tried_to_save_r1);
+ }
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON) db_printf("didn't save r1\n");
+#endif
+ return 0;
}
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON) db_printf("didn't save r1\n");
- #endif
- return 0;
- }
-
- ret_addr = saved_reg_value(1);
-
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON)
- db_printf("Return value is = %x, function_addr is %x.\n",
- ret_addr, function_addr);
- #endif
-
- /*
- * In support of this, continuation.s puts the low bit on the
- * return address for continuations (the return address will never
- * be used, so it's ok to do anything you want to it).
- */
- if (ret_addr & 1) {
- note = "<<can not trace past a continuation>>";
- ret_addr = 0;
- } else if (ret_addr != 0x00) {
- switch(is_jump_source_ok(ret_addr, function_addr)) {
- case JUMP_SOURCE_IS_OK:
- break; /* excellent */
-
- case JUMP_SOURCE_IS_BAD:
- #ifdef TRACE_DEBUG
- if (DEBUGGING_ON) db_printf("jump is bad\n");
- #endif
- return 0; /* bummer */
-
- case JUMP_SOURCE_IS_UNLIKELY:
- next_address_likely_wrong = 1;;
- break;
+
+ ret_addr = saved_reg_value(1);
+
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON)
+ db_printf("Return value is = %x, function_addr is %x.\n",
+ ret_addr, function_addr);
+#endif
+
+ /*
+ * In support of this, continuation.s puts the low bit on the
+ * return address for continuations (the return address will never
+ * be used, so it's ok to do anything you want to it).
+ */
+ if (ret_addr & 1) {
+ note = "<<can not trace past a continuation>>";
+ ret_addr = 0;
+ } else if (ret_addr != 0x00) {
+ switch (is_jump_source_ok(ret_addr, function_addr)) {
+ case JUMP_SOURCE_IS_OK:
+ break; /* excellent */
+
+ case JUMP_SOURCE_IS_BAD:
+#ifdef TRACE_DEBUG
+ if (DEBUGGING_ON) db_printf("jump is bad\n");
+#endif
+ return 0; /* bummer */
+
+ case JUMP_SOURCE_IS_UNLIKELY:
+ next_address_likely_wrong = 1;;
+ break;
+ }
}
- }
- return ret_addr;
+ return ret_addr;
}
static void
db_stack_trace_cmd2(db_regs_t *regs)
{
- unsigned stack;
- unsigned depth=1;
- unsigned where;
- unsigned ft;
- unsigned pair[2];
- int i;
-
- /*
- * Frame_is_sane returns:
- * 1 if regs seems to be a reasonable kernel exception frame.
- * 2 if regs seems to be a reasonable user exception frame
- * (in the current task).
- * 0 if this looks like neither.
- */
- if (ft = frame_is_sane(regs), ft == 0)
- {
- db_printf("Register frame 0x%x is suspicous; skipping trace\n", regs);
- return;
- }
-
- /* if user space and no user space trace specified, puke */
- if (ft == 2 && !(trace_flags & TRACE_USER_FLAG))
- return;
-
- /* fetch address */
- /* use sxip if valid, otherwise try snip or sfip */
- where = ((regs->sxip & 2) ? regs->sxip :
- ((regs->snip & 2) ? regs->snip :
- regs->sfip) ) & ~3;
- stack = regs->r[31];
- db_printf("stack base = 0x%x\n", stack);
- db_printf("(0) "); /*depth of trace */
- if (trace_flags & TRACE_SHOWADDRESS_FLAG)
- db_printf("%08x ", where);
- db_printsym(where, DB_STGY_PROC);
- clear_global_saved_regs();
-
- /* see if this routine had a stack frame */
- if ((where=stack_decode(where, &stack))==0)
- {
- where = regs->r[1];
- db_printf("(stackless)");
- }
- else
- {
- print_args();
- if (trace_flags & TRACE_SHOWFRAME_FLAG)
- db_printf(" [frame 0x%x]", stack);
- }
- db_printf("\n");
- if (note) {
- db_printf(" %s\n", note);
- note = 0;
- }
-
- do
- {
+ unsigned stack;
+ unsigned depth=1;
+ unsigned where;
+ unsigned ft;
+ unsigned pair[2];
+ int i;
+
/*
- * If requested, show preserved registers at the time
- * the next-shown call was made. Only registers known to have
- * changed from the last exception frame are shown, as others
- * can be gotten at by looking at the exception frame.
+ * Frame_is_sane returns:
+ * 1 if regs seems to be a reasonable kernel exception frame.
+ * 2 if regs seems to be a reasonable user exception frame
+ * (in the current task).
+ * 0 if this looks like neither.
*/
- if (trace_flags & TRACE_SHOWCALLPRESERVED_FLAG)
- {
- int r, title_printed = 0;
-
- for (r = FIRST_CALLPRESERVED_REG; r<=LAST_CALLPRESERVED_REG; r++) {
- if (have_global_reg(r)) {
- unsigned value = saved_reg_value(r);
- if (title_printed == 0) {
- title_printed = 1;
- db_printf("[in next func:");
- }
- if (value == 0)
- db_printf(" r%d", r);
- else if (value <= 9)
- db_printf(" r%d=%x", r, value);
- else
- db_printf(" r%d=x%x", r, value);
- }
- }
- if (title_printed)
- db_printf("]\n");
+ if (ft = frame_is_sane(regs), ft == 0) {
+ db_printf("Register frame 0x%x is suspicous; skipping trace\n", regs);
+ return;
}
- db_printf("(%d)%c", depth++, next_address_likely_wrong ? '?':' ');
- next_address_likely_wrong = 0;
+ /* if user space and no user space trace specified, puke */
+ if (ft == 2 && !(trace_flags & TRACE_USER_FLAG))
+ return;
+ /* fetch address */
+ /* use sxip if valid, otherwise try snip or sfip */
+ if (cputyp == CPU_88110) {
+ where = regs->exip & ~3;
+ } else {
+ where = ((regs->sxip & 2) ? regs->sxip :
+ ((regs->snip & 2) ? regs->snip :
+ regs->sfip) ) & ~3;
+ }
+ stack = regs->r[31];
+ db_printf("stack base = 0x%x\n", stack);
+ db_printf("(0) "); /*depth of trace */
if (trace_flags & TRACE_SHOWADDRESS_FLAG)
- db_printf("%08x ", where);
+ db_printf("%08x ", where);
db_printsym(where, DB_STGY_PROC);
- where = stack_decode(where, &stack);
- print_args();
- if (trace_flags & TRACE_SHOWFRAME_FLAG)
- db_printf(" [frame 0x%x]", stack);
+ clear_global_saved_regs();
+
+ /* see if this routine had a stack frame */
+ if ((where=stack_decode(where, &stack))==0) {
+ where = regs->r[1];
+ db_printf("(stackless)");
+ } else {
+ print_args();
+ if (trace_flags & TRACE_SHOWFRAME_FLAG)
+ db_printf(" [frame 0x%x]", stack);
+ }
db_printf("\n");
if (note) {
- db_printf(" %s\n", note);
- note = 0;
+ db_printf(" %s\n", note);
+ note = 0;
}
- } while (where);
- /* try to trace back over trap/exception */
+ do {
+ /*
+ * If requested, show preserved registers at the time
+ * the next-shown call was made. Only registers known to have
+ * changed from the last exception frame are shown, as others
+ * can be gotten at by looking at the exception frame.
+ */
+ if (trace_flags & TRACE_SHOWCALLPRESERVED_FLAG) {
+ int r, title_printed = 0;
+
+ for (r = FIRST_CALLPRESERVED_REG; r<=LAST_CALLPRESERVED_REG; r++) {
+ if (have_global_reg(r)) {
+ unsigned value = saved_reg_value(r);
+ if (title_printed == 0) {
+ title_printed = 1;
+ db_printf("[in next func:");
+ }
+ if (value == 0)
+ db_printf(" r%d", r);
+ else if (value <= 9)
+ db_printf(" r%d=%x", r, value);
+ else
+ db_printf(" r%d=x%x", r, value);
+ }
+ }
+ if (title_printed)
+ db_printf("]\n");
+ }
+
+ db_printf("(%d)%c", depth++, next_address_likely_wrong ? '?':' ');
+ next_address_likely_wrong = 0;
+
+ if (trace_flags & TRACE_SHOWADDRESS_FLAG)
+ db_printf("%08x ", where);
+ db_printsym(where, DB_STGY_PROC);
+ where = stack_decode(where, &stack);
+ print_args();
+ if (trace_flags & TRACE_SHOWFRAME_FLAG)
+ db_printf(" [frame 0x%x]", stack);
+ db_printf("\n");
+ if (note) {
+ db_printf(" %s\n", note);
+ note = 0;
+ }
+ } while (where);
- stack &= ~7; /* double word aligned */
- /* take last top of stack, and try to find an exception frame near it */
+ /* try to trace back over trap/exception */
- i = FRAME_PLAY;
+ stack &= ~7; /* double word aligned */
+ /* take last top of stack, and try to find an exception frame near it */
- #ifdef TRACE_DEBUG
+ i = FRAME_PLAY;
+
+#ifdef TRACE_DEBUG
if (DEBUGGING_ON)
- db_printf("(searching for exception frame at 0x%x)\n", stack);
- #endif
+ db_printf("(searching for exception frame at 0x%x)\n", stack);
+#endif
+
+ while (i) {
+ /*
+ * On the stack, a pointer to the exception frame is written
+ * in two adjacent words. In the case of a fault from the kernel,
+ * this should point to the frame right above them:
+ *
+ * Exception Frame Top
+ * ..
+ * Exception Frame Bottom <-- frame addr
+ * frame addr
+ * frame addr <-- stack pointer
+ *
+ * In the case of a fault from user mode, the top of stack
+ * will just have the address of the frame
+ * replicated twice.
+ *
+ * frame addr <-- top of stack
+ * frame addr
+ *
+ * Here we are just looking for kernel exception frames.
+ */
+
+ if (badwordaddr((vm_offset_t)stack) ||
+ badwordaddr((vm_offset_t)(stack+4)))
+ break;
+
+ db_read_bytes((vm_offset_t)stack, 2*sizeof(int), (char*)pair);
+
+ /* the pairs should match and equal stack+8 */
+ if (pair[0] == pair[1]) {
+ if (pair[0] != stack+8) {
+ /*
+ if (!badwordaddr((vm_offset_t)pair[0]) && (pair[0]!=0))
+ db_printf("stack_trace:found pair 0x%x but != to stack+8\n",
+ pair[0]);
+ */
+
+ }
+
+ else if (frame_is_sane((db_regs_t*)pair[0])) {
+ db_regs_t *frame = (db_regs_t *) pair[0];
+ char *cause = m88k_exception_name(frame -> vector);
+
+ db_printf("-------------- %s [EF: 0x%x] -------------\n",
+ cause, frame);
+ db_stack_trace_cmd2(frame);
+ return;
+ }
+#ifdef TRACE_DEBUG
+ else if (DEBUGGING_ON)
+ db_printf("pair matched, but frame at 0x%x looks insane\n",
+ stack+8);
+#endif
+ }
+ stack += 8;
+ i--;
+ }
- while (i)
- {
/*
- * On the stack, a pointer to the exception frame is written
- * in two adjacent words. In the case of a fault from the kernel,
- * this should point to the frame right above them:
- *
- * Exception Frame Top
- * ..
- * Exception Frame Bottom <-- frame addr
- * frame addr
- * frame addr <-- stack pointer
- *
- * In the case of a fault from user mode, the top of stack
- * will just have the address of the frame
- * replicated twice.
- *
- * frame addr <-- top of stack
- * frame addr
- *
- * Here we are just looking for kernel exception frames.
+ * If we go here, crawling back on the stack failed to find us
+ * a previous exception frame. Look for a user frame pointer
+ * pointed to by a word 8 bytes off of the top of the stack
+ * if the "u" option was specified.
*/
+ if (trace_flags & TRACE_USER_FLAG) {
+ db_regs_t *user;
- if (badwordaddr((vm_offset_t)stack) ||
- badwordaddr((vm_offset_t)(stack+4)))
- break;
+ /* Make sure we are back on the right page */
+ stack -= 4*FRAME_PLAY;
+ stack = stack & ~(KERNEL_STACK_SIZE-1); /* point to the bottom */
+ stack += KERNEL_STACK_SIZE - 8;
- db_read_bytes((vm_offset_t)stack, 2*sizeof(int), (char*)pair);
+ if (badwordaddr((vm_offset_t)stack) ||
+ badwordaddr((vm_offset_t)stack))
+ return;
- /* the pairs should match and equal stack+8 */
- if (pair[0] == pair[1])
- {
- if (pair[0] != stack+8)
- {
- /*
- if (!badwordaddr((vm_offset_t)pair[0]) && (pair[0]!=0))
- db_printf("stack_trace:found pair 0x%x but != to stack+8\n",
- pair[0]);
- */
- }
- else if (frame_is_sane((db_regs_t*)pair[0]))
- {
- db_regs_t *frame = (db_regs_t *) pair[0];
- char *cause = m88k_exception_name(frame -> vector);
-
- db_printf("-------------- %s [EF: 0x%x] -------------\n",
- cause, frame);
- db_stack_trace_cmd2(frame);
- return;
- }
- #ifdef TRACE_DEBUG
- else if (DEBUGGING_ON)
- db_printf("pair matched, but frame at 0x%x looks insane\n",
- stack+8);
- #endif
- }
- stack += 8;
- i--;
- }
-
- /*
- * If we go here, crawling back on the stack failed to find us
- * a previous exception frame. Look for a user frame pointer
- * pointed to by a word 8 bytes off of the top of the stack
- * if the "u" option was specified.
- */
- if (trace_flags & TRACE_USER_FLAG)
- {
- db_regs_t *user;
-
- /* Make sure we are back on the right page */
- stack -= 4*FRAME_PLAY;
- stack = stack & ~(KERNEL_STACK_SIZE-1); /* point to the bottom */
- stack += KERNEL_STACK_SIZE - 8;
-
- if (badwordaddr((vm_offset_t)stack) ||
- badwordaddr((vm_offset_t)stack))
- return;
-
- db_read_bytes((vm_offset_t)stack, 2*sizeof(int), (char*)pair);
- if (pair[0] != pair[1])
- return;
-
- /* have a hit */
- user = *((db_regs_t **) stack);
-
- if (frame_is_sane(user) == 2)
- {
- db_printf("---------------- %s [EF : 0x%x] -------------\n",
- m88k_exception_name(user->vector), user);
- db_stack_trace_cmd2(user);
+ db_read_bytes((vm_offset_t)stack, 2*sizeof(int), (char*)pair);
+ if (pair[0] != pair[1])
+ return;
+
+ /* have a hit */
+ user = *((db_regs_t **) stack);
+
+ if (frame_is_sane(user) == 2) {
+ db_printf("---------------- %s [EF : 0x%x] -------------\n",
+ m88k_exception_name(user->vector), user);
+ db_stack_trace_cmd2(user);
+ }
}
- }
}
/*
@@ -1012,154 +1006,151 @@ db_stack_trace_cmd2(db_regs_t *regs)
* printed.
*/
void
-db_stack_trace_cmd(
- db_regs_t *addr,
- int have_addr,
- db_expr_t count,
- char *modif)
+db_stack_trace_cmd(db_regs_t *addr,
+ int have_addr,
+ db_expr_t count,
+ char *modif)
{
- enum { Default, Stack, Proc, Frame } style = Default;
- db_regs_t frame; /* a m88100_saved_state */
- db_regs_t *regs;
- union {
- db_regs_t *frame;
- struct proc *proc;
- unsigned num;
- } arg;
- arg.frame = addr;
-
- trace_flags = 0; /* flags will be set via modifers */
-
- while (modif && *modif) {
- switch (*modif++)
- {
- case 'd':
- #ifdef TRACE_DEBUG
- trace_flags |= TRACE_DEBUG_FLAG;
- #else
- db_printtf("<debug trace not compiled in, ignoring>\n");
- #endif
- break;
-
- case 's': style = Stack ; break;
- case 'f': style = Frame ; break;
- case 'p': trace_flags |= TRACE_SHOWCALLPRESERVED_FLAG; break;
- case 'a': trace_flags |= TRACE_SHOWADDRESS_FLAG; break;
- case 'F': trace_flags |= TRACE_SHOWFRAME_FLAG; break;
- case 'u': trace_flags |= TRACE_USER_FLAG; break;
- default:
- db_printf("unknown trace modifier [%c]\n", modif[-1]);
- /*FALLTHROUGH*/
- case 'h':
- db_printf("usage: trace/[MODIFIER] [ARG]\n");
- db_printf(" u = include user trace\n");
- db_printf(" F = print stack frames\n");
- db_printf(" a = show return addresses\n");
- db_printf(" p = show call-preserved registers\n");
- db_printf(" s = ARG is a stack pointer\n");
- db_printf(" f = ARG is a frame pointer\n");
- #ifdef TRACE_DEBUG
- db_printf(" d = trace-debugging output\n");
- #endif
- return;
+ enum {
+ Default, Stack, Proc, Frame
+ } style = Default;
+ db_regs_t frame; /* a m88100_saved_state */
+ db_regs_t *regs;
+ union {
+ db_regs_t *frame;
+ struct proc *proc;
+ unsigned num;
+ } arg;
+ arg.frame = addr;
+
+ trace_flags = 0; /* flags will be set via modifers */
+
+ while (modif && *modif) {
+ switch (*modif++) {
+ case 'd':
+#ifdef TRACE_DEBUG
+ trace_flags |= TRACE_DEBUG_FLAG;
+#else
+ db_printtf("<debug trace not compiled in, ignoring>\n");
+#endif
+ break;
+
+ case 's': style = Stack ; break;
+ case 'f': style = Frame ; break;
+ case 'p': trace_flags |= TRACE_SHOWCALLPRESERVED_FLAG; break;
+ case 'a': trace_flags |= TRACE_SHOWADDRESS_FLAG; break;
+ case 'F': trace_flags |= TRACE_SHOWFRAME_FLAG; break;
+ case 'u': trace_flags |= TRACE_USER_FLAG; break;
+ default:
+ db_printf("unknown trace modifier [%c]\n", modif[-1]);
+ /*FALLTHROUGH*/
+ case 'h':
+ db_printf("usage: trace/[MODIFIER] [ARG]\n");
+ db_printf(" u = include user trace\n");
+ db_printf(" F = print stack frames\n");
+ db_printf(" a = show return addresses\n");
+ db_printf(" p = show call-preserved registers\n");
+ db_printf(" s = ARG is a stack pointer\n");
+ db_printf(" f = ARG is a frame pointer\n");
+#ifdef TRACE_DEBUG
+ db_printf(" d = trace-debugging output\n");
+#endif
+ return;
+ }
}
- }
-
- if (!have_addr && style != Default) {
- db_printf("expecting argument with /s or /f\n");
- return;
- }
- if (have_addr && style == Default)
- style = Proc;
-
- switch(style)
- {
- case Default:
- regs = DDB_REGS;
- break;
-
- case Frame:
- regs = arg.frame;
- break;
-
- case Proc:
- break;
-
- case Stack:
- {
- unsigned val1, val2, sxip;
- unsigned ptr;
- bzero((void*)&frame, sizeof(frame));
- #define REASONABLE_FRAME_DISTANCE 2048
- /*
- * We've got to find the top of a stack frame so we can get both
- * a PC and and real SP.
- */
- for (ptr = arg.num;/**/; ptr += 4) {
- /* Read a word from the named stack */
- if (db_trace_get_val(ptr, &val1) == 0) {
- db_printf("can't read from %x, aborting.\n", ptr);
+ if (!have_addr && style != Default) {
+ db_printf("expecting argument with /s or /f\n");
return;
- }
-
- /*
- * See if it's a frame pointer.... if so it will be larger than
- * the address it was taken from (i.e. point back up the stack)
- * and we'll be able to read where it points.
- */
- if (val1 <= ptr ||
- (val1 & 3) ||
- val1 > (ptr + REASONABLE_FRAME_DISTANCE))
- continue;
-
- /* peek at the next word to see if it could be a return address */
- if (db_trace_get_val(ptr, &sxip) == 0) {
- db_printf("can't read from %x, aborting.\n", ptr);
- return;
- }
- if (sxip == 0 || !db_trace_get_val(sxip, &val2))
- continue;
-
- if (db_trace_get_val(val1, &val2) == 0) {
- db_printf("can't read from %x, aborting.\n", val1);
- continue;
- }
-
- /*
- * The value we've just read will be either another frame pointer,
- * or the start of another exception frame.
- */
- if (
- #ifdef JEFF_DEBUG
- val2 == 0
- #else
- val2 == 0x12345678
- #endif
- && db_trace_get_val(val1-4, &val2) && val2 == val1
- && db_trace_get_val(val1-8, &val2) && val2 == val1)
- {
- /* we've found a frame, so the stack must have been good */
- db_printf("%x looks like a frame, accepting %x\n",val1,ptr);
- break;
- }
-
- if (val2 > val1 && (val2 & 3) == 0) {
- /* well, looks close enough to be another frame pointer */
- db_printf("*%x = %x looks like a stack frame pointer, accepting %x\n", val1, val2, ptr);
- break;
- }
}
+ if (have_addr && style == Default)
+ style = Proc;
- frame.r[31] = ptr;
- frame.epsr = 0x800003f0U;
- frame.sxip = sxip | 2;
- frame.snip = frame.sxip + 4;
- frame.sfip = frame.snip + 4;
- db_printf("[r31=%x, sxip=%x]\n", frame.r[31], frame.sxip);
- regs = &frame;
- }
- }
-
- db_stack_trace_cmd2(regs);
+ switch (style) {
+ case Default:
+ regs = DDB_REGS;
+ break;
+ case Frame:
+ regs = arg.frame;
+ break;
+ case Proc:
+ break;
+ case Stack:
+ {
+ unsigned val1, val2, sxip;
+ unsigned ptr;
+ bzero((void*)&frame, sizeof(frame));
+#define REASONABLE_FRAME_DISTANCE 2048
+
+ /*
+ * We've got to find the top of a stack frame so we can get both
+ * a PC and and real SP.
+ */
+ for (ptr = arg.num;/**/; ptr += 4) {
+ /* Read a word from the named stack */
+ if (db_trace_get_val(ptr, &val1) == 0) {
+ db_printf("can't read from %x, aborting.\n", ptr);
+ return;
+ }
+
+ /*
+ * See if it's a frame pointer.... if so it will be larger than
+ * the address it was taken from (i.e. point back up the stack)
+ * and we'll be able to read where it points.
+ */
+ if (val1 <= ptr ||
+ (val1 & 3) ||
+ val1 > (ptr + REASONABLE_FRAME_DISTANCE))
+ continue;
+
+ /* peek at the next word to see if it could be a return address */
+ if (db_trace_get_val(ptr, &sxip) == 0) {
+ db_printf("can't read from %x, aborting.\n", ptr);
+ return;
+ }
+ if (sxip == 0 || !db_trace_get_val(sxip, &val2))
+ continue;
+
+ if (db_trace_get_val(val1, &val2) == 0) {
+ db_printf("can't read from %x, aborting.\n", val1);
+ continue;
+ }
+
+ /*
+ * The value we've just read will be either another frame pointer,
+ * or the start of another exception frame.
+ */
+ if (
+#ifdef JEFF_DEBUG
+ val2 == 0
+#else
+ val2 == 0x12345678
+#endif
+ && db_trace_get_val(val1-4, &val2) && val2 == val1
+ && db_trace_get_val(val1-8, &val2) && val2 == val1) {
+ /* we've found a frame, so the stack must have been good */
+ db_printf("%x looks like a frame, accepting %x\n",val1,ptr);
+ break;
+ }
+
+ if (val2 > val1 && (val2 & 3) == 0) {
+ /* well, looks close enough to be another frame pointer */
+ db_printf("*%x = %x looks like a stack frame pointer, accepting %x\n", val1, val2, ptr);
+ break;
+ }
+ }
+ frame.r[31] = ptr;
+ frame.epsr = 0x800003f0U;
+ if (cputyp != CPU_88110) {
+ frame.sxip = sxip | 2;
+ frame.snip = frame.sxip + 4;
+ frame.sfip = frame.snip + 4;
+ }
+ db_printf("[r31=%x, %sxip=%x]\n", frame.r[31],
+ cputyp == CPU_88110 ? "e" : "s", frame.sxip);
+ regs = &frame;
+ }
+ }
+ db_stack_trace_cmd2(regs);
}
+