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#include <linux/string.h>
170#include <linux/signal.h>
171#include <linux/kernel.h>
172#include <linux/delay.h>
173#include <linux/linkage.h>
174#include <linux/reboot.h>
175
176#include <asm/setup.h>
177#include <asm/ptrace.h>
178
179#include <arch/svinto.h>
180#include <asm/irq.h>
181
182static int kgdb_started = 0;
183
184
185
186
187
188
189
190
191
192
193
194typedef
195struct register_image
196{
197
198 unsigned int r0;
199 unsigned int r1;
200 unsigned int r2;
201 unsigned int r3;
202 unsigned int r4;
203 unsigned int r5;
204 unsigned int r6;
205 unsigned int r7;
206 unsigned int r8;
207 unsigned int r9;
208 unsigned int r10;
209 unsigned int r11;
210 unsigned int r12;
211 unsigned int r13;
212 unsigned int sp;
213 unsigned int pc;
214
215 unsigned char p0;
216 unsigned char vr;
217
218 unsigned short p4;
219 unsigned short ccr;
220
221 unsigned int mof;
222
223 unsigned int p8;
224 unsigned int ibr;
225 unsigned int irp;
226 unsigned int srp;
227 unsigned int bar;
228 unsigned int dccr;
229 unsigned int brp;
230 unsigned int usp;
231} registers;
232
233
234int getDebugChar (void);
235
236
237void putDebugChar (int val);
238
239void enableDebugIRQ (void);
240
241
242
243
244void putDebugString (const unsigned char *str, int length);
245
246
247
248void handle_breakpoint (void);
249
250
251void handle_interrupt (void);
252
253
254void breakpoint (void);
255
256
257
258extern unsigned char executing_task;
259
260
261#define HEXCHARS_IN_THREAD_ID 16
262
263
264
265
266#define BUFMAX 512
267
268
269#define RUNLENMAX 64
270
271
272static char remcomInBuffer[BUFMAX];
273static char remcomOutBuffer[BUFMAX];
274
275
276enum error_type
277{
278 SUCCESS, E01, E02, E03, E04, E05, E06, E07
279};
280static char *error_message[] =
281{
282 "",
283 "E01 Set current or general thread - H[c,g] - internal error.",
284 "E02 Change register content - P - cannot change read-only register.",
285 "E03 Thread is not alive.",
286 "E04 The command is not supported - [s,C,S,!,R,d,r] - internal error.",
287 "E05 Change register content - P - the register is not implemented..",
288 "E06 Change memory content - M - internal error.",
289 "E07 Change register content - P - the register is not stored on the stack"
290};
291
292
293
294
295
296
297
298
299
300enum register_name
301{
302 R0, R1, R2, R3,
303 R4, R5, R6, R7,
304 R8, R9, R10, R11,
305 R12, R13, SP, PC,
306 P0, VR, P2, P3,
307 P4, CCR, P6, MOF,
308 P8, IBR, IRP, SRP,
309 BAR, DCCR, BRP, USP
310};
311
312
313
314static int register_size[] =
315{
316 4, 4, 4, 4,
317 4, 4, 4, 4,
318 4, 4, 4, 4,
319 4, 4, 4, 4,
320 1, 1, 0, 0,
321 2, 2, 0, 4,
322 4, 4, 4, 4,
323 4, 4, 4, 4
324};
325
326
327
328registers cris_reg;
329
330
331
332
333static int consistency_status = SUCCESS;
334
335
336
337
338
339
340
341
342
343
344
345
346#define INTERNAL_STACK_SIZE 1024
347char internal_stack[INTERNAL_STACK_SIZE];
348
349
350
351
352
353
354static unsigned char is_dyn_brkp = 0;
355
356
357
358
359
360static char*
361gdb_cris_strcpy (char *s1, const char *s2)
362{
363 char *s = s1;
364
365 for (s = s1; (*s++ = *s2++) != '\0'; )
366 ;
367 return (s1);
368}
369
370
371static int
372gdb_cris_strlen (const char *s)
373{
374 const char *sc;
375
376 for (sc = s; *sc != '\0'; sc++)
377 ;
378 return (sc - s);
379}
380
381
382static void*
383gdb_cris_memchr (const void *s, int c, int n)
384{
385 const unsigned char uc = c;
386 const unsigned char *su;
387
388 for (su = s; 0 < n; ++su, --n)
389 if (*su == uc)
390 return ((void *)su);
391 return (NULL);
392}
393
394
395
396static int
397gdb_cris_strtol (const char *s, char **endptr, int base)
398{
399 char *s1;
400 char *sd;
401 int x = 0;
402
403 for (s1 = (char*)s; (sd = gdb_cris_memchr(hex_asc, *s1, base)) != NULL; ++s1)
404 x = x * base + (sd - hex_asc);
405
406 if (endptr)
407 {
408
409 *endptr = s1;
410 }
411
412 return x;
413}
414
415
416
417static int
418hex (char ch)
419{
420 if ((ch >= 'a') && (ch <= 'f'))
421 return (ch - 'a' + 10);
422 if ((ch >= '0') && (ch <= '9'))
423 return (ch - '0');
424 if ((ch >= 'A') && (ch <= 'F'))
425 return (ch - 'A' + 10);
426 return (-1);
427}
428
429
430
431
432
433static char *
434mem2hex(char *buf, unsigned char *mem, int count)
435{
436 int i;
437 int ch;
438
439 if (mem == NULL) {
440
441 for (i = 0; i < count; i++) {
442 *buf++ = '0';
443 *buf++ = '0';
444 }
445 } else {
446
447 for (i = 0; i < count; i++) {
448 ch = *mem++;
449 buf = hex_byte_pack(buf, ch);
450 }
451 }
452
453
454 *buf = '\0';
455 return (buf);
456}
457
458
459
460
461static unsigned char*
462hex2mem (unsigned char *mem, char *buf, int count)
463{
464 int i;
465 unsigned char ch;
466 for (i = 0; i < count; i++) {
467 ch = hex (*buf++) << 4;
468 ch = ch + hex (*buf++);
469 *mem++ = ch;
470 }
471 return (mem);
472}
473
474
475
476
477
478static unsigned char*
479bin2mem (unsigned char *mem, unsigned char *buf, int count)
480{
481 int i;
482 unsigned char *next;
483 for (i = 0; i < count; i++) {
484
485
486 if (*buf == 0x7d) {
487 next = buf + 1;
488 if (*next == 0x3 || *next == 0x4 || *next == 0x5D)
489 {
490 buf++;
491 *buf += 0x20;
492 }
493 }
494 *mem++ = *buf++;
495 }
496 return (mem);
497}
498
499
500
501static void
502getpacket (char *buffer)
503{
504 unsigned char checksum;
505 unsigned char xmitcsum;
506 int i;
507 int count;
508 char ch;
509 do {
510 while ((ch = getDebugChar ()) != '$')
511 ;
512 checksum = 0;
513 xmitcsum = -1;
514 count = 0;
515
516 while (count < BUFMAX - 1) {
517 ch = getDebugChar ();
518 if (ch == '#')
519 break;
520 checksum = checksum + ch;
521 buffer[count] = ch;
522 count = count + 1;
523 }
524 buffer[count] = '\0';
525
526 if (ch == '#') {
527 xmitcsum = hex (getDebugChar ()) << 4;
528 xmitcsum += hex (getDebugChar ());
529 if (checksum != xmitcsum) {
530
531 putDebugChar ('-');
532 }
533 else {
534
535 putDebugChar ('+');
536
537 if (buffer[2] == ':') {
538 putDebugChar (buffer[0]);
539 putDebugChar (buffer[1]);
540
541 count = gdb_cris_strlen (buffer);
542 for (i = 3; i <= count; i++)
543 buffer[i - 3] = buffer[i];
544 }
545 }
546 }
547 } while (checksum != xmitcsum);
548}
549
550
551
552static void
553putpacket(char *buffer)
554{
555 int checksum;
556 int runlen;
557 int encode;
558
559 do {
560 char *src = buffer;
561 putDebugChar ('$');
562 checksum = 0;
563 while (*src) {
564
565 putDebugChar (*src);
566 checksum += *src;
567 runlen = 0;
568 while (runlen < RUNLENMAX && *src == src[runlen]) {
569 runlen++;
570 }
571 if (runlen > 3) {
572
573 putDebugChar ('*');
574 checksum += '*';
575 encode = runlen + ' ' - 4;
576 putDebugChar (encode);
577 checksum += encode;
578 src += runlen;
579 }
580 else {
581 src++;
582 }
583 }
584 putDebugChar('#');
585 putDebugChar(hex_asc_hi(checksum));
586 putDebugChar(hex_asc_lo(checksum));
587 } while(kgdb_started && (getDebugChar() != '+'));
588}
589
590
591
592void
593putDebugString (const unsigned char *str, int length)
594{
595 remcomOutBuffer[0] = 'O';
596 mem2hex(&remcomOutBuffer[1], (unsigned char *)str, length);
597 putpacket(remcomOutBuffer);
598}
599
600
601
602
603static int
604write_register (int regno, char *val)
605{
606 int status = SUCCESS;
607 registers *current_reg = &cris_reg;
608
609 if (regno >= R0 && regno <= PC) {
610
611 hex2mem ((unsigned char *)current_reg + regno * sizeof(unsigned int),
612 val, sizeof(unsigned int));
613 }
614 else if (regno == P0 || regno == VR || regno == P4 || regno == P8) {
615
616 status = E02;
617 }
618 else if (regno == CCR) {
619
620
621 hex2mem ((unsigned char *)&(current_reg->ccr) + (regno-CCR) * sizeof(unsigned short),
622 val, sizeof(unsigned short));
623 }
624 else if (regno >= MOF && regno <= USP) {
625
626 hex2mem ((unsigned char *)&(current_reg->ibr) + (regno-IBR) * sizeof(unsigned int),
627 val, sizeof(unsigned int));
628 }
629 else {
630
631 status = E05;
632 }
633 return status;
634}
635
636
637
638
639
640static int
641read_register (char regno, unsigned int *valptr)
642{
643 registers *current_reg = &cris_reg;
644
645 if (regno >= R0 && regno <= PC) {
646
647 *valptr = *(unsigned int *)((char *)current_reg + regno * sizeof(unsigned int));
648 return SUCCESS;
649 }
650 else if (regno == P0 || regno == VR) {
651
652 *valptr = (unsigned int)(*(unsigned char *)
653 ((char *)&(current_reg->p0) + (regno-P0) * sizeof(char)));
654 return SUCCESS;
655 }
656 else if (regno == P4 || regno == CCR) {
657
658 *valptr = (unsigned int)(*(unsigned short *)
659 ((char *)&(current_reg->p4) + (regno-P4) * sizeof(unsigned short)));
660 return SUCCESS;
661 }
662 else if (regno >= MOF && regno <= USP) {
663
664 *valptr = *(unsigned int *)((char *)&(current_reg->p8)
665 + (regno-P8) * sizeof(unsigned int));
666 return SUCCESS;
667 }
668 else {
669
670 consistency_status = E05;
671 return E05;
672 }
673}
674
675
676
677
678
679
680
681
682
683
684
685
686static void
687stub_is_stopped(int sigval)
688{
689 char *ptr = remcomOutBuffer;
690 int regno;
691
692 unsigned int reg_cont;
693 int status;
694
695
696
697 *ptr++ = 'T';
698 ptr = hex_byte_pack(ptr, sigval);
699
700
701
702
703
704
705 for (regno = R0; regno <= USP; regno++) {
706
707
708 status = read_register (regno, ®_cont);
709
710 if (status == SUCCESS) {
711 ptr = hex_byte_pack(ptr, regno);
712 *ptr++ = ':';
713
714 ptr = mem2hex(ptr, (unsigned char *)®_cont,
715 register_size[regno]);
716 *ptr++ = ';';
717 }
718
719 }
720
721
722
723 *ptr = 0;
724
725 putpacket (remcomOutBuffer);
726}
727
728
729static void
730kill_restart (void)
731{
732 machine_restart("");
733}
734
735
736
737void
738handle_exception (int sigval)
739{
740
741
742 stub_is_stopped (sigval);
743
744 for (;;) {
745 remcomOutBuffer[0] = '\0';
746 getpacket (remcomInBuffer);
747 switch (remcomInBuffer[0]) {
748 case 'g':
749
750
751
752
753
754
755 mem2hex(remcomOutBuffer, (char *)&cris_reg, sizeof(registers));
756 break;
757
758 case 'G':
759
760
761
762
763 hex2mem((char *)&cris_reg, &remcomInBuffer[1], sizeof(registers));
764 gdb_cris_strcpy (remcomOutBuffer, "OK");
765 break;
766
767 case 'P':
768
769
770
771
772
773
774
775 {
776 char *suffix;
777 int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16);
778 int status;
779 status = write_register (regno, suffix+1);
780
781 switch (status) {
782 case E02:
783
784 gdb_cris_strcpy (remcomOutBuffer, error_message[E02]);
785 break;
786 case E05:
787
788 gdb_cris_strcpy (remcomOutBuffer, error_message[E05]);
789 break;
790 case E07:
791
792 gdb_cris_strcpy (remcomOutBuffer, error_message[E07]);
793 break;
794 default:
795
796 gdb_cris_strcpy (remcomOutBuffer, "OK");
797 break;
798 }
799 }
800 break;
801
802 case 'm':
803
804
805
806
807
808
809 {
810 char *suffix;
811 unsigned char *addr = (unsigned char *)gdb_cris_strtol(&remcomInBuffer[1],
812 &suffix, 16); int length = gdb_cris_strtol(suffix+1, 0, 16);
813
814 mem2hex(remcomOutBuffer, addr, length);
815 }
816 break;
817
818 case 'X':
819
820
821
822
823
824 case 'M':
825
826
827
828
829
830 {
831 char *lenptr;
832 char *dataptr;
833 unsigned char *addr = (unsigned char *)gdb_cris_strtol(&remcomInBuffer[1],
834 &lenptr, 16);
835 int length = gdb_cris_strtol(lenptr+1, &dataptr, 16);
836 if (*lenptr == ',' && *dataptr == ':') {
837 if (remcomInBuffer[0] == 'M') {
838 hex2mem(addr, dataptr + 1, length);
839 }
840 else {
841 bin2mem(addr, dataptr + 1, length);
842 }
843 gdb_cris_strcpy (remcomOutBuffer, "OK");
844 }
845 else {
846 gdb_cris_strcpy (remcomOutBuffer, error_message[E06]);
847 }
848 }
849 break;
850
851 case 'c':
852
853
854
855
856
857 if (remcomInBuffer[1] != '\0') {
858 cris_reg.pc = gdb_cris_strtol (&remcomInBuffer[1], 0, 16);
859 }
860 enableDebugIRQ();
861 return;
862
863 case 's':
864
865
866
867
868
869
870
871 gdb_cris_strcpy (remcomOutBuffer, error_message[E04]);
872 putpacket (remcomOutBuffer);
873 return;
874
875 case '?':
876
877
878
879 remcomOutBuffer[0] = 'S';
880 remcomOutBuffer[1] = hex_asc_hi(sigval);
881 remcomOutBuffer[2] = hex_asc_lo(sigval);
882 remcomOutBuffer[3] = 0;
883 break;
884
885 case 'D':
886
887
888
889 putpacket ("OK");
890 return;
891
892 case 'k':
893 case 'r':
894
895
896
897 kill_restart ();
898 break;
899
900 case 'C':
901 case 'S':
902 case '!':
903 case 'R':
904 case 'd':
905
906
907
908
909
910
911
912 gdb_cris_strcpy (remcomOutBuffer, error_message[E04]);
913 break;
914
915 default:
916
917
918
919 remcomOutBuffer[0] = 0;
920 break;
921 }
922 putpacket(remcomOutBuffer);
923 }
924}
925
926
927
928
929
930
931
932
933void kgdb_handle_breakpoint(void);
934
935asm ("\n"
936" .global kgdb_handle_breakpoint\n"
937"kgdb_handle_breakpoint:\n"
938";;\n"
939";; Response to the break-instruction\n"
940";;\n"
941";; Create a register image of the caller\n"
942";;\n"
943" move $dccr,[cris_reg+0x5E] ; Save the flags in DCCR before disable interrupts\n"
944" di ; Disable interrupts\n"
945" move.d $r0,[cris_reg] ; Save R0\n"
946" move.d $r1,[cris_reg+0x04] ; Save R1\n"
947" move.d $r2,[cris_reg+0x08] ; Save R2\n"
948" move.d $r3,[cris_reg+0x0C] ; Save R3\n"
949" move.d $r4,[cris_reg+0x10] ; Save R4\n"
950" move.d $r5,[cris_reg+0x14] ; Save R5\n"
951" move.d $r6,[cris_reg+0x18] ; Save R6\n"
952" move.d $r7,[cris_reg+0x1C] ; Save R7\n"
953" move.d $r8,[cris_reg+0x20] ; Save R8\n"
954" move.d $r9,[cris_reg+0x24] ; Save R9\n"
955" move.d $r10,[cris_reg+0x28] ; Save R10\n"
956" move.d $r11,[cris_reg+0x2C] ; Save R11\n"
957" move.d $r12,[cris_reg+0x30] ; Save R12\n"
958" move.d $r13,[cris_reg+0x34] ; Save R13\n"
959" move.d $sp,[cris_reg+0x38] ; Save SP (R14)\n"
960";; Due to the old assembler-versions BRP might not be recognized\n"
961" .word 0xE670 ; move brp,$r0\n"
962" subq 2,$r0 ; Set to address of previous instruction.\n"
963" move.d $r0,[cris_reg+0x3c] ; Save the address in PC (R15)\n"
964" clear.b [cris_reg+0x40] ; Clear P0\n"
965" move $vr,[cris_reg+0x41] ; Save special register P1\n"
966" clear.w [cris_reg+0x42] ; Clear P4\n"
967" move $ccr,[cris_reg+0x44] ; Save special register CCR\n"
968" move $mof,[cris_reg+0x46] ; P7\n"
969" clear.d [cris_reg+0x4A] ; Clear P8\n"
970" move $ibr,[cris_reg+0x4E] ; P9,\n"
971" move $irp,[cris_reg+0x52] ; P10,\n"
972" move $srp,[cris_reg+0x56] ; P11,\n"
973" move $dtp0,[cris_reg+0x5A] ; P12, register BAR, assembler might not know BAR\n"
974" ; P13, register DCCR already saved\n"
975";; Due to the old assembler-versions BRP might not be recognized\n"
976" .word 0xE670 ; move brp,r0\n"
977";; Static (compiled) breakpoints must return to the next instruction in order\n"
978";; to avoid infinite loops. Dynamic (gdb-invoked) must restore the instruction\n"
979";; in order to execute it when execution is continued.\n"
980" test.b [is_dyn_brkp] ; Is this a dynamic breakpoint?\n"
981" beq is_static ; No, a static breakpoint\n"
982" nop\n"
983" subq 2,$r0 ; rerun the instruction the break replaced\n"
984"is_static:\n"
985" moveq 1,$r1\n"
986" move.b $r1,[is_dyn_brkp] ; Set the state variable to dynamic breakpoint\n"
987" move.d $r0,[cris_reg+0x62] ; Save the return address in BRP\n"
988" move $usp,[cris_reg+0x66] ; USP\n"
989";;\n"
990";; Handle the communication\n"
991";;\n"
992" move.d internal_stack+1020,$sp ; Use the internal stack which grows upward\n"
993" moveq 5,$r10 ; SIGTRAP\n"
994" jsr handle_exception ; Interactive routine\n"
995";;\n"
996";; Return to the caller\n"
997";;\n"
998" move.d [cris_reg],$r0 ; Restore R0\n"
999" move.d [cris_reg+0x04],$r1 ; Restore R1\n"
1000" move.d [cris_reg+0x08],$r2 ; Restore R2\n"
1001" move.d [cris_reg+0x0C],$r3 ; Restore R3\n"
1002" move.d [cris_reg+0x10],$r4 ; Restore R4\n"
1003" move.d [cris_reg+0x14],$r5 ; Restore R5\n"
1004" move.d [cris_reg+0x18],$r6 ; Restore R6\n"
1005" move.d [cris_reg+0x1C],$r7 ; Restore R7\n"
1006" move.d [cris_reg+0x20],$r8 ; Restore R8\n"
1007" move.d [cris_reg+0x24],$r9 ; Restore R9\n"
1008" move.d [cris_reg+0x28],$r10 ; Restore R10\n"
1009" move.d [cris_reg+0x2C],$r11 ; Restore R11\n"
1010" move.d [cris_reg+0x30],$r12 ; Restore R12\n"
1011" move.d [cris_reg+0x34],$r13 ; Restore R13\n"
1012";;\n"
1013";; FIXME: Which registers should be restored?\n"
1014";;\n"
1015" move.d [cris_reg+0x38],$sp ; Restore SP (R14)\n"
1016" move [cris_reg+0x56],$srp ; Restore the subroutine return pointer.\n"
1017" move [cris_reg+0x5E],$dccr ; Restore DCCR\n"
1018" move [cris_reg+0x66],$usp ; Restore USP\n"
1019" jump [cris_reg+0x62] ; A jump to the content in register BRP works.\n"
1020" nop ;\n"
1021"\n");
1022
1023
1024
1025
1026
1027
1028
1029
1030void kgdb_handle_serial(void);
1031
1032asm ("\n"
1033" .global kgdb_handle_serial\n"
1034"kgdb_handle_serial:\n"
1035";;\n"
1036";; Response to a serial interrupt\n"
1037";;\n"
1038"\n"
1039" move $dccr,[cris_reg+0x5E] ; Save the flags in DCCR\n"
1040" di ; Disable interrupts\n"
1041" move.d $r0,[cris_reg] ; Save R0\n"
1042" move.d $r1,[cris_reg+0x04] ; Save R1\n"
1043" move.d $r2,[cris_reg+0x08] ; Save R2\n"
1044" move.d $r3,[cris_reg+0x0C] ; Save R3\n"
1045" move.d $r4,[cris_reg+0x10] ; Save R4\n"
1046" move.d $r5,[cris_reg+0x14] ; Save R5\n"
1047" move.d $r6,[cris_reg+0x18] ; Save R6\n"
1048" move.d $r7,[cris_reg+0x1C] ; Save R7\n"
1049" move.d $r8,[cris_reg+0x20] ; Save R8\n"
1050" move.d $r9,[cris_reg+0x24] ; Save R9\n"
1051" move.d $r10,[cris_reg+0x28] ; Save R10\n"
1052" move.d $r11,[cris_reg+0x2C] ; Save R11\n"
1053" move.d $r12,[cris_reg+0x30] ; Save R12\n"
1054" move.d $r13,[cris_reg+0x34] ; Save R13\n"
1055" move.d $sp,[cris_reg+0x38] ; Save SP (R14)\n"
1056" move $irp,[cris_reg+0x3c] ; Save the address in PC (R15)\n"
1057" clear.b [cris_reg+0x40] ; Clear P0\n"
1058" move $vr,[cris_reg+0x41] ; Save special register P1,\n"
1059" clear.w [cris_reg+0x42] ; Clear P4\n"
1060" move $ccr,[cris_reg+0x44] ; Save special register CCR\n"
1061" move $mof,[cris_reg+0x46] ; P7\n"
1062" clear.d [cris_reg+0x4A] ; Clear P8\n"
1063" move $ibr,[cris_reg+0x4E] ; P9,\n"
1064" move $irp,[cris_reg+0x52] ; P10,\n"
1065" move $srp,[cris_reg+0x56] ; P11,\n"
1066" move $dtp0,[cris_reg+0x5A] ; P12, register BAR, assembler might not know BAR\n"
1067" ; P13, register DCCR already saved\n"
1068";; Due to the old assembler-versions BRP might not be recognized\n"
1069" .word 0xE670 ; move brp,r0\n"
1070" move.d $r0,[cris_reg+0x62] ; Save the return address in BRP\n"
1071" move $usp,[cris_reg+0x66] ; USP\n"
1072"\n"
1073";; get the serial character (from debugport.c) and check if it is a ctrl-c\n"
1074"\n"
1075" jsr getDebugChar\n"
1076" cmp.b 3, $r10\n"
1077" bne goback\n"
1078" nop\n"
1079"\n"
1080" move.d [cris_reg+0x5E], $r10 ; Get DCCR\n"
1081" btstq 8, $r10 ; Test the U-flag.\n"
1082" bmi goback\n"
1083" nop\n"
1084"\n"
1085";;\n"
1086";; Handle the communication\n"
1087";;\n"
1088" move.d internal_stack+1020,$sp ; Use the internal stack\n"
1089" moveq 2,$r10 ; SIGINT\n"
1090" jsr handle_exception ; Interactive routine\n"
1091"\n"
1092"goback:\n"
1093";;\n"
1094";; Return to the caller\n"
1095";;\n"
1096" move.d [cris_reg],$r0 ; Restore R0\n"
1097" move.d [cris_reg+0x04],$r1 ; Restore R1\n"
1098" move.d [cris_reg+0x08],$r2 ; Restore R2\n"
1099" move.d [cris_reg+0x0C],$r3 ; Restore R3\n"
1100" move.d [cris_reg+0x10],$r4 ; Restore R4\n"
1101" move.d [cris_reg+0x14],$r5 ; Restore R5\n"
1102" move.d [cris_reg+0x18],$r6 ; Restore R6\n"
1103" move.d [cris_reg+0x1C],$r7 ; Restore R7\n"
1104" move.d [cris_reg+0x20],$r8 ; Restore R8\n"
1105" move.d [cris_reg+0x24],$r9 ; Restore R9\n"
1106" move.d [cris_reg+0x28],$r10 ; Restore R10\n"
1107" move.d [cris_reg+0x2C],$r11 ; Restore R11\n"
1108" move.d [cris_reg+0x30],$r12 ; Restore R12\n"
1109" move.d [cris_reg+0x34],$r13 ; Restore R13\n"
1110";;\n"
1111";; FIXME: Which registers should be restored?\n"
1112";;\n"
1113" move.d [cris_reg+0x38],$sp ; Restore SP (R14)\n"
1114" move [cris_reg+0x56],$srp ; Restore the subroutine return pointer.\n"
1115" move [cris_reg+0x5E],$dccr ; Restore DCCR\n"
1116" move [cris_reg+0x66],$usp ; Restore USP\n"
1117" reti ; Return from the interrupt routine\n"
1118" nop\n"
1119"\n");
1120
1121
1122
1123void
1124breakpoint(void)
1125{
1126 kgdb_started = 1;
1127 is_dyn_brkp = 0;
1128 __asm__ volatile ("break 8");
1129}
1130
1131
1132
1133void
1134kgdb_init(void)
1135{
1136
1137
1138
1139 set_int_vector(8, kgdb_handle_serial);
1140
1141 enableDebugIRQ();
1142}
1143
1144
1145