summaryrefslogtreecommitdiff
path: root/sys/arch/mvme88k/include/db_machdep.h
blob: 1ae049ebddf8dc1f9988d09cc9305be429cf3443 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*	$OpenBSD: db_machdep.h,v 1.21 2002/03/14 03:15:57 millert Exp $ */
/*
 * Mach Operating System
 * Copyright (c) 1993-1991 Carnegie Mellon University
 * Copyright (c) 1991 OMRON Corporation
 * All Rights Reserved.
 *
 * Permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie the
 * rights to redistribute these changes.
 */
/*
 * HISTORY
 */

/*
 * Machine-dependent defined for the new kernel debugger
 */

#ifndef  _M88K_DB_MACHDEP_H_
#define  _M88K_DB_MACHDEP_H_

/* trap numbers used by ddb */
#define	DDB_ENTRY_BKPT_NO	130
#define	DDB_ENTRY_TRACE_NO	131
#define DDB_ENTRY_TRAP_NO	132

#ifndef	_LOCORE

#include <machine/pcb.h>	/* m88100_saved_state */
#include <machine/psl.h>
#include <machine/trap.h>

#include <uvm/uvm_param.h>

/* 
 * This is a hack so that mc88100 can use software single step
 * and mc88110 can use the wonderful hardware single step 
 * feature. XXX smurph
 */
#define INTERNAL_SSTEP		/* Use local Single Step routines */

#define BKPT_SIZE	(4)	/* number of bytes in bkpt inst. */
#define BKPT_INST	(0xF000D000 | DDB_ENTRY_BKPT_NO) /* tb0, 0,r0, vector 130 */
#define BKPT_SET(inst)	(BKPT_INST)

/* Entry trap for the debugger - used for inline assembly breaks*/
#define ENTRY_ASM       	"tb0 0, r0, 132"

typedef	vm_offset_t		db_addr_t;
typedef	int			db_expr_t;
typedef	struct m88100_saved_state db_regs_t;
extern db_regs_t	ddb_regs;	/* register state */
#define	DDB_REGS	(&ddb_regs)

/*
 * the low two bits of sxip, snip, sfip have valid bits
 * in them that need to masked to get the correct addresses
 */

#define m88k_pc(regs) \
({ \
    int ret; \
 \
    if (cputyp == CPU_88110) \
	ret = regs->exip & ~3; \
    else if (regs->sxip & 2) /* is valid */ \
	ret = regs->sxip & ~3; \
    else if (regs->snip & 2) \
	ret = regs->snip & ~3; \
    else if (regs->sfip & 2) \
	ret = regs->sfip & ~3; \
    /* we are in trouble - none of the program counters is valid */ \
    ret;  \
})

/*
 * This is an actual function due to the fact that the sxip
 * or snip could be nooped out due to a jmp or rte
 */
#define PC_REGS(regs) cputyp == CPU_88110 ? (regs->exip & ~3) :\
	((regs->sxip & 2) ?  regs->sxip & ~3 : \
	(regs->snip & 2 ? regs->snip & ~3 : regs->sfip & ~3))
#define l_PC_REGS(regs) cputyp == CPU_88110 ? (regs->exip & ~3) :\
	((regs->sxip & 2) ?  regs->sxip : \
	(regs->snip & 2 ? regs->snip : regs->sfip ))

#define pC_REGS(regs) cputyp == CPU_88110 ? (regs->exip & ~3) :\
	(regs->sxip & 2) ? regs->sxip : (regs->snip & 2 ? \
				regs->snip : regs->sfip)
extern int db_noisy;
#define NOISY(x) if (db_noisy) x
#define NOISY2(x) if (db_noisy >= 2) x
#define NOISY3(x) if (db_noisy >= 3) x

extern int quiet_db_read_bytes;

/* These versions are not constantly doing SPL */
/*#define	cnmaygetc	db_getc*/
/*#define	cngetc		db_getc*/
/*#define	cnputc		db_putc*/

unsigned inst_load(unsigned);
unsigned inst_store(unsigned);
boolean_t inst_branch(unsigned);
db_addr_t next_instr_address(db_addr_t, unsigned);
db_addr_t branch_taken(u_int, db_addr_t, db_expr_t (*)(db_regs_t *, int),
		       db_regs_t *);
int ddb_break_trap(int type, db_regs_t *eframe);
int ddb_entry_trap(int level, db_regs_t *eframe);

/* breakpoint/watchpoint foo */
#define IS_BREAKPOINT_TRAP(type,code) ((type)==T_KDB_BREAK)
#if defined(T_WATCHPOINT)
#define IS_WATCHPOINT_TRAP(type,code) ((type)==T_KDB_WATCH)
#else
#define IS_WATCHPOINT_TRAP(type,code) 0
#endif /* T_WATCHPOINT */

/* we don't want coff support */
#define DB_NO_COFF 1

#ifdef INTERNAL_SSTEP
extern register_t getreg_val(db_regs_t *, int);
void db_set_single_step(register db_regs_t *);
void db_clear_single_step(register db_regs_t *);
#else
/* need software single step */
#define SOFTWARE_SSTEP 1 /* we need this for mc88100 */
#endif 

/*
 * Debugger can get to any address space
 */

#define DB_ACCESS_LEVEL DB_ACCESS_ANY

#define DB_VALID_KERN_ADDR(addr) (!badaddr((void *)(addr), 1))
#define DB_VALID_ADDRESS(addr,user) \
  (user ? db_check_user_addr(addr) : DB_VALID_KERN_ADDR(addr))

/* instruction type checking - others are implemented in db_sstep.c */

#define inst_trap_return(ins)  ((ins) == 0xf400fc00U)

/* don't need to load symbols */
#define DB_SYMBOLS_PRELOADED 1

/* machine specific commands have been added to ddb */
#define DB_MACHINE_COMMANDS 1
/* inst_return(ins) - is the instruction a function call return.
 * Not mutually exclusive with inst_branch. Should be a jmp r1. */
#define inst_return(I) (((I)&0xfffffbffU) == 0xf400c001U ? TRUE : FALSE)

#ifdef __GNUC__
/*
 * inst_call - function call predicate: is the instruction a function call.
 * Could be either bsr or jsr
 */
#define inst_call(I) ({ unsigned i = (I); \
	((((i) & 0xf8000000U) == 0xc8000000U || /*bsr*/ \
          ((i) & 0xfffffbe0U) == 0xf400c800U)   /*jsr*/ \
	? TRUE : FALSE) \
;})

/*
 * This routine should return true for instructions that result in unconditonal
 * transfers of the flow of control. (Unconditional Jumps, subroutine calls,
 * subroutine returns, etc).
 *
 *  Trap and return from trap  should not  be listed here.
 */
#define inst_unconditional_flow_transfer(I) ({ unsigned i = (I); \
    ((((i) & 0xf0000000U) == 0xc0000000U || /* br, bsr */ \
      ((i) & 0xfffff3e0U) == 0xf400c000U)   /* jmp, jsr */ \
     ? TRUE: FALSE) \
;})

/* Return true if the instruction has a delay slot.  */
#define db_branch_is_delayed(I)	inst_delayed(I)

#endif	/* __GNUC__ */

#define	db_printf_enter	db_printing

int m88k_print_instruction(unsigned iadr, long inst);

#endif	/* _LOCORE */

#endif	/* _M88K_DB_MACHDEP_H_ */