summaryrefslogtreecommitdiff
path: root/sys/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/db_interface.c651
-rw-r--r--sys/ia64/ia64/db_trace.c54
-rw-r--r--sys/ia64/include/db_machdep.h120
3 files changed, 349 insertions, 476 deletions
diff --git a/sys/ia64/ia64/db_interface.c b/sys/ia64/ia64/db_interface.c
index 525966fbc29d3..7d1bdc79dcadd 100644
--- a/sys/ia64/ia64/db_interface.c
+++ b/sys/ia64/ia64/db_interface.c
@@ -1,5 +1,3 @@
-/* $FreeBSD$ */
-
/*
* Mach Operating System
* Copyright (c) 1992,1991,1990 Carnegie Mellon University
@@ -28,29 +26,26 @@
* db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
*/
-/*
- * Parts of this file are derived from Mach 3:
- *
- * File: alpha_instruction.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 6/92
- */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
/*
* Interface to DDB.
*/
#include <sys/param.h>
-#include <sys/proc.h>
-#include <sys/reboot.h>
#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/smp.h>
#include <sys/cons.h>
+#include <sys/kdb.h>
#include <sys/ktr.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/smp.h>
#include <vm/vm.h>
#include <machine/db_machdep.h>
+#include <machine/frame.h>
#include <machine/mutex.h>
#include <machine/setjmp.h>
@@ -61,433 +56,319 @@
#include <ia64/disasm/disasm.h>
-static jmp_buf *db_nofault = 0;
-extern jmp_buf db_jmpbuf;
+#define TMPL_BITS 5
+#define TMPL_MASK ((1 << TMPL_BITS) - 1)
+#define SLOT_BITS 41
+#define SLOT_COUNT 3
+#define SLOT_MASK ((1ULL << SLOT_BITS) - 1ULL)
+#define SLOT_SHIFT(i) (TMPL_BITS+((i)<<3)+(i))
-extern void gdb_handle_exception(db_regs_t *, int);
-
-int db_active;
-db_regs_t ddb_regs;
-
-static int db_get_rse_reg(struct db_variable *vp, db_expr_t *valuep, int op);
-static int db_get_ip_reg(struct db_variable *vp, db_expr_t *valuep, int op);
+static db_varfcn_t db_frame;
+static db_varfcn_t db_getrse;
+static db_varfcn_t db_getip;
+#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x)
struct db_variable db_regs[] = {
- /* Misc control/app registers */
-#define DB_MISC_REGS 13 /* make sure this is correct */
-
- {"ip", NULL, db_get_ip_reg},
- {"psr", (db_expr_t*) &ddb_regs.tf_special.psr, FCN_NULL},
- {"cr.isr", (db_expr_t*) &ddb_regs.tf_special.isr, FCN_NULL},
- {"cr.ifa", (db_expr_t*) &ddb_regs.tf_special.ifa, FCN_NULL},
- {"pr", (db_expr_t*) &ddb_regs.tf_special.pr, FCN_NULL},
- {"ar.rsc", (db_expr_t*) &ddb_regs.tf_special.rsc, FCN_NULL},
- {"ar.pfs", (db_expr_t*) &ddb_regs.tf_special.pfs, FCN_NULL},
- {"cr.ifs", (db_expr_t*) &ddb_regs.tf_special.cfm, FCN_NULL},
- {"ar.bspstore", (db_expr_t*) &ddb_regs.tf_special.bspstore, FCN_NULL},
- {"ndirty", (db_expr_t*) &ddb_regs.tf_special.ndirty, FCN_NULL},
- {"ar.rnat", (db_expr_t*) &ddb_regs.tf_special.rnat, FCN_NULL},
- {"ar.unat", (db_expr_t*) &ddb_regs.tf_special.unat, FCN_NULL},
- {"ar.fpsr", (db_expr_t*) &ddb_regs.tf_special.fpsr, FCN_NULL},
-
- /* Branch registers */
- {"rp", (db_expr_t*) &ddb_regs.tf_special.rp, FCN_NULL},
- /* b1, b2, b3, b4, b5 are preserved */
- {"b6", (db_expr_t*) &ddb_regs.tf_scratch.br6, FCN_NULL},
- {"b7", (db_expr_t*) &ddb_regs.tf_scratch.br7, FCN_NULL},
-
- /* Static registers */
- {"gp", (db_expr_t*) &ddb_regs.tf_special.gp, FCN_NULL},
- {"r2", (db_expr_t*) &ddb_regs.tf_scratch.gr2, FCN_NULL},
- {"r3", (db_expr_t*) &ddb_regs.tf_scratch.gr3, FCN_NULL},
- {"r8", (db_expr_t*) &ddb_regs.tf_scratch.gr8, FCN_NULL},
- {"r9", (db_expr_t*) &ddb_regs.tf_scratch.gr9, FCN_NULL},
- {"r10", (db_expr_t*) &ddb_regs.tf_scratch.gr10, FCN_NULL},
- {"r11", (db_expr_t*) &ddb_regs.tf_scratch.gr11, FCN_NULL},
- {"sp", (db_expr_t*) &ddb_regs.tf_special.sp, FCN_NULL},
- {"tp", (db_expr_t*) &ddb_regs.tf_special.tp, FCN_NULL},
- {"r14", (db_expr_t*) &ddb_regs.tf_scratch.gr14, FCN_NULL},
- {"r15", (db_expr_t*) &ddb_regs.tf_scratch.gr15, FCN_NULL},
- {"r16", (db_expr_t*) &ddb_regs.tf_scratch.gr16, FCN_NULL},
- {"r17", (db_expr_t*) &ddb_regs.tf_scratch.gr17, FCN_NULL},
- {"r18", (db_expr_t*) &ddb_regs.tf_scratch.gr18, FCN_NULL},
- {"r19", (db_expr_t*) &ddb_regs.tf_scratch.gr19, FCN_NULL},
- {"r20", (db_expr_t*) &ddb_regs.tf_scratch.gr20, FCN_NULL},
- {"r21", (db_expr_t*) &ddb_regs.tf_scratch.gr21, FCN_NULL},
- {"r22", (db_expr_t*) &ddb_regs.tf_scratch.gr22, FCN_NULL},
- {"r23", (db_expr_t*) &ddb_regs.tf_scratch.gr23, FCN_NULL},
- {"r24", (db_expr_t*) &ddb_regs.tf_scratch.gr24, FCN_NULL},
- {"r25", (db_expr_t*) &ddb_regs.tf_scratch.gr25, FCN_NULL},
- {"r26", (db_expr_t*) &ddb_regs.tf_scratch.gr26, FCN_NULL},
- {"r27", (db_expr_t*) &ddb_regs.tf_scratch.gr27, FCN_NULL},
- {"r28", (db_expr_t*) &ddb_regs.tf_scratch.gr28, FCN_NULL},
- {"r29", (db_expr_t*) &ddb_regs.tf_scratch.gr29, FCN_NULL},
- {"r30", (db_expr_t*) &ddb_regs.tf_scratch.gr30, FCN_NULL},
- {"r31", (db_expr_t*) &ddb_regs.tf_scratch.gr31, FCN_NULL},
-
- /* Stacked registers */
- {"r32", (db_expr_t*) 32, db_get_rse_reg},
- {"r33", (db_expr_t*) 33, db_get_rse_reg},
- {"r34", (db_expr_t*) 34, db_get_rse_reg},
- {"r35", (db_expr_t*) 35, db_get_rse_reg},
- {"r36", (db_expr_t*) 36, db_get_rse_reg},
- {"r37", (db_expr_t*) 37, db_get_rse_reg},
- {"r38", (db_expr_t*) 38, db_get_rse_reg},
- {"r39", (db_expr_t*) 39, db_get_rse_reg},
- {"r40", (db_expr_t*) 40, db_get_rse_reg},
- {"r41", (db_expr_t*) 41, db_get_rse_reg},
- {"r42", (db_expr_t*) 42, db_get_rse_reg},
- {"r43", (db_expr_t*) 43, db_get_rse_reg},
- {"r44", (db_expr_t*) 44, db_get_rse_reg},
- {"r45", (db_expr_t*) 45, db_get_rse_reg},
- {"r46", (db_expr_t*) 46, db_get_rse_reg},
- {"r47", (db_expr_t*) 47, db_get_rse_reg},
- {"r48", (db_expr_t*) 48, db_get_rse_reg},
- {"r49", (db_expr_t*) 49, db_get_rse_reg},
- {"r50", (db_expr_t*) 50, db_get_rse_reg},
- {"r51", (db_expr_t*) 51, db_get_rse_reg},
- {"r52", (db_expr_t*) 52, db_get_rse_reg},
- {"r53", (db_expr_t*) 53, db_get_rse_reg},
- {"r54", (db_expr_t*) 54, db_get_rse_reg},
- {"r55", (db_expr_t*) 55, db_get_rse_reg},
- {"r56", (db_expr_t*) 56, db_get_rse_reg},
- {"r57", (db_expr_t*) 57, db_get_rse_reg},
- {"r58", (db_expr_t*) 58, db_get_rse_reg},
- {"r59", (db_expr_t*) 59, db_get_rse_reg},
- {"r60", (db_expr_t*) 60, db_get_rse_reg},
- {"r61", (db_expr_t*) 61, db_get_rse_reg},
- {"r62", (db_expr_t*) 62, db_get_rse_reg},
- {"r63", (db_expr_t*) 63, db_get_rse_reg},
- {"r64", (db_expr_t*) 64, db_get_rse_reg},
- {"r65", (db_expr_t*) 65, db_get_rse_reg},
- {"r66", (db_expr_t*) 66, db_get_rse_reg},
- {"r67", (db_expr_t*) 67, db_get_rse_reg},
- {"r68", (db_expr_t*) 68, db_get_rse_reg},
- {"r69", (db_expr_t*) 69, db_get_rse_reg},
- {"r70", (db_expr_t*) 70, db_get_rse_reg},
- {"r71", (db_expr_t*) 71, db_get_rse_reg},
- {"r72", (db_expr_t*) 72, db_get_rse_reg},
- {"r73", (db_expr_t*) 73, db_get_rse_reg},
- {"r74", (db_expr_t*) 74, db_get_rse_reg},
- {"r75", (db_expr_t*) 75, db_get_rse_reg},
- {"r76", (db_expr_t*) 76, db_get_rse_reg},
- {"r77", (db_expr_t*) 77, db_get_rse_reg},
- {"r78", (db_expr_t*) 78, db_get_rse_reg},
- {"r79", (db_expr_t*) 79, db_get_rse_reg},
- {"r80", (db_expr_t*) 80, db_get_rse_reg},
- {"r81", (db_expr_t*) 81, db_get_rse_reg},
- {"r82", (db_expr_t*) 82, db_get_rse_reg},
- {"r83", (db_expr_t*) 83, db_get_rse_reg},
- {"r84", (db_expr_t*) 84, db_get_rse_reg},
- {"r85", (db_expr_t*) 85, db_get_rse_reg},
- {"r86", (db_expr_t*) 86, db_get_rse_reg},
- {"r87", (db_expr_t*) 87, db_get_rse_reg},
- {"r88", (db_expr_t*) 88, db_get_rse_reg},
- {"r89", (db_expr_t*) 89, db_get_rse_reg},
- {"r90", (db_expr_t*) 90, db_get_rse_reg},
- {"r91", (db_expr_t*) 91, db_get_rse_reg},
- {"r92", (db_expr_t*) 92, db_get_rse_reg},
- {"r93", (db_expr_t*) 93, db_get_rse_reg},
- {"r94", (db_expr_t*) 94, db_get_rse_reg},
- {"r95", (db_expr_t*) 95, db_get_rse_reg},
- {"r96", (db_expr_t*) 96, db_get_rse_reg},
- {"r97", (db_expr_t*) 97, db_get_rse_reg},
- {"r98", (db_expr_t*) 98, db_get_rse_reg},
- {"r99", (db_expr_t*) 99, db_get_rse_reg},
- {"r100", (db_expr_t*) 100, db_get_rse_reg},
- {"r101", (db_expr_t*) 101, db_get_rse_reg},
- {"r102", (db_expr_t*) 102, db_get_rse_reg},
- {"r103", (db_expr_t*) 103, db_get_rse_reg},
- {"r104", (db_expr_t*) 104, db_get_rse_reg},
- {"r105", (db_expr_t*) 105, db_get_rse_reg},
- {"r106", (db_expr_t*) 106, db_get_rse_reg},
- {"r107", (db_expr_t*) 107, db_get_rse_reg},
- {"r108", (db_expr_t*) 108, db_get_rse_reg},
- {"r109", (db_expr_t*) 109, db_get_rse_reg},
- {"r110", (db_expr_t*) 110, db_get_rse_reg},
- {"r111", (db_expr_t*) 111, db_get_rse_reg},
- {"r112", (db_expr_t*) 112, db_get_rse_reg},
- {"r113", (db_expr_t*) 113, db_get_rse_reg},
- {"r114", (db_expr_t*) 114, db_get_rse_reg},
- {"r115", (db_expr_t*) 115, db_get_rse_reg},
- {"r116", (db_expr_t*) 116, db_get_rse_reg},
- {"r117", (db_expr_t*) 117, db_get_rse_reg},
- {"r118", (db_expr_t*) 118, db_get_rse_reg},
- {"r119", (db_expr_t*) 119, db_get_rse_reg},
- {"r120", (db_expr_t*) 120, db_get_rse_reg},
- {"r121", (db_expr_t*) 121, db_get_rse_reg},
- {"r122", (db_expr_t*) 122, db_get_rse_reg},
- {"r123", (db_expr_t*) 123, db_get_rse_reg},
- {"r124", (db_expr_t*) 124, db_get_rse_reg},
- {"r125", (db_expr_t*) 125, db_get_rse_reg},
- {"r126", (db_expr_t*) 126, db_get_rse_reg},
- {"r127", (db_expr_t*) 127, db_get_rse_reg},
+ {"ip", NULL, db_getip},
+ {"cr.ifs", DB_OFFSET(tf_special.cfm), db_frame},
+ {"cr.ifa", DB_OFFSET(tf_special.ifa), db_frame},
+ {"ar.bspstore", DB_OFFSET(tf_special.bspstore), db_frame},
+ {"ndirty", DB_OFFSET(tf_special.ndirty), db_frame},
+ {"rp", DB_OFFSET(tf_special.rp), db_frame},
+ {"ar.pfs", DB_OFFSET(tf_special.pfs), db_frame},
+ {"psr", DB_OFFSET(tf_special.psr), db_frame},
+ {"cr.isr", DB_OFFSET(tf_special.isr), db_frame},
+ {"pr", DB_OFFSET(tf_special.pr), db_frame},
+ {"ar.rsc", DB_OFFSET(tf_special.rsc), db_frame},
+ {"ar.rnat", DB_OFFSET(tf_special.rnat), db_frame},
+ {"ar.unat", DB_OFFSET(tf_special.unat), db_frame},
+ {"ar.fpsr", DB_OFFSET(tf_special.fpsr), db_frame},
+ {"gp", DB_OFFSET(tf_special.gp), db_frame},
+ {"sp", DB_OFFSET(tf_special.sp), db_frame},
+ {"tp", DB_OFFSET(tf_special.tp), db_frame},
+ {"b6", DB_OFFSET(tf_scratch.br6), db_frame},
+ {"b7", DB_OFFSET(tf_scratch.br7), db_frame},
+ {"r2", DB_OFFSET(tf_scratch.gr2), db_frame},
+ {"r3", DB_OFFSET(tf_scratch.gr3), db_frame},
+ {"r8", DB_OFFSET(tf_scratch.gr8), db_frame},
+ {"r9", DB_OFFSET(tf_scratch.gr9), db_frame},
+ {"r10", DB_OFFSET(tf_scratch.gr10), db_frame},
+ {"r11", DB_OFFSET(tf_scratch.gr11), db_frame},
+ {"r14", DB_OFFSET(tf_scratch.gr14), db_frame},
+ {"r15", DB_OFFSET(tf_scratch.gr15), db_frame},
+ {"r16", DB_OFFSET(tf_scratch.gr16), db_frame},
+ {"r17", DB_OFFSET(tf_scratch.gr17), db_frame},
+ {"r18", DB_OFFSET(tf_scratch.gr18), db_frame},
+ {"r19", DB_OFFSET(tf_scratch.gr19), db_frame},
+ {"r20", DB_OFFSET(tf_scratch.gr20), db_frame},
+ {"r21", DB_OFFSET(tf_scratch.gr21), db_frame},
+ {"r22", DB_OFFSET(tf_scratch.gr22), db_frame},
+ {"r23", DB_OFFSET(tf_scratch.gr23), db_frame},
+ {"r24", DB_OFFSET(tf_scratch.gr24), db_frame},
+ {"r25", DB_OFFSET(tf_scratch.gr25), db_frame},
+ {"r26", DB_OFFSET(tf_scratch.gr26), db_frame},
+ {"r27", DB_OFFSET(tf_scratch.gr27), db_frame},
+ {"r28", DB_OFFSET(tf_scratch.gr28), db_frame},
+ {"r29", DB_OFFSET(tf_scratch.gr29), db_frame},
+ {"r30", DB_OFFSET(tf_scratch.gr30), db_frame},
+ {"r31", DB_OFFSET(tf_scratch.gr31), db_frame},
+ {"r32", (db_expr_t*)0, db_getrse},
+ {"r33", (db_expr_t*)1, db_getrse},
+ {"r34", (db_expr_t*)2, db_getrse},
+ {"r35", (db_expr_t*)3, db_getrse},
+ {"r36", (db_expr_t*)4, db_getrse},
+ {"r37", (db_expr_t*)5, db_getrse},
+ {"r38", (db_expr_t*)6, db_getrse},
+ {"r39", (db_expr_t*)7, db_getrse},
+ {"r40", (db_expr_t*)8, db_getrse},
+ {"r41", (db_expr_t*)9, db_getrse},
+ {"r42", (db_expr_t*)10, db_getrse},
+ {"r43", (db_expr_t*)11, db_getrse},
+ {"r44", (db_expr_t*)12, db_getrse},
+ {"r45", (db_expr_t*)13, db_getrse},
+ {"r46", (db_expr_t*)14, db_getrse},
+ {"r47", (db_expr_t*)15, db_getrse},
+ {"r48", (db_expr_t*)16, db_getrse},
+ {"r49", (db_expr_t*)17, db_getrse},
+ {"r50", (db_expr_t*)18, db_getrse},
+ {"r51", (db_expr_t*)19, db_getrse},
+ {"r52", (db_expr_t*)20, db_getrse},
+ {"r53", (db_expr_t*)21, db_getrse},
+ {"r54", (db_expr_t*)22, db_getrse},
+ {"r55", (db_expr_t*)23, db_getrse},
+ {"r56", (db_expr_t*)24, db_getrse},
+ {"r57", (db_expr_t*)25, db_getrse},
+ {"r58", (db_expr_t*)26, db_getrse},
+ {"r59", (db_expr_t*)27, db_getrse},
+ {"r60", (db_expr_t*)28, db_getrse},
+ {"r61", (db_expr_t*)29, db_getrse},
+ {"r62", (db_expr_t*)30, db_getrse},
+ {"r63", (db_expr_t*)31, db_getrse},
+ {"r64", (db_expr_t*)32, db_getrse},
+ {"r65", (db_expr_t*)33, db_getrse},
+ {"r66", (db_expr_t*)34, db_getrse},
+ {"r67", (db_expr_t*)35, db_getrse},
+ {"r68", (db_expr_t*)36, db_getrse},
+ {"r69", (db_expr_t*)37, db_getrse},
+ {"r70", (db_expr_t*)38, db_getrse},
+ {"r71", (db_expr_t*)39, db_getrse},
+ {"r72", (db_expr_t*)40, db_getrse},
+ {"r73", (db_expr_t*)41, db_getrse},
+ {"r74", (db_expr_t*)42, db_getrse},
+ {"r75", (db_expr_t*)43, db_getrse},
+ {"r76", (db_expr_t*)44, db_getrse},
+ {"r77", (db_expr_t*)45, db_getrse},
+ {"r78", (db_expr_t*)46, db_getrse},
+ {"r79", (db_expr_t*)47, db_getrse},
+ {"r80", (db_expr_t*)48, db_getrse},
+ {"r81", (db_expr_t*)49, db_getrse},
+ {"r82", (db_expr_t*)50, db_getrse},
+ {"r83", (db_expr_t*)51, db_getrse},
+ {"r84", (db_expr_t*)52, db_getrse},
+ {"r85", (db_expr_t*)53, db_getrse},
+ {"r86", (db_expr_t*)54, db_getrse},
+ {"r87", (db_expr_t*)55, db_getrse},
+ {"r88", (db_expr_t*)56, db_getrse},
+ {"r89", (db_expr_t*)57, db_getrse},
+ {"r90", (db_expr_t*)58, db_getrse},
+ {"r91", (db_expr_t*)59, db_getrse},
+ {"r92", (db_expr_t*)60, db_getrse},
+ {"r93", (db_expr_t*)61, db_getrse},
+ {"r94", (db_expr_t*)62, db_getrse},
+ {"r95", (db_expr_t*)63, db_getrse},
+ {"r96", (db_expr_t*)64, db_getrse},
+ {"r97", (db_expr_t*)65, db_getrse},
+ {"r98", (db_expr_t*)66, db_getrse},
+ {"r99", (db_expr_t*)67, db_getrse},
+ {"r100", (db_expr_t*)68, db_getrse},
+ {"r101", (db_expr_t*)69, db_getrse},
+ {"r102", (db_expr_t*)70, db_getrse},
+ {"r103", (db_expr_t*)71, db_getrse},
+ {"r104", (db_expr_t*)72, db_getrse},
+ {"r105", (db_expr_t*)73, db_getrse},
+ {"r106", (db_expr_t*)74, db_getrse},
+ {"r107", (db_expr_t*)75, db_getrse},
+ {"r108", (db_expr_t*)76, db_getrse},
+ {"r109", (db_expr_t*)77, db_getrse},
+ {"r110", (db_expr_t*)78, db_getrse},
+ {"r111", (db_expr_t*)79, db_getrse},
+ {"r112", (db_expr_t*)80, db_getrse},
+ {"r113", (db_expr_t*)81, db_getrse},
+ {"r114", (db_expr_t*)82, db_getrse},
+ {"r115", (db_expr_t*)83, db_getrse},
+ {"r116", (db_expr_t*)84, db_getrse},
+ {"r117", (db_expr_t*)85, db_getrse},
+ {"r118", (db_expr_t*)86, db_getrse},
+ {"r119", (db_expr_t*)87, db_getrse},
+ {"r120", (db_expr_t*)88, db_getrse},
+ {"r121", (db_expr_t*)89, db_getrse},
+ {"r122", (db_expr_t*)90, db_getrse},
+ {"r123", (db_expr_t*)91, db_getrse},
+ {"r124", (db_expr_t*)92, db_getrse},
+ {"r125", (db_expr_t*)93, db_getrse},
+ {"r126", (db_expr_t*)94, db_getrse},
+ {"r127", (db_expr_t*)95, db_getrse},
};
struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
static int
-db_get_rse_reg(struct db_variable *vp, db_expr_t *valuep, int op)
+db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
+{
+ uint64_t *reg;
+
+ if (kdb_frame == NULL)
+ return (0);
+ reg = (uint64_t*)((uintptr_t)kdb_frame + (uintptr_t)vp->valuep);
+ if (op == DB_VAR_GET)
+ *valuep = *reg;
+ else
+ *reg = *valuep;
+ return (1);
+}
+
+static int
+db_getrse(struct db_variable *vp, db_expr_t *valuep, int op)
{
u_int64_t *reg;
uint64_t bsp;
int nats, regno, sof;
- bsp = ddb_regs.tf_special.bspstore + ddb_regs.tf_special.ndirty;
- regno = (db_expr_t)vp->valuep - 32;
- sof = (int)(ddb_regs.tf_special.cfm & 0x7f);
- nats = (sof - regno + 63 - ((int)(bsp >> 3) & 0x3f)) / 63;
-
- reg = (void*)(bsp - ((sof - regno + nats) << 3));
+ if (kdb_frame == NULL)
+ return (0);
- if (regno < sof) {
- if (op == DB_VAR_GET)
- *valuep = *reg;
- else
- *reg = *valuep;
- } else {
- if (op == DB_VAR_GET)
- *valuep = 0xdeadbeefdeadbeef;
- }
+ regno = (int)(intptr_t)valuep;
+ bsp = kdb_frame->tf_special.bspstore + kdb_frame->tf_special.ndirty;
+ sof = (int)(kdb_frame->tf_special.cfm & 0x7f);
- return (0);
-}
+ if (regno >= sof)
+ return (0);
-static int
-db_get_ip_reg(struct db_variable *vp, db_expr_t *valuep, int op)
-{
- /* Read only */
+ nats = (sof - regno + 63 - ((int)(bsp >> 3) & 0x3f)) / 63;
+ reg = (void*)(bsp - ((sof - regno + nats) << 3));
if (op == DB_VAR_GET)
- *valuep = PC_REGS(DDB_REGS);
- return 0;
+ *valuep = *reg;
+ else
+ *reg = *valuep;
+ return (1);
}
-#if 0
-/*
- * Print trap reason.
- */
-static void
-ddbprinttrap(int vector)
+static int
+db_getip(struct db_variable *vp, db_expr_t *valuep, int op)
{
+ u_long iip, slot;
- /* XXX Implement. */
-
- printf("ddbprinttrap(%d)\n", vector);
-}
-#endif
-
-#define CPUSTOP_ON_DDBBREAK
-#define VERBOSE_CPUSTOP_ON_DDBBREAK
+ if (kdb_frame == NULL)
+ return (0);
-/*
- * ddb_trap - field a kernel trap
- */
-int
-kdb_trap(int vector, struct trapframe *regs)
-{
- int ddb_mode = !(boothowto & RB_GDB);
- register_t s;
-
- /*
- * Don't bother checking for usermode, since a benign entry
- * by the kernel (call to Debugger() or a breakpoint) has
- * already checked for usermode. If neither of those
- * conditions exist, something Bad has happened.
- */
-
- if (vector != IA64_VEC_BREAK
- && vector != IA64_VEC_SINGLE_STEP_TRAP) {
-#if 0
- if (ddb_mode) {
- db_printf("ddbprinttrap from 0x%lx\n", /* XXX */
- regs->tf_regs[FRAME_PC]);
- ddbprinttrap(a0, a1, a2, entry);
- /*
- * Tell caller "We did NOT handle the trap."
- * Caller should panic, or whatever.
- */
+ if (op == DB_VAR_GET) {
+ iip = kdb_frame->tf_special.iip;
+ slot = (kdb_frame->tf_special.psr >> 41) & 3;
+ *valuep = iip + slot;
+ } else {
+ iip = *valuep & ~0xf;
+ slot = *valuep & 0xf;
+ if (slot > 2)
return (0);
- }
-#endif
- if (db_nofault) {
- jmp_buf *no_fault = db_nofault;
- db_nofault = 0;
- longjmp(*no_fault, 1);
- }
- }
-
- /*
- * XXX Should switch to DDB's own stack, here.
- */
-
- s = intr_disable();
-
-#ifdef SMP
-#ifdef CPUSTOP_ON_DDBBREAK
-
-#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
- db_printf("CPU%d stopping CPUs: 0x%08x...", PCPU_GET(cpuid),
- PCPU_GET(other_cpus));
-#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
-
- /* We stop all CPUs except ourselves (obviously) */
- stop_cpus(PCPU_GET(other_cpus));
-
-#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
- db_printf(" stopped.\n");
-#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
-
-#endif /* CPUSTOP_ON_DDBBREAK */
-#endif /* SMP */
-
- ddb_regs = *regs;
-
- /*
- * XXX pretend that registers outside the current frame don't exist.
- */
- db_eregs = db_regs + DB_MISC_REGS + 3 + 27 +
- (ddb_regs.tf_special.cfm & 0x7f);
-
- __asm __volatile("flushrs"); /* so we can look at them */
-
- db_active++;
-
- if (ddb_mode) {
- cndbctl(TRUE); /* DDB active, unblank video */
- db_trap(vector, 0); /* Where the work happens */
- cndbctl(FALSE); /* DDB inactive */
- } else
- gdb_handle_exception(&ddb_regs, vector);
-
- db_active--;
-
-#ifdef SMP
-#ifdef CPUSTOP_ON_DDBBREAK
-
-#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
- db_printf("CPU%d restarting CPUs: 0x%08x...", PCPU_GET(cpuid),
- stopped_cpus);
-#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
-
- /* Restart all the CPUs we previously stopped */
- if (stopped_cpus != PCPU_GET(other_cpus) && smp_started != 0) {
- db_printf("whoa, other_cpus: 0x%08x, stopped_cpus: 0x%08x\n",
- PCPU_GET(other_cpus), stopped_cpus);
- panic("stop_cpus() failed");
+ kdb_frame->tf_special.iip = iip;
+ kdb_frame->tf_special.psr &= ~IA64_PSR_RI;
+ kdb_frame->tf_special.psr |= slot << 41;
}
- restart_cpus(stopped_cpus);
-
-#if defined(VERBOSE_CPUSTOP_ON_DDBBREAK)
- db_printf(" restarted.\n");
-#endif /* VERBOSE_CPUSTOP_ON_DDBBREAK */
-
-#endif /* CPUSTOP_ON_DDBBREAK */
-#endif /* SMP */
-
- *regs = ddb_regs;
-
- intr_restore(s);
-
-
- /*
- * Tell caller "We HAVE handled the trap."
- */
return (1);
}
/*
* Read bytes from kernel address space for debugger.
*/
-void
+int
db_read_bytes(vm_offset_t addr, size_t size, char *data)
{
-
- db_nofault = &db_jmpbuf;
-
- if (addr < VM_MAX_ADDRESS)
- copyin((char *)addr, data, size);
- else
- bcopy((char *)addr, data, size);
-
- db_nofault = 0;
+ jmp_buf jb;
+ void *prev_jb;
+ char *src;
+ int ret;
+
+ prev_jb = kdb_jmpbuf(jb);
+ ret = setjmp(jb);
+ if (ret == 0) {
+ src = (char *)addr;
+ while (size-- > 0)
+ *data++ = *src++;
+ }
+ (void)kdb_jmpbuf(prev_jb);
+ return (ret);
}
/*
* Write bytes to kernel address space for debugger.
*/
-void
+int
db_write_bytes(vm_offset_t addr, size_t size, char *data)
{
-
- db_nofault = &db_jmpbuf;
-
- if (addr < VM_MAX_ADDRESS)
- copyout(data, (char *)addr, size);
- else
- bcopy(data, (char *)addr, size);
-
- db_nofault = 0;
+ jmp_buf jb;
+ void *prev_jb;
+ char *dst;
+ int ret;
+
+ prev_jb = kdb_jmpbuf(jb);
+ ret = setjmp(jb);
+ if (ret == 0) {
+ dst = (char *)addr;
+ while (size-- > 0)
+ *dst++ = *data++;
+ }
+ (void)kdb_jmpbuf(prev_jb);
+ return (ret);
}
void
-Debugger(const char* msg)
+db_bkpt_write(db_addr_t addr, BKPT_INST_TYPE *storage)
{
- printf("%s\n", msg);
- __asm("break 0x80100");
-}
+ BKPT_INST_TYPE tmp;
+ db_addr_t loc;
+ int slot;
-u_long
-db_register_value(db_regs_t *regs, int regno)
-{
- uint64_t *rsp;
- uint64_t bsp;
- int nats, sof;
+ slot = addr & 0xfUL;
+ if (slot >= SLOT_COUNT)
+ return;
+ loc = (addr & ~0xfUL) + (slot << 2);
- if (regno == 0)
- return (0);
- if (regno == 1)
- return (regs->tf_special.gp);
- if (regno >= 2 && regno <= 3)
- return ((&regs->tf_scratch.gr2)[regno - 2]);
- if (regno >= 8 && regno <= 11)
- return ((&regs->tf_scratch.gr8)[regno - 8]);
- if (regno == 12)
- return (regs->tf_special.sp);
- if (regno == 13)
- return (regs->tf_special.tp);
- if (regno >= 14 && regno <= 31)
- return ((&regs->tf_scratch.gr14)[regno - 14]);
-
- sof = (int)(regs->tf_special.cfm & 0x7f);
- if (regno >= 32 && regno < sof + 32) {
- bsp = regs->tf_special.bspstore + regs->tf_special.ndirty;
- regno -= 32;
- nats = (sof - regno + 63 - ((int)(bsp >> 3) & 0x3f)) / 63;
- rsp = (void*)(bsp - ((sof - regno + nats) << 3));
- return (*rsp);
- }
+ db_read_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp);
+ *storage = (tmp >> SLOT_SHIFT(slot)) & SLOT_MASK;
- db_printf(" **** STRANGE REGISTER NUMBER %d **** ", regno);
- return (0);
+ tmp &= ~(SLOT_MASK << SLOT_SHIFT(slot));
+ tmp |= (0x84000 << 6) << SLOT_SHIFT(slot);
+ db_write_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp);
}
void
-db_write_breakpoint(vm_offset_t addr, u_int64_t *storage)
+db_bkpt_clear(db_addr_t addr, BKPT_INST_TYPE *storage)
{
+ BKPT_INST_TYPE tmp;
+ db_addr_t loc;
+ int slot;
+
+ slot = addr & 0xfUL;
+ if (slot >= SLOT_COUNT)
+ return;
+ loc = (addr & ~0xfUL) + (slot << 2);
+
+ db_read_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp);
+ tmp &= ~(SLOT_MASK << SLOT_SHIFT(slot));
+ tmp |= *storage << SLOT_SHIFT(slot);
+ db_write_bytes(loc, sizeof(BKPT_INST_TYPE), (char *)&tmp);
}
void
-db_clear_breakpoint(vm_offset_t addr, u_int64_t *storage)
+db_bkpt_skip(void)
{
-}
-void
-db_skip_breakpoint()
-{
+ if (kdb_frame == NULL)
+ return;
- ddb_regs.tf_special.psr += IA64_PSR_RI_1;
- if ((ddb_regs.tf_special.psr & IA64_PSR_RI) > IA64_PSR_RI_2) {
- ddb_regs.tf_special.psr &= ~IA64_PSR_RI;
- ddb_regs.tf_special.iip += 16;
+ kdb_frame->tf_special.psr += IA64_PSR_RI_1;
+ if ((kdb_frame->tf_special.psr & IA64_PSR_RI) > IA64_PSR_RI_2) {
+ kdb_frame->tf_special.psr &= ~IA64_PSR_RI;
+ kdb_frame->tf_special.iip += 16;
}
}
diff --git a/sys/ia64/ia64/db_trace.c b/sys/ia64/ia64/db_trace.c
index be301797e1f2b..11a2e5582771b 100644
--- a/sys/ia64/ia64/db_trace.c
+++ b/sys/ia64/ia64/db_trace.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2003, 2004 Marcel Moolenaar
* Copyright (c) 2000-2001 Doug Rabson
* All rights reserved.
*
@@ -27,8 +28,13 @@
*/
#include <sys/param.h>
+#include <sys/kdb.h>
#include <sys/proc.h>
+
#include <machine/db_machdep.h>
+#include <machine/frame.h>
+#include <machine/md_var.h>
+#include <machine/pcb.h>
#include <machine/unwind.h>
#include <machine/vmparam.h>
@@ -38,14 +44,12 @@
#include <ddb/db_variables.h>
#include <ddb/db_output.h>
-
int db_md_set_watchpoint(db_expr_t addr, db_expr_t size);
int db_md_clr_watchpoint(db_expr_t addr, db_expr_t size);
void db_md_list_watchpoints(void);
-void
-db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
- char *modif)
+static int
+db_backtrace(struct thread *td, struct pcb *pcb, int count)
{
struct unw_regstate rs;
struct trapframe *tf;
@@ -55,8 +59,7 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
c_db_sym_t sym;
int args, error, i;
- tf = &ddb_regs;
- error = unw_create(&rs, tf);
+ error = unw_create_from_pcb(&rs, pcb);
while (!error && count--) {
error = unw_get_cfm(&rs, &cfm);
if (!error)
@@ -68,15 +71,14 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
if (error)
break;
- args = (cfm >> 7) & 0x7f;
+ args = IA64_CFM_SOL(cfm);
if (args > 8)
args = 8;
error = unw_step(&rs);
if (!error) {
- error = unw_get_cfm(&rs, &pfs);
- if (!error) {
- i = (pfs & 0x7f) - ((pfs >> 7) & 0x7f);
+ if (!unw_get_cfm(&rs, &pfs)) {
+ i = IA64_CFM_SOF(pfs) - IA64_CFM_SOL(pfs);
if (args > i)
args = i;
}
@@ -115,15 +117,43 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
/* XXX ask if we should unwind across the trapframe. */
db_printf("--- trapframe at %p\n", tf);
unw_delete(&rs);
- error = unw_create(&rs, tf);
+ error = unw_create_from_frame(&rs, tf);
}
unw_delete(&rs);
+ return (error);
}
void
-db_print_backtrace(void)
+db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
+ char *modif)
{
+ struct thread *td;
+
+ td = (have_addr) ? kdb_thr_lookup(addr) : kdb_thread;
+ if (td == NULL) {
+ db_printf("Thread %d not found\n", (int)addr);
+ return;
+ }
+ db_trace_thread(td, count);
+}
+
+void
+db_trace_self(void)
+{
+ struct pcb pcb;
+
+ savectx(&pcb);
+ db_backtrace(curthread, &pcb, -1);
+}
+
+int
+db_trace_thread(struct thread *td, int count)
+{
+ struct pcb *ctx;
+
+ ctx = kdb_thr_ctx(td);
+ return (db_backtrace(td, ctx, count));
}
int
diff --git a/sys/ia64/include/db_machdep.h b/sys/ia64/include/db_machdep.h
index 4b801f6279bdd..25288cd331e27 100644
--- a/sys/ia64/include/db_machdep.h
+++ b/sys/ia64/include/db_machdep.h
@@ -1,66 +1,64 @@
-/* $FreeBSD$ */
-/* $NetBSD: db_machdep.h,v 1.6 1997/09/06 02:02:25 thorpej Exp $ */
-
/*
- * Copyright (c) 1995 Carnegie-Mellon University.
+ * Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
- * Author: Chris G. Demetriou
- *
- * 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.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ * 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.
*
- * Carnegie Mellon requests users of this software to return to
+ * 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.
*
- * 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.
+ * $FreeBSD$
*/
#ifndef _MACHINE_DB_MACHDEP_H_
#define _MACHINE_DB_MACHDEP_H_
-/*
- * Machine-dependent defines for new kernel debugger.
- */
-
-#include <sys/param.h>
-#include <vm/vm.h>
-#include <machine/frame.h>
#include <machine/ia64_cpu.h>
-#define DB_NO_AOUT
+/* We define some of our own commands. */
+#define DB_MACHINE_COMMANDS
+
+/* We use Elf64 symbols in DDB. */
+#define DB_ELFSIZE 64
-struct ia64_bundle;
+/* Pretty arbitrary. */
+#define DB_SMALL_VALUE_MAX 0x7fffffff
+#define DB_SMALL_VALUE_MIN (-0x400001)
typedef vm_offset_t db_addr_t; /* address - unsigned */
typedef long db_expr_t; /* expression - signed */
-typedef struct trapframe db_regs_t;
-extern db_regs_t ddb_regs; /* register state */
-#define DDB_REGS (&ddb_regs)
-#define PC_REGS(regs) ((db_addr_t)(regs)->tf_special.iip + \
- (((regs)->tf_special.psr >> 41) & 3))
+#define PC_REGS() ((kdb_thrctx->pcb_special.__spare == 0) ? \
+ kdb_thrctx->pcb_special.rp : \
+ kdb_thrctx->pcb_special.iip + ((kdb_thrctx->pcb_special.psr>>41) & 3))
-#define BKPT_WRITE(addr, storage) db_write_breakpoint(addr, storage)
-#define BKPT_CLEAR(addr, storage) db_clear_breakpoint(addr, storage)
-#define BKPT_INST_TYPE u_int64_t
+#define BKPT_WRITE(addr, storage) db_bkpt_write(addr, storage)
+#define BKPT_CLEAR(addr, storage) db_bkpt_clear(addr, storage)
+#define BKPT_SKIP db_bkpt_skip()
+#define BKPT_INST_TYPE uint64_t
-#define BKPT_SKIP db_skip_breakpoint()
+void db_bkpt_write(db_addr_t, BKPT_INST_TYPE *storage);
+void db_bkpt_clear(db_addr_t, uint64_t *storage);
+void db_bkpt_skip(void);
-#define db_clear_single_step(regs) ddb_regs.tf_special.psr &= ~IA64_PSR_SS
-#define db_set_single_step(regs) ddb_regs.tf_special.psr |= IA64_PSR_SS
+#define db_clear_single_step kdb_cpu_clear_singlestep
+#define db_set_single_step kdb_cpu_set_singlestep
#define IS_BREAKPOINT_TRAP(type, code) (type == IA64_VEC_BREAK)
#define IS_WATCHPOINT_TRAP(type, code) 0
@@ -72,43 +70,7 @@ extern db_regs_t ddb_regs; /* register state */
#define inst_load(ins) (ins & 0)
#define inst_store(ins) (ins & 0)
#define inst_unconditional_flow_transfer(ins) (ins & 0)
-
-#define branch_taken(ins, pc, regs) pc
-
-/*
- * Functions needed for software single-stepping.
- */
-
-/* No delay slots on Alpha. */
-#define next_instr_address(v, b) ((db_addr_t) ((b) ? (v) : ((v) + 4)))
-u_long db_register_value(db_regs_t *, int);
-int kdb_trap(int vector, struct trapframe *regs);
-
-u_int64_t *db_rse_current_frame(void);
-u_int64_t *db_rse_previous_frame(u_int64_t *bsp, int sof);
-u_int64_t *db_rse_register_address(u_int64_t *bsp, int regno);
-
-void db_read_bundle(db_addr_t addr, struct ia64_bundle *bp);
-void db_write_bundle(db_addr_t addr, struct ia64_bundle *bp);
-void db_write_breakpoint(db_addr_t addr, u_int64_t *storage);
-void db_clear_breakpoint(db_addr_t addr, u_int64_t *storage);
-void db_skip_breakpoint(void);
-
-/*
- * Pretty arbitrary
- */
-#define DB_SMALL_VALUE_MAX 0x7fffffff
-#define DB_SMALL_VALUE_MIN (-0x400001)
-
-/*
- * We define some of our own commands.
- */
-#define DB_MACHINE_COMMANDS
-
-/*
- * We use Elf64 symbols in DDB.
- */
-#define DB_ELFSIZE 64
+#define branch_taken(ins, pc, regs) pc
#endif /* _MACHINE_DB_MACHDEP_H_ */