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