summaryrefslogtreecommitdiff
path: root/sys/arch/mvme88k
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/mvme88k')
-rw-r--r--sys/arch/mvme88k/conf/files.mvme88k5
-rw-r--r--sys/arch/mvme88k/ddb/db_disasm.c689
-rw-r--r--sys/arch/mvme88k/ddb/db_sstep.c337
-rw-r--r--sys/arch/mvme88k/ddb/db_trace.c1143
4 files changed, 1 insertions, 2173 deletions
diff --git a/sys/arch/mvme88k/conf/files.mvme88k b/sys/arch/mvme88k/conf/files.mvme88k
index 5f9fcce0556..f1dd4d37ab5 100644
--- a/sys/arch/mvme88k/conf/files.mvme88k
+++ b/sys/arch/mvme88k/conf/files.mvme88k
@@ -1,4 +1,4 @@
-# $OpenBSD: files.mvme88k,v 1.29 2004/05/07 18:12:55 miod Exp $
+# $OpenBSD: files.mvme88k,v 1.30 2004/06/19 18:28:37 miod Exp $
#
maxpartitions 16
@@ -88,10 +88,7 @@ file arch/mvme88k/mvme88k/mem.c
file arch/mvme88k/mvme88k/pmap.c
file arch/mvme88k/mvme88k/pmap_table.c
file arch/mvme88k/mvme88k/vm_machdep.c
-file arch/mvme88k/ddb/db_disasm.c ddb
file arch/mvme88k/ddb/db_interface.c ddb
-file arch/mvme88k/ddb/db_sstep.c ddb
-file arch/mvme88k/ddb/db_trace.c ddb
file arch/mvme88k/dev/bugio.c
file arch/mvme88k/dev/mainbus.c
file arch/mvme88k/dev/memdevs.c nvram | sram
diff --git a/sys/arch/mvme88k/ddb/db_disasm.c b/sys/arch/mvme88k/ddb/db_disasm.c
deleted file mode 100644
index e97647618cb..00000000000
--- a/sys/arch/mvme88k/ddb/db_disasm.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/* $OpenBSD: db_disasm.c,v 1.13 2004/01/07 17:52:30 miod Exp $ */
-/*
- * Mach Operating System
- * Copyright (c) 1993-1991 Carnegie Mellon University
- * Copyright (c) 1991 OMRON Corporation
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-/*
- * m88k disassembler for use in ddb
- */
-
-#include <sys/param.h> /* cputyp and friends */
-#include <sys/types.h>
-
-#include <machine/db_machdep.h>
-
-#include <ddb/db_sym.h> /* DB_STGY_PROC, db_printsym() */
-#include <ddb/db_access.h> /* db_get_value() */
-#include <ddb/db_output.h> /* db_printf() */
-#include <ddb/db_interface.h>
-
-static const char *instwidth[4] = {
- ".d", " ", ".h", ".b"
-};
-
-static const char *condname[6] = {
- "gt0 ", "eq0 ", "ge0 ", "lt0 ", "ne0 ", "le0 "
-};
-
-static const char *m88100_ctrlreg[64] = {
- "cr0(PID) ",
- "cr1(PSR) ",
- "cr2(EPSR) ",
- "cr3(SSBR) ",
- "cr4(SXIP) ",
- "cr5(SNIP) ",
- "cr6(SFIP) ",
- "cr7(VBR) ",
- "cr8(DMT0) ",
- "cr9(DMD0) ",
- "cr10(DMA0) ",
- "cr11(DMT1) ",
- "cr12(DMD1) ",
- "cr13(DMA1) ",
- "cr14(DMT2) ",
- "cr15(DMD2) ",
- "cr16(DMA2) ",
- "cr17(SR0) ",
- "cr18(SR1) ",
- "cr19(SR2) ",
- "cr20(SR3) ",
- "fcr0(FPECR)",
- "fcr1(FPHS1)",
- "fcr2(FPLS1)",
- "fcr3(FPHS2)",
- "fcr4(FPLS2)",
- "fcr5(FPPT) ",
- "fcr6(FPRH) ",
- "fcr7(FPRL) ",
- "fcr8(FPIT) ",
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- "fcr62(FPSR)",
- "fcr63(FPCR)"
-};
-
-static const char *m88110_ctrlreg[64] = {
- "cr0(PID) ",
- "cr1(PSR) ",
- "cr2(EPSR) ",
- NULL,
- "cr4(EXIP) ",
- "cr5(ENIP) ",
- NULL,
- "cr7(VBR) ",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- "cr14(RES1) ",
- "cr15(RES2) ",
- "cr16(SR0) ",
- "cr17(SR1) ",
- "cr18(SR2) ",
- "cr19(SR3) ",
- "cr20(SR4) ",
- "fcr0(FPECR)",
- NULL,
- NULL,
- NULL,
- "cr25(ICMD) ",
- "cr26(ICTL) ",
- "cr27(ISAR) ",
- "cr28(ISAP) ",
- "cr29(IUAP) ",
- "cr30(IIR) ",
- "cr31(IBP) ",
- "cr32(IPPU) ",
- "cr33(IPPL) ",
- "cr34(ISR) ",
- "cr35(ILAR) ",
- "cr36(IPAR) ",
- NULL,
- NULL,
- NULL,
- "cr40(DCMD) ",
- "cr41(DCTL) ",
- "cr42(DSAR) ",
- "cr43(DSAP) ",
- "cr44(DUAP) ",
- "cr45(DIR) ",
- "cr46(DBP) ",
- "cr47(DPPU) ",
- "cr48(DPPL) ",
- "cr49(DSR) ",
- "cr50(DLAR) ",
- "cr51(DPAR) ",
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL,
- "fcr62(FPSR)",
- "fcr63(FPCR)"
-};
-
-#define printval(x) \
- do { \
- if ((x) < 0) \
- db_printf("-0x%X", -(x)); \
- else \
- db_printf("0x%X", (x)); \
- } while (0)
-
-/* prototypes */
-void oimmed(int, const char *, long);
-void ctrlregs(int, const char *, long);
-void printsod(int);
-void sindou(int, const char *, long);
-void jump(int, const char *, long);
-void instset(int, const char *, long);
-void symofset(int, int, int);
-void obranch(int, const char *, long);
-void brcond(int, const char *, long);
-void otrap(int, const char *, long);
-void obit(int, const char *, long);
-void bitman(int, const char *, long);
-void immem(int, const char *, long);
-void nimmem(int, const char *, long);
-void lognim(int, const char *, long);
-void onimmed(int, const char *, long);
-
-/* Handlers immediate integer arithmetic instructions */
-void
-oimmed(int inst, const char *opcode, long iadr)
-{
- int Linst = inst & 0177777;
- int Hinst = inst >> 16;
- int H6inst = Hinst >> 10;
- int rs1 = Hinst & 037;
- 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);
-}
-
-
-/* Handles instructions dealing with control registers */
-void
-ctrlregs(int inst, const char *opcode, long iadr)
-{
- int L6inst = (inst >> 11) & 037;
- int creg = (inst >> 5) & 077;
- int rd = (inst >> 21) & 037;
- 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");
-}
-
-/* Handles floating point instructions */
-void
-sindou(int inst, const char *opcode, long iadr)
-{
- int rs2 = inst & 037;
- int td = ( inst >> 5 ) & 03;
- int t2 = ( inst >> 7 ) & 03;
- int t1 = ( inst >> 9 ) & 03;
- int rs1 = ( inst >> 16 ) & 037;
- int rd = ( inst >> 21 ) & 037;
- 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, const char *opcode, long iadr)
-{
- int rs2 = inst & 037;
- 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);
-}
-
-
-/* Handles ff1, ff0, tbnd and rte instructions */
-void
-instset(int inst, const char *opcode, long iadr)
-{
- int rs2 = inst & 037;
- int rs1 = ( inst >> 16 ) & 037;
- int rd = ( inst >> 21 ) & 037;
- int checkbits = ( inst >> 10 ) & 077;
- 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, db_printf);
- return;
-}
-
-void
-obranch(int inst, const 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);
- }
-}
-
-
-/* Handles branch on conditions instructions */
-void
-brcond(int inst, const 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);
-}
-
-
-void
-otrap(int inst, const 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);
-}
-
-
-/* Handles 10 bit immediate bit field operations */
-void
-obit(int inst, const 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(">");
- }
-}
-
-
-/* Handles triadic mode bit field instructions */
-void
-bitman(int inst, const 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);
-}
-
-
-/* Handles immediate load/store/exchange instructions */
-void
-immem(int inst, const char *opcode, long iadr)
-{
- int immed = inst & 0xFFFF;
- int rd = (inst >> 21) & 037;
- int rs = (inst >> 16) & 037;
- int st_lda = (inst >> 28) & 03;
- 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);
-}
-
-
-/* Handles triadic mode load/store/exchange instructions */
-void
-nimmem(int inst, const char *opcode, long iadr)
-{
- int scaled = (inst >> 9) & 01;
- int rd = (inst >> 21) & 037;
- int rs1 = (inst >> 16) & 037;
- int rs2 = inst & 037;
- int st_lda = (inst >> 12) & 03;
- int aryno = (inst >> 10) & 03;
- 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);
-}
-
-
-/* Handles triadic mode logical instructions */
-void
-lognim(int inst, const char *opcode, long iadr)
-{
- int rd = (inst >> 21) & 037;
- int rs1 = (inst >> 16) & 037;
- int rs2 = inst & 037;
- 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);
-}
-
-
-/* Handles triadic mode arithmetic instructions */
-void
-onimmed(int inst, const char *opcode, long iadr)
-{
- int rd = (inst >> 21) & 037;
- int rs1 = (inst >> 16) & 037;
- int rs2 = inst & 037;
- int carry = (inst >> 8) & 03;
- int nochar = (inst >> 10) & 07;
- 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";
- else
- c = " ";
- } else
- c = " ";
-
- db_printf("\t%s%s%sr%-3d,r%-3d,r%-3d", opcode, c,
- tab, rd, rs1, rs2);
-}
-
-static const struct opdesc {
- unsigned mask, match;
- void (*opfun)(int, const char *, long);
- const char *farg;
-} opdecode[] = {
-
- /* ORDER IS IMPORTANT BELOW */
-
- { 0xF0000000U, 0x00000000U, immem, NULL},
- { 0xF0000000U, 0x10000000U, immem, NULL},
- { 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, NULL},
- { 0xFC00F2E0U, 0xF4000200U, nimmem, NULL},
- { 0xFC00F2E0U, 0xF4001000U, nimmem, NULL},
- { 0xFC00F2E0U, 0xF4001200U, nimmem, NULL},
- { 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, NULL, NULL}
-};
-
-static const char *badop = "\t???";
-
-int
-m88k_print_instruction(unsigned iadr, long inst)
-{
- const 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);
- }
-
- 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;
-}
diff --git a/sys/arch/mvme88k/ddb/db_sstep.c b/sys/arch/mvme88k/ddb/db_sstep.c
deleted file mode 100644
index e281eebe6b5..00000000000
--- a/sys/arch/mvme88k/ddb/db_sstep.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/* $OpenBSD: db_sstep.c,v 1.14 2004/01/07 17:52:30 miod Exp $ */
-/*
- * Mach Operating System
- * Copyright (c) 1993-1991 Carnegie Mellon University
- * Copyright (c) 1991 OMRON Corporation
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#include <sys/param.h>
-#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.
- *
- * Author: Daniel Stodolsky (danner@cs.cmu.edu)
- *
- */
-
-boolean_t inst_delayed(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
- * (br, bb0, bb1, bcnd, jmp) but not a function call (bsr or jsr)
- */
-boolean_t
-inst_branch(ins)
- unsigned int ins;
-{
- /* check high five bits */
- switch (ins >> (32 - 5)) {
- case 0x18: /* br */
- case 0x1a: /* bb0 */
- case 0x1b: /* bb1 */
- case 0x1d: /* bcnd */
- return TRUE;
- break;
- case 0x1e: /* could be jmp */
- if ((ins & 0xfffffbe0U) == 0xf400c000U)
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*
- * inst_load(ins)
- * Returns the number of words the instruction loads. byte,
- * half and word count as 1; double word as 2
- */
-unsigned
-inst_load(ins)
- unsigned int ins;
-{
- /* look at the top six bits, for starters */
- switch (ins >> (32 - 6)) {
- case 0x0: /* xmem byte imm */
- case 0x1: /* xmem word imm */
-
- case 0x2: /* unsigned half-word load imm */
- case 0x3: /* unsigned byte load imm */
- case 0x5: /* signed word load imm */
- case 0x6: /* signed half-word load imm */
- case 0x7: /* signed byte load imm */
- return 1;
-
- case 0x4: /* signed double word load imm */
- return 2;
-
- case 0x3d: /* load/store/xmem scaled/unscaled instruction */
- 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 */
- case 0x2: /* unsigned half word */
- case 0x3: /* unsigned byte load */
- case 0x5: /* signed word load */
- case 0x6: /* signed half-word load */
- case 0x7: /* signed byte load */
- return 1;
-
- case 0x4: /* signed double word load */
- return 2;
- } /* end switch load/xmem */
- break;
- } /* end switch 32-6 */
-
- return 0;
-}
-
-/*
- * inst_store
- * Like inst_load, except for store instructions.
- */
-unsigned
-inst_store(ins)
- unsigned int ins;
-{
- /* decode top 6 bits again */
- switch (ins >> (32 - 6)) {
- case 0x0: /* xmem byte imm */
- case 0x1: /* xmem word imm */
- case 0x9: /* store word imm */
- case 0xa: /* store half-word imm */
- case 0xb: /* store byte imm */
- return 1;
-
- case 0x8: /* store double word */
- return 2;
- case 0x3d: /* load/store/xmem scaled/unscaled instruction */
- /* check bits 15,14,12,7,6,5 are all 0 */
- if ((ins & 0x0000d0e0U) == 0)
- switch ((ins & 0x00003c00U) >> 10) { /* decode bits 10-13 */
- case 0x0: /* xmem byte imm */
- case 0x1: /* xmem word imm */
- case 0x9: /* store word */
- case 0xa: /* store half-word */
- case 0xb: /* store byte */
- return 1;
-
- case 0x8: /* store double word */
- return 2;
- } /* end switch store/xmem */
- break;
- } /* end switch 32-6 */
-
- return 0;
-}
-
-/*
- * inst_delayed
- * Returns TRUE if this instruction is followed by a delay slot.
- * Could be br.n, bsr.n bb0.n, bb1.n, bcnd.n or jmp.n or jsr.n
- */
-boolean_t
-inst_delayed(ins)
- unsigned int ins;
-{
- /* check the br, bsr, bb0, bb1, bcnd cases */
- switch ((ins & 0xfc000000U) >> (32 - 6)) {
- case 0x31: /* br */
- case 0x33: /* bsr */
- case 0x35: /* bb0 */
- case 0x37: /* bb1 */
- case 0x3b: /* bcnd */
- return TRUE;
- }
-
- /* check the jmp, jsr cases */
- /* mask out bits 0-4, bit 11 */
- return ((ins & 0xfffff7e0U) == 0xf400c400U) ? TRUE : FALSE;
-}
-
-/*
- * next_instr_address(pc,delay_slot,task) has the following semantics.
- * Let inst be the instruction at pc.
- * If delay_slot = 1, next_instr_address should return
- * the address of the instruction in the delay slot; if this instruction
- * does not have a delay slot, it should return pc.
- * If delay_slot = 0, next_instr_address should return the
- * address of next sequential instruction, or pc if the instruction is
- * followed by a delay slot.
- *
- * 91-11-28 jfriedl: I think the above is wrong. I think it should be:
- * if delay_slot true, return address of the delay slot if there is one,
- * return pc otherwise.
- * if delay_slot false, return (pc + 4) regardless.
- *
- */
-db_addr_t
-next_instr_address(pc, delay_slot)
- db_addr_t pc;
- unsigned delay_slot;
-{
- if (delay_slot == 0)
- return pc + 4;
- else {
- if (inst_delayed(db_get_value(pc, sizeof(int), FALSE)))
- return pc + 4;
- else
- return pc;
- }
-}
-
-
-/*
- * branch_taken(instruction, program counter, func, func_data)
- *
- * instruction will be a control flow instruction location at address pc.
- * Branch taken is supposed to return the address to which the instruction
- * would jump if the branch is taken. Func can be used to get the current
- * register values when invoked with a register number and func_data as
- * arguments.
- *
- * If the instruction is not a control flow instruction, panic.
- */
-db_addr_t
-branch_taken(inst, pc, func, func_data)
- u_int inst;
- db_addr_t pc;
- db_expr_t (*func)(db_regs_t *, int);
- db_regs_t *func_data;
-{
- /* check if br/bsr */
- if ((inst & 0xf0000000U) == 0xc0000000U) {
- /* signed 26 bit pc relative displacement, shift left two bits */
- inst = (inst & 0x03ffffffU) << 2;
- /* check if sign extension is needed */
- if (inst & 0x08000000U)
- inst |= 0xf0000000U;
- return pc + inst;
- }
-
- /* check if bb0/bb1/bcnd case */
- switch ((inst & 0xf8000000U)) {
- case 0xd0000000U: /* bb0 */
- case 0xd8000000U: /* bb1 */
- case 0xe8000000U: /* bcnd */
- /* signed 16 bit pc relative displacement, shift left two bits */
- inst = (inst & 0x0000ffffU) << 2;
- /* check if sign extension is needed */
- if (inst & 0x00020000U)
- inst |= 0xfffc0000U;
- return pc + inst;
- }
-
- /* check jmp/jsr case */
- /* check bits 5-31, skipping 10 & 11 */
- if ((inst & 0xfffff3e0U) == 0xf400c000U) {
- return (*func)(func_data, (inst & 0x0000001fU)); /* the register value */
- }
-
-
- panic("branch_taken");
- return 0; /* keeps compiler happy */
-}
-
-/*
- * getreg_val - handed a register number and an exception frame.
- * Returns the value of the register in the specified
- * frame. Only makes sense for general registers.
- */
-
-db_expr_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 (%d) to getreg_val.", regno);
-}
-
-#ifdef INTERNAL_SSTEP
-void
-db_set_single_step(regs)
- 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
deleted file mode 100644
index 93204aaf84e..00000000000
--- a/sys/arch/mvme88k/ddb/db_trace.c
+++ /dev/null
@@ -1,1143 +0,0 @@
-/* $OpenBSD: db_trace.c,v 1.27 2004/01/29 21:39:05 deraadt Exp $ */
-/*
- * Mach Operating System
- * Copyright (c) 1993-1991 Carnegie Mellon University
- * Copyright (c) 1991 OMRON Corporation
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-
-#include <machine/db_machdep.h>
-#include <machine/locore.h>
-
-#include <ddb/db_variables.h> /* db_variable, DB_VAR_GET, etc. */
-#include <ddb/db_output.h> /* db_printf */
-#include <ddb/db_sym.h> /* DB_STGY_PROC, etc. */
-#include <ddb/db_command.h> /* db_recover */
-#include <ddb/db_access.h>
-#include <ddb/db_interface.h>
-
-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 */
-
-};
-
-static inline unsigned br_dest(unsigned addr, union instruction inst)
-{
- return addr + inst.br.d26 * 4;
-}
-
-
-#define TRACE_DEBUG /* undefine to disable debugging */
-
-int frame_is_sane(db_regs_t *regs, int);
-char *m88k_exception_name(unsigned vector);
-unsigned db_trace_get_val(vaddr_t addr, unsigned *ptr);
-
-/*
- * Some macros to tell if the given text is the instruction.
- */
-#define JMPN_R1(I) ( (I) == 0xf400c401U) /* jmp.n r1 */
-#define JMP_R1(I) ( (I) == 0xf400c001U) /* jmp r1 */
-
-/* gets the IMM16 value from an instruction */
-#define IMM16VAL(I) (((union instruction)(I)).diatic.i16)
-
-/* subu r31, r31, IMM */
-#define SUBU_R31_R31_IMM(I) (((I) & 0xffff0000U) == 0x67ff0000U)
-
-/* st r1, r31, IMM */
-#define ST_R1_R31_IMM(I) (((I) & 0xffff0000U) == 0x243f0000U)
-
-static int trace_flags;
-#define TRACE_DEBUG_FLAG 0x01
-#define TRACE_SHOWCALLPRESERVED_FLAG 0x02
-#define TRACE_SHOWADDRESS_FLAG 0x04
-#define TRACE_SHOWFRAME_FLAG 0x08
-#define TRACE_USER_FLAG 0x10
-
-#ifdef TRACE_DEBUG
- #define DEBUGGING_ON (trace_flags & TRACE_DEBUG_FLAG)
-#endif
-
-#ifndef TRACE_DEBUG
- #define SHOW_INSTRUCTION(Addr, Inst, Note) { /*nothing*/ }
-#else
- #define SHOW_INSTRUCTION(Addr, Inst, Note) if (DEBUGGING_ON) { \
- db_printf("%s0x%x: (0x%08x) ", Note, (unsigned)(Addr), (Inst)); \
- m88k_print_instruction((unsigned)(Addr), (Inst)); \
- db_printf("\n"); \
- }
-#endif
-
-extern label_t *db_recover;
-
-/*
- * m88k trace/register state interface for ddb.
- */
-
-/* lifted from mips */
-static int
-db_setf_regs(struct db_variable *vp,
- db_expr_t *valuep,
- int op) /* read/write */
-{
- int *regp = (int *) ((char *) DDB_REGS + (int) (vp->valuep));
-
- if (op == DB_VAR_GET)
- *valuep = *regp;
- else if (op == DB_VAR_SET)
- *regp = *valuep;
-
- 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),
-};
-#undef N
-
-struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
-
-
-#define TRASHES 0x001 /* clobbers instruction field D */
-#define STORE 0x002 /* does a store to S1+IMM16 */
-#define LOAD 0x004 /* does a load from S1+IMM16 */
-#define DOUBLE 0x008 /* double-register */
-#define FLOW_CTRL 0x010 /* flow-control instruction */
-#define DELAYED 0x020 /* delayed flow control */
-#define JSR 0x040 /* flow-control is a jsr[.n] */
-#define BSR 0x080 /* flow-control is a bsr[.n] */
-
-/*
- * Given a word of instruction text, return some flags about that
- * instruction (flags defined above).
- */
-static unsigned
-m88k_instruction_info(unsigned instruction)
-{
- static const 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;
-
- 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;
-}
-
-/*
- * 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.
- */
-int
-frame_is_sane(db_regs_t *regs, int quiet)
-{
- /* no good if we can't read the whole frame */
- if (badwordaddr((vaddr_t)regs) || badwordaddr((vaddr_t)&regs->fpit)) {
- if (quiet == 0)
- db_printf("[WARNING: frame at %p : unreadable]\n", regs);
- return 0;
- }
-
- /* r0 must be 0 (obviously) */
- if (regs->r[0] != 0) {
- if (quiet == 0)
- db_printf("[WARNING: frame at %p : r[0] != 0]\n", regs);
- return 0;
- }
-
- /* stack sanity ... r31 must be nonzero, and must be word aligned */
- if (regs->r[31] == 0 || (regs->r[31] & 3) != 0) {
- if (quiet == 0)
- db_printf("[WARNING: frame at %p : r[31] == 0 or not word aligned]\n", regs);
- return 0;
- }
-
- if (cputyp != CPU_88110) {
- /* sxip is reasonable */
-#if 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;
- }
-
- /* epsr sanity */
- if ((regs->epsr & PSR_MODE)) { /* kernel mode */
- if (regs->epsr & PSR_BO)
- return 0;
- return 1;
- }
- if (!(regs->epsr & PSR_MODE)) { /* user mode */
- if (regs->epsr & PSR_BO)
- return 0;
- return 2;
- }
- if (quiet == 0)
- db_printf("[WARNING: not an exception frame?]\n");
- return 0;
-}
-
-char *
-m88k_exception_name(unsigned vector)
-{
- switch (vector) {
- default:
- case 0: return "Reset";
- case 1: return "Interrupt";
- case 2: return "Instruction Access Exception";
- case 3: return "Data Access Exception";
- case 4: return "Misaligned Access Exception";
- case 5: return "Unimplemented Opcode Exception";
- case 6: return "Privilege Violation";
- case 7: return "Bounds Check";
- 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:
- return "ddb break";
- case DDB_ENTRY_TRACE_NO:
- return "ddb trace";
- case DDB_ENTRY_TRAP_NO:
- return "ddb trap";
- case 451: return "Syscall";
- }
-}
-
-/*
- * Read a word at address addr.
- * Return 1 if was able to read, 0 otherwise.
- */
-unsigned
-db_trace_get_val(vaddr_t addr, unsigned *ptr)
-{
- label_t db_jmpbuf;
- label_t *prev = db_recover;
-
- if (setjmp((db_recover = &db_jmpbuf)) != 0) {
- db_recover = prev;
- return 0;
- } else {
- db_read_bytes(addr, 4, (char *)ptr);
- db_recover = prev;
- return 1;
- }
-}
-
-#define FIRST_CALLPRESERVED_REG 14
-#define LAST_CALLPRESERVED_REG 29
-#define FIRST_ARG_REG 2
-#define LAST_ARG_REG 9
-#define RETURN_VAL_REG 1
-
-static unsigned global_saved_list = 0x0; /* one bit per register */
-static unsigned local_saved_list = 0x0; /* one bit per register */
-static unsigned trashed_list = 0x0; /* one bit per register */
-static unsigned saved_reg[32]; /* one value per register */
-
-#define reg_bit(reg) (1<<((reg)%32))
-
-static void
-save_reg(int reg, unsigned value)
-{
-#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);
-}
-
-#define mark_reg_trashed(reg) (trashed_list |= reg_bit(reg))
-
-#define have_global_reg(reg) (global_saved_list & (1<<(reg)))
-#define have_local_reg(reg) (local_saved_list & (1<<(reg)))
-
-#define clear_local_saved_regs() { local_saved_list = trashed_list = 0; }
-#define clear_global_saved_regs() { local_saved_list = global_saved_list = 0; }
-
-#define saved_reg_value(reg) (saved_reg[(reg)])
-
-/*
- * Show any arguments that we might have been able to determine.
- */
-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);
- }
- if (reg == last_arg)
- break;
- else
- db_printf(", ");
- }
- db_printf(")");
-}
-
-
-#define JUMP_SOURCE_IS_BAD 0
-#define JUMP_SOURCE_IS_OK 1
-#define JUMP_SOURCE_IS_UNLIKELY 2
-
-/*
- * Give an address to where we return, and an address to where we'd jumped,
- * Decided if it all makes sense.
- *
- * Gcc sometimes optimized something like
- * if (condition)
- * func1();
- * else
- * OtherStuff...
- * to
- * bcnd !condition mark
- * bsr.n func1
- * or r1, r0, mark2
- * mark:
- * OtherStuff...
- * mark2:
- *
- * So RETURN_TO will be MARK2, even though we really did branch via
- * 'bsr.n func1', so this makes it difficult to be certaian about being
- * wrong.
- */
-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;
-}
-
-static char *note = 0;
-static int next_address_likely_wrong = 0;
-
-/* How much slop we expect in the stack trace */
-#define FRAME_PLAY 8
-
-/*
- * Stack decode -
- * unsigned addr; program counter
- * unsigned *stack; IN/OUT stack pointer
- *
- * given an address within a function and a stack pointer,
- * try to find the function from which this one was called
- * and the stack pointer for that function.
- *
- * The return value is zero (if we get confused) or
- * we determine that the return address has not yet
- * been saved (early in the function prologue). Otherwise
- * the return value is the address from which this function
- * was called.
- *
- * Note that even is zero is returned (the second case) the
- * stack pointer can be adjusted.
- *
- */
-static int
-stack_decode(db_addr_t addr, unsigned *stack, int (*pr)(const char *, ...))
-{
- db_sym_t proc;
- db_expr_t offset_from_proc;
- unsigned instructions_to_search;
- db_addr_t check_addr;
- db_addr_t 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)
- (*pr)("\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) (*pr)("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; /* success */
-#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)
- (*pr)("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)
- (*pr)("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) (*pr)("at start of func\n");
-#endif
- return 0;
- }
- if (!db_trace_get_val(function_addr, &inst)) {
-#ifdef TRACE_DEBUG
- if (DEBUGGING_ON) (*pr)("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) (*pr)("<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 (DEBUGGING_ON) (*pr)("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 we didn't save r1 at some point, we're hosed.
- */
- if (!have_local_reg(1)) {
- if (tried_to_save_r1) {
- (*pr)(" <return value of next fcn unreadable in %08x>\n",
- tried_to_save_r1);
- }
-#ifdef TRACE_DEBUG
- if (DEBUGGING_ON) (*pr)("didn't save r1\n");
-#endif
- return 0;
- }
-
- ret_addr = saved_reg_value(1);
-
-#ifdef TRACE_DEBUG
- if (DEBUGGING_ON)
- (*pr)("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) (*pr)("jump is bad\n");
-#endif
- return 0; /* bummer */
-
- case JUMP_SOURCE_IS_UNLIKELY:
- next_address_likely_wrong = 1;
- break;
- }
- }
-
- return ret_addr;
-}
-
-static void
-db_stack_trace_cmd2(db_regs_t *regs, int (*pr)(const char *, ...))
-{
- 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, 1)) == 0) {
- (*pr)("Register frame 0x%x is suspicious; 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 */
- 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];
- (*pr)("stack base = 0x%x\n", stack);
- (*pr)("(0) "); /*depth of trace */
- if (trace_flags & TRACE_SHOWADDRESS_FLAG)
- (*pr)("%08x ", where);
- db_printsym(where, DB_STGY_PROC, pr);
- clear_global_saved_regs();
-
- /* see if this routine had a stack frame */
- if ((where=stack_decode(where, &stack, pr))==0) {
- where = regs->r[1];
- (*pr)("(stackless)");
- } else {
- print_args();
- if (trace_flags & TRACE_SHOWFRAME_FLAG)
- (*pr)(" [frame 0x%x]", stack);
- }
- (*pr)("\n");
- if (note) {
- (*pr)(" %s\n", note);
- note = 0;
- }
-
- 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;
- (*pr)("[in next func:");
- }
- if (value == 0)
- (*pr)(" r%d", r);
- else if (value <= 9)
- (*pr)(" r%d=%x", r, value);
- else
- (*pr)(" r%d=x%x", r, value);
- }
- }
- if (title_printed)
- (*pr)("]\n");
- }
-
- (*pr)("(%d)%c", depth++, next_address_likely_wrong ? '?':' ');
- next_address_likely_wrong = 0;
-
- if (trace_flags & TRACE_SHOWADDRESS_FLAG)
- (*pr)("%08x ", where);
- db_printsym(where, DB_STGY_PROC, pr);
- where = stack_decode(where, &stack, pr);
- print_args();
- if (trace_flags & TRACE_SHOWFRAME_FLAG)
- (*pr)(" [frame 0x%x]", stack);
- (*pr)("\n");
- if (note) {
- (*pr)(" %s\n", note);
- note = 0;
- }
- } while (where);
-
- /* try to trace back over trap/exception */
-
- stack &= ~7; /* double word aligned */
- /* take last top of stack, and try to find an exception frame near it */
-
- i = FRAME_PLAY;
-
-#ifdef TRACE_DEBUG
- if (DEBUGGING_ON)
- (*pr)("(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((vaddr_t)stack) ||
- badwordaddr((vaddr_t)(stack+4)))
- break;
-
- db_read_bytes((vaddr_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((vaddr_t)pair[0]) && (pair[0]!=0))
- (*pr)("stack_trace:found pair 0x%x but != to stack+8\n",
- pair[0]);
- */
- }
-
- else if (frame_is_sane((db_regs_t*)pair[0], 1) != 0) {
- struct trapframe *frame =
- (struct trapframe *)pair[0];
-
- (*pr)("-------------- %s [EF: 0x%x] -------------\n",
- m88k_exception_name(frame->tf_vector),
- frame);
- db_stack_trace_cmd2(&frame->tf_regs, pr);
- return;
- }
-#ifdef TRACE_DEBUG
- else if (DEBUGGING_ON)
- (*pr)("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) {
- struct trapframe *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((vaddr_t)stack) ||
- badwordaddr((vaddr_t)stack))
- return;
-
- db_read_bytes((vaddr_t)stack, 2*sizeof(int), (char *)pair);
- if (pair[0] != pair[1])
- return;
-
- /* have a hit */
- user = *((struct trapframe **)stack);
-
- if (frame_is_sane(&user->tf_regs, 1) == 2) {
- (*pr)("---------------- %s [EF : 0x%x] -------------\n",
- m88k_exception_name(user->tf_vector), user);
- db_stack_trace_cmd2(&user->tf_regs, pr);
- }
- }
-}
-
-/*
- * stack trace - needs a pointer to a m88k saved state.
- *
- * If argument f is given, the stack pointer of each call frame is
- * printed.
- */
-void
-db_stack_trace_print(db_expr_t addr,
- int have_addr,
- db_expr_t count,
- char *modif,
- int (*pr)(const char *, ...))
-{
- enum {
- Default, Stack, Frame
- } style = Default;
- db_regs_t frame;
- db_regs_t *regs;
- union {
- db_regs_t *frame;
- db_expr_t num;
- } arg;
-
- arg.num = 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:
- (*pr)("unknown trace modifier [%c]\n", modif[-1]);
- /*FALLTHROUGH*/
- case 'h':
- (*pr)("usage: trace/[MODIFIER] [ARG]\n");
- (*pr)(" u = include user trace\n");
- (*pr)(" F = print stack frames\n");
- (*pr)(" a = show return addresses\n");
- (*pr)(" p = show call-preserved registers\n");
- (*pr)(" s = ARG is a stack pointer\n");
- (*pr)(" f = ARG is a frame pointer\n");
-#ifdef TRACE_DEBUG
- (*pr)(" d = trace-debugging output\n");
-#endif
- return;
- }
- }
-
- if (!have_addr && style != Default) {
- (*pr)("expecting argument with /s or /f\n");
- return;
- }
- if (have_addr && style == Default)
- style = Frame;
-
- switch (style) {
- case Default:
- regs = DDB_REGS;
- break;
- case Frame:
- regs = arg.frame;
- 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) {
- (*pr)("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) {
- (*pr)("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) {
- (*pr)("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 */
- (*pr)("%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 */
- (*pr)("*%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;
- }
- (*pr)("[r31=%x, %sxip=%x]\n", frame.r[31],
- cputyp == CPU_88110 ? "e" : "s", frame.sxip);
- regs = &frame;
- }
- }
- db_stack_trace_cmd2(regs, pr);
-}