Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc64 Add debugger single-stepping and fix interr...



details:   https://anonhg.NetBSD.org/src/rev/1c9d6687054e
branches:  trunk
changeset: 480372:1c9d6687054e
user:      eeh <eeh%NetBSD.org@localhost>
date:      Mon Jan 10 03:53:20 2000 +0000

description:
Add debugger single-stepping and fix interrupt dispatch bugs.

diffstat:

 sys/arch/sparc64/include/db_machdep.h      |   41 +++-
 sys/arch/sparc64/include/instr.h           |   31 +++-
 sys/arch/sparc64/include/reg.h             |   12 +-
 sys/arch/sparc64/sparc64/db_interface.c    |  248 +++++++++++++++++++++++++++-
 sys/arch/sparc64/sparc64/intr.c            |   20 +-
 sys/arch/sparc64/sparc64/locore.s          |   46 +++-
 sys/arch/sparc64/sparc64/process_machdep.c |    9 +-
 sys/arch/sparc64/sparc64/trap.c            |    9 +-
 8 files changed, 355 insertions(+), 61 deletions(-)

diffs (truncated from 695 to 300 lines):

diff -r 81a08dd595f9 -r 1c9d6687054e sys/arch/sparc64/include/db_machdep.h
--- a/sys/arch/sparc64/include/db_machdep.h     Mon Jan 10 03:24:31 2000 +0000
+++ b/sys/arch/sparc64/include/db_machdep.h     Mon Jan 10 03:53:20 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_machdep.h,v 1.8 1999/11/06 20:13:50 eeh Exp $ */
+/*     $NetBSD: db_machdep.h,v 1.9 2000/01/10 03:53:20 eeh Exp $ */
 
 /*
  * Mach Operating System
@@ -96,18 +96,39 @@
 #define        BKPT_SIZE       (4)             /* size of breakpoint inst */
 #define        BKPT_SET(inst)  (BKPT_INST)
 
-#define        db_clear_single_step(regs)      (void) (0)
-#define        db_set_single_step(regs)        (void) (0)
-
 #define        IS_BREAKPOINT_TRAP(type, code)  \
        ((type) == T_BREAKPOINT || (type) == T_KGDB_EXEC)
-#define IS_WATCHPOINT_TRAP(type, code) (0)
+#define IS_WATCHPOINT_TRAP(type, code) \
+       ((type) ==T_PA_WATCHPT || (type) == T_VA_WATCHPT)
+
+/*
+ * Sparc cpus have no hardware single-step.
+ */
+#define SOFTWARE_SSTEP
 
-#define        inst_trap_return(ins)   ((ins)&0)
-#define        inst_return(ins)        ((ins)&0)
-#define        inst_call(ins)          ((ins)&0)
-#define inst_load(ins)         0
-#define inst_store(ins)                0
+boolean_t      db_inst_trap_return __P((int inst));
+boolean_t      db_inst_return __P((int inst));
+boolean_t      db_inst_call __P((int inst));
+boolean_t      db_inst_branch __P((int inst));
+int            db_inst_load __P((int inst));
+int            db_inst_store __P((int inst));
+boolean_t      db_inst_unconditional_flow_transfer __P((int inst));
+db_addr_t      db_branch_taken __P((int inst, db_addr_t pc, db_regs_t *regs));
+
+#define inst_trap_return(ins)  db_inst_trap_return(ins)
+#define inst_return(ins)       db_inst_return(ins)
+#define inst_call(ins)         db_inst_call(ins)
+#define inst_branch(ins)       db_inst_branch(ins)
+#define inst_load(ins)         db_inst_load(ins)
+#define inst_store(ins)                db_inst_store(ins)
+#define        inst_unconditional_flow_transfer(ins) \
+                               db_inst_unconditional_flow_transfer(ins)
+#define branch_taken(ins, pc, regs) \
+                               db_branch_taken((ins), (pc), (regs))
+
+/* see note in db_interface.c about reversed breakpoint addrs */
+#define next_instr_address(pc, bd) \
+       ((bd) ? (pc) : ddb_regs.ddb_tf.tf_npc)
 
 #define DB_MACHINE_COMMANDS
 
diff -r 81a08dd595f9 -r 1c9d6687054e sys/arch/sparc64/include/instr.h
--- a/sys/arch/sparc64/include/instr.h  Mon Jan 10 03:24:31 2000 +0000
+++ b/sys/arch/sparc64/include/instr.h  Mon Jan 10 03:53:20 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: instr.h,v 1.2 1998/09/22 02:48:43 eeh Exp $ */
+/*     $NetBSD: instr.h,v 1.3 2000/01/10 03:53:20 eeh Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -46,8 +46,8 @@
 
 /* see also Appendix F of the SPARC version 8 document */
 enum IOP { IOP_OP2, IOP_CALL, IOP_reg, IOP_mem };
