diff options
author | Steve Murphree <smurph@cvs.openbsd.org> | 2001-12-22 08:31:06 +0000 |
---|---|---|
committer | Steve Murphree <smurph@cvs.openbsd.org> | 2001-12-22 08:31:06 +0000 |
commit | 87380d574c2af338617f92def75a97a172f2ec25 (patch) | |
tree | e2780ec83a78305e17168990da932274cab1642a /sys/arch | |
parent | 832a91320a5723dc06b1cf25dfea92a78db07fa1 (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')
-rw-r--r-- | sys/arch/mvme88k/ddb/db_disasm.c | 862 | ||||
-rw-r--r-- | sys/arch/mvme88k/ddb/db_interface.c | 238 | ||||
-rw-r--r-- | sys/arch/mvme88k/ddb/db_sstep.c | 93 | ||||
-rw-r--r-- | sys/arch/mvme88k/ddb/db_trace.c | 1613 | ||||
-rw-r--r-- | sys/arch/mvme88k/include/db_machdep.h | 37 | ||||
-rw-r--r-- | sys/arch/mvme88k/include/m88410.h | 32 |
6 files changed, 1526 insertions, 1349 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)®s->mode)) - return 0; + /* no good if we can't read the whole frame */ + if (badwordaddr((vm_offset_t)regs) || badwordaddr((vm_offset_t)®s->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); } + diff --git a/sys/arch/mvme88k/include/db_machdep.h b/sys/arch/mvme88k/include/db_machdep.h index 0cc38b7a625..286f136553a 100644 --- a/sys/arch/mvme88k/include/db_machdep.h +++ b/sys/arch/mvme88k/include/db_machdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: db_machdep.h,v 1.18 2001/12/16 23:49:46 miod Exp $ */ +/* $OpenBSD: db_machdep.h,v 1.19 2001/12/22 08:31:05 smurph Exp $ */ /* * Mach Operating System * Copyright (c) 1993-1991 Carnegie Mellon University @@ -49,8 +49,15 @@ #include <uvm/uvm_param.h> -#define BKPT_SIZE (4) /* number of bytes in bkpt inst. */ -#define BKPT_INST (0xF000D000 | DDB_ENTRY_BKPT_NO) /* tb0, 0,r0, vector 130 */ +/* + * This is a hack so that mc88100 can use software single step + * and mc88110 can use the wonderful hardware single step + * feature. XXX smurph + */ +#define INTERNAL_SSTEP /* Use local Single Step routines */ + +#define BKPT_SIZE (4) /* number of bytes in bkpt inst. */ +#define BKPT_INST (0xF000D000 | DDB_ENTRY_BKPT_NO) /* tb0, 0,r0, vector 130 */ #define BKPT_SET(inst) (BKPT_INST) /* Entry trap for the debugger - used for inline assembly breaks*/ @@ -71,7 +78,9 @@ extern db_regs_t ddb_regs; /* register state */ ({ \ int ret; \ \ - if (regs->sxip & 2) /* is valid */ \ + if (cputyp == CPU_88110) \ + ret = regs->exip & ~3; \ + else if (regs->sxip & 2) /* is valid */ \ ret = regs->sxip & ~3; \ else if (regs->snip & 2) \ ret = regs->snip & ~3; \ @@ -85,12 +94,15 @@ extern db_regs_t ddb_regs; /* register state */ * This is an actual function due to the fact that the sxip * or snip could be nooped out due to a jmp or rte */ -#define PC_REGS(regs) ((regs->sxip & 2) ? regs->sxip & ~3 : \ +#define PC_REGS(regs) cputyp == CPU_88110 ? (regs->exip & ~3) :\ + ((regs->sxip & 2) ? regs->sxip & ~3 : \ (regs->snip & 2 ? regs->snip & ~3 : regs->sfip & ~3)) -#define l_PC_REGS(regs) ((regs->sxip & 2) ? regs->sxip : \ +#define l_PC_REGS(regs) cputyp == CPU_88110 ? (regs->exip & ~3) :\ + ((regs->sxip & 2) ? regs->sxip : \ (regs->snip & 2 ? regs->snip : regs->sfip )) -#define pC_REGS(regs) (regs->sxip & 2) ? regs->sxip : (regs->snip & 2 ? \ +#define pC_REGS(regs) cputyp == CPU_88110 ? (regs->exip & ~3) :\ + (regs->sxip & 2) ? regs->sxip : (regs->snip & 2 ? \ regs->snip : regs->sfip) extern int db_noisy; #define NOISY(x) if (db_noisy) x @@ -109,7 +121,8 @@ unsigned inst_store __P((unsigned)); boolean_t inst_branch __P((unsigned)); db_addr_t next_instr_address __P((db_addr_t, unsigned)); db_addr_t branch_taken __P((u_int, db_addr_t, - db_expr_t (*) __P((db_regs_t *, int)), db_regs_t *)); + db_expr_t (*) __P((db_regs_t *, int)), + db_regs_t *)); int ddb_break_trap __P((int type, db_regs_t *eframe)); int ddb_entry_trap __P((int level, db_regs_t *eframe)); @@ -124,8 +137,14 @@ int ddb_entry_trap __P((int level, db_regs_t *eframe)); /* we don't want coff support */ #define DB_NO_COFF 1 +#ifdef INTERNAL_SSTEP +extern register_t getreg_val __P((db_regs_t *, int)); +void db_set_single_step __P((register db_regs_t *)); +void db_clear_single_step __P((register db_regs_t *)); +#else /* need software single step */ -#define SOFTWARE_SSTEP 1 /* we need this XXX nivas */ +#define SOFTWARE_SSTEP 1 /* we need this for mc88100 */ +#endif /* * Debugger can get to any address space diff --git a/sys/arch/mvme88k/include/m88410.h b/sys/arch/mvme88k/include/m88410.h index 932a8999033..ee587006b0a 100644 --- a/sys/arch/mvme88k/include/m88410.h +++ b/sys/arch/mvme88k/include/m88410.h @@ -1,4 +1,34 @@ -/* $OpenBSD: m88410.h,v 1.3 2001/12/21 05:53:38 smurph Exp $ */ +/* $OpenBSD: m88410.h,v 1.4 2001/12/22 08:31:05 smurph Exp $ */ +/* + * Copyright (c) 2001 Steve Murphree, Jr. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Steve Murphree. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ #ifndef __MACHINE_M88410_H__ #define __MACHINE_M88410_H__ |