]>
Commit | Line | Data |
---|---|---|
1dda0b1f WD |
1 | /* |
2 | * Bedbug Functions specific to the MPC603e core | |
3 | */ | |
4 | ||
5 | #include <common.h> | |
6 | #include <command.h> | |
7 | #include <linux/ctype.h> | |
8bde7f77 | 8 | #include <bedbug/type.h> |
1dda0b1f WD |
9 | #include <bedbug/bedbug.h> |
10 | #include <bedbug/regs.h> | |
11 | #include <bedbug/ppc.h> | |
12 | ||
4431283c | 13 | #if defined(CONFIG_CMD_BEDBUG) \ |
f48070fe | 14 | && (defined(CONFIG_MPC824X) || defined(CONFIG_MPC8260)) |
1dda0b1f WD |
15 | |
16 | #define MAX_BREAK_POINTS 1 | |
17 | ||
18 | extern CPU_DEBUG_CTX bug_ctx; | |
19 | ||
20 | void bedbug603e_init __P((void)); | |
21 | void bedbug603e_do_break __P((cmd_tbl_t*,int,int,char*[])); | |
22 | void bedbug603e_break_isr __P((struct pt_regs*)); | |
23 | int bedbug603e_find_empty __P((void)); | |
24 | int bedbug603e_set __P((int,unsigned long)); | |
25 | int bedbug603e_clear __P((int)); | |
26 | ||
27 | \f | |
28 | /* ====================================================================== | |
29 | * Initialize the global bug_ctx structure for the processor. Clear all | |
30 | * of the breakpoints. | |
31 | * ====================================================================== */ | |
32 | ||
33 | void bedbug603e_init( void ) | |
34 | { | |
35 | int i; | |
36 | /* -------------------------------------------------- */ | |
37 | ||
38 | bug_ctx.hw_debug_enabled = 0; | |
39 | bug_ctx.stopped = 0; | |
40 | bug_ctx.current_bp = 0; | |
41 | bug_ctx.regs = NULL; | |
42 | ||
43 | bug_ctx.do_break = bedbug603e_do_break; | |
44 | bug_ctx.break_isr = bedbug603e_break_isr; | |
45 | bug_ctx.find_empty = bedbug603e_find_empty; | |
46 | bug_ctx.set = bedbug603e_set; | |
47 | bug_ctx.clear = bedbug603e_clear; | |
48 | ||
49 | for( i = 1; i <= MAX_BREAK_POINTS; ++i ) | |
50 | (*bug_ctx.clear)( i ); | |
51 | ||
52 | puts ("BEDBUG:ready\n"); | |
53 | return; | |
54 | } /* bedbug_init_breakpoints */ | |
55 | ||
56 | ||
57 | \f | |
58 | /* ====================================================================== | |
59 | * Set/clear/show the hardware breakpoint for the 603e. The "off" | |
60 | * string will disable a specific breakpoint. The "show" string will | |
61 | * display the current breakpoints. Otherwise an address will set a | |
62 | * breakpoint at that address. Setting a breakpoint uses the CPU-specific | |
63 | * set routine which will assign a breakpoint number. | |
64 | * ====================================================================== */ | |
65 | ||
66 | void bedbug603e_do_break (cmd_tbl_t *cmdtp, int flag, int argc, | |
8bde7f77 | 67 | char *argv[]) |
1dda0b1f WD |
68 | { |
69 | long addr; /* Address to break at */ | |
70 | int which_bp; /* Breakpoint number */ | |
71 | /* -------------------------------------------------- */ | |
72 | ||
73 | if (argc < 2) | |
74 | { | |
62c3ae7c | 75 | cmd_usage(cmdtp); |
1dda0b1f WD |
76 | return; |
77 | } | |
78 | ||
79 | /* Turn off a breakpoint */ | |
80 | ||
81 | if( strcmp( argv[ 1 ], "off" ) == 0 ) | |
82 | { | |
83 | if( bug_ctx.hw_debug_enabled == 0 ) | |
84 | { | |
4b9206ed | 85 | puts ( "No breakpoints enabled\n" ); |
1dda0b1f WD |
86 | return; |
87 | } | |
88 | ||
89 | which_bp = simple_strtoul( argv[ 2 ], NULL, 10 ); | |
90 | ||
91 | if( bug_ctx.clear ) | |
92 | (*bug_ctx.clear)( which_bp ); | |
93 | ||
94 | printf( "Breakpoint %d removed\n", which_bp ); | |
95 | return; | |
96 | } | |
97 | ||
98 | /* Show a list of breakpoints */ | |
99 | ||
100 | if( strcmp( argv[ 1 ], "show" ) == 0 ) | |
101 | { | |
102 | for( which_bp = 1; which_bp <= MAX_BREAK_POINTS; ++which_bp ) | |
103 | { | |
104 | ||
105 | addr = GET_IABR(); | |
106 | ||
107 | printf( "Breakpoint [%d]: ", which_bp ); | |
108 | if( (addr & 0x00000002) == 0 ) | |
4b9206ed | 109 | puts ( "NOT SET\n" ); |
1dda0b1f WD |
110 | else |
111 | disppc( (unsigned char *)(addr & 0xFFFFFFFC), 0, 1, bedbug_puts, F_RADHEX ); | |
112 | } | |
113 | return; | |
114 | } | |
115 | ||
116 | /* Set a breakpoint at the address */ | |
117 | ||
118 | if(!(( isdigit( argv[ 1 ][ 0 ] )) || | |
8bde7f77 WD |
119 | (( argv[ 1 ][ 0 ] >= 'a' ) && ( argv[ 1 ][ 0 ] <= 'f' )) || |
120 | (( argv[ 1 ][ 0 ] >= 'A' ) && ( argv[ 1 ][ 0 ] <= 'F' )))) | |
1dda0b1f | 121 | { |
62c3ae7c | 122 | cmd_usage(cmdtp); |
1dda0b1f WD |
123 | return; |
124 | } | |
125 | ||
126 | addr = simple_strtoul( argv[ 1 ], NULL, 16 ); | |
127 | ||
128 | if(( bug_ctx.set ) && ( which_bp = (*bug_ctx.set)( 0, addr )) > 0 ) | |
129 | { | |
130 | printf( "Breakpoint [%d]: ", which_bp ); | |
131 | disppc( (unsigned char *)addr, 0, 1, bedbug_puts, F_RADHEX ); | |
132 | } | |
133 | ||
134 | return; | |
135 | } /* bedbug603e_do_break */ | |
136 | ||
137 | ||
138 | \f | |
139 | /* ====================================================================== | |
140 | * Handle a breakpoint. Enter a mini main loop. Stay in the loop until | |
141 | * the stopped flag in the debug context is cleared. | |
142 | * ====================================================================== */ | |
143 | ||
144 | void bedbug603e_break_isr( struct pt_regs *regs ) | |
145 | { | |
146 | unsigned long addr; /* Address stopped at */ | |
147 | /* -------------------------------------------------- */ | |
148 | ||
149 | bug_ctx.current_bp = 1; | |
150 | addr = GET_IABR() & 0xFFFFFFFC; | |
151 | ||
152 | bedbug_main_loop( addr, regs ); | |
153 | return; | |
154 | } /* bedbug603e_break_isr */ | |
155 | ||
156 | ||
157 | \f | |
158 | /* ====================================================================== | |
159 | * See if the hardware breakpoint is available. | |
160 | * ====================================================================== */ | |
161 | ||
162 | int bedbug603e_find_empty( void ) | |
163 | { | |
164 | /* -------------------------------------------------- */ | |
165 | ||
166 | if( (GET_IABR() && 0x00000002) == 0 ) | |
167 | return 1; | |
168 | ||
169 | return 0; | |
170 | } /* bedbug603e_find_empty */ | |
171 | ||
172 | ||
173 | \f | |
174 | /* ====================================================================== | |
175 | * Set a breakpoint. If 'which_bp' is zero then find an unused breakpoint | |
176 | * number, otherwise reassign the given breakpoint. If hardware debugging | |
177 | * is not enabled, then turn it on via the MSR and DBCR0. Set the break | |
178 | * address in the IABR register. | |
179 | * ====================================================================== */ | |
180 | ||
181 | int bedbug603e_set( int which_bp, unsigned long addr ) | |
182 | { | |
183 | /* -------------------------------------------------- */ | |
184 | ||
185 | if(( addr & 0x00000003 ) != 0 ) | |
186 | { | |
4b9206ed | 187 | puts ( "Breakpoints must be on a 32 bit boundary\n" ); |
1dda0b1f WD |
188 | return 0; |
189 | } | |
190 | ||
191 | /* Only look if which_bp == 0, else use which_bp */ | |
192 | if(( bug_ctx.find_empty ) && ( !which_bp ) && | |
193 | ( which_bp = (*bug_ctx.find_empty)()) == 0 ) | |
194 | { | |
4b9206ed | 195 | puts ( "All breakpoints in use\n" ); |
1dda0b1f WD |
196 | return 0; |
197 | } | |
198 | ||
199 | if( which_bp < 1 || which_bp > MAX_BREAK_POINTS ) | |
200 | { | |
201 | printf( "Invalid break point # %d\n", which_bp ); | |
202 | return 0; | |
203 | } | |
204 | ||
205 | if( ! bug_ctx.hw_debug_enabled ) | |
206 | { | |
207 | bug_ctx.hw_debug_enabled = 1; | |
208 | } | |
209 | ||
210 | SET_IABR( addr | 0x00000002 ); | |
211 | ||
212 | return which_bp; | |
213 | } /* bedbug603e_set */ | |
214 | ||
215 | ||
216 | \f | |
217 | /* ====================================================================== | |
218 | * Disable a specific breakoint by setting the IABR register to zero. | |
219 | * ====================================================================== */ | |
220 | ||
221 | int bedbug603e_clear( int which_bp ) | |
222 | { | |
223 | /* -------------------------------------------------- */ | |
224 | ||
225 | if( which_bp < 1 || which_bp > MAX_BREAK_POINTS ) | |
226 | { | |
227 | printf( "Invalid break point # (%d)\n", which_bp ); | |
228 | return -1; | |
229 | } | |
230 | ||
231 | SET_IABR( 0 ); | |
232 | ||
233 | return 0; | |
234 | } /* bedbug603e_clear */ | |
235 | ||
236 | ||
237 | /* ====================================================================== */ | |
238 | #endif |