-enum IOP2 { IOP2_UNIMP, IOP2_err1, IOP2_Bicc, IOP2_err3,
-       IOP2_SETHI, IOP2_err5, IOP2_FBfcc, IOP2_CBccc };
+enum IOP2 { IOP2_UNIMP, IOP2_BPcc, IOP2_Bicc, IOP2_BPr,
+       IOP2_SETHI, IOP2_FBPfcc, IOP2_FBfcc, IOP2_CBccc };
 enum IOP3_reg {
        IOP3_ADD, IOP3_AND, IOP3_OR, IOP3_XOR,
        IOP3_SUB, IOP3_ANDN, IOP3_ORN, IOP3_XNOR,
@@ -193,6 +193,31 @@
                int     i_disp:22;      /* branch displacement */
        } i_branch;
 
+       /* more branches: BPcc, FBPfcc */
+       struct {
+               u_int   :2;             /* 00 */
+               u_int   i_annul:1;      /* annul bit */
+               u_int   i_cond:4;       /* condition codes */
+               u_int   i_op2:3;        /* opcode: {BP,FBPf}cc */
+               u_int   i_cc:2;         /* condition code selector */
+               u_int   i_pred:1;       /* branch prediction bit */
+               int     i_disp:19;      /* branch displacement */
+       } i_branch_p;
+
+       /* one last branch: BPr */
+       struct {
+               u_int   :2;             /* 00 */
+               u_int   i_annul:1;      /* annul bit */
+               u_int   :1;             /* 0 */
+               u_int   i_rcond:4;      /* register condition */
+               u_int   :3;             /* 011 */
+               int     i_disphi:2;     /* branch displacement, hi bits */
+               u_int   i_pred:1;       /* branch prediction bit */
+               u_int   i_rs1:1;        /* source register 1 */
+               u_int   i_displo:16;    /* branch displacement, lo bits */
+       } i_branch_pr;
+
+
        /*
         * Format 3 instructions (memory reference; arithmetic, logical,
         * shift, and other miscellaneous operations).  The second-level
diff -r 81a08dd595f9 -r 1c9d6687054e sys/arch/sparc64/include/reg.h
--- a/sys/arch/sparc64/include/reg.h    Mon Jan 10 03:24:31 2000 +0000
+++ b/sys/arch/sparc64/include/reg.h    Mon Jan 10 03:53:20 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: reg.h,v 1.5 1999/12/30 16:20:43 eeh Exp $ */
+/*     $NetBSD: reg.h,v 1.6 2000/01/10 03:53:20 eeh Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -142,6 +142,8 @@
  * ``I'd suggest allowing 16 ... allowing an indeterminate variable
  * size would be even better''.  Of course, we cannot do that; we
  * need to malloc these.
+ *
+ * XXXX UltraSPARC processors don't implement a floating point queue.
  */
 #define        FP_QSIZE        16
 #define ALIGNFPSTATE(f)                ((struct fpstate64 *)(((long)(f))&(~BLOCK_ALIGN)))
@@ -170,14 +172,14 @@
 };
 
 /*
- * Clone fpstate into an fpreg structure to satisfy <kern/sys_process.c>
+ * The actual FP registers are made accessable (c.f. ptrace(2)) through
+ * a `struct fpreg'; <arch/sparc64/sparc64/process_machdep.c> relies on the
+ * fact that `fpreg' is a prefix of `fpstate'.
  */
 struct fpreg64 {
        u_int   fr_regs[64];            /* our view is 64 32-bit registers */
        int64_t fr_fsr;                 /* %fsr */
        int     fr_gsr;                 /* graphics state reg */
-       int     fr_qsize;               /* actual queue depth */
-       struct  fp_qentry fr_queue[FP_QSIZE];   /* queue contents */
 };
 
 /*
@@ -186,8 +188,6 @@
 struct fpreg32 {
        u_int   fr_regs[32];            /* our view is 32 32-bit registers */
        int     fr_fsr;                 /* %fsr */
-       int     fr_qsize;               /* actual queue depth */
-       struct  fp_qentry fr_queue[FP_QSIZE];   /* queue contents */
 };
 
 #if defined(__arch64__)
