Wed Dec 2 07:55:53 2009 UTC ()
print the fplwp in "mach cpu" list.


(mrg)
diff -r1.119 -r1.120 src/sys/arch/sparc64/sparc64/db_interface.c

cvs diff -r1.119 -r1.120 src/sys/arch/sparc64/sparc64/db_interface.c (switch to unified diff)

--- src/sys/arch/sparc64/sparc64/db_interface.c 2009/12/01 18:51:20 1.119
+++ src/sys/arch/sparc64/sparc64/db_interface.c 2009/12/02 07:55:53 1.120
@@ -1,1506 +1,1507 @@ @@ -1,1506 +1,1507 @@
1/* $NetBSD: db_interface.c,v 1.119 2009/12/01 18:51:20 martin Exp $ */ 1/* $NetBSD: db_interface.c,v 1.120 2009/12/02 07:55:53 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved. 4 * Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
5 * Mach Operating System 5 * Mach Operating System
6 * Copyright (c) 1991,1990 Carnegie Mellon University 6 * Copyright (c) 1991,1990 Carnegie Mellon University
7 * All Rights Reserved. 7 * All Rights Reserved.
8 * 8 *
9 * Permission to use, copy, modify and distribute this software and its 9 * Permission to use, copy, modify and distribute this software and its
10 * documentation is hereby granted, provided that both the copyright 10 * documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the 11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions 12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation. 13 * thereof, and that both notices appear in supporting documentation.
14 * 14 *
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
17 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 17 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 * 18 *
19 * Carnegie Mellon requests users of this software to return to 19 * Carnegie Mellon requests users of this software to return to
20 * 20 *
21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22 * School of Computer Science 22 * School of Computer Science
23 * Carnegie Mellon University 23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890 24 * Pittsburgh PA 15213-3890
25 * 25 *
26 * any improvements or extensions that they make and grant Carnegie the 26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes. 27 * rights to redistribute these changes.
28 * 28 *
29 * From: db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU) 29 * From: db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU)
30 */ 30 */
31 31
32/* 32/*
33 * Interface to new debugger. 33 * Interface to new debugger.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.119 2009/12/01 18:51:20 martin Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.120 2009/12/02 07:55:53 mrg Exp $");
38 38
39#include "opt_ddb.h" 39#include "opt_ddb.h"
40#include "opt_multiprocessor.h" 40#include "opt_multiprocessor.h"
41 41
42#include <sys/param.h> 42#include <sys/param.h>
43#include <sys/proc.h> 43#include <sys/proc.h>
44#include <sys/reboot.h> 44#include <sys/reboot.h>
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <sys/atomic.h> 46#include <sys/atomic.h>
47 47
48#include <uvm/uvm_extern.h> 48#include <uvm/uvm_extern.h>
49 49
50#include <dev/cons.h> 50#include <dev/cons.h>
51 51
52#include <machine/db_machdep.h> 52#include <machine/db_machdep.h>
53#include <ddb/db_command.h> 53#include <ddb/db_command.h>
54#include <ddb/db_sym.h> 54#include <ddb/db_sym.h>
55#include <ddb/db_variables.h> 55#include <ddb/db_variables.h>
56#include <ddb/db_extern.h> 56#include <ddb/db_extern.h>
57#include <ddb/db_access.h> 57#include <ddb/db_access.h>
58#include <ddb/db_output.h> 58#include <ddb/db_output.h>
59#include <ddb/db_interface.h> 59#include <ddb/db_interface.h>
60#include <ddb/ddbvar.h> 60#include <ddb/ddbvar.h>
61 61
62#include <machine/instr.h> 62#include <machine/instr.h>
63#include <machine/cpu.h> 63#include <machine/cpu.h>
64#include <machine/promlib.h> 64#include <machine/promlib.h>
65#include <machine/ctlreg.h> 65#include <machine/ctlreg.h>
66#include <machine/pmap.h> 66#include <machine/pmap.h>
67#include <machine/intr.h> 67#include <machine/intr.h>
68 68
69#include "fb.h" 69#include "fb.h"
70 70
71extern struct traptrace { 71extern struct traptrace {
72 unsigned short tl:3, /* Trap level */ 72 unsigned short tl:3, /* Trap level */
73 ns:4, /* PCB nsaved */ 73 ns:4, /* PCB nsaved */
74 tt:9; /* Trap type */ 74 tt:9; /* Trap type */
75 unsigned short pid; /* PID */ 75 unsigned short pid; /* PID */
76 u_int tstate; /* tstate */ 76 u_int tstate; /* tstate */
77 u_int tsp; /* sp */ 77 u_int tsp; /* sp */
78 u_int tpc; /* pc */ 78 u_int tpc; /* pc */
79 u_int tfault; /* MMU tag access */ 79 u_int tfault; /* MMU tag access */
80} trap_trace[], trap_trace_end[]; 80} trap_trace[], trap_trace_end[];
81 81
82/* 82/*
83 * Helpers for ddb variables. 83 * Helpers for ddb variables.
84 */ 84 */
85static uint64_t nil; 85static uint64_t nil;
86 86
87#ifdef MULTIPROCESSOR 87#ifdef MULTIPROCESSOR
88#define pmap_ctx(PM) ((PM)->pm_ctx[cpu_number()]) 88#define pmap_ctx(PM) ((PM)->pm_ctx[cpu_number()])
89#else 89#else
90#define pmap_ctx(PM) ((PM)->pm_ctx) 90#define pmap_ctx(PM) ((PM)->pm_ctx)
91#endif 91#endif
92 92
93void fill_ddb_regs_from_tf(struct trapframe64 *tf); 93void fill_ddb_regs_from_tf(struct trapframe64 *tf);
94void ddb_restore_state(void); 94void ddb_restore_state(void);
95bool ddb_running_on_this_cpu(void); 95bool ddb_running_on_this_cpu(void);
96 96
97static int 97static int
98db_sparc_charop(const struct db_variable *vp, db_expr_t *val, int opcode) 98db_sparc_charop(const struct db_variable *vp, db_expr_t *val, int opcode)
99{ 99{
100 char *regaddr = 100 char *regaddr =
101 (char *)(((uint8_t *)DDB_REGS) + (size_t)vp->valuep); 101 (char *)(((uint8_t *)DDB_REGS) + (size_t)vp->valuep);
102 102
103 switch (opcode) { 103 switch (opcode) {
104 case DB_VAR_GET: 104 case DB_VAR_GET:
105 *val = *regaddr; 105 *val = *regaddr;
106 break; 106 break;
107 case DB_VAR_SET: 107 case DB_VAR_SET:
108 *regaddr = *val; 108 *regaddr = *val;
109 break; 109 break;
110#ifdef DIAGNOSTIC 110#ifdef DIAGNOSTIC
111 default: 111 default:
112 printf("db_sparc_charop: opcode %d\n", opcode); 112 printf("db_sparc_charop: opcode %d\n", opcode);
113 break; 113 break;
114#endif 114#endif
115 } 115 }
116 116
117 return 0; 117 return 0;
118} 118}
119 119
120#ifdef not_used 120#ifdef not_used
121static int 121static int
122db_sparc_shortop(const struct db_variable *vp, db_expr_t *val, int opcode) 122db_sparc_shortop(const struct db_variable *vp, db_expr_t *val, int opcode)
123{ 123{
124 short *regaddr = 124 short *regaddr =
125 (short *)(((uint8_t *)DDB_REGS) + (size_t)vp->valuep); 125 (short *)(((uint8_t *)DDB_REGS) + (size_t)vp->valuep);
126 126
127 switch (opcode) { 127 switch (opcode) {
128 case DB_VAR_GET: 128 case DB_VAR_GET:
129 *val = *regaddr; 129 *val = *regaddr;
130 break; 130 break;
131 case DB_VAR_SET: 131 case DB_VAR_SET:
132 *regaddr = *val; 132 *regaddr = *val;
133 break; 133 break;
134#ifdef DIAGNOSTIC 134#ifdef DIAGNOSTIC
135 default: 135 default:
136 printf("sparc_shortop: opcode %d\n", opcode); 136 printf("sparc_shortop: opcode %d\n", opcode);
137 break; 137 break;
138#endif 138#endif
139 } 139 }
140 140
141 return 0; 141 return 0;
142} 142}
143#endif 143#endif
144 144
145static int 145static int
146db_sparc_intop(const struct db_variable *vp, db_expr_t *val, int opcode) 146db_sparc_intop(const struct db_variable *vp, db_expr_t *val, int opcode)
147{ 147{
148 int *regaddr = 148 int *regaddr =
149 (int *)(((uint8_t *)DDB_REGS) + (size_t)vp->valuep); 149 (int *)(((uint8_t *)DDB_REGS) + (size_t)vp->valuep);
150 150
151 switch (opcode) { 151 switch (opcode) {
152 case DB_VAR_GET: 152 case DB_VAR_GET:
153 *val = *regaddr; 153 *val = *regaddr;
154 break; 154 break;
155 case DB_VAR_SET: 155 case DB_VAR_SET:
156 *regaddr = *val; 156 *regaddr = *val;
157 break; 157 break;
158#ifdef DIAGNOSTIC 158#ifdef DIAGNOSTIC
159 default: 159 default:
160 printf("db_sparc_intop: opcode %d\n", opcode); 160 printf("db_sparc_intop: opcode %d\n", opcode);
161 break; 161 break;
162#endif 162#endif
163 } 163 }
164 164
165 return 0; 165 return 0;
166} 166}
167 167
168static int 168static int
169db_sparc_regop(const struct db_variable *vp, db_expr_t *val, int opcode) 169db_sparc_regop(const struct db_variable *vp, db_expr_t *val, int opcode)
170{ 170{
171 db_expr_t *regaddr = 171 db_expr_t *regaddr =
172 (db_expr_t *)(((uint8_t *)DDB_REGS) + (size_t)vp->valuep); 172 (db_expr_t *)(((uint8_t *)DDB_REGS) + (size_t)vp->valuep);
173 173
174 switch (opcode) { 174 switch (opcode) {
175 case DB_VAR_GET: 175 case DB_VAR_GET:
176 *val = *regaddr; 176 *val = *regaddr;
177 break; 177 break;
178 case DB_VAR_SET: 178 case DB_VAR_SET:
179 *regaddr = *val; 179 *regaddr = *val;
180 break; 180 break;
181#ifdef DIAGNOSTIC 181#ifdef DIAGNOSTIC
182 default: 182 default:
183 printf("db_sparc_regop: unknown op %d\n", opcode); 183 printf("db_sparc_regop: unknown op %d\n", opcode);
184 break; 184 break;
185#endif 185#endif
186 } 186 }
187 return 0; 187 return 0;
188} 188}
189 189
190/* 190/*
191 * Machine register set. 191 * Machine register set.
192 */ 192 */
193#define dbreg(xx) (long *)offsetof(db_regs_t, db_tf.tf_ ## xx) 193#define dbreg(xx) (long *)offsetof(db_regs_t, db_tf.tf_ ## xx)
194#define dbregfr(xx) (long *)offsetof(db_regs_t, db_fr.fr_ ## xx) 194#define dbregfr(xx) (long *)offsetof(db_regs_t, db_fr.fr_ ## xx)
195#define dbregfp(xx) (long *)offsetof(db_regs_t, db_fpstate.fs_ ## xx) 195#define dbregfp(xx) (long *)offsetof(db_regs_t, db_fpstate.fs_ ## xx)
196 196
197static int db_sparc_regop(const struct db_variable *, db_expr_t *, int); 197static int db_sparc_regop(const struct db_variable *, db_expr_t *, int);
198 198
199const struct db_variable db_regs[] = { 199const struct db_variable db_regs[] = {
200 { "tstate", dbreg(tstate), db_sparc_regop, 0 }, 200 { "tstate", dbreg(tstate), db_sparc_regop, 0 },
201 { "pc", dbreg(pc), db_sparc_regop, 0 }, 201 { "pc", dbreg(pc), db_sparc_regop, 0 },
202 { "npc", dbreg(npc), db_sparc_regop, 0 }, 202 { "npc", dbreg(npc), db_sparc_regop, 0 },
203 { "ipl", dbreg(oldpil), db_sparc_charop, 0 }, 203 { "ipl", dbreg(oldpil), db_sparc_charop, 0 },
204 { "y", dbreg(y), db_sparc_intop, 0 }, 204 { "y", dbreg(y), db_sparc_intop, 0 },
205 { "g0", (void *)&nil, FCN_NULL, 0 }, 205 { "g0", (void *)&nil, FCN_NULL, 0 },
206 { "g1", dbreg(global[1]), db_sparc_regop, 0 }, 206 { "g1", dbreg(global[1]), db_sparc_regop, 0 },
207 { "g2", dbreg(global[2]), db_sparc_regop, 0 }, 207 { "g2", dbreg(global[2]), db_sparc_regop, 0 },
208 { "g3", dbreg(global[3]), db_sparc_regop, 0 }, 208 { "g3", dbreg(global[3]), db_sparc_regop, 0 },
209 { "g4", dbreg(global[4]), db_sparc_regop, 0 }, 209 { "g4", dbreg(global[4]), db_sparc_regop, 0 },
210 { "g5", dbreg(global[5]), db_sparc_regop, 0 }, 210 { "g5", dbreg(global[5]), db_sparc_regop, 0 },
211 { "g6", dbreg(global[6]), db_sparc_regop, 0 }, 211 { "g6", dbreg(global[6]), db_sparc_regop, 0 },
212 { "g7", dbreg(global[7]), db_sparc_regop, 0 }, 212 { "g7", dbreg(global[7]), db_sparc_regop, 0 },
213 { "o0", dbreg(out[0]), db_sparc_regop, 0 }, 213 { "o0", dbreg(out[0]), db_sparc_regop, 0 },
214 { "o1", dbreg(out[1]), db_sparc_regop, 0 }, 214 { "o1", dbreg(out[1]), db_sparc_regop, 0 },
215 { "o2", dbreg(out[2]), db_sparc_regop, 0 }, 215 { "o2", dbreg(out[2]), db_sparc_regop, 0 },
216 { "o3", dbreg(out[3]), db_sparc_regop, 0 }, 216 { "o3", dbreg(out[3]), db_sparc_regop, 0 },
217 { "o4", dbreg(out[4]), db_sparc_regop, 0 }, 217 { "o4", dbreg(out[4]), db_sparc_regop, 0 },
218 { "o5", dbreg(out[5]), db_sparc_regop, 0 }, 218 { "o5", dbreg(out[5]), db_sparc_regop, 0 },
219 { "o6", dbreg(out[6]), db_sparc_regop, 0 }, 219 { "o6", dbreg(out[6]), db_sparc_regop, 0 },
220 { "o7", dbreg(out[7]), db_sparc_regop, 0 }, 220 { "o7", dbreg(out[7]), db_sparc_regop, 0 },
221 { "l0", dbregfr(local[0]), db_sparc_regop, 0 }, 221 { "l0", dbregfr(local[0]), db_sparc_regop, 0 },
222 { "l1", dbregfr(local[1]), db_sparc_regop, 0 }, 222 { "l1", dbregfr(local[1]), db_sparc_regop, 0 },
223 { "l2", dbregfr(local[2]), db_sparc_regop, 0 }, 223 { "l2", dbregfr(local[2]), db_sparc_regop, 0 },
224 { "l3", dbregfr(local[3]), db_sparc_regop, 0 }, 224 { "l3", dbregfr(local[3]), db_sparc_regop, 0 },
225 { "l4", dbregfr(local[4]), db_sparc_regop, 0 }, 225 { "l4", dbregfr(local[4]), db_sparc_regop, 0 },
226 { "l5", dbregfr(local[5]), db_sparc_regop, 0 }, 226 { "l5", dbregfr(local[5]), db_sparc_regop, 0 },
227 { "l6", dbregfr(local[6]), db_sparc_regop, 0 }, 227 { "l6", dbregfr(local[6]), db_sparc_regop, 0 },
228 { "l7", dbregfr(local[7]), db_sparc_regop, 0 }, 228 { "l7", dbregfr(local[7]), db_sparc_regop, 0 },
229 { "i0", dbregfr(arg[0]), db_sparc_regop, 0 }, 229 { "i0", dbregfr(arg[0]), db_sparc_regop, 0 },
230 { "i1", dbregfr(arg[1]), db_sparc_regop, 0 }, 230 { "i1", dbregfr(arg[1]), db_sparc_regop, 0 },
231 { "i2", dbregfr(arg[2]), db_sparc_regop, 0 }, 231 { "i2", dbregfr(arg[2]), db_sparc_regop, 0 },
232 { "i3", dbregfr(arg[3]), db_sparc_regop, 0 }, 232 { "i3", dbregfr(arg[3]), db_sparc_regop, 0 },
233 { "i4", dbregfr(arg[4]), db_sparc_regop, 0 }, 233 { "i4", dbregfr(arg[4]), db_sparc_regop, 0 },
234 { "i5", dbregfr(arg[5]), db_sparc_regop, 0 }, 234 { "i5", dbregfr(arg[5]), db_sparc_regop, 0 },
235 { "i6", dbregfr(arg[6]), db_sparc_regop, 0 }, 235 { "i6", dbregfr(arg[6]), db_sparc_regop, 0 },
236 { "i7", dbregfr(arg[7]), db_sparc_regop, 0 }, 236 { "i7", dbregfr(arg[7]), db_sparc_regop, 0 },
237 { "f0", dbregfp(regs[0]), db_sparc_regop, 0 }, 237 { "f0", dbregfp(regs[0]), db_sparc_regop, 0 },
238 { "f2", dbregfp(regs[2]), db_sparc_regop, 0 }, 238 { "f2", dbregfp(regs[2]), db_sparc_regop, 0 },
239 { "f4", dbregfp(regs[4]), db_sparc_regop, 0 }, 239 { "f4", dbregfp(regs[4]), db_sparc_regop, 0 },
240 { "f6", dbregfp(regs[6]), db_sparc_regop, 0 }, 240 { "f6", dbregfp(regs[6]), db_sparc_regop, 0 },
241 { "f8", dbregfp(regs[8]), db_sparc_regop, 0 }, 241 { "f8", dbregfp(regs[8]), db_sparc_regop, 0 },
242 { "f10", dbregfp(regs[10]), db_sparc_regop, 0 }, 242 { "f10", dbregfp(regs[10]), db_sparc_regop, 0 },
243 { "f12", dbregfp(regs[12]), db_sparc_regop, 0 }, 243 { "f12", dbregfp(regs[12]), db_sparc_regop, 0 },
244 { "f14", dbregfp(regs[14]), db_sparc_regop, 0 }, 244 { "f14", dbregfp(regs[14]), db_sparc_regop, 0 },
245 { "f16", dbregfp(regs[16]), db_sparc_regop, 0 }, 245 { "f16", dbregfp(regs[16]), db_sparc_regop, 0 },
246 { "f18", dbregfp(regs[18]), db_sparc_regop, 0 }, 246 { "f18", dbregfp(regs[18]), db_sparc_regop, 0 },
247 { "f20", dbregfp(regs[20]), db_sparc_regop, 0 }, 247 { "f20", dbregfp(regs[20]), db_sparc_regop, 0 },
248 { "f22", dbregfp(regs[22]), db_sparc_regop, 0 }, 248 { "f22", dbregfp(regs[22]), db_sparc_regop, 0 },
249 { "f24", dbregfp(regs[24]), db_sparc_regop, 0 }, 249 { "f24", dbregfp(regs[24]), db_sparc_regop, 0 },
250 { "f26", dbregfp(regs[26]), db_sparc_regop, 0 }, 250 { "f26", dbregfp(regs[26]), db_sparc_regop, 0 },
251 { "f28", dbregfp(regs[28]), db_sparc_regop, 0 }, 251 { "f28", dbregfp(regs[28]), db_sparc_regop, 0 },
252 { "f30", dbregfp(regs[30]), db_sparc_regop, 0 }, 252 { "f30", dbregfp(regs[30]), db_sparc_regop, 0 },
253 { "f32", dbregfp(regs[32]), db_sparc_regop, 0 }, 253 { "f32", dbregfp(regs[32]), db_sparc_regop, 0 },
254 { "f34", dbregfp(regs[34]), db_sparc_regop, 0 }, 254 { "f34", dbregfp(regs[34]), db_sparc_regop, 0 },
255 { "f36", dbregfp(regs[36]), db_sparc_regop, 0 }, 255 { "f36", dbregfp(regs[36]), db_sparc_regop, 0 },
256 { "f38", dbregfp(regs[38]), db_sparc_regop, 0 }, 256 { "f38", dbregfp(regs[38]), db_sparc_regop, 0 },
257 { "f40", dbregfp(regs[40]), db_sparc_regop, 0 }, 257 { "f40", dbregfp(regs[40]), db_sparc_regop, 0 },
258 { "f42", dbregfp(regs[42]), db_sparc_regop, 0 }, 258 { "f42", dbregfp(regs[42]), db_sparc_regop, 0 },
259 { "f44", dbregfp(regs[44]), db_sparc_regop, 0 }, 259 { "f44", dbregfp(regs[44]), db_sparc_regop, 0 },
260 { "f46", dbregfp(regs[46]), db_sparc_regop, 0 }, 260 { "f46", dbregfp(regs[46]), db_sparc_regop, 0 },
261 { "f48", dbregfp(regs[48]), db_sparc_regop, 0 }, 261 { "f48", dbregfp(regs[48]), db_sparc_regop, 0 },
262 { "f50", dbregfp(regs[50]), db_sparc_regop, 0 }, 262 { "f50", dbregfp(regs[50]), db_sparc_regop, 0 },
263 { "f52", dbregfp(regs[52]), db_sparc_regop, 0 }, 263 { "f52", dbregfp(regs[52]), db_sparc_regop, 0 },
264 { "f54", dbregfp(regs[54]), db_sparc_regop, 0 }, 264 { "f54", dbregfp(regs[54]), db_sparc_regop, 0 },
265 { "f56", dbregfp(regs[56]), db_sparc_regop, 0 }, 265 { "f56", dbregfp(regs[56]), db_sparc_regop, 0 },
266 { "f58", dbregfp(regs[58]), db_sparc_regop, 0 }, 266 { "f58", dbregfp(regs[58]), db_sparc_regop, 0 },
267 { "f60", dbregfp(regs[60]), db_sparc_regop, 0 }, 267 { "f60", dbregfp(regs[60]), db_sparc_regop, 0 },
268 { "f62", dbregfp(regs[62]), db_sparc_regop, 0 }, 268 { "f62", dbregfp(regs[62]), db_sparc_regop, 0 },
269 { "fsr", dbregfp(fsr), db_sparc_regop, 0 }, 269 { "fsr", dbregfp(fsr), db_sparc_regop, 0 },
270 { "gsr", dbregfp(gsr), db_sparc_intop, 0 }, 270 { "gsr", dbregfp(gsr), db_sparc_intop, 0 },
271}; 271};
272const struct db_variable * const db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); 272const struct db_variable * const db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
273 273
274int db_active = 0; 274int db_active = 0;
275 275
276extern char *trap_type[]; 276extern char *trap_type[];
277 277
278void kdb_kbd_trap(struct trapframe64 *); 278void kdb_kbd_trap(struct trapframe64 *);
279void db_prom_cmd(db_expr_t, bool, db_expr_t, const char *); 279void db_prom_cmd(db_expr_t, bool, db_expr_t, const char *);
280void db_lwp_cmd(db_expr_t, bool, db_expr_t, const char *); 280void db_lwp_cmd(db_expr_t, bool, db_expr_t, const char *);
281void db_proc_cmd(db_expr_t, bool, db_expr_t, const char *); 281void db_proc_cmd(db_expr_t, bool, db_expr_t, const char *);
282void db_ctx_cmd(db_expr_t, bool, db_expr_t, const char *); 282void db_ctx_cmd(db_expr_t, bool, db_expr_t, const char *);
283void db_dump_pcb(db_expr_t, bool, db_expr_t, const char *); 283void db_dump_pcb(db_expr_t, bool, db_expr_t, const char *);
284void db_dump_pv(db_expr_t, bool, db_expr_t, const char *); 284void db_dump_pv(db_expr_t, bool, db_expr_t, const char *);
285void db_setpcb(db_expr_t, bool, db_expr_t, const char *); 285void db_setpcb(db_expr_t, bool, db_expr_t, const char *);
286void db_dump_dtlb(db_expr_t, bool, db_expr_t, const char *); 286void db_dump_dtlb(db_expr_t, bool, db_expr_t, const char *);
287void db_dump_itlb(db_expr_t, bool, db_expr_t, const char *); 287void db_dump_itlb(db_expr_t, bool, db_expr_t, const char *);
288void db_dump_dtsb(db_expr_t, bool, db_expr_t, const char *); 288void db_dump_dtsb(db_expr_t, bool, db_expr_t, const char *);
289void db_dump_itsb(db_expr_t, bool, db_expr_t, const char *); 289void db_dump_itsb(db_expr_t, bool, db_expr_t, const char *);
290void db_pmap_kernel(db_expr_t, bool, db_expr_t, const char *); 290void db_pmap_kernel(db_expr_t, bool, db_expr_t, const char *);
291void db_pload_cmd(db_expr_t, bool, db_expr_t, const char *); 291void db_pload_cmd(db_expr_t, bool, db_expr_t, const char *);
292void db_pmap_cmd(db_expr_t, bool, db_expr_t, const char *); 292void db_pmap_cmd(db_expr_t, bool, db_expr_t, const char *);
293void db_traptrace(db_expr_t, bool, db_expr_t, const char *); 293void db_traptrace(db_expr_t, bool, db_expr_t, const char *);
294void db_watch(db_expr_t, bool, db_expr_t, const char *); 294void db_watch(db_expr_t, bool, db_expr_t, const char *);
295void db_pm_extract(db_expr_t, bool, db_expr_t, const char *); 295void db_pm_extract(db_expr_t, bool, db_expr_t, const char *);
296void db_cpu_cmd(db_expr_t, bool, db_expr_t, const char *); 296void db_cpu_cmd(db_expr_t, bool, db_expr_t, const char *);
297void db_sir_cmd(db_expr_t, bool, db_expr_t, const char *); 297void db_sir_cmd(db_expr_t, bool, db_expr_t, const char *);
298 298
299#ifdef DDB 299#ifdef DDB
300static void db_dump_pmap(struct pmap *); 300static void db_dump_pmap(struct pmap *);
301static void db_print_trace_entry(struct traptrace *, int); 301static void db_print_trace_entry(struct traptrace *, int);
302 302
303#ifdef MULTIPROCESSOR 303#ifdef MULTIPROCESSOR
304 304
305#define NOCPU -1 305#define NOCPU -1
306 306
307static int db_suspend_others(void); 307static int db_suspend_others(void);
308static void ddb_suspend(struct trapframe64 *); 308static void ddb_suspend(struct trapframe64 *);
309void db_resume_others(void); 309void db_resume_others(void);
310 310
311int ddb_cpu = NOCPU; 311int ddb_cpu = NOCPU;
312 312
313bool 313bool
314ddb_running_on_this_cpu(void) 314ddb_running_on_this_cpu(void)
315{ 315{
316 return ddb_cpu == cpu_number(); 316 return ddb_cpu == cpu_number();
317} 317}
318 318
319static int 319static int
320db_suspend_others(void) 320db_suspend_others(void)
321{ 321{
322 int cpu_me = cpu_number(); 322 int cpu_me = cpu_number();
323 bool win; 323 bool win;
324 324
325 if (cpus == NULL) 325 if (cpus == NULL)
326 return 1; 326 return 1;
327 327
328 win = atomic_cas_32(&ddb_cpu, NOCPU, cpu_me) == (uint32_t)NOCPU; 328 win = atomic_cas_32(&ddb_cpu, NOCPU, cpu_me) == (uint32_t)NOCPU;
329 if (win) 329 if (win)
330 mp_pause_cpus(); 330 mp_pause_cpus();
331 331
332 return win; 332 return win;
333} 333}
334 334
335void 335void
336db_resume_others(void) 336db_resume_others(void)
337{ 337{
338 int cpu_me = cpu_number(); 338 int cpu_me = cpu_number();
339 339
340 if (atomic_cas_32(&ddb_cpu, cpu_me, NOCPU) == cpu_me) 340 if (atomic_cas_32(&ddb_cpu, cpu_me, NOCPU) == cpu_me)
341 mp_resume_cpus(); 341 mp_resume_cpus();
342} 342}
343 343
344static void 344static void
345ddb_suspend(struct trapframe64 *tf) 345ddb_suspend(struct trapframe64 *tf)
346{ 346{
347 347
348 sparc64_ipi_pause_thiscpu(tf); 348 sparc64_ipi_pause_thiscpu(tf);
349} 349}
350#endif /* MULTIPROCESSOR */ 350#endif /* MULTIPROCESSOR */
351 351
352/* 352/*
353 * Received keyboard interrupt sequence. 353 * Received keyboard interrupt sequence.
354 */ 354 */
355void 355void
356kdb_kbd_trap(struct trapframe64 *tf) 356kdb_kbd_trap(struct trapframe64 *tf)
357{ 357{
358 if (db_active == 0 /* && (boothowto & RB_KDB) */) { 358 if (db_active == 0 /* && (boothowto & RB_KDB) */) {
359 printf("\n\nkernel: keyboard interrupt tf=%p\n", tf); 359 printf("\n\nkernel: keyboard interrupt tf=%p\n", tf);
360 kdb_trap(-1, tf); 360 kdb_trap(-1, tf);
361 } 361 }
362} 362}
363 363
364void 364void
365fill_ddb_regs_from_tf(struct trapframe64 *tf) 365fill_ddb_regs_from_tf(struct trapframe64 *tf)
366{ 366{
367 extern int savetstate(struct trapstate *); 367 extern int savetstate(struct trapstate *);
368 368
369#ifdef MULTIPROCESSOR 369#ifdef MULTIPROCESSOR
370 static db_regs_t ddbregs[CPUSET_MAXNUMCPU]; 370 static db_regs_t ddbregs[CPUSET_MAXNUMCPU];
371 371
372 curcpu()->ci_ddb_regs = &ddbregs[cpu_number()]; 372 curcpu()->ci_ddb_regs = &ddbregs[cpu_number()];
373#else 373#else
374 static db_regs_t ddbregs; 374 static db_regs_t ddbregs;
375 375
376 curcpu()->ci_ddb_regs = &ddbregs; 376 curcpu()->ci_ddb_regs = &ddbregs;
377#endif 377#endif
378 378
379 DDB_REGS->db_tf = *tf; 379 DDB_REGS->db_tf = *tf;
380#ifdef __arch64__ 380#ifdef __arch64__
381 DDB_REGS->db_fr = *(struct frame64 *)(uintptr_t)tf->tf_out[6]; 381 DDB_REGS->db_fr = *(struct frame64 *)(uintptr_t)tf->tf_out[6];
382#else 382#else
383 { 383 {
384 struct frame32 *tf32 = (struct frame32 *)(uintptr_t)tf->tf_out[6]; 384 struct frame32 *tf32 = (struct frame32 *)(uintptr_t)tf->tf_out[6];
385 int i; 385 int i;
386 386
387 for (i = 0; i < 8; i++) 387 for (i = 0; i < 8; i++)
388 DDB_REGS->db_fr.fr_local[i] = (uint32_t)tf32->fr_local[i]; 388 DDB_REGS->db_fr.fr_local[i] = (uint32_t)tf32->fr_local[i];
389 for (i = 0; i < 6; i++) 389 for (i = 0; i < 6; i++)
390 DDB_REGS->db_fr.fr_arg[i] = (uint32_t)tf32->fr_arg[i]; 390 DDB_REGS->db_fr.fr_arg[i] = (uint32_t)tf32->fr_arg[i];
391 DDB_REGS->db_fr.fr_fp = tf32->fr_fp; 391 DDB_REGS->db_fr.fr_fp = tf32->fr_fp;
392 DDB_REGS->db_fr.fr_pc = tf32->fr_pc; 392 DDB_REGS->db_fr.fr_pc = tf32->fr_pc;
393 } 393 }
394#endif 394#endif
395 395
396 if (fplwp) { 396 if (fplwp) {
397 savefpstate(fplwp->l_md.md_fpstate); 397 savefpstate(fplwp->l_md.md_fpstate);
398 DDB_REGS->db_fpstate = *fplwp->l_md.md_fpstate; 398 DDB_REGS->db_fpstate = *fplwp->l_md.md_fpstate;
399 loadfpstate(fplwp->l_md.md_fpstate); 399 loadfpstate(fplwp->l_md.md_fpstate);
400 } 400 }
401 /* We should do a proper copyin and xlate 64-bit stack frames, but... */ 401 /* We should do a proper copyin and xlate 64-bit stack frames, but... */
402/* if (tf->tf_tstate & TSTATE_PRIV) { .. } */ 402/* if (tf->tf_tstate & TSTATE_PRIV) { .. } */
403  403
404#if 0 404#if 0
405 /* make sure this is not causing ddb problems. */ 405 /* make sure this is not causing ddb problems. */
406 if (tf->tf_out[6] & 1) { 406 if (tf->tf_out[6] & 1) {
407 if ((unsigned)(tf->tf_out[6] + BIAS) > (unsigned)KERNBASE) 407 if ((unsigned)(tf->tf_out[6] + BIAS) > (unsigned)KERNBASE)
408 DDB_REGS->db_fr = *(struct frame64 *)(tf->tf_out[6] + BIAS); 408 DDB_REGS->db_fr = *(struct frame64 *)(tf->tf_out[6] + BIAS);
409 else 409 else
410 copyin((void *)(tf->tf_out[6] + BIAS), &DDB_REGS->db_fr, sizeof(struct frame64)); 410 copyin((void *)(tf->tf_out[6] + BIAS), &DDB_REGS->db_fr, sizeof(struct frame64));
411 } else { 411 } else {
412 struct frame32 tfr; 412 struct frame32 tfr;
413 int i; 413 int i;
414 414
415 /* First get a local copy of the frame32 */ 415 /* First get a local copy of the frame32 */
416 if ((unsigned)(tf->tf_out[6]) > (unsigned)KERNBASE) 416 if ((unsigned)(tf->tf_out[6]) > (unsigned)KERNBASE)
417 tfr = *(struct frame32 *)tf->tf_out[6]; 417 tfr = *(struct frame32 *)tf->tf_out[6];
418 else 418 else
419 copyin((void *)(tf->tf_out[6]), &tfr, sizeof(struct frame32)); 419 copyin((void *)(tf->tf_out[6]), &tfr, sizeof(struct frame32));
420 /* Now copy each field from the 32-bit value to the 64-bit value */ 420 /* Now copy each field from the 32-bit value to the 64-bit value */
421 for (i=0; i<8; i++) 421 for (i=0; i<8; i++)
422 DDB_REGS->db_fr.fr_local[i] = tfr.fr_local[i]; 422 DDB_REGS->db_fr.fr_local[i] = tfr.fr_local[i];
423 for (i=0; i<6; i++) 423 for (i=0; i<6; i++)
424 DDB_REGS->db_fr.fr_arg[i] = tfr.fr_arg[i]; 424 DDB_REGS->db_fr.fr_arg[i] = tfr.fr_arg[i];
425 DDB_REGS->db_fr.fr_fp = (long)tfr.fr_fp; 425 DDB_REGS->db_fr.fr_fp = (long)tfr.fr_fp;
426 DDB_REGS->db_fr.fr_pc = tfr.fr_pc; 426 DDB_REGS->db_fr.fr_pc = tfr.fr_pc;
427 } 427 }
428#endif 428#endif
429 DDB_REGS->db_tl = savetstate(&DDB_REGS->db_ts[0]); 429 DDB_REGS->db_tl = savetstate(&DDB_REGS->db_ts[0]);
430} 430}
431 431
432void 432void
433ddb_restore_state(void) 433ddb_restore_state(void)
434{ 434{
435 extern void restoretstate(int, struct trapstate *); 435 extern void restoretstate(int, struct trapstate *);
436 436
437 restoretstate(DDB_REGS->db_tl, &DDB_REGS->db_ts[0]); 437 restoretstate(DDB_REGS->db_tl, &DDB_REGS->db_ts[0]);
438 if (fplwp) {  438 if (fplwp) {
439 *fplwp->l_md.md_fpstate = DDB_REGS->db_fpstate; 439 *fplwp->l_md.md_fpstate = DDB_REGS->db_fpstate;
440 loadfpstate(fplwp->l_md.md_fpstate); 440 loadfpstate(fplwp->l_md.md_fpstate);
441 } 441 }
442} 442}
443 443
444/* 444/*
445 * kdb_trap - field a TRACE or BPT trap 445 * kdb_trap - field a TRACE or BPT trap
446 */ 446 */
447int 447int
448kdb_trap(int type, struct trapframe64 *tf) 448kdb_trap(int type, struct trapframe64 *tf)
449{ 449{
450 int s; 450 int s;
451 extern int trap_trace_dis; 451 extern int trap_trace_dis;
452 extern int doing_shutdown; 452 extern int doing_shutdown;
453 453
454 trap_trace_dis++; 454 trap_trace_dis++;
455 doing_shutdown++; 455 doing_shutdown++;
456#if NFB > 0 456#if NFB > 0
457 fb_unblank(); 457 fb_unblank();
458#endif 458#endif
459 switch (type) { 459 switch (type) {
460 case T_BREAKPOINT: /* breakpoint */ 460 case T_BREAKPOINT: /* breakpoint */
461 break; 461 break;
462 case -1: /* keyboard interrupt */ 462 case -1: /* keyboard interrupt */
463 printf("kdb tf=%p\n", tf); 463 printf("kdb tf=%p\n", tf);
464 break; 464 break;
465 default: 465 default:
466 if (!db_onpanic && db_recover==0) 466 if (!db_onpanic && db_recover==0)
467 return (0); 467 return (0);
468 468
469 printf("kernel trap %x: %s\n", type, trap_type[type & 0x1ff]); 469 printf("kernel trap %x: %s\n", type, trap_type[type & 0x1ff]);
470 if (db_recover != 0) { 470 if (db_recover != 0) {
471 prom_abort(); 471 prom_abort();
472 db_error("Faulted in DDB; continuing...\n"); 472 db_error("Faulted in DDB; continuing...\n");
473 prom_abort(); 473 prom_abort();
474 /*NOTREACHED*/ 474 /*NOTREACHED*/
475 } 475 }
476 db_recover = (label_t *)1; 476 db_recover = (label_t *)1;
477 } 477 }
478 478
479 /* Should switch to kdb`s own stack here. */ 479 /* Should switch to kdb`s own stack here. */
480 write_all_windows(); 480 write_all_windows();
481 481
482#if defined(MULTIPROCESSOR) 482#if defined(MULTIPROCESSOR)
483 if (!db_suspend_others()) { 483 if (!db_suspend_others()) {
484 ddb_suspend(tf); 484 ddb_suspend(tf);
485 return 1; 485 return 1;
486 } 486 }
487#endif 487#endif
488 488
489 /* Initialise local dbregs storage from trap frame */ 489 /* Initialise local dbregs storage from trap frame */
490 fill_ddb_regs_from_tf(tf); 490 fill_ddb_regs_from_tf(tf);
491 491
492 s = splhigh(); 492 s = splhigh();
493 db_active++; 493 db_active++;
494 cnpollc(TRUE); 494 cnpollc(TRUE);
495 /* Need to do spl stuff till cnpollc works */ 495 /* Need to do spl stuff till cnpollc works */
496 db_dump_ts(0, 0, 0, 0); 496 db_dump_ts(0, 0, 0, 0);
497 db_trap(type, 0/*code*/); 497 db_trap(type, 0/*code*/);
498 ddb_restore_state(); 498 ddb_restore_state();
499 cnpollc(FALSE); 499 cnpollc(FALSE);
500 db_active--; 500 db_active--;
501 501
502 splx(s); 502 splx(s);
503 503
504 *tf = DDB_REGS->db_tf; 504 *tf = DDB_REGS->db_tf;
505 curcpu()->ci_ddb_regs = NULL; 505 curcpu()->ci_ddb_regs = NULL;
506 506
507 trap_trace_dis--; 507 trap_trace_dis--;
508 doing_shutdown--; 508 doing_shutdown--;
509 509
510#if defined(MULTIPROCESSOR) 510#if defined(MULTIPROCESSOR)
511 db_resume_others(); 511 db_resume_others();
512#endif 512#endif
513 513
514 return (1); 514 return (1);
515} 515}
516#endif /* DDB */ 516#endif /* DDB */
517 517
518/* 518/*
519 * Read bytes from kernel address space for debugger. 519 * Read bytes from kernel address space for debugger.
520 */ 520 */
521void 521void
522db_read_bytes(db_addr_t addr, size_t size, char *data) 522db_read_bytes(db_addr_t addr, size_t size, char *data)
523{ 523{
524 char *src; 524 char *src;
525 525
526 src = (char *)(uintptr_t)addr; 526 src = (char *)(uintptr_t)addr;
527 while (size-- > 0) { 527 while (size-- > 0) {
528 if (src >= (char *)VM_MIN_KERNEL_ADDRESS) 528 if (src >= (char *)VM_MIN_KERNEL_ADDRESS)
529 *data++ = probeget((paddr_t)(u_long)src++, ASI_P, 1); 529 *data++ = probeget((paddr_t)(u_long)src++, ASI_P, 1);
530 else 530 else
531 *data++ = fubyte(src++); 531 *data++ = fubyte(src++);
532 } 532 }
533} 533}
534 534
535 535
536/* 536/*
537 * Write bytes to kernel address space for debugger. 537 * Write bytes to kernel address space for debugger.
538 */ 538 */
539void 539void
540db_write_bytes(db_addr_t addr, size_t size, const char *data) 540db_write_bytes(db_addr_t addr, size_t size, const char *data)
541{ 541{
542 char *dst; 542 char *dst;
543 extern paddr_t pmap_kextract(vaddr_t va); 543 extern paddr_t pmap_kextract(vaddr_t va);
544 544
545 dst = (char *)(uintptr_t)addr; 545 dst = (char *)(uintptr_t)addr;
546 while (size-- > 0) { 546 while (size-- > 0) {
547 if ((dst >= (char *)VM_MIN_KERNEL_ADDRESS+0x400000)) 547 if ((dst >= (char *)VM_MIN_KERNEL_ADDRESS+0x400000))
548 *dst = *data; 548 *dst = *data;
549 else if ((dst >= (char *)VM_MIN_KERNEL_ADDRESS) && 549 else if ((dst >= (char *)VM_MIN_KERNEL_ADDRESS) &&
550 (dst < (char *)VM_MIN_KERNEL_ADDRESS+0x400000)) 550 (dst < (char *)VM_MIN_KERNEL_ADDRESS+0x400000))
551 /* Read Only mapping -- need to do a bypass access */ 551 /* Read Only mapping -- need to do a bypass access */
552 stba(pmap_kextract((vaddr_t)dst), ASI_PHYS_CACHED, *data); 552 stba(pmap_kextract((vaddr_t)dst), ASI_PHYS_CACHED, *data);
553 else 553 else
554 subyte(dst, *data); 554 subyte(dst, *data);
555 dst++, data++; 555 dst++, data++;
556 } 556 }
557 557
558} 558}
559 559
560#ifdef DDB 560#ifdef DDB
561void 561void
562Debugger(void) 562Debugger(void)
563{ 563{
564 /* We use the breakpoint to trap into DDB */ 564 /* We use the breakpoint to trap into DDB */
565 __asm("ta 1; nop"); 565 __asm("ta 1; nop");
566} 566}
567 567
568void 568void
569db_prom_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 569db_prom_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
570{ 570{
571 prom_abort(); 571 prom_abort();
572} 572}
573 573
574void 574void
575db_dump_dtlb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 575db_dump_dtlb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
576{ 576{
577 extern void print_dtlb(void); 577 extern void print_dtlb(void);
578 578
579 print_dtlb(); 579 print_dtlb();
580} 580}
581 581
582void 582void
583db_dump_itlb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 583db_dump_itlb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
584{ 584{
585 extern void print_itlb(void); 585 extern void print_itlb(void);
586 586
587 print_itlb(); 587 print_itlb();
588} 588}
589 589
590void 590void
591db_pload_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 591db_pload_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
592{ 592{
593 static paddr_t oldaddr = -1; 593 static paddr_t oldaddr = -1;
594 int asi = ASI_PHYS_CACHED; 594 int asi = ASI_PHYS_CACHED;
595 595
596 if (!have_addr) { 596 if (!have_addr) {
597 addr = oldaddr; 597 addr = oldaddr;
598 } 598 }
599 if (addr == -1) { 599 if (addr == -1) {
600 db_printf("no address\n"); 600 db_printf("no address\n");
601 return; 601 return;
602 } 602 }
603 addr &= ~0x7; /* align */ 603 addr &= ~0x7; /* align */
604 { 604 {
605 register char c; 605 register char c;
606 register const char *cp = modif; 606 register const char *cp = modif;
607 while ((c = *cp++) != 0) 607 while ((c = *cp++) != 0)
608 if (c == 'u') 608 if (c == 'u')
609 asi = ASI_AIUS; 609 asi = ASI_AIUS;
610 } 610 }
611 while (count--) { 611 while (count--) {
612 if (db_print_position() == 0) { 612 if (db_print_position() == 0) {
613 /* Always print the address. */ 613 /* Always print the address. */
614 db_printf("%16.16lx:\t", (long)addr); 614 db_printf("%16.16lx:\t", (long)addr);
615 } 615 }
616 oldaddr=addr; 616 oldaddr=addr;
617 db_printf("%8.8lx\n", (long)ldxa(addr, asi)); 617 db_printf("%8.8lx\n", (long)ldxa(addr, asi));
618 addr += 8; 618 addr += 8;
619 if (db_print_position() != 0) 619 if (db_print_position() != 0)
620 db_end_line(); 620 db_end_line();
621 } 621 }
622} 622}
623 623
624int64_t pseg_get(struct pmap *, vaddr_t); 624int64_t pseg_get(struct pmap *, vaddr_t);
625 625
626void 626void
627db_dump_pmap(struct pmap *pm) 627db_dump_pmap(struct pmap *pm)
628{ 628{
629 /* print all valid pages in the kernel pmap */ 629 /* print all valid pages in the kernel pmap */
630 unsigned long long i, j, k, n, data0, data1; 630 unsigned long long i, j, k, n, data0, data1;
631 paddr_t *pdir, *ptbl; 631 paddr_t *pdir, *ptbl;
632  632
633 n = 0; 633 n = 0;
634 for (i = 0; i < STSZ; i++) { 634 for (i = 0; i < STSZ; i++) {
635 pdir = (paddr_t *)(u_long)ldxa((vaddr_t)&pm->pm_segs[i], ASI_PHYS_CACHED); 635 pdir = (paddr_t *)(u_long)ldxa((vaddr_t)&pm->pm_segs[i], ASI_PHYS_CACHED);
636 if (!pdir) { 636 if (!pdir) {
637 continue; 637 continue;
638 } 638 }
639 db_printf("pdir %lld at %lx:\n", i, (long)pdir); 639 db_printf("pdir %lld at %lx:\n", i, (long)pdir);
640 for (k = 0; k < PDSZ; k++) { 640 for (k = 0; k < PDSZ; k++) {
641 ptbl = (paddr_t *)(u_long)ldxa((vaddr_t)&pdir[k], ASI_PHYS_CACHED); 641 ptbl = (paddr_t *)(u_long)ldxa((vaddr_t)&pdir[k], ASI_PHYS_CACHED);
642 if (!ptbl) { 642 if (!ptbl) {
643 continue; 643 continue;
644 } 644 }
645 db_printf("\tptable %lld:%lld at %lx:\n", i, k, (long)ptbl); 645 db_printf("\tptable %lld:%lld at %lx:\n", i, k, (long)ptbl);
646 for (j = 0; j < PTSZ; j++) { 646 for (j = 0; j < PTSZ; j++) {
647 data0 = ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED); 647 data0 = ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED);
648 j++; 648 j++;
649 data1 = ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED); 649 data1 = ldxa((vaddr_t)&ptbl[j], ASI_PHYS_CACHED);
650 if (!data0 && !data1) { 650 if (!data0 && !data1) {
651 continue; 651 continue;
652 } 652 }
653 db_printf("%016llx: %016llx\t", 653 db_printf("%016llx: %016llx\t",
654 (i << STSHIFT) | (k << PDSHIFT) | ((j - 1) << PTSHIFT), 654 (i << STSHIFT) | (k << PDSHIFT) | ((j - 1) << PTSHIFT),
655 data0); 655 data0);
656 db_printf("%016llx: %016llx\n", 656 db_printf("%016llx: %016llx\n",
657 (i << STSHIFT) | (k << PDSHIFT) | (j << PTSHIFT), 657 (i << STSHIFT) | (k << PDSHIFT) | (j << PTSHIFT),
658 data1); 658 data1);
659 } 659 }
660 } 660 }
661 } 661 }
662} 662}
663 663
664void 664void
665db_pmap_kernel(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 665db_pmap_kernel(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
666{ 666{
667 int i, j, full = 0; 667 int i, j, full = 0;
668 uint64_t data; 668 uint64_t data;
669 669
670 { 670 {
671 register char c; 671 register char c;
672 register const char *cp = modif; 672 register const char *cp = modif;
673 while ((c = *cp++) != 0) 673 while ((c = *cp++) != 0)
674 if (c == 'f') 674 if (c == 'f')
675 full = 1; 675 full = 1;
676 } 676 }
677 if (have_addr) { 677 if (have_addr) {
678 /* lookup an entry for this VA */ 678 /* lookup an entry for this VA */
679  679
680 if ((data = pseg_get(pmap_kernel(), (vaddr_t)addr))) { 680 if ((data = pseg_get(pmap_kernel(), (vaddr_t)addr))) {
681 db_printf("pmap_kernel(%p)->pm_segs[%lx][%lx][%lx]=>%qx\n", 681 db_printf("pmap_kernel(%p)->pm_segs[%lx][%lx][%lx]=>%qx\n",
682 (void *)(uintptr_t)addr, (u_long)va_to_seg(addr),  682 (void *)(uintptr_t)addr, (u_long)va_to_seg(addr),
683 (u_long)va_to_dir(addr), (u_long)va_to_pte(addr), 683 (u_long)va_to_dir(addr), (u_long)va_to_pte(addr),
684 (unsigned long long)data); 684 (unsigned long long)data);
685 } else { 685 } else {
686 db_printf("No mapping for %p\n", (void *)(uintptr_t)addr); 686 db_printf("No mapping for %p\n", (void *)(uintptr_t)addr);
687 } 687 }
688 return; 688 return;
689 } 689 }
690 690
691 db_printf("pmap_kernel(%p) psegs %p phys %llx\n", 691 db_printf("pmap_kernel(%p) psegs %p phys %llx\n",
692 pmap_kernel(), pmap_kernel()->pm_segs, 692 pmap_kernel(), pmap_kernel()->pm_segs,
693 (unsigned long long)pmap_kernel()->pm_physaddr); 693 (unsigned long long)pmap_kernel()->pm_physaddr);
694 if (full) { 694 if (full) {
695 db_dump_pmap(pmap_kernel()); 695 db_dump_pmap(pmap_kernel());
696 } else { 696 } else {
697 for (j=i=0; i<STSZ; i++) { 697 for (j=i=0; i<STSZ; i++) {
698 long seg = (long)ldxa((vaddr_t)pmap_kernel()->pm_segs[i], ASI_PHYS_CACHED); 698 long seg = (long)ldxa((vaddr_t)pmap_kernel()->pm_segs[i], ASI_PHYS_CACHED);
699 if (seg) 699 if (seg)
700 db_printf("seg %d => %lx%c", i, seg, (j++%4)?'\t':'\n'); 700 db_printf("seg %d => %lx%c", i, seg, (j++%4)?'\t':'\n');
701 } 701 }
702 } 702 }
703} 703}
704 704
705void 705void
706db_pm_extract(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 706db_pm_extract(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
707{ 707{
708 if (have_addr) { 708 if (have_addr) {
709 paddr_t pa; 709 paddr_t pa;
710 710
711 if (pmap_extract(pmap_kernel(), addr, &pa)) 711 if (pmap_extract(pmap_kernel(), addr, &pa))
712 db_printf("pa = %llx\n", (long long)pa); 712 db_printf("pa = %llx\n", (long long)pa);
713 else 713 else
714 db_printf("%p not found\n", (void *)(uintptr_t)addr); 714 db_printf("%p not found\n", (void *)(uintptr_t)addr);
715 } else 715 } else
716 db_printf("pmap_extract: no address\n"); 716 db_printf("pmap_extract: no address\n");
717} 717}
718 718
719void 719void
720db_pmap_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 720db_pmap_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
721{ 721{
722 struct pmap* pm=NULL; 722 struct pmap* pm=NULL;
723 int i, j=0, full = 0; 723 int i, j=0, full = 0;
724 724
725 { 725 {
726 register char c; 726 register char c;
727 register const char *cp = modif; 727 register const char *cp = modif;
728 if (modif) 728 if (modif)
729 while ((c = *cp++) != 0) 729 while ((c = *cp++) != 0)
730 if (c == 'f') 730 if (c == 'f')
731 full = 1; 731 full = 1;
732 } 732 }
733 if (curlwp && curlwp->l_proc->p_vmspace) 733 if (curlwp && curlwp->l_proc->p_vmspace)
734 pm = curlwp->l_proc->p_vmspace->vm_map.pmap; 734 pm = curlwp->l_proc->p_vmspace->vm_map.pmap;
735 if (have_addr) 735 if (have_addr)
736 pm = (struct pmap*)(uintptr_t)addr; 736 pm = (struct pmap*)(uintptr_t)addr;
737 737
738 db_printf("pmap %p: ctx %x refs %d physaddr %llx psegs %p\n", 738 db_printf("pmap %p: ctx %x refs %d physaddr %llx psegs %p\n",
739 pm, pmap_ctx(pm), pm->pm_refs, 739 pm, pmap_ctx(pm), pm->pm_refs,
740 (unsigned long long)pm->pm_physaddr, pm->pm_segs); 740 (unsigned long long)pm->pm_physaddr, pm->pm_segs);
741 741
742 if (full) { 742 if (full) {
743 db_dump_pmap(pm); 743 db_dump_pmap(pm);
744 } else { 744 } else {
745 for (i=0; i<STSZ; i++) { 745 for (i=0; i<STSZ; i++) {
746 long seg = (long)ldxa((vaddr_t)pmap_kernel()->pm_segs[i], ASI_PHYS_CACHED); 746 long seg = (long)ldxa((vaddr_t)pmap_kernel()->pm_segs[i], ASI_PHYS_CACHED);
747 if (seg) 747 if (seg)
748 db_printf("seg %d => %lx%c", i, seg, (j++%4)?'\t':'\n'); 748 db_printf("seg %d => %lx%c", i, seg, (j++%4)?'\t':'\n');
749 } 749 }
750 } 750 }
751} 751}
752 752
753#define TSBENTS (512 << tsbsize) 753#define TSBENTS (512 << tsbsize)
754extern pte_t *tsb_dmmu, *tsb_immu; 754extern pte_t *tsb_dmmu, *tsb_immu;
755extern int tsbsize; 755extern int tsbsize;
756 756
757void db_dump_tsb_common(pte_t *); 757void db_dump_tsb_common(pte_t *);
758 758
759void 759void
760db_dump_dtsb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 760db_dump_dtsb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
761{ 761{
762 762
763 db_printf("DTSB:\n"); 763 db_printf("DTSB:\n");
764 db_dump_tsb_common(curcpu()->ci_tsb_dmmu); 764 db_dump_tsb_common(curcpu()->ci_tsb_dmmu);
765} 765}
766 766
767void 767void
768db_dump_itsb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 768db_dump_itsb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
769{ 769{
770 770
771 db_printf("ITSB:\n"); 771 db_printf("ITSB:\n");
772 db_dump_tsb_common(curcpu()->ci_tsb_immu); 772 db_dump_tsb_common(curcpu()->ci_tsb_immu);
773} 773}
774 774
775void 775void
776db_dump_tsb_common(pte_t *tsb) 776db_dump_tsb_common(pte_t *tsb)
777{ 777{
778 uint64_t tag, data; 778 uint64_t tag, data;
779 int i; 779 int i;
780 780
781 for (i = 0; i < TSBENTS; i++) { 781 for (i = 0; i < TSBENTS; i++) {
782 tag = tsb[i].tag; 782 tag = tsb[i].tag;
783 data = tsb[i].data; 783 data = tsb[i].data;
784 db_printf("%4d:%4d:%08x %08x:%08x ", i, 784 db_printf("%4d:%4d:%08x %08x:%08x ", i,
785 (int)((tag & TSB_TAG_G) ? -1 : TSB_TAG_CTX(tag)), 785 (int)((tag & TSB_TAG_G) ? -1 : TSB_TAG_CTX(tag)),
786 (int)((i << 13) | TSB_TAG_VA(tag)), 786 (int)((i << 13) | TSB_TAG_VA(tag)),
787 (int)(data >> 32), (int)data); 787 (int)(data >> 32), (int)data);
788 i++; 788 i++;
789 tag = tsb[i].tag; 789 tag = tsb[i].tag;
790 data = tsb[i].data; 790 data = tsb[i].data;
791 db_printf("%4d:%4d:%08x %08x:%08x\n", i, 791 db_printf("%4d:%4d:%08x %08x:%08x\n", i,
792 (int)((tag & TSB_TAG_G) ? -1 : TSB_TAG_CTX(tag)), 792 (int)((tag & TSB_TAG_G) ? -1 : TSB_TAG_CTX(tag)),
793 (int)((i << 13) | TSB_TAG_VA(tag)), 793 (int)((i << 13) | TSB_TAG_VA(tag)),
794 (int)(data >> 32), (int)data); 794 (int)(data >> 32), (int)data);
795 } 795 }
796} 796}
797 797
798void db_page_cmd(db_expr_t, bool, db_expr_t, const char *); 798void db_page_cmd(db_expr_t, bool, db_expr_t, const char *);
799void 799void
800db_page_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 800db_page_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
801{ 801{
802 802
803 if (!have_addr) { 803 if (!have_addr) {
804 db_printf("Need paddr for page\n"); 804 db_printf("Need paddr for page\n");
805 return; 805 return;
806 } 806 }
807 807
808 db_printf("pa %llx pg %p\n", (unsigned long long)addr, 808 db_printf("pa %llx pg %p\n", (unsigned long long)addr,
809 PHYS_TO_VM_PAGE(addr)); 809 PHYS_TO_VM_PAGE(addr));
810} 810}
811 811
812void 812void
813db_lwp_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 813db_lwp_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
814{ 814{
815 struct lwp *l; 815 struct lwp *l;
816 816
817 l = curlwp; 817 l = curlwp;
818 if (have_addr)  818 if (have_addr)
819 l = (struct lwp*)(uintptr_t)addr; 819 l = (struct lwp*)(uintptr_t)addr;
820 if (l == NULL) { 820 if (l == NULL) {
821 db_printf("no current lwp\n"); 821 db_printf("no current lwp\n");
822 return; 822 return;
823 } 823 }
824 db_printf("lwp %p: lid %d\n", l, l->l_lid); 824 db_printf("lwp %p: lid %d\n", l, l->l_lid);
825 db_printf("wchan:%p pri:%d epri:%d tf:%p\n", 825 db_printf("wchan:%p pri:%d epri:%d tf:%p\n",
826 l->l_wchan, l->l_priority, lwp_eprio(l), l->l_md.md_tf); 826 l->l_wchan, l->l_priority, lwp_eprio(l), l->l_md.md_tf);
827 db_printf("pcb: %p fpstate: %p\n", lwp_getpcb(l), 827 db_printf("pcb: %p fpstate: %p\n", lwp_getpcb(l),
828 l->l_md.md_fpstate); 828 l->l_md.md_fpstate);
829 return; 829 return;
830} 830}
831 831
832void 832void
833db_proc_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 833db_proc_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
834{ 834{
835 struct proc *p = NULL; 835 struct proc *p = NULL;
836 836
837 if (curlwp) 837 if (curlwp)
838 p = curlwp->l_proc; 838 p = curlwp->l_proc;
839 if (have_addr)  839 if (have_addr)
840 p = (struct proc*)(uintptr_t)addr; 840 p = (struct proc*)(uintptr_t)addr;
841 if (p == NULL) { 841 if (p == NULL) {
842 db_printf("no current process\n"); 842 db_printf("no current process\n");
843 return; 843 return;
844 } 844 }
845 db_printf("process %p:", p); 845 db_printf("process %p:", p);
846 db_printf("pid:%d vmspace:%p pmap:%p ctx:%x\n", 846 db_printf("pid:%d vmspace:%p pmap:%p ctx:%x\n",
847 p->p_pid, p->p_vmspace, p->p_vmspace->vm_map.pmap, 847 p->p_pid, p->p_vmspace, p->p_vmspace->vm_map.pmap,
848 pmap_ctx(p->p_vmspace->vm_map.pmap)); 848 pmap_ctx(p->p_vmspace->vm_map.pmap));
849 db_printf("maxsaddr:%p ssiz:%dpg or %llxB\n", 849 db_printf("maxsaddr:%p ssiz:%dpg or %llxB\n",
850 p->p_vmspace->vm_maxsaddr, p->p_vmspace->vm_ssize,  850 p->p_vmspace->vm_maxsaddr, p->p_vmspace->vm_ssize,
851 (unsigned long long)ctob(p->p_vmspace->vm_ssize)); 851 (unsigned long long)ctob(p->p_vmspace->vm_ssize));
852 db_printf("profile timer: %" PRId64 " sec %ld nsec\n", 852 db_printf("profile timer: %" PRId64 " sec %ld nsec\n",
853 p->p_stats->p_timer[ITIMER_PROF].it_value.tv_sec, 853 p->p_stats->p_timer[ITIMER_PROF].it_value.tv_sec,
854 p->p_stats->p_timer[ITIMER_PROF].it_value.tv_nsec); 854 p->p_stats->p_timer[ITIMER_PROF].it_value.tv_nsec);
855 return; 855 return;
856} 856}
857 857
858void 858void
859db_ctx_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 859db_ctx_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
860{ 860{
861 struct proc *p; 861 struct proc *p;
862 struct lwp *l; 862 struct lwp *l;
863 struct pcb *pcb; 863 struct pcb *pcb;
864 864
865 /* XXX LOCKING XXX */ 865 /* XXX LOCKING XXX */
866 LIST_FOREACH(p, &allproc, p_list) { 866 LIST_FOREACH(p, &allproc, p_list) {
867 if (p->p_stat) { 867 if (p->p_stat) {
868 db_printf("process %p:", p); 868 db_printf("process %p:", p);
869 db_printf("pid:%d pmap:%p ctx:%x\n", 869 db_printf("pid:%d pmap:%p ctx:%x\n",
870 p->p_pid, p->p_vmspace->vm_map.pmap, 870 p->p_pid, p->p_vmspace->vm_map.pmap,
871 pmap_ctx(p->p_vmspace->vm_map.pmap)); 871 pmap_ctx(p->p_vmspace->vm_map.pmap));
872 LIST_FOREACH(l, &p->p_lwps, l_sibling) { 872 LIST_FOREACH(l, &p->p_lwps, l_sibling) {
873 pcb = lwp_getpcb(l); 873 pcb = lwp_getpcb(l);
874 db_printf("\tlwp %p: lid:%d tf:%p fpstate %p " 874 db_printf("\tlwp %p: lid:%d tf:%p fpstate %p "
875 "lastcall:%s\n", 875 "lastcall:%s\n",
876 l, l->l_lid, l->l_md.md_tf, l->l_md.md_fpstate, 876 l, l->l_lid, l->l_md.md_tf, l->l_md.md_fpstate,
877 (pcb->lastcall) ? 877 (pcb->lastcall) ?
878 pcb->lastcall : "Null"); 878 pcb->lastcall : "Null");
879 } 879 }
880 } 880 }
881 } 881 }
882 return; 882 return;
883} 883}
884 884
885void 885void
886db_dump_pcb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 886db_dump_pcb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
887{ 887{
888 struct pcb *pcb; 888 struct pcb *pcb;
889 int i; 889 int i;
890 890
891 pcb = curpcb; 891 pcb = curpcb;
892 if (have_addr)  892 if (have_addr)
893 pcb = (struct pcb*)(uintptr_t)addr; 893 pcb = (struct pcb*)(uintptr_t)addr;
894 894
895 db_printf("pcb@%p sp:%p pc:%p cwp:%d pil:%d nsaved:%x onfault:%p\nlastcall:%s\nfull windows:\n", 895 db_printf("pcb@%p sp:%p pc:%p cwp:%d pil:%d nsaved:%x onfault:%p\nlastcall:%s\nfull windows:\n",
896 pcb, (void *)(long)pcb->pcb_sp, (void *)(long)pcb->pcb_pc, pcb->pcb_cwp, 896 pcb, (void *)(long)pcb->pcb_sp, (void *)(long)pcb->pcb_pc, pcb->pcb_cwp,
897 pcb->pcb_pil, pcb->pcb_nsaved, (void *)pcb->pcb_onfault, 897 pcb->pcb_pil, pcb->pcb_nsaved, (void *)pcb->pcb_onfault,
898 (pcb->lastcall)?pcb->lastcall:"Null"); 898 (pcb->lastcall)?pcb->lastcall:"Null");
899  899
900 for (i=0; i<pcb->pcb_nsaved; i++) { 900 for (i=0; i<pcb->pcb_nsaved; i++) {
901 db_printf("win %d: at %llx local, in\n", i,  901 db_printf("win %d: at %llx local, in\n", i,
902 (unsigned long long)pcb->pcb_rw[i+1].rw_in[6]); 902 (unsigned long long)pcb->pcb_rw[i+1].rw_in[6]);
903 db_printf("%16llx %16llx %16llx %16llx\n", 903 db_printf("%16llx %16llx %16llx %16llx\n",
904 (unsigned long long)pcb->pcb_rw[i].rw_local[0], 904 (unsigned long long)pcb->pcb_rw[i].rw_local[0],
905 (unsigned long long)pcb->pcb_rw[i].rw_local[1], 905 (unsigned long long)pcb->pcb_rw[i].rw_local[1],
906 (unsigned long long)pcb->pcb_rw[i].rw_local[2], 906 (unsigned long long)pcb->pcb_rw[i].rw_local[2],
907 (unsigned long long)pcb->pcb_rw[i].rw_local[3]); 907 (unsigned long long)pcb->pcb_rw[i].rw_local[3]);
908 db_printf("%16llx %16llx %16llx %16llx\n", 908 db_printf("%16llx %16llx %16llx %16llx\n",
909 (unsigned long long)pcb->pcb_rw[i].rw_local[4], 909 (unsigned long long)pcb->pcb_rw[i].rw_local[4],
910 (unsigned long long)pcb->pcb_rw[i].rw_local[5], 910 (unsigned long long)pcb->pcb_rw[i].rw_local[5],
911 (unsigned long long)pcb->pcb_rw[i].rw_local[6], 911 (unsigned long long)pcb->pcb_rw[i].rw_local[6],
912 (unsigned long long)pcb->pcb_rw[i].rw_local[7]); 912 (unsigned long long)pcb->pcb_rw[i].rw_local[7]);
913 db_printf("%16llx %16llx %16llx %16llx\n", 913 db_printf("%16llx %16llx %16llx %16llx\n",
914 (unsigned long long)pcb->pcb_rw[i].rw_in[0], 914 (unsigned long long)pcb->pcb_rw[i].rw_in[0],
915 (unsigned long long)pcb->pcb_rw[i].rw_in[1], 915 (unsigned long long)pcb->pcb_rw[i].rw_in[1],
916 (unsigned long long)pcb->pcb_rw[i].rw_in[2], 916 (unsigned long long)pcb->pcb_rw[i].rw_in[2],
917 (unsigned long long)pcb->pcb_rw[i].rw_in[3]); 917 (unsigned long long)pcb->pcb_rw[i].rw_in[3]);
918 db_printf("%16llx %16llx %16llx %16llx\n", 918 db_printf("%16llx %16llx %16llx %16llx\n",
919 (unsigned long long)pcb->pcb_rw[i].rw_in[4], 919 (unsigned long long)pcb->pcb_rw[i].rw_in[4],
920 (unsigned long long)pcb->pcb_rw[i].rw_in[5], 920 (unsigned long long)pcb->pcb_rw[i].rw_in[5],
921 (unsigned long long)pcb->pcb_rw[i].rw_in[6], 921 (unsigned long long)pcb->pcb_rw[i].rw_in[6],
922 (unsigned long long)pcb->pcb_rw[i].rw_in[7]); 922 (unsigned long long)pcb->pcb_rw[i].rw_in[7]);
923 } 923 }
924} 924}
925 925
926 926
927void 927void
928db_setpcb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 928db_setpcb(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
929{ 929{
930 struct proc *p, *pp; 930 struct proc *p, *pp;
931 int ctx; 931 int ctx;
932 932
933 if (!have_addr) { 933 if (!have_addr) {
934 db_printf("What PID do you want to map in?\n"); 934 db_printf("What PID do you want to map in?\n");
935 return; 935 return;
936 } 936 }
937  937
938 LIST_FOREACH(p, &allproc, p_list) { 938 LIST_FOREACH(p, &allproc, p_list) {
939 pp = p->p_pptr; 939 pp = p->p_pptr;
940 if (p->p_stat && p->p_pid == addr) { 940 if (p->p_stat && p->p_pid == addr) {
941#if 0 941#if 0
942/* XXX Do we need to do the following too?: */ 942/* XXX Do we need to do the following too?: */
943 extern struct pcb *cpcb; 943 extern struct pcb *cpcb;
944 944
945 curlwp = p; 945 curlwp = p;
946 cpcb = (struct pcb*)p->p_addr; 946 cpcb = (struct pcb*)p->p_addr;
947#endif 947#endif
948 if (p->p_vmspace->vm_map.pmap == pmap_kernel()) { 948 if (p->p_vmspace->vm_map.pmap == pmap_kernel()) {
949 db_printf("PID %ld has a kernel context.\n", 949 db_printf("PID %ld has a kernel context.\n",
950 (long)addr); 950 (long)addr);
951 return; 951 return;
952 } 952 }
953 ctx = pmap_ctx(p->p_vmspace->vm_map.pmap); 953 ctx = pmap_ctx(p->p_vmspace->vm_map.pmap);
954 if (ctx < 0) { 954 if (ctx < 0) {
955 ctx = -ctx; 955 ctx = -ctx;
956 pmap_ctx(p->p_vmspace->vm_map.pmap) = ctx; 956 pmap_ctx(p->p_vmspace->vm_map.pmap) = ctx;
957 } else if (ctx == 0) { 957 } else if (ctx == 0) {
958 pmap_activate_pmap(p->p_vmspace->vm_map.pmap); 958 pmap_activate_pmap(p->p_vmspace->vm_map.pmap);
959 ctx = pmap_ctx(p->p_vmspace->vm_map.pmap); 959 ctx = pmap_ctx(p->p_vmspace->vm_map.pmap);
960 } 960 }
961 if (ctx > 0) { 961 if (ctx > 0) {
962 switchtoctx(ctx); 962 switchtoctx(ctx);
963 return; 963 return;
964 } 964 }
965 db_printf("could not activate pmap for PID %ld.\n", 965 db_printf("could not activate pmap for PID %ld.\n",
966 (long)addr); 966 (long)addr);
967 return; 967 return;
968 } 968 }
969 } 969 }
970 db_printf("PID %ld not found.\n", (long)addr); 970 db_printf("PID %ld not found.\n", (long)addr);
971} 971}
972 972
973static void 973static void
974db_print_trace_entry(struct traptrace *te, int i) 974db_print_trace_entry(struct traptrace *te, int i)
975{ 975{
976 db_printf("%d:%d p:%d tt:%x:%llx:%llx %llx:%llx ", i,  976 db_printf("%d:%d p:%d tt:%x:%llx:%llx %llx:%llx ", i,
977 (int)te->tl, (int)te->pid,  977 (int)te->tl, (int)te->pid,
978 (int)te->tt, (unsigned long long)te->tstate,  978 (int)te->tt, (unsigned long long)te->tstate,
979 (unsigned long long)te->tfault, (unsigned long long)te->tsp, 979 (unsigned long long)te->tfault, (unsigned long long)te->tsp,
980 (unsigned long long)te->tpc); 980 (unsigned long long)te->tpc);
981 db_printsym((u_long)te->tpc, DB_STGY_PROC, db_printf); 981 db_printsym((u_long)te->tpc, DB_STGY_PROC, db_printf);
982 db_printf(": "); 982 db_printf(": ");
983 if ((te->tpc && !(te->tpc&0x3)) && 983 if ((te->tpc && !(te->tpc&0x3)) &&
984 curlwp && 984 curlwp &&
985 (curproc->p_pid == te->pid)) { 985 (curproc->p_pid == te->pid)) {
986 db_disasm((u_long)te->tpc, 0); 986 db_disasm((u_long)te->tpc, 0);
987 } else db_printf("\n"); 987 } else db_printf("\n");
988} 988}
989 989
990void 990void
991db_traptrace(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 991db_traptrace(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
992{ 992{
993 int i, start = 0, full = 0, reverse = 0; 993 int i, start = 0, full = 0, reverse = 0;
994 struct traptrace *end; 994 struct traptrace *end;
995 995
996 start = 0; 996 start = 0;
997 end = &trap_trace_end[0]; 997 end = &trap_trace_end[0];
998 998
999 { 999 {
1000 register char c; 1000 register char c;
1001 register const char *cp = modif; 1001 register const char *cp = modif;
1002 if (modif) 1002 if (modif)
1003 while ((c = *cp++) != 0) { 1003 while ((c = *cp++) != 0) {
1004 if (c == 'f') 1004 if (c == 'f')
1005 full = 1; 1005 full = 1;
1006 if (c == 'r') 1006 if (c == 'r')
1007 reverse = 1; 1007 reverse = 1;
1008 } 1008 }
1009 } 1009 }
1010 1010
1011 if (have_addr) { 1011 if (have_addr) {
1012 start = addr / (sizeof (struct traptrace)); 1012 start = addr / (sizeof (struct traptrace));
1013 if (&trap_trace[start] > &trap_trace_end[0]) { 1013 if (&trap_trace[start] > &trap_trace_end[0]) {
1014 db_printf("Address out of range.\n"); 1014 db_printf("Address out of range.\n");
1015 return; 1015 return;
1016 } 1016 }
1017 if (!full) end = &trap_trace[start+1]; 1017 if (!full) end = &trap_trace[start+1];
1018 } 1018 }
1019 1019
1020 db_printf("#:tl p:pid tt:tt:tstate:tfault sp:pc\n"); 1020 db_printf("#:tl p:pid tt:tt:tstate:tfault sp:pc\n");
1021 if (reverse) { 1021 if (reverse) {
1022 if (full && start) 1022 if (full && start)
1023 for (i=start; --i;) { 1023 for (i=start; --i;) {
1024 db_print_trace_entry(&trap_trace[i], i); 1024 db_print_trace_entry(&trap_trace[i], i);
1025 } 1025 }
1026 i = (end - &trap_trace[0]); 1026 i = (end - &trap_trace[0]);
1027 while(--i > start) { 1027 while(--i > start) {
1028 db_print_trace_entry(&trap_trace[i], i); 1028 db_print_trace_entry(&trap_trace[i], i);
1029 } 1029 }
1030 } else { 1030 } else {
1031 for (i=start; &trap_trace[i] < end ; i++) { 1031 for (i=start; &trap_trace[i] < end ; i++) {
1032 db_print_trace_entry(&trap_trace[i], i); 1032 db_print_trace_entry(&trap_trace[i], i);
1033 } 1033 }
1034 if (full && start) 1034 if (full && start)
1035 for (i=0; i < start ; i++) { 1035 for (i=0; i < start ; i++) {
1036 db_print_trace_entry(&trap_trace[i], i); 1036 db_print_trace_entry(&trap_trace[i], i);
1037 } 1037 }
1038 } 1038 }
1039} 1039}
1040 1040
1041/*  1041/*
1042 * Use physical or virtul watchpoint registers -- ugh 1042 * Use physical or virtul watchpoint registers -- ugh
1043 * 1043 *
1044 * UltraSPARC I and II have both a virtual and physical 1044 * UltraSPARC I and II have both a virtual and physical
1045 * watchpoint register. They are controlled by the LSU  1045 * watchpoint register. They are controlled by the LSU
1046 * control register.  1046 * control register.
1047 */ 1047 */
1048void 1048void
1049db_watch(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 1049db_watch(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
1050{ 1050{
1051 int phys = 0; 1051 int phys = 0;
1052 int read = 0; 1052 int read = 0;
1053 int width = 8; /* Default to 8 bytes */ 1053 int width = 8; /* Default to 8 bytes */
1054 int64_t mask = 0xff; 1054 int64_t mask = 0xff;
1055 1055
1056#define WATCH_VR (1L<<22) 1056#define WATCH_VR (1L<<22)
1057#define WATCH_VW (1L<<21) 1057#define WATCH_VW (1L<<21)
1058#define WATCH_PR (1L<<24) 1058#define WATCH_PR (1L<<24)
1059#define WATCH_PW (1L<<23) 1059#define WATCH_PW (1L<<23)
1060#define WATCH_PM_SHIFT 33 1060#define WATCH_PM_SHIFT 33
1061#define WATCH_PM (((uint64_t)0xffffL)<<WATCH_PM_SHIFT) 1061#define WATCH_PM (((uint64_t)0xffffL)<<WATCH_PM_SHIFT)
1062#define WATCH_VM_SHIFT 25 1062#define WATCH_VM_SHIFT 25
1063#define WATCH_VM (((uint64_t)0xffffL)<<WATCH_VM_SHIFT) 1063#define WATCH_VM (((uint64_t)0xffffL)<<WATCH_VM_SHIFT)
1064 1064
1065 { 1065 {
1066 register char c; 1066 register char c;
1067 register const char *cp = modif; 1067 register const char *cp = modif;
1068 if (modif) 1068 if (modif)
1069 while ((c = *cp++) != 0) 1069 while ((c = *cp++) != 0)
1070 switch (c) { 1070 switch (c) {
1071 case 'p': 1071 case 'p':
1072 /* Physical watchpoint */ 1072 /* Physical watchpoint */
1073 phys = 1; 1073 phys = 1;
1074 break; 1074 break;
1075 case 'r': 1075 case 'r':
1076 /* Trap reads too */ 1076 /* Trap reads too */
1077 read = 1; 1077 read = 1;
1078 break; 1078 break;
1079 case 'b': 1079 case 'b':
1080 width = 1; 1080 width = 1;
1081 mask = 0x1 << (addr & 0x7); 1081 mask = 0x1 << (addr & 0x7);
1082 break; 1082 break;
1083 case 'h': 1083 case 'h':
1084 width = 2; 1084 width = 2;
1085 mask = 0x3 << (addr & 0x6); 1085 mask = 0x3 << (addr & 0x6);
1086 break; 1086 break;
1087 case 'l': 1087 case 'l':
1088 width = 4; 1088 width = 4;
1089 mask = 0x7 << (addr & 0x4); 1089 mask = 0x7 << (addr & 0x4);
1090 break; 1090 break;
1091 case 'L': 1091 case 'L':
1092 width = 8; 1092 width = 8;
1093 mask = 0xf; 1093 mask = 0xf;
1094 break; 1094 break;
1095 default: 1095 default:
1096 break; 1096 break;
1097 } 1097 }
1098 } 1098 }
1099 1099
1100 if (have_addr) { 1100 if (have_addr) {
1101 /* turn on the watchpoint */ 1101 /* turn on the watchpoint */
1102 int64_t tmp = ldxa(0, ASI_MCCR); 1102 int64_t tmp = ldxa(0, ASI_MCCR);
1103  1103
1104 if (phys) { 1104 if (phys) {
1105 tmp &= ~WATCH_PM; 1105 tmp &= ~WATCH_PM;
1106 tmp |= WATCH_PW | (mask << WATCH_PM_SHIFT); 1106 tmp |= WATCH_PW | (mask << WATCH_PM_SHIFT);
1107 if (read) tmp |= WATCH_PR; 1107 if (read) tmp |= WATCH_PR;
1108 1108
1109 stxa(PHYSICAL_WATCHPOINT, ASI_DMMU, addr); 1109 stxa(PHYSICAL_WATCHPOINT, ASI_DMMU, addr);
1110 db_printf("Setting physical watchpoint to %llx-%llx\n", 1110 db_printf("Setting physical watchpoint to %llx-%llx\n",
1111 (long long)addr, (long long)addr + width); 1111 (long long)addr, (long long)addr + width);
1112 } else { 1112 } else {
1113 tmp &= ~WATCH_VM; 1113 tmp &= ~WATCH_VM;
1114 tmp |= WATCH_VW | (mask << WATCH_VM_SHIFT); 1114 tmp |= WATCH_VW | (mask << WATCH_VM_SHIFT);
1115 if (read) tmp |= WATCH_VR; 1115 if (read) tmp |= WATCH_VR;
1116 1116
1117 stxa(VIRTUAL_WATCHPOINT, ASI_DMMU, addr); 1117 stxa(VIRTUAL_WATCHPOINT, ASI_DMMU, addr);
1118 db_printf("Setting virtual watchpoint to %llx-%llx\n", 1118 db_printf("Setting virtual watchpoint to %llx-%llx\n",
1119 (long long)addr, (long long)addr + width); 1119 (long long)addr, (long long)addr + width);
1120 } 1120 }
1121 stxa(0, ASI_MCCR, tmp); 1121 stxa(0, ASI_MCCR, tmp);
1122 } else { 1122 } else {
1123 /* turn off the watchpoint */ 1123 /* turn off the watchpoint */
1124 int64_t tmp = ldxa(0, ASI_MCCR); 1124 int64_t tmp = ldxa(0, ASI_MCCR);
1125 if (phys) { 1125 if (phys) {
1126 tmp &= ~(WATCH_PM|WATCH_PR|WATCH_PW); 1126 tmp &= ~(WATCH_PM|WATCH_PR|WATCH_PW);
1127 db_printf("Disabling physical watchpoint\n"); 1127 db_printf("Disabling physical watchpoint\n");
1128 } else { 1128 } else {
1129 tmp &= ~(WATCH_VM|WATCH_VR|WATCH_VW); 1129 tmp &= ~(WATCH_VM|WATCH_VR|WATCH_VW);
1130 db_printf("Disabling virtual watchpoint\n"); 1130 db_printf("Disabling virtual watchpoint\n");
1131 } 1131 }
1132 stxa(0, ASI_MCCR, tmp); 1132 stxa(0, ASI_MCCR, tmp);
1133 } 1133 }
1134} 1134}
1135 1135
1136/* XXX this belongs in cpu.c */ 1136/* XXX this belongs in cpu.c */
1137static void cpu_debug_dump(void); 1137static void cpu_debug_dump(void);
1138static void 1138static void
1139cpu_debug_dump(void) 1139cpu_debug_dump(void)
1140{ 1140{
1141 struct cpu_info *ci; 1141 struct cpu_info *ci;
1142 1142
1143 for (ci = cpus; ci; ci = ci->ci_next) { 1143 for (ci = cpus; ci; ci = ci->ci_next) {
1144 db_printf("cpu%d: self 0x%08lx lwp 0x%08lx pcb 0x%08lx\n", 1144 db_printf("cpu%d: self 0x%08lx lwp 0x%08lx pcb 0x%08lx "
1145 ci->ci_index, (u_long)ci->ci_self, 1145 "fplwp 0x%08lx\n", ci->ci_index, (u_long)ci->ci_self,
1146 (u_long)ci->ci_curlwp, (u_long)ci->ci_cpcb); 1146 (u_long)ci->ci_curlwp, (u_long)ci->ci_cpcb,
 1147 (u_long)ci->ci_fplwp);
1147 } 1148 }
1148} 1149}
1149 1150
1150void 1151void
1151db_cpu_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 1152db_cpu_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
1152{ 1153{
1153#ifdef MULTIPROCESSOR 1154#ifdef MULTIPROCESSOR
1154 struct cpu_info *ci; 1155 struct cpu_info *ci;
1155#endif 1156#endif
1156  1157
1157 if (!have_addr) { 1158 if (!have_addr) {
1158 cpu_debug_dump(); 1159 cpu_debug_dump();
1159 return; 1160 return;
1160 } 1161 }
1161#ifdef MULTIPROCESSOR 1162#ifdef MULTIPROCESSOR
1162 for (ci = cpus; ci != NULL; ci = ci->ci_next) 1163 for (ci = cpus; ci != NULL; ci = ci->ci_next)
1163 if (ci->ci_index == addr) 1164 if (ci->ci_index == addr)
1164 break; 1165 break;
1165 if (ci == NULL) { 1166 if (ci == NULL) {
1166 db_printf("CPU %ld not configured\n", (long)addr); 1167 db_printf("CPU %ld not configured\n", (long)addr);
1167 return; 1168 return;
1168 } 1169 }
1169 if (ci != curcpu()) { 1170 if (ci != curcpu()) {
1170 if (!mp_cpu_is_paused(ci->ci_index)) { 1171 if (!mp_cpu_is_paused(ci->ci_index)) {
1171 db_printf("CPU %ld not paused\n", (long)addr); 1172 db_printf("CPU %ld not paused\n", (long)addr);
1172 return; 1173 return;
1173 } 1174 }
1174 /* no locking needed - all other cpus are paused */ 1175 /* no locking needed - all other cpus are paused */
1175 ddb_cpu = ci->ci_index; 1176 ddb_cpu = ci->ci_index;
1176 mp_resume_cpu(ddb_cpu); 1177 mp_resume_cpu(ddb_cpu);
1177 sparc64_do_pause(); 1178 sparc64_do_pause();
1178 } 1179 }
1179#endif 1180#endif
1180} 1181}
1181 1182
1182void 1183void
1183db_sir_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 1184db_sir_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
1184{ 1185{
1185 1186
1186 __asm("sir; nop"); 1187 __asm("sir; nop");
1187} 1188}
1188 1189
1189const struct db_command db_machine_command_table[] = { 1190const struct db_command db_machine_command_table[] = {
1190 { DDB_ADD_CMD("ctx", db_ctx_cmd, 0,  1191 { DDB_ADD_CMD("ctx", db_ctx_cmd, 0,
1191 "Print process MMU context information", NULL,NULL) }, 1192 "Print process MMU context information", NULL,NULL) },
1192#ifdef MULTIPROCESSOR 1193#ifdef MULTIPROCESSOR
1193 { DDB_ADD_CMD("cpu", db_cpu_cmd, 0, 1194 { DDB_ADD_CMD("cpu", db_cpu_cmd, 0,
1194 "switch to another cpu", "cpu-no", NULL) }, 1195 "switch to another cpu", "cpu-no", NULL) },
1195#endif 1196#endif
1196 { DDB_ADD_CMD("dtlb", db_dump_dtlb, 0, 1197 { DDB_ADD_CMD("dtlb", db_dump_dtlb, 0,
1197 "Print data translation look-aside buffer context information.", 1198 "Print data translation look-aside buffer context information.",
1198 NULL,NULL) }, 1199 NULL,NULL) },
1199 { DDB_ADD_CMD("itlb", db_dump_itlb, 0, 1200 { DDB_ADD_CMD("itlb", db_dump_itlb, 0,
1200 "Display instruction translation storage buffer information.", 1201 "Display instruction translation storage buffer information.",
1201 NULL,NULL) }, 1202 NULL,NULL) },
1202 { DDB_ADD_CMD("dtsb", db_dump_dtsb, 0, 1203 { DDB_ADD_CMD("dtsb", db_dump_dtsb, 0,
1203 "Display data translation storage buffer information.", NULL,NULL) }, 1204 "Display data translation storage buffer information.", NULL,NULL) },
1204 { DDB_ADD_CMD("itsb", db_dump_itsb, 0, 1205 { DDB_ADD_CMD("itsb", db_dump_itsb, 0,
1205 "Display instruction translation storage buffer information.", 1206 "Display instruction translation storage buffer information.",
1206 NULL,NULL) }, 1207 NULL,NULL) },
1207 { DDB_ADD_CMD("extract", db_pm_extract, 0, 1208 { DDB_ADD_CMD("extract", db_pm_extract, 0,
1208 "Extract the physical address from the kernel pmap.", 1209 "Extract the physical address from the kernel pmap.",
1209 "address", " address:\tvirtual address to look up") }, 1210 "address", " address:\tvirtual address to look up") },
1210 { DDB_ADD_CMD("fpstate", db_dump_fpstate,0, 1211 { DDB_ADD_CMD("fpstate", db_dump_fpstate,0,
1211 "Dump the FPU state." ,NULL,NULL) }, 1212 "Dump the FPU state." ,NULL,NULL) },
1212 { DDB_ADD_CMD("kmap", db_pmap_kernel, 0, 1213 { DDB_ADD_CMD("kmap", db_pmap_kernel, 0,
1213 "Display information about mappings in the kernel pmap.", 1214 "Display information about mappings in the kernel pmap.",
1214 "[/f] [address]", 1215 "[/f] [address]",
1215 " address:\tdisplay the mapping for this virtual address\n" 1216 " address:\tdisplay the mapping for this virtual address\n"
1216 " /f:\tif no address is given, display a full dump of the pmap") }, 1217 " /f:\tif no address is given, display a full dump of the pmap") },
1217 { DDB_ADD_CMD("lwp", db_lwp_cmd, 0, 1218 { DDB_ADD_CMD("lwp", db_lwp_cmd, 0,
1218 "Display a struct lwp", 1219 "Display a struct lwp",
1219 "[address]", 1220 "[address]",
1220 " address:\tthe struct lwp to print (curlwp otherwise)") }, 1221 " address:\tthe struct lwp to print (curlwp otherwise)") },
1221 { DDB_ADD_CMD("pcb", db_dump_pcb, 0, 1222 { DDB_ADD_CMD("pcb", db_dump_pcb, 0,
1222 "Display information about a struct pcb", 1223 "Display information about a struct pcb",
1223 "[address]", 1224 "[address]",
1224 " address:\tthe struct pcb to print (curpcb otherwise)") }, 1225 " address:\tthe struct pcb to print (curpcb otherwise)") },
1225 { DDB_ADD_CMD("pctx", db_setpcb, 0, 1226 { DDB_ADD_CMD("pctx", db_setpcb, 0,
1226 "Attempt to change MMU process context","pid", 1227 "Attempt to change MMU process context","pid",
1227 " pid:\tthe process id to switch the MMU context to") }, 1228 " pid:\tthe process id to switch the MMU context to") },
1228 { DDB_ADD_CMD("page", db_page_cmd, 0, 1229 { DDB_ADD_CMD("page", db_page_cmd, 0,
1229 "Display the address of a struct vm_page given a physical address", 1230 "Display the address of a struct vm_page given a physical address",
1230 "pa", " pa:\tphysical address to look up") }, 1231 "pa", " pa:\tphysical address to look up") },
1231 { DDB_ADD_CMD("phys", db_pload_cmd, 0, 1232 { DDB_ADD_CMD("phys", db_pload_cmd, 0,
1232 "Display physical memory.", "[address][,count]", 1233 "Display physical memory.", "[address][,count]",
1233 " adddress:\tphysical address to start (8 byte aligned)\n" 1234 " adddress:\tphysical address to start (8 byte aligned)\n"
1234 " count:\tnumber of bytes to display") }, 1235 " count:\tnumber of bytes to display") },
1235 { DDB_ADD_CMD("pmap", db_pmap_cmd, 0, 1236 { DDB_ADD_CMD("pmap", db_pmap_cmd, 0,
1236 "Display the pmap", "[/f] [pm_addr]", 1237 "Display the pmap", "[/f] [pm_addr]",
1237 " pm_addr:\tAddress of struct pmap to display\n" 1238 " pm_addr:\tAddress of struct pmap to display\n"
1238 " /f:\tdo a full dump of the pmap") }, 1239 " /f:\tdo a full dump of the pmap") },
1239 { DDB_ADD_CMD("proc", db_proc_cmd, 0, 1240 { DDB_ADD_CMD("proc", db_proc_cmd, 0,
1240 "Display some information about a process", 1241 "Display some information about a process",
1241 "[addr]"," addr:\tstruct proc address (curproc otherwise)") }, 1242 "[addr]"," addr:\tstruct proc address (curproc otherwise)") },
1242 { DDB_ADD_CMD("prom", db_prom_cmd, 0, 1243 { DDB_ADD_CMD("prom", db_prom_cmd, 0,
1243 "Enter the OFW PROM.", NULL,NULL) }, 1244 "Enter the OFW PROM.", NULL,NULL) },
1244 { DDB_ADD_CMD("pv", db_dump_pv, 0, 1245 { DDB_ADD_CMD("pv", db_dump_pv, 0,
1245 "Display a struct pv for a physical address", 1246 "Display a struct pv for a physical address",
1246 "pa", " pa:\tphysical address of a managed page") }, 1247 "pa", " pa:\tphysical address of a managed page") },
1247 { DDB_ADD_CMD("sir", db_sir_cmd, 0, 1248 { DDB_ADD_CMD("sir", db_sir_cmd, 0,
1248 "do a Software Initiated Reset (entering PROM)", NULL,NULL) }, 1249 "do a Software Initiated Reset (entering PROM)", NULL,NULL) },
1249 { DDB_ADD_CMD("stack", db_dump_stack, 0, 1250 { DDB_ADD_CMD("stack", db_dump_stack, 0,
1250 "Dump the window stack.", "[/u] [addr]", 1251 "Dump the window stack.", "[/u] [addr]",
1251 " addr:\tstart address of dump (current stack otherwise)\n" 1252 " addr:\tstart address of dump (current stack otherwise)\n"
1252 " /u:\tcontinue trace into userland") }, 1253 " /u:\tcontinue trace into userland") },
1253 { DDB_ADD_CMD("tf", db_dump_trap, 0, 1254 { DDB_ADD_CMD("tf", db_dump_trap, 0,
1254 "Display full trap frame state.", 1255 "Display full trap frame state.",
1255 "[/u] [addr]", 1256 "[/u] [addr]",
1256 " addr:\tdisplay this trap frame (current kernel frame otherwise)\n" 1257 " addr:\tdisplay this trap frame (current kernel frame otherwise)\n"
1257 " /u:\tdisplay the current userland trap frame") }, 1258 " /u:\tdisplay the current userland trap frame") },
1258 { DDB_ADD_CMD("ts", db_dump_ts, 0, 1259 { DDB_ADD_CMD("ts", db_dump_ts, 0,
1259 "Display trap state.", NULL,NULL) }, 1260 "Display trap state.", NULL,NULL) },
1260 { DDB_ADD_CMD("traptrace", db_traptrace, 0, 1261 { DDB_ADD_CMD("traptrace", db_traptrace, 0,
1261 "Display or set trap trace information.", 1262 "Display or set trap trace information.",
1262 "[/fr] [addr]", 1263 "[/fr] [addr]",
1263 " addr:\tstart address of trace\n" 1264 " addr:\tstart address of trace\n"
1264 " /f:\tdisplay full information\n" 1265 " /f:\tdisplay full information\n"
1265 " /r:\treverse the trace order") }, 1266 " /r:\treverse the trace order") },
1266 { DDB_ADD_CMD("watch", db_watch, 0, 1267 { DDB_ADD_CMD("watch", db_watch, 0,
1267 "Set or clear a physical or virtual hardware watchpoint.", 1268 "Set or clear a physical or virtual hardware watchpoint.",
1268 "[/prbhlL] [addr]", 1269 "[/prbhlL] [addr]",
1269 " addr:\tset the breakpoint (clear watchpoint if not present)\n" 1270 " addr:\tset the breakpoint (clear watchpoint if not present)\n"
1270 " /p:\taddress is physical\n" 1271 " /p:\taddress is physical\n"
1271 " /r:\ttrap on reads too (otherwise only write access)\n" 1272 " /r:\ttrap on reads too (otherwise only write access)\n"
1272 " /b:\t8 bit\n" 1273 " /b:\t8 bit\n"
1273 " /h:\t16 bit\n" 1274 " /h:\t16 bit\n"
1274 " /l:\t32 bit\n" 1275 " /l:\t32 bit\n"
1275 " /L:\t64 bit") }, 1276 " /L:\t64 bit") },
1276 { DDB_ADD_CMD("window", db_dump_window, 0, 1277 { DDB_ADD_CMD("window", db_dump_window, 0,
1277 "Print register window information", 1278 "Print register window information",
1278 "[no]", " no:\tstack frame number (0, i.e. top, if missing)") }, 1279 "[no]", " no:\tstack frame number (0, i.e. top, if missing)") },
1279 { DDB_ADD_CMD(NULL, NULL, 0, NULL,NULL,NULL) } 1280 { DDB_ADD_CMD(NULL, NULL, 0, NULL,NULL,NULL) }
1280}; 1281};
1281 1282
1282#endif /* DDB */ 1283#endif /* DDB */
1283 1284
1284/* 1285/*
1285 * support for SOFTWARE_SSTEP: 1286 * support for SOFTWARE_SSTEP:
1286 * return the next pc if the given branch is taken. 1287 * return the next pc if the given branch is taken.
1287 * 1288 *
1288 * note: in the case of conditional branches with annul, 1289 * note: in the case of conditional branches with annul,
1289 * this actually returns the next pc in the "not taken" path, 1290 * this actually returns the next pc in the "not taken" path,
1290 * but in that case next_instr_address() will return the 1291 * but in that case next_instr_address() will return the
1291 * next pc in the "taken" path. so even tho the breakpoints 1292 * next pc in the "taken" path. so even tho the breakpoints
1292 * are backwards, everything will still work, and the logic is 1293 * are backwards, everything will still work, and the logic is
1293 * much simpler this way. 1294 * much simpler this way.
1294 */ 1295 */
1295db_addr_t 1296db_addr_t
1296db_branch_taken(int inst, db_addr_t pc, db_regs_t *regs) 1297db_branch_taken(int inst, db_addr_t pc, db_regs_t *regs)
1297{ 1298{
1298 union instr insn; 1299 union instr insn;
1299 db_addr_t npc; 1300 db_addr_t npc;
1300 1301
1301 npc = DDB_REGS->db_tf.tf_npc; 1302 npc = DDB_REGS->db_tf.tf_npc;
1302 1303
1303 insn.i_int = inst; 1304 insn.i_int = inst;
1304 1305
1305 /* 1306 /*
1306 * if this is not an annulled conditional branch, the next pc is "npc". 1307 * if this is not an annulled conditional branch, the next pc is "npc".
1307 */ 1308 */
1308 1309
1309 if (insn.i_any.i_op != IOP_OP2 || insn.i_branch.i_annul != 1) 1310 if (insn.i_any.i_op != IOP_OP2 || insn.i_branch.i_annul != 1)
1310 return npc; 1311 return npc;
1311 1312
1312 switch (insn.i_op2.i_op2) { 1313 switch (insn.i_op2.i_op2) {
1313 case IOP2_Bicc: 1314 case IOP2_Bicc:
1314 case IOP2_FBfcc: 1315 case IOP2_FBfcc:
1315 case IOP2_BPcc: 1316 case IOP2_BPcc:
1316 case IOP2_FBPfcc: 1317 case IOP2_FBPfcc:
1317 case IOP2_CBccc: 1318 case IOP2_CBccc:
1318 /* branch on some condition-code */ 1319 /* branch on some condition-code */
1319 switch (insn.i_branch.i_cond) 1320 switch (insn.i_branch.i_cond)
1320 { 1321 {
1321 case Icc_A: /* always */ 1322 case Icc_A: /* always */
1322 return pc + ((inst << 10) >> 8); 1323 return pc + ((inst << 10) >> 8);
1323 1324
1324 default: /* all other conditions */ 1325 default: /* all other conditions */
1325 return npc + 4; 1326 return npc + 4;
1326 } 1327 }
1327 1328
1328 case IOP2_BPr: 1329 case IOP2_BPr:
1329 /* branch on register, always conditional */ 1330 /* branch on register, always conditional */
1330 return npc + 4; 1331 return npc + 4;
1331 1332
1332 default: 1333 default:
1333 /* not a branch */ 1334 /* not a branch */
1334 panic("branch_taken() on non-branch"); 1335 panic("branch_taken() on non-branch");
1335 } 1336 }
1336} 1337}
1337 1338
1338bool 1339bool
1339db_inst_branch(int inst) 1340db_inst_branch(int inst)
1340{ 1341{
1341 union instr insn; 1342 union instr insn;
1342 1343
1343 insn.i_int = inst; 1344 insn.i_int = inst;
1344 1345
1345 if (insn.i_any.i_op != IOP_OP2) 1346 if (insn.i_any.i_op != IOP_OP2)
1346 return FALSE; 1347 return FALSE;
1347 1348
1348 switch (insn.i_op2.i_op2) { 1349 switch (insn.i_op2.i_op2) {
1349 case IOP2_BPcc: 1350 case IOP2_BPcc:
1350 case IOP2_Bicc: 1351 case IOP2_Bicc:
1351 case IOP2_BPr: 1352 case IOP2_BPr:
1352 case IOP2_FBPfcc: 1353 case IOP2_FBPfcc:
1353 case IOP2_FBfcc: 1354 case IOP2_FBfcc:
1354 case IOP2_CBccc: 1355 case IOP2_CBccc:
1355 return TRUE; 1356 return TRUE;
1356 1357
1357 default: 1358 default:
1358 return FALSE; 1359 return FALSE;
1359 } 1360 }
1360} 1361}
1361 1362
1362 1363
1363bool 1364bool
1364db_inst_call(int inst) 1365db_inst_call(int inst)
1365{ 1366{
1366 union instr insn; 1367 union instr insn;
1367 1368
1368 insn.i_int = inst; 1369 insn.i_int = inst;
1369 1370
1370 switch (insn.i_any.i_op) { 1371 switch (insn.i_any.i_op) {
1371 case IOP_CALL: 1372 case IOP_CALL:
1372 return TRUE; 1373 return TRUE;
1373 1374
1374 case IOP_reg: 1375 case IOP_reg:
1375 return (insn.i_op3.i_op3 == IOP3_JMPL) && !db_inst_return(inst); 1376 return (insn.i_op3.i_op3 == IOP3_JMPL) && !db_inst_return(inst);
1376 1377
1377 default: 1378 default:
1378 return FALSE; 1379 return FALSE;
1379 } 1380 }
1380} 1381}
1381 1382
1382 1383
1383bool 1384bool
1384db_inst_unconditional_flow_transfer(int inst) 1385db_inst_unconditional_flow_transfer(int inst)
1385{ 1386{
1386 union instr insn; 1387 union instr insn;
1387 1388
1388 insn.i_int = inst; 1389 insn.i_int = inst;
1389 1390
1390 if (db_inst_call(inst)) 1391 if (db_inst_call(inst))
1391 return TRUE; 1392 return TRUE;
1392 1393
1393 if (insn.i_any.i_op != IOP_OP2) 1394 if (insn.i_any.i_op != IOP_OP2)
1394 return FALSE; 1395 return FALSE;
1395 1396
1396 switch (insn.i_op2.i_op2) 1397 switch (insn.i_op2.i_op2)
1397 { 1398 {
1398 case IOP2_BPcc: 1399 case IOP2_BPcc:
1399 case IOP2_Bicc: 1400 case IOP2_Bicc:
1400 case IOP2_FBPfcc: 1401 case IOP2_FBPfcc:
1401 case IOP2_FBfcc: 1402 case IOP2_FBfcc:
1402 case IOP2_CBccc: 1403 case IOP2_CBccc:
1403 return insn.i_branch.i_cond == Icc_A; 1404 return insn.i_branch.i_cond == Icc_A;
1404 1405
1405 default: 1406 default:
1406 return FALSE; 1407 return FALSE;
1407 } 1408 }
1408} 1409}
1409 1410
1410 1411
1411bool 1412bool
1412db_inst_return(int inst) 1413db_inst_return(int inst)
1413{ 1414{
1414 return (inst == I_JMPLri(I_G0, I_O7, 8) || /* ret */ 1415 return (inst == I_JMPLri(I_G0, I_O7, 8) || /* ret */
1415 inst == I_JMPLri(I_G0, I_I7, 8)); /* retl */ 1416 inst == I_JMPLri(I_G0, I_I7, 8)); /* retl */
1416} 1417}
1417 1418
1418bool 1419bool
1419db_inst_trap_return(int inst) 1420db_inst_trap_return(int inst)
1420{ 1421{
1421 union instr insn; 1422 union instr insn;
1422 1423
1423 insn.i_int = inst; 1424 insn.i_int = inst;
1424 1425
1425 return (insn.i_any.i_op == IOP_reg && 1426 return (insn.i_any.i_op == IOP_reg &&
1426 insn.i_op3.i_op3 == IOP3_RETT); 1427 insn.i_op3.i_op3 == IOP3_RETT);
1427} 1428}
1428 1429
1429 1430
1430int 1431int
1431db_inst_load(int inst) 1432db_inst_load(int inst)
1432{ 1433{
1433 union instr insn; 1434 union instr insn;
1434 1435
1435 insn.i_int = inst; 1436 insn.i_int = inst;
1436 1437
1437 if (insn.i_any.i_op != IOP_mem) 1438 if (insn.i_any.i_op != IOP_mem)
1438 return 0; 1439 return 0;
1439 1440
1440 switch (insn.i_op3.i_op3) { 1441 switch (insn.i_op3.i_op3) {
1441 case IOP3_LD: 1442 case IOP3_LD:
1442 case IOP3_LDUB: 1443 case IOP3_LDUB:
1443 case IOP3_LDUH: 1444 case IOP3_LDUH:
1444 case IOP3_LDD: 1445 case IOP3_LDD:
1445 case IOP3_LDSB: 1446 case IOP3_LDSB:
1446 case IOP3_LDSH: 1447 case IOP3_LDSH:
1447 case IOP3_LDSTUB: 1448 case IOP3_LDSTUB:
1448 case IOP3_SWAP: 1449 case IOP3_SWAP:
1449 case IOP3_LDA: 1450 case IOP3_LDA:
1450 case IOP3_LDUBA: 1451 case IOP3_LDUBA:
1451 case IOP3_LDUHA: 1452 case IOP3_LDUHA:
1452 case IOP3_LDDA: 1453 case IOP3_LDDA:
1453 case IOP3_LDSBA: 1454 case IOP3_LDSBA:
1454 case IOP3_LDSHA: 1455 case IOP3_LDSHA:
1455 case IOP3_LDSTUBA: 1456 case IOP3_LDSTUBA:
1456 case IOP3_SWAPA: 1457 case IOP3_SWAPA:
1457 case IOP3_LDF: 1458 case IOP3_LDF:
1458 case IOP3_LDFSR: 1459 case IOP3_LDFSR:
1459 case IOP3_LDDF: 1460 case IOP3_LDDF:
1460 case IOP3_LFC: 1461 case IOP3_LFC:
1461 case IOP3_LDCSR: 1462 case IOP3_LDCSR:
1462 case IOP3_LDDC: 1463 case IOP3_LDDC:
1463 return 1; 1464 return 1;
1464 1465
1465 default: 1466 default:
1466 return 0; 1467 return 0;
1467 } 1468 }
1468} 1469}
1469 1470
1470int 1471int
1471db_inst_store(int inst) 1472db_inst_store(int inst)
1472{ 1473{
1473 union instr insn; 1474 union instr insn;
1474 1475
1475 insn.i_int = inst; 1476 insn.i_int = inst;
1476 1477
1477 if (insn.i_any.i_op != IOP_mem) 1478 if (insn.i_any.i_op != IOP_mem)
1478 return 0; 1479 return 0;
1479 1480
1480 switch (insn.i_op3.i_op3) { 1481 switch (insn.i_op3.i_op3) {
1481 case IOP3_ST: 1482 case IOP3_ST:
1482 case IOP3_STB: 1483 case IOP3_STB:
1483 case IOP3_STH: 1484 case IOP3_STH:
1484 case IOP3_STD: 1485 case IOP3_STD:
1485 case IOP3_LDSTUB: 1486 case IOP3_LDSTUB:
1486 case IOP3_SWAP: 1487 case IOP3_SWAP:
1487 case IOP3_STA: 1488 case IOP3_STA:
1488 case IOP3_STBA: 1489 case IOP3_STBA:
1489 case IOP3_STHA: 1490 case IOP3_STHA:
1490 case IOP3_STDA: 1491 case IOP3_STDA:
1491 case IOP3_LDSTUBA: 1492 case IOP3_LDSTUBA:
1492 case IOP3_SWAPA: 1493 case IOP3_SWAPA:
1493 case IOP3_STF: 1494 case IOP3_STF:
1494 case IOP3_STFSR: 1495 case IOP3_STFSR:
1495 case IOP3_STDFQ: 1496 case IOP3_STDFQ:
1496 case IOP3_STDF: 1497 case IOP3_STDF:
1497 case IOP3_STC: 1498 case IOP3_STC:
1498 case IOP3_STCSR: 1499 case IOP3_STCSR:
1499 case IOP3_STDCQ: 1500 case IOP3_STDCQ:
1500 case IOP3_STDC: 1501 case IOP3_STDC:
1501 return 1; 1502 return 1;
1502 1503
1503 default: 1504 default:
1504 return 0; 1505 return 0;
1505 } 1506 }
1506} 1507}