1 /*
2  * U-boot - architecture specific kgdb code
3  *
4  * Copyright 2009 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2 or later.
7  */
8 
9 #include <common.h>
10 #include <command.h>
11 
12 #include <kgdb.h>
13 #include <asm/processor.h>
14 #include <asm/mach-common/bits/core.h>
15 #include "kgdb.h"
16 #include <asm/deferred.h>
17 #include <asm/traps.h>
18 #include <asm/signal.h>
19 
kgdb_enter(struct pt_regs * regs,kgdb_data * kdp)20 void kgdb_enter(struct pt_regs *regs, kgdb_data *kdp)
21 {
22 	/* disable interrupts */
23 	disable_interrupts();
24 
25 	/* reply to host that an exception has occurred */
26 	kdp->sigval = kgdb_trap(regs);
27 
28 	/* send the PC and the Stack Pointer */
29 	kdp->nregs = 2;
30 	kdp->regs[0].num = BFIN_PC;
31 	kdp->regs[0].val = regs->pc;
32 
33 	kdp->regs[1].num = BFIN_SP;
34 	kdp->regs[1].val = (unsigned long)regs;
35 
36 }
37 
kgdb_exit(struct pt_regs * regs,kgdb_data * kdp)38 void kgdb_exit(struct pt_regs *regs, kgdb_data *kdp)
39 {
40 	if (kdp->extype & KGDBEXIT_WITHADDR)
41 		printf("KGDBEXIT_WITHADDR\n");
42 
43 	switch (kdp->extype & KGDBEXIT_TYPEMASK) {
44 	case KGDBEXIT_KILL:
45 		printf("KGDBEXIT_KILL:\n");
46 		break;
47 	case KGDBEXIT_CONTINUE:
48 		/* Make sure the supervisor single step bit is clear */
49 		regs->syscfg &= ~1;
50 		break;
51 	case KGDBEXIT_SINGLE:
52 		/* set the supervisor single step bit */
53 		regs->syscfg |= 1;
54 		break;
55 	default:
56 		printf("KGDBEXIT : %d\n", kdp->extype);
57 	}
58 
59 	/* enable interrupts */
60 	enable_interrupts();
61 }
62 
kgdb_trap(struct pt_regs * regs)63 int kgdb_trap(struct pt_regs *regs)
64 {
65 	/* ipend doesn't get filled in properly */
66 	switch (regs->seqstat & EXCAUSE) {
67 	case VEC_EXCPT01:
68 		return SIGTRAP;
69 	case VEC_EXCPT03:
70 		return SIGSEGV;
71 	case VEC_EXCPT02:
72 		return SIGTRAP;
73 	case VEC_EXCPT04 ... VEC_EXCPT15:
74 		return SIGILL;
75 	case VEC_STEP:
76 		return SIGTRAP;
77 	case VEC_OVFLOW:
78 		return SIGTRAP;
79 	case VEC_UNDEF_I:
80 		return SIGILL;
81 	case VEC_ILGAL_I:
82 		return SIGILL;
83 	case VEC_CPLB_VL:
84 		return SIGSEGV;
85 	case VEC_MISALI_D:
86 		return SIGBUS;
87 	case VEC_UNCOV:
88 		return SIGILL;
89 	case VEC_CPLB_MHIT:
90 		return SIGSEGV;
91 	case VEC_MISALI_I:
92 		return SIGBUS;
93 	case VEC_CPLB_I_VL:
94 		return SIGBUS;
95 	case VEC_CPLB_I_MHIT:
96 		return SIGSEGV;
97 	default:
98 		return SIGBUS;
99 	}
100 }
101 
102 /*
103  * getregs - gets the pt_regs, and gives them to kgdb's buffer
104  */
kgdb_getregs(struct pt_regs * regs,char * buf,int max)105 int kgdb_getregs(struct pt_regs *regs, char *buf, int max)
106 {
107 	unsigned long *gdb_regs = (unsigned long *)buf;
108 
109 	if (max < NUMREGBYTES)
110 		kgdb_error(KGDBERR_NOSPACE);
111 
112 	if ((unsigned long)gdb_regs & 3)
113 		kgdb_error(KGDBERR_ALIGNFAULT);
114 
115 	gdb_regs[BFIN_R0] = regs->r0;
116 	gdb_regs[BFIN_R1] = regs->r1;
117 	gdb_regs[BFIN_R2] = regs->r2;
118 	gdb_regs[BFIN_R3] = regs->r3;
119 	gdb_regs[BFIN_R4] = regs->r4;
120 	gdb_regs[BFIN_R5] = regs->r5;
121 	gdb_regs[BFIN_R6] = regs->r6;
122 	gdb_regs[BFIN_R7] = regs->r7;
123 	gdb_regs[BFIN_P0] = regs->p0;
124 	gdb_regs[BFIN_P1] = regs->p1;
125 	gdb_regs[BFIN_P2] = regs->p2;
126 	gdb_regs[BFIN_P3] = regs->p3;
127 	gdb_regs[BFIN_P4] = regs->p4;
128 	gdb_regs[BFIN_P5] = regs->p5;
129 	gdb_regs[BFIN_SP] = (unsigned long)regs;
130 	gdb_regs[BFIN_FP] = regs->fp;
131 	gdb_regs[BFIN_I0] = regs->i0;
132 	gdb_regs[BFIN_I1] = regs->i1;
133 	gdb_regs[BFIN_I2] = regs->i2;
134 	gdb_regs[BFIN_I3] = regs->i3;
135 	gdb_regs[BFIN_M0] = regs->m0;
136 	gdb_regs[BFIN_M1] = regs->m1;
137 	gdb_regs[BFIN_M2] = regs->m2;
138 	gdb_regs[BFIN_M3] = regs->m3;
139 	gdb_regs[BFIN_B0] = regs->b0;
140 	gdb_regs[BFIN_B1] = regs->b1;
141 	gdb_regs[BFIN_B2] = regs->b2;
142 	gdb_regs[BFIN_B3] = regs->b3;
143 	gdb_regs[BFIN_L0] = regs->l0;
144 	gdb_regs[BFIN_L1] = regs->l1;
145 	gdb_regs[BFIN_L2] = regs->l2;
146 	gdb_regs[BFIN_L3] = regs->l3;
147 	gdb_regs[BFIN_A0_DOT_X] = regs->a0x;
148 	gdb_regs[BFIN_A0_DOT_W] = regs->a0w;
149 	gdb_regs[BFIN_A1_DOT_X] = regs->a1x;
150 	gdb_regs[BFIN_A1_DOT_W] = regs->a1w;
151 	gdb_regs[BFIN_ASTAT] = regs->astat;
152 	gdb_regs[BFIN_RETS] = regs->rets;
153 	gdb_regs[BFIN_LC0] = regs->lc0;
154 	gdb_regs[BFIN_LT0] = regs->lt0;
155 	gdb_regs[BFIN_LB0] = regs->lb0;
156 	gdb_regs[BFIN_LC1] = regs->lc1;
157 	gdb_regs[BFIN_LT1] = regs->lt1;
158 	gdb_regs[BFIN_LB1] = regs->lb1;
159 	gdb_regs[BFIN_CYCLES] = 0;
160 	gdb_regs[BFIN_CYCLES2] = 0;
161 	gdb_regs[BFIN_USP] = regs->usp;
162 	gdb_regs[BFIN_SEQSTAT] = regs->seqstat;
163 	gdb_regs[BFIN_SYSCFG] = regs->syscfg;
164 	gdb_regs[BFIN_RETI] = regs->pc;
165 	gdb_regs[BFIN_RETX] = regs->retx;
166 	gdb_regs[BFIN_RETN] = regs->retn;
167 	gdb_regs[BFIN_RETE] = regs->rete;
168 	gdb_regs[BFIN_PC] = regs->pc;
169 	gdb_regs[BFIN_CC] = 0;
170 	gdb_regs[BFIN_EXTRA1] = 0;
171 	gdb_regs[BFIN_EXTRA2] = 0;
172 	gdb_regs[BFIN_EXTRA3] = 0;
173 	gdb_regs[BFIN_IPEND] = regs->ipend;
174 
175 	return NUMREGBYTES;
176 }
177 
178 /*
179  * putreg - put kgdb's reg (regno) into the pt_regs
180  */
kgdb_putreg(struct pt_regs * regs,int regno,char * buf,int length)181 void kgdb_putreg(struct pt_regs *regs, int regno, char *buf, int length)
182 {
183 	unsigned long *ptr = (unsigned long *)buf;
184 
185 	if (regno < 0 || regno > BFIN_NUM_REGS)
186 		kgdb_error(KGDBERR_BADPARAMS);
187 
188 	if (length < 4)
189 		kgdb_error(KGDBERR_NOSPACE);
190 
191 	if ((unsigned long)ptr & 3)
192 		kgdb_error(KGDBERR_ALIGNFAULT);
193 
194 	switch (regno) {
195 	case BFIN_R0:
196 		regs->r0 = *ptr;
197 		break;
198 	case BFIN_R1:
199 		regs->r1 = *ptr;
200 		break;
201 	case BFIN_R2:
202 		regs->r2 = *ptr;
203 		break;
204 	case BFIN_R3:
205 		regs->r3 = *ptr;
206 		break;
207 	case BFIN_R4:
208 		regs->r4 = *ptr;
209 		break;
210 	case BFIN_R5:
211 		regs->r5 = *ptr;
212 		break;
213 	case BFIN_R6:
214 		regs->r6 = *ptr;
215 		break;
216 	case BFIN_R7:
217 		regs->r7 = *ptr;
218 		break;
219 	case BFIN_P0:
220 		regs->p0 = *ptr;
221 		break;
222 	case BFIN_P1:
223 		regs->p1 = *ptr;
224 		break;
225 	case BFIN_P2:
226 		regs->p2 = *ptr;
227 		break;
228 	case BFIN_P3:
229 		regs->p3 = *ptr;
230 		break;
231 	case BFIN_P4:
232 		regs->p4 = *ptr;
233 		break;
234 	case BFIN_P5:
235 		regs->p5 = *ptr;
236 		break;
237 	case BFIN_SP:
238 		regs->reserved = *ptr;
239 		break;
240 	case BFIN_FP:
241 		regs->fp = *ptr;
242 		break;
243 	case BFIN_I0:
244 		regs->i0 = *ptr;
245 		break;
246 	case BFIN_I1:
247 		regs->i1 = *ptr;
248 		break;
249 	case BFIN_I2:
250 		regs->i2 = *ptr;
251 		break;
252 	case BFIN_I3:
253 		regs->i3 = *ptr;
254 		break;
255 	case BFIN_M0:
256 		regs->m0 = *ptr;
257 		break;
258 	case BFIN_M1:
259 		regs->m1 = *ptr;
260 		break;
261 	case BFIN_M2:
262 		regs->m2 = *ptr;
263 		break;
264 	case BFIN_M3:
265 		regs->m3 = *ptr;
266 		break;
267 	case BFIN_B0:
268 		regs->b0 = *ptr;
269 		break;
270 	case BFIN_B1:
271 		regs->b1 = *ptr;
272 		break;
273 	case BFIN_B2:
274 		regs->b2 = *ptr;
275 		break;
276 	case BFIN_B3:
277 		regs->b3 = *ptr;
278 		break;
279 	case BFIN_L0:
280 		regs->l0 = *ptr;
281 		break;
282 	case BFIN_L1:
283 		regs->l1 = *ptr;
284 		break;
285 	case BFIN_L2:
286 		regs->l2 = *ptr;
287 		break;
288 	case BFIN_L3:
289 		regs->l3 = *ptr;
290 		break;
291 	case BFIN_A0_DOT_X:
292 		regs->a0x = *ptr;
293 		break;
294 	case BFIN_A0_DOT_W:
295 		regs->a0w = *ptr;
296 		break;
297 	case BFIN_A1_DOT_X:
298 		regs->a1x = *ptr;
299 		break;
300 	case BFIN_A1_DOT_W:
301 		regs->a1w = *ptr;
302 		break;
303 	case BFIN_ASTAT:
304 		regs->astat = *ptr;
305 		break;
306 	case BFIN_RETS:
307 		regs->rets = *ptr;
308 		break;
309 	case BFIN_LC0:
310 		regs->lc0 = *ptr;
311 		break;
312 	case BFIN_LT0:
313 		regs->lt0 = *ptr;
314 		break;
315 	case BFIN_LB0:
316 		regs->lb0 = *ptr;
317 		break;
318 	case BFIN_LC1:
319 		regs->lc1 = *ptr;
320 		break;
321 	case BFIN_LT1:
322 		regs->lt1 = *ptr;
323 		break;
324 	case BFIN_LB1:
325 		regs->lb1 = *ptr;
326 		break;
327 /*
328   BFIN_CYCLES,
329   BFIN_CYCLES2,
330   BFIN_USP,
331   BFIN_SEQSTAT,
332   BFIN_SYSCFG,
333 */
334 	case BFIN_RETX:
335 		regs->retx = *ptr;
336 		break;
337 	case BFIN_RETN:
338 		regs->retn = *ptr;
339 		break;
340 	case BFIN_RETE:
341 		regs->rete = *ptr;
342 		break;
343 	case BFIN_PC:
344 		regs->pc = *ptr;
345 		break;
346 
347 	default:
348 		kgdb_error(KGDBERR_BADPARAMS);
349 	}
350 }
351 
kgdb_putregs(struct pt_regs * regs,char * buf,int length)352 void kgdb_putregs(struct pt_regs *regs, char *buf, int length)
353 {
354 	unsigned long *gdb_regs = (unsigned long *)buf;
355 
356 	if (length != BFIN_NUM_REGS)
357 		kgdb_error(KGDBERR_NOSPACE);
358 
359 	if ((unsigned long)gdb_regs & 3)
360 		kgdb_error(KGDBERR_ALIGNFAULT);
361 
362 	regs->r0 = gdb_regs[BFIN_R0];
363 	regs->r1 = gdb_regs[BFIN_R1];
364 	regs->r2 = gdb_regs[BFIN_R2];
365 	regs->r3 = gdb_regs[BFIN_R3];
366 	regs->r4 = gdb_regs[BFIN_R4];
367 	regs->r5 = gdb_regs[BFIN_R5];
368 	regs->r6 = gdb_regs[BFIN_R6];
369 	regs->r7 = gdb_regs[BFIN_R7];
370 	regs->p0 = gdb_regs[BFIN_P0];
371 	regs->p1 = gdb_regs[BFIN_P1];
372 	regs->p2 = gdb_regs[BFIN_P2];
373 	regs->p3 = gdb_regs[BFIN_P3];
374 	regs->p4 = gdb_regs[BFIN_P4];
375 	regs->p5 = gdb_regs[BFIN_P5];
376 	regs->fp = gdb_regs[BFIN_FP];
377 /*	regs->sp = gdb_regs[BFIN_ ]; */
378 	regs->i0 = gdb_regs[BFIN_I0];
379 	regs->i1 = gdb_regs[BFIN_I1];
380 	regs->i2 = gdb_regs[BFIN_I2];
381 	regs->i3 = gdb_regs[BFIN_I3];
382 	regs->m0 = gdb_regs[BFIN_M0];
383 	regs->m1 = gdb_regs[BFIN_M1];
384 	regs->m2 = gdb_regs[BFIN_M2];
385 	regs->m3 = gdb_regs[BFIN_M3];
386 	regs->b0 = gdb_regs[BFIN_B0];
387 	regs->b1 = gdb_regs[BFIN_B1];
388 	regs->b2 = gdb_regs[BFIN_B2];
389 	regs->b3 = gdb_regs[BFIN_B3];
390 	regs->l0 = gdb_regs[BFIN_L0];
391 	regs->l1 = gdb_regs[BFIN_L1];
392 	regs->l2 = gdb_regs[BFIN_L2];
393 	regs->l3 = gdb_regs[BFIN_L3];
394 	regs->a0x = gdb_regs[BFIN_A0_DOT_X];
395 	regs->a0w = gdb_regs[BFIN_A0_DOT_W];
396 	regs->a1x = gdb_regs[BFIN_A1_DOT_X];
397 	regs->a1w = gdb_regs[BFIN_A1_DOT_W];
398 	regs->rets = gdb_regs[BFIN_RETS];
399 	regs->lc0 = gdb_regs[BFIN_LC0];
400 	regs->lt0 = gdb_regs[BFIN_LT0];
401 	regs->lb0 = gdb_regs[BFIN_LB0];
402 	regs->lc1 = gdb_regs[BFIN_LC1];
403 	regs->lt1 = gdb_regs[BFIN_LT1];
404 	regs->lb1 = gdb_regs[BFIN_LB1];
405 	regs->usp = gdb_regs[BFIN_USP];
406 	regs->syscfg = gdb_regs[BFIN_SYSCFG];
407 	regs->retx = gdb_regs[BFIN_PC];
408 	regs->retn = gdb_regs[BFIN_RETN];
409 	regs->rete = gdb_regs[BFIN_RETE];
410 	regs->pc = gdb_regs[BFIN_PC];
411 
412 #if 0	/* can't change these */
413 	regs->astat = gdb_regs[BFIN_ASTAT];
414 	regs->seqstat = gdb_regs[BFIN_SEQSTAT];
415 	regs->ipend = gdb_regs[BFIN_IPEND];
416 #endif
417 
418 }
419 
kgdb_breakpoint(int argc,char * argv[])420 void kgdb_breakpoint(int argc, char *argv[])
421 {
422 	asm volatile ("excpt 0x1\n");
423 }
424