]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/blackfin/lib/kgdb.c
Make sure that argv[] argument pointers are not modified.
[karo-tx-uboot.git] / arch / blackfin / lib / kgdb.c
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
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
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
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  */
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  */
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
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
420 void kgdb_breakpoint(int argc, char * const argv[])
421 {
422         asm volatile ("excpt 0x1\n");
423 }