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