diff -r 81a08dd595f9 -r 1c9d6687054e sys/arch/sparc64/sparc64/db_interface.c
--- a/sys/arch/sparc64/sparc64/db_interface.c   Mon Jan 10 03:24:31 2000 +0000
+++ b/sys/arch/sparc64/sparc64/db_interface.c   Mon Jan 10 03:53:20 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_interface.c,v 1.25 1999/12/30 16:34:02 eeh Exp $ */
+/*     $NetBSD: db_interface.c,v 1.26 2000/01/10 03:53:22 eeh Exp $ */
 
 /*
  * Mach Operating System
@@ -52,6 +52,7 @@
 #include <ddb/db_output.h>
 #include <ddb/db_interface.h>
 
+#include <machine/instr.h>
 #include <machine/cpu.h>
 #include <machine/openfirm.h>
 #include <machine/ctlreg.h>
@@ -179,13 +180,6 @@
        default:
                printf("kernel trap %x: %s\n", type, trap_type[type & 0x1ff]);
                if (db_recover != 0) {
-#if 0
-#ifdef __arch64__
-                       /* For now, don't get into infinite DDB trap loop */
-                       printf("Faulted in DDB; going to OBP...\n");
-                       OF_enter();
-#endif
-#endif
                        db_error("Faulted in DDB; continuing...\n");
                        OF_enter();
                        /*NOTREACHED*/
@@ -224,10 +218,10 @@
        }
 #endif
 
+       s = splhigh();
        db_active++;
        cnpollc(TRUE);
        /* Need to do spl stuff till cnpollc works */
-       s = splhigh();
        tl = savetstate(ts);
        for (i=0; i<tl; i++) {
                printf("%d tt=%lx tstate=%lx tpc=%p tnpc=%p\n",
@@ -236,15 +230,15 @@
        }
        db_trap(type, 0/*code*/);
        restoretstate(tl,ts);
-       splx(s);
        cnpollc(FALSE);
        db_active--;
+       splx(s);
 
 #if 0
        /* We will not alter the machine's running state until we get everything else working */
        *(struct frame *)tf->tf_out[6] = ddb_regs.ddb_fr;
+#endif
        *tf = ddb_regs.ddb_tf;
-#endif
        trap_trace_dis = traptrace_enabled;
 
        return (1);
@@ -865,3 +859,235 @@
 {
        db_machine_commands_install(sparc_db_command_table);
 }
+
+/*
+ * support for SOFTWARE_SSTEP:
+ * return the next pc if the given branch is taken.
+ *
+ * note: in the case of conditional branches with annul,
+ * this actually returns the next pc in the "not taken" path,
+ * but in that case next_instr_address() will return the
+ * next pc in the "taken" path.  so even tho the breakpoints
+ * are backwards, everything will still work, and the logic is
+ * much simpler this way.
+ */
+db_addr_t
+db_branch_taken(inst, pc, regs)
+       int inst;
+       db_addr_t pc;
+       db_regs_t *regs;
+{
+    union instr insn;
+    db_addr_t npc = ddb_regs.ddb_tf.tf_npc;
+
+    insn.i_int = inst;
+
+    /*
+     * if this is not an annulled conditional branch, the next pc is "npc".
+     */
+
+    if (insn.i_any.i_op != IOP_OP2 || insn.i_branch.i_annul != 1)
+       return npc;
+
+    switch (insn.i_op2.i_op2) {
+      case IOP2_Bicc:
+      case IOP2_FBfcc:
+      case IOP2_BPcc:
+      case IOP2_FBPfcc:
+      case IOP2_CBccc:
+       /* branch on some condition-code */
+       switch (insn.i_branch.i_cond)
+       {
+         case Icc_A: /* always */
+           return pc + ((inst << 10) >> 8);
+
+         default: /* all other conditions */
+           return npc + 4;
+       }
+
+      case IOP2_BPr:
+       /* branch on register, always conditional */
+       return npc + 4;
+
+      default:
+       /* not a branch */
+       panic("branch_taken() on non-branch");
+    }
+}
+
+boolean_t
+db_inst_branch(inst)
+       int inst;
+{
+    union instr insn;
+
+    insn.i_int = inst;
+
+    if (insn.i_any.i_op != IOP_OP2)
+       return FALSE;
+
+    switch (insn.i_op2.i_op2) {
+      case IOP2_BPcc:
+      case IOP2_Bicc:
+      case IOP2_BPr:
+      case IOP2_FBPfcc:
+      case IOP2_FBfcc:
+      case IOP2_CBccc:
+       return TRUE;
+
+      default:
+       return FALSE;
+    }
+}



Home | Main Index | Thread Index | Old Index