1 /* $OpenBSD: db_machdep.c,v 1.2 1998/09/15 10:50:13 pefo Exp $ */
4 * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed under OpenBSD by
17 * Per Fogelstrom, Opsycon AB, Sweden.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * JNPR: db_interface.c,v 1.6.2.1 2007/08/29 12:24:49 girish
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/systm.h>
45 #include <vm/vm_object.h>
46 #include <vm/vm_page.h>
48 #include <vm/vm_map.h>
51 #include <sys/reboot.h>
53 #include <machine/cache.h>
54 #include <machine/db_machdep.h>
55 #include <machine/mips_opcode.h>
56 #include <machine/vmparam.h>
57 #include <machine/md_var.h>
58 #define NO_REG_DEFS 1 /* Prevent asm.h from including regdef.h */
59 #include <machine/asm.h>
60 #include <machine/setjmp.h>
63 #include <ddb/db_sym.h>
64 #include <ddb/db_access.h>
65 #include <ddb/db_output.h>
66 #include <ddb/db_variables.h>
69 static db_varfcn_t db_frame;
71 #define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x)
72 struct db_variable db_regs[] = {
73 { "at", DB_OFFSET(ast), db_frame },
74 { "v0", DB_OFFSET(v0), db_frame },
75 { "v1", DB_OFFSET(v1), db_frame },
76 { "a0", DB_OFFSET(a0), db_frame },
77 { "a1", DB_OFFSET(a1), db_frame },
78 { "a2", DB_OFFSET(a2), db_frame },
79 { "a3", DB_OFFSET(a3), db_frame },
80 { "t0", DB_OFFSET(t0), db_frame },
81 { "t1", DB_OFFSET(t1), db_frame },
82 { "t2", DB_OFFSET(t2), db_frame },
83 { "t3", DB_OFFSET(t3), db_frame },
84 { "t4", DB_OFFSET(t4), db_frame },
85 { "t5", DB_OFFSET(t5), db_frame },
86 { "t6", DB_OFFSET(t6), db_frame },
87 { "t7", DB_OFFSET(t7), db_frame },
88 { "s0", DB_OFFSET(s0), db_frame },
89 { "s1", DB_OFFSET(s1), db_frame },
90 { "s2", DB_OFFSET(s2), db_frame },
91 { "s3", DB_OFFSET(s3), db_frame },
92 { "s4", DB_OFFSET(s4), db_frame },
93 { "s5", DB_OFFSET(s5), db_frame },
94 { "s6", DB_OFFSET(s6), db_frame },
95 { "s7", DB_OFFSET(s7), db_frame },
96 { "t8", DB_OFFSET(t8), db_frame },
97 { "t9", DB_OFFSET(t9), db_frame },
98 { "k0", DB_OFFSET(k0), db_frame },
99 { "k1", DB_OFFSET(k1), db_frame },
100 { "gp", DB_OFFSET(gp), db_frame },
101 { "sp", DB_OFFSET(sp), db_frame },
102 { "s8", DB_OFFSET(s8), db_frame },
103 { "ra", DB_OFFSET(ra), db_frame },
104 { "sr", DB_OFFSET(sr), db_frame },
105 { "lo", DB_OFFSET(mullo), db_frame },
106 { "hi", DB_OFFSET(mulhi), db_frame },
107 { "bad", DB_OFFSET(badvaddr), db_frame },
108 { "cs", DB_OFFSET(cause), db_frame },
109 { "pc", DB_OFFSET(pc), db_frame },
111 struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]);
113 int (*do_db_log_stack_trace_cmd)(char *);
116 db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
120 if (kdb_frame == NULL)
123 reg = (register_t *)((uintptr_t)kdb_frame + (size_t)(intptr_t)vp->valuep);
124 if (op == DB_VAR_GET)
132 db_read_bytes(vm_offset_t addr, size_t size, char *data)
138 prev_jb = kdb_jmpbuf(jb);
142 * 'addr' could be a memory-mapped I/O address. Try to
143 * do atomic load/store in unit of size requested.
145 if ((size == 2 || size == 4 || size == 8) &&
146 ((addr & (size -1)) == 0) &&
147 (((vm_offset_t)data & (size -1)) == 0)) {
150 *(uint16_t *)data = *(uint16_t *)addr;
153 *(uint32_t *)data = *(uint32_t *)addr;
156 atomic_load_64((volatile u_int64_t *)addr,
169 (void)kdb_jmpbuf(prev_jb);
174 db_write_bytes(vm_offset_t addr, size_t size, char *data)
180 prev_jb = kdb_jmpbuf(jb);
185 * 'addr' could be a memory-mapped I/O address. Try to
186 * do atomic load/store in unit of size requested.
188 if ((size == 2 || size == 4 || size == 8) &&
189 ((addr & (size -1)) == 0) &&
190 (((vm_offset_t)data & (size -1)) == 0)) {
193 *(uint16_t *)addr = *(uint16_t *)data;
196 *(uint32_t *)addr = *(uint32_t *)data;
199 atomic_store_64((volatile u_int64_t *)addr,
212 mips_icache_sync_range((db_addr_t) addr, size);
213 mips_dcache_wbinv_range((db_addr_t) addr, size);
215 (void)kdb_jmpbuf(prev_jb);
220 * To do a single step ddb needs to know the next address
221 * that we will get to. It means that we need to find out
222 * both the address for a branch taken and for not taken, NOT! :-)
223 * MipsEmulateBranch will do the job to find out _exactly_ which
224 * address we will end up at so the 'dual bp' method is not
228 next_instr_address(db_addr_t pc, boolean_t bd)
232 next = (db_addr_t)MipsEmulateBranch(kdb_frame, pc, 0, 0);
238 * Decode instruction and figure out type.
241 db_inst_type(int ins)
247 switch ((int)inst.JType.op) {
249 switch ((int)inst.RType.func) {
261 switch ((int)inst.IType.rt) {
295 switch (inst.RType.rs) {
326 * Return the next pc if the given branch is taken.
327 * MachEmulateBranch() runs analysis for branch delay slot.
330 branch_taken(int inst, db_addr_t pc)
335 /* TBD: when is fsr set */
336 fpucsr = (curthread) ? curthread->td_pcb->pcb_regs.fsr : 0;
337 ra = (db_addr_t)MipsEmulateBranch(kdb_frame, pc, fpucsr, 0);