This source file includes following definitions.
- hex
- getpacket
- putpacket
- mem2hex
- hex2mem
- set_debug_traps
- fltr_set_mem_err
- set_mem_fault_trap
- computeSignal
- hexToInt
- handle_exception
- breakpoint
- adel
- show_gdbregs
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 #include <linux/string.h>
68 #include <linux/signal.h>
69 #include <linux/kernel.h>
70
71 #include <asm/asm.h>
72 #include <asm/mipsregs.h>
73 #include <asm/segment.h>
74 #include <asm/cachectl.h>
75 #include <asm/system.h>
76 #include <asm/gdb-stub.h>
77
78
79
80
81
82 extern int putDebugChar(char c);
83 extern char getDebugChar(void);
84 extern void fltr_set_mem_err(void);
85 extern void trap_low(void);
86
87
88
89
90 extern void breakpoint(void);
91 extern void breakinst(void);
92 extern void adel(void);
93
94
95
96
97
98 static void getpacket(char *buffer);
99 static void putpacket(char *buffer);
100 static void set_mem_fault_trap(int enable);
101 static int computeSignal(int tt);
102 static int hex(unsigned char ch);
103 static int hexToInt(char **ptr, int *intValue);
104 static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault);
105 void handle_exception(struct gdb_regs *regs);
106 static void show_gdbregs(struct gdb_regs *regs);
107
108
109
110
111
112 #define BUFMAX 2048
113
114 static char input_buffer[BUFMAX];
115 static char output_buffer[BUFMAX];
116 static int initialized = 0;
117 static const char hexchars[]="0123456789abcdef";
118
119
120
121
122
123 static int hex(unsigned char ch)
124 {
125 if (ch >= 'a' && ch <= 'f')
126 return ch-'a'+10;
127 if (ch >= '0' && ch <= '9')
128 return ch-'0';
129 if (ch >= 'A' && ch <= 'F')
130 return ch-'A'+10;
131 return -1;
132 }
133
134
135
136
137 static void getpacket(char *buffer)
138 {
139 unsigned char checksum;
140 unsigned char xmitcsum;
141 int i;
142 int count;
143 unsigned char ch;
144
145 do {
146
147
148
149
150 while ((ch = (getDebugChar() & 0x7f)) != '$') ;
151
152 checksum = 0;
153 xmitcsum = -1;
154 count = 0;
155
156
157
158
159 while (count < BUFMAX) {
160 ch = getDebugChar() & 0x7f;
161 if (ch == '#')
162 break;
163 checksum = checksum + ch;
164 buffer[count] = ch;
165 count = count + 1;
166 }
167
168 if (count >= BUFMAX)
169 continue;
170
171 buffer[count] = 0;
172
173 if (ch == '#') {
174 xmitcsum = hex(getDebugChar() & 0x7f) << 4;
175 xmitcsum |= hex(getDebugChar() & 0x7f);
176
177 if (checksum != xmitcsum)
178 putDebugChar('-');
179 else {
180 putDebugChar('+');
181
182
183
184
185
186 if (buffer[2] == ':') {
187 putDebugChar(buffer[0]);
188 putDebugChar(buffer[1]);
189
190
191
192
193 count = strlen(buffer);
194 for (i=3; i <= count; i++)
195 buffer[i-3] = buffer[i];
196 }
197 }
198 }
199 }
200 while (checksum != xmitcsum);
201 }
202
203
204
205
206 static void putpacket(char *buffer)
207 {
208 unsigned char checksum;
209 int count;
210 unsigned char ch;
211
212
213
214
215
216 do {
217 putDebugChar('$');
218 checksum = 0;
219 count = 0;
220
221 while ((ch = buffer[count]) != 0) {
222 if (!(putDebugChar(ch)))
223 return;
224 checksum += ch;
225 count += 1;
226 }
227
228 putDebugChar('#');
229 putDebugChar(hexchars[checksum >> 4]);
230 putDebugChar(hexchars[checksum & 0xf]);
231
232 }
233 while ((getDebugChar() & 0x7f) != '+');
234 }
235
236
237
238
239
240
241 static volatile int mem_err = 0;
242
243
244
245
246
247
248
249
250 static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
251 {
252 unsigned char ch;
253
254
255
256 while (count-- > 0) {
257 ch = *(mem++);
258 if (mem_err)
259 return 0;
260 *buf++ = hexchars[ch >> 4];
261 *buf++ = hexchars[ch & 0xf];
262 }
263
264 *buf = 0;
265
266
267
268 return buf;
269 }
270
271
272
273
274
275 static char *hex2mem(char *buf, char *mem, int count, int may_fault)
276 {
277 int i;
278 unsigned char ch;
279
280
281
282 for (i=0; i<count; i++)
283 {
284 ch = hex(*buf++) << 4;
285 ch |= hex(*buf++);
286 *(mem++) = ch;
287 if (mem_err)
288 return 0;
289 }
290
291
292
293 return mem;
294 }
295
296
297
298
299
300
301 static struct hard_trap_info
302 {
303 unsigned char tt;
304 unsigned char signo;
305 } hard_trap_info[] = {
306 { 4, SIGBUS },
307 { 5, SIGBUS },
308 { 6, SIGBUS },
309 { 7, SIGBUS },
310 { 9, SIGTRAP },
311 { 10, SIGILL },
312
313 { 12, SIGFPE },
314 { 13, SIGTRAP },
315 { 14, SIGSEGV },
316 { 15, SIGFPE },
317 { 23, SIGSEGV },
318 { 31, SIGSEGV },
319 { 0, 0}
320 };
321
322
323
324
325
326 void set_debug_traps(void)
327 {
328 struct hard_trap_info *ht;
329
330 for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
331 set_except_vector(ht->tt, trap_low);
332
333
334
335
336
337
338 putDebugChar ('+');
339 initialized = 1;
340
341 breakpoint();
342 }
343
344
345
346
347
348
349
350
351 extern void fltr_set_mem_err(void)
352 {
353
354 }
355
356
357 static void set_mem_fault_trap(int enable)
358 {
359 mem_err = 0;
360
361 #if 0
362 if (enable)
363 exceptionHandler(9, fltr_set_mem_err);
364 else
365 exceptionHandler(9, trap_low);
366 #endif
367 }
368
369
370
371
372 static int computeSignal(int tt)
373 {
374 struct hard_trap_info *ht;
375
376 for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
377 if (ht->tt == tt)
378 return ht->signo;
379
380 return SIGHUP;
381 }
382
383
384
385
386
387 static int hexToInt(char **ptr, int *intValue)
388 {
389 int numChars = 0;
390 int hexValue;
391
392 *intValue = 0;
393
394 while (**ptr)
395 {
396 hexValue = hex(**ptr);
397 if (hexValue < 0)
398 break;
399
400 *intValue = (*intValue << 4) | hexValue;
401 numChars ++;
402
403 (*ptr)++;
404 }
405
406 return (numChars);
407 }
408
409
410
411
412
413
414 void handle_exception (struct gdb_regs *regs)
415 {
416 int trap;
417 int sigval;
418 int addr;
419 int length;
420 char *ptr;
421 unsigned long *stack;
422
423 #if 0
424 printk("in handle_exception()\n");
425 show_gdbregs(regs);
426 #endif
427
428
429
430
431
432
433
434
435 trap = (regs->cp0_cause & 0x7c) >> 2;
436
437 if (trap == 11) {
438 if (((regs->cp0_cause >> CAUSEB_CE) & 3) == 1) {
439 regs->cp0_status |= ST0_CU1;
440 return;
441 }
442 }
443
444
445
446
447 if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst)
448 regs->cp0_epc += 4;
449
450 stack = (long *)regs->reg29;
451 sigval = computeSignal(trap);
452
453
454
455
456 ptr = output_buffer;
457
458
459
460
461 *ptr++ = 'T';
462 *ptr++ = hexchars[sigval >> 4];
463 *ptr++ = hexchars[sigval & 0xf];
464
465
466
467
468 *ptr++ = hexchars[REG_EPC >> 4];
469 *ptr++ = hexchars[REG_EPC & 0xf];
470 *ptr++ = ':';
471 ptr = mem2hex((char *)®s->cp0_epc, ptr, 4, 0);
472 *ptr++ = ';';
473
474
475
476
477 *ptr++ = hexchars[REG_FP >> 4];
478 *ptr++ = hexchars[REG_FP & 0xf];
479 *ptr++ = ':';
480 ptr = mem2hex((char *)®s->reg30, ptr, 4, 0);
481 *ptr++ = ';';
482
483
484
485
486 *ptr++ = hexchars[REG_SP >> 4];
487 *ptr++ = hexchars[REG_SP & 0xf];
488 *ptr++ = ':';
489 ptr = mem2hex((char *)®s->reg29, ptr, 4, 0);
490 *ptr++ = ';';
491
492 *ptr++ = 0;
493 putpacket(output_buffer);
494
495
496
497
498 while (1) {
499 output_buffer[0] = 0;
500 getpacket(input_buffer);
501
502 switch (input_buffer[0])
503 {
504 case '?':
505 output_buffer[0] = 'S';
506 output_buffer[1] = hexchars[sigval >> 4];
507 output_buffer[2] = hexchars[sigval & 0xf];
508 output_buffer[3] = 0;
509 break;
510
511 case 'd':
512
513 break;
514
515
516
517
518 case 'g':
519 ptr = output_buffer;
520 ptr = mem2hex((char *)®s->reg0, ptr, 32*4, 0);
521 ptr = mem2hex((char *)®s->cp0_status, ptr, 6*4, 0);
522 ptr = mem2hex((char *)®s->fpr0, ptr, 32*4, 0);
523 ptr = mem2hex((char *)®s->cp1_fsr, ptr, 2*4, 0);
524 ptr = mem2hex((char *)®s->frame_ptr, ptr, 2*4, 0);
525 ptr = mem2hex((char *)®s->cp0_index, ptr, 16*4, 0);
526 break;
527
528
529
530
531
532 case 'G':
533 {
534 #if 0
535 unsigned long *newsp, psr;
536
537 ptr = &input_buffer[1];
538 hex2mem(ptr, (char *)registers, 16 * 4, 0);
539
540
541
542
543
544
545 newsp = (unsigned long *)registers[SP];
546 if (sp != newsp)
547 sp = memcpy(newsp, sp, 16 * 4);
548
549 #endif
550 strcpy(output_buffer,"OK");
551 }
552 break;
553
554
555
556
557 case 'm':
558 ptr = &input_buffer[1];
559
560 if (hexToInt(&ptr, &addr)
561 && *ptr++ == ','
562 && hexToInt(&ptr, &length)) {
563 if (mem2hex((char *)addr, output_buffer, length, 1))
564 break;
565 strcpy (output_buffer, "E03");
566 } else
567 strcpy(output_buffer,"E01");
568 break;
569
570
571
572
573 case 'M':
574 ptr = &input_buffer[1];
575
576 if (hexToInt(&ptr, &addr)
577 && *ptr++ == ','
578 && hexToInt(&ptr, &length)
579 && *ptr++ == ':') {
580 if (hex2mem(ptr, (char *)addr, length, 1))
581 strcpy(output_buffer, "OK");
582 else
583 strcpy(output_buffer, "E03");
584 }
585 else
586 strcpy(output_buffer, "E02");
587 break;
588
589
590
591
592 case 'c':
593
594
595 ptr = &input_buffer[1];
596 if (hexToInt(&ptr, &addr))
597 regs->cp0_epc = addr;
598
599
600
601
602
603
604
605
606
607
608 sys_cacheflush((void *)KSEG0,KSEG1-KSEG0,BCACHE);
609 return;
610
611 break;
612
613
614
615
616
617 case 'k' :
618 break;
619
620
621
622
623
624 case 'r':
625 break;
626
627
628
629
630
631
632 case 's':
633 strcpy (output_buffer, "S01");
634 break;
635
636
637
638
639
640 case 'b':
641 {
642 #if 0
643 int baudrate;
644 extern void set_timer_3();
645
646 ptr = &input_buffer[1];
647 if (!hexToInt(&ptr, &baudrate))
648 {
649 strcpy(output_buffer,"B01");
650 break;
651 }
652
653
654
655 switch (baudrate)
656 {
657 case 38400:
658 baudrate = 16;
659 break;
660 case 19200:
661 baudrate = 33;
662 break;
663 case 9600:
664 baudrate = 65;
665 break;
666 default:
667 baudrate = 0;
668 strcpy(output_buffer,"B02");
669 goto x1;
670 }
671
672 if (baudrate) {
673 putpacket("OK");
674 set_timer_3(baudrate);
675 }
676 #endif
677 }
678 break;
679
680 }
681
682
683
684
685
686 putpacket(output_buffer);
687
688 }
689 }
690
691
692
693
694
695
696
697 void breakpoint(void)
698 {
699 if (!initialized)
700 return;
701
702 __asm__ __volatile__("
703 .globl breakinst
704 .set noreorder
705 nop
706 breakinst: break
707 nop
708 .set reorder
709 ");
710 }
711
712 void adel(void)
713 {
714 __asm__ __volatile__("
715 .globl adel
716 la $8,0x80000001
717 lw $9,0($8)
718 ");
719 }
720
721
722
723
724
725 void show_gdbregs(struct gdb_regs * regs)
726 {
727
728
729
730 printk("$0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
731 regs->reg0, regs->reg1, regs->reg2, regs->reg3,
732 regs->reg4, regs->reg5, regs->reg6, regs->reg7);
733 printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
734 regs->reg8, regs->reg9, regs->reg10, regs->reg11,
735 regs->reg12, regs->reg13, regs->reg14, regs->reg15);
736 printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
737 regs->reg16, regs->reg17, regs->reg18, regs->reg19,
738 regs->reg20, regs->reg21, regs->reg22, regs->reg23);
739 printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
740 regs->reg24, regs->reg25, regs->reg26, regs->reg27,
741 regs->reg28, regs->reg29, regs->reg30, regs->reg31);
742
743
744
745
746 printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\n",
747 regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
748 }