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
234
235
236static char *gdb_cris_strcpy (char *s1, const char *s2);
237
238
239static int gdb_cris_strlen (const char *s);
240
241
242static void *gdb_cris_memchr (const void *s, int c, int n);
243
244
245static int gdb_cris_strtol (const char *s, char **endptr, int base);
246
247
248
249
250
251static void copy_registers (registers *dptr, registers *sptr, int n);
252
253
254
255static void copy_registers_from_stack (int thread_id, registers *reg);
256
257
258
259static void copy_registers_to_stack (int thread_id, registers *reg);
260
261
262
263static int write_register (int regno, char *val);
264
265
266
267static int write_stack_register(int thread_id, int regno, char *valptr);
268
269
270
271static int read_register (char regno, unsigned int *valptr);
272
273
274int getDebugChar (void);
275
276
277void putDebugChar (int val);
278
279void enableDebugIRQ (void);
280
281
282static int hex (char ch);
283
284
285
286
287static char *mem2hex (char *buf, unsigned char *mem, int count);
288
289
290
291
292static unsigned char *hex2mem (unsigned char *mem, char *buf, int count);
293
294
295
296
297static unsigned char *bin2mem (unsigned char *mem, unsigned char *buf, int count);
298
299
300
301static void getpacket (char *buffer);
302
303
304static void putpacket (char *buffer);
305
306
307
308static void stub_is_stopped (int sigval);
309
310
311
312static void handle_exception (int sigval);
313
314
315static void kill_restart (void);
316
317
318
319
320void putDebugString (const unsigned char *str, int length);
321
322
323
324void handle_breakpoint (void);
325
326
327void handle_interrupt (void);
328
329
330void breakpoint (void);
331
332
333
334extern unsigned char executing_task;
335
336
337#define HEXCHARS_IN_THREAD_ID 16
338
339
340#define USEDVAR(name) { if (name) { ; } }
341#define USEDFUN(name) { void (*pf)(void) = (void *)name; USEDVAR(pf) }
342
343
344
345
346#define BUFMAX 512
347
348
349#define RUNLENMAX 64
350
351
352static char remcomInBuffer[BUFMAX];
353static char remcomOutBuffer[BUFMAX];
354
355
356enum error_type
357{
358 SUCCESS, E01, E02, E03, E04, E05, E06, E07
359};
360static char *error_message[] =
361{
362 "",
363 "E01 Set current or general thread - H[c,g] - internal error.",
364 "E02 Change register content - P - cannot change read-only register.",
365 "E03 Thread is not alive.",
366 "E04 The command is not supported - [s,C,S,!,R,d,r] - internal error.",
367 "E05 Change register content - P - the register is not implemented..",
368 "E06 Change memory content - M - internal error.",
369 "E07 Change register content - P - the register is not stored on the stack"
370};
371
372
373
374
375
376
377
378
379
380enum register_name
381{
382 R0, R1, R2, R3,
383 R4, R5, R6, R7,
384 R8, R9, R10, R11,
385 R12, R13, SP, PC,
386 P0, VR, P2, P3,
387 P4, CCR, P6, MOF,
388 P8, IBR, IRP, SRP,
389 BAR, DCCR, BRP, USP
390};
391
392
393
394static int register_size[] =
395{
396 4, 4, 4, 4,
397 4, 4, 4, 4,
398 4, 4, 4, 4,
399 4, 4, 4, 4,
400 1, 1, 0, 0,
401 2, 2, 0, 4,
402 4, 4, 4, 4,
403 4, 4, 4, 4
404};
405
406
407
408static registers reg;
409
410
411
412
413static int consistency_status = SUCCESS;
414
415
416
417
418
419
420
421
422
423
424
425static int current_thread_c = 0;
426static int current_thread_g = 0;
427
428
429
430static registers reg_g;
431
432
433
434#define INTERNAL_STACK_SIZE 1024
435static char internal_stack[INTERNAL_STACK_SIZE];
436
437
438
439
440
441
442static unsigned char is_dyn_brkp = 0;
443
444
445
446
447
448static char*
449gdb_cris_strcpy (char *s1, const char *s2)
450{
451 char *s = s1;
452
453 for (s = s1; (*s++ = *s2++) != '\0'; )
454 ;
455 return (s1);
456}
457
458
459static int
460gdb_cris_strlen (const char *s)
461{
462 const char *sc;
463
464 for (sc = s; *sc != '\0'; sc++)
465 ;
466 return (sc - s);
467}
468
469
470static void*
471gdb_cris_memchr (const void *s, int c, int n)
472{
473 const unsigned char uc = c;
474 const unsigned char *su;
475
476 for (su = s; 0 < n; ++su, --n)
477 if (*su == uc)
478 return ((void *)su);
479 return (NULL);
480}
481
482
483
484static int
485gdb_cris_strtol (const char *s, char **endptr, int base)
486{
487 char *s1;
488 char *sd;
489 int x = 0;
490
491 for (s1 = (char*)s; (sd = gdb_cris_memchr(hex_asc, *s1, base)) != NULL; ++s1)
492 x = x * base + (sd - hex_asc);
493
494 if (endptr)
495 {
496
497 *endptr = s1;
498 }
499
500 return x;
501}
502
503
504
505
506
507static void
508copy_registers (registers *dptr, registers *sptr, int n)
509{
510 unsigned char *dreg;
511 unsigned char *sreg;
512
513 for (dreg = (unsigned char*)dptr, sreg = (unsigned char*)sptr; n > 0; n--)
514 *dreg++ = *sreg++;
515}
516
517#ifdef PROCESS_SUPPORT
518
519
520static void
521copy_registers_from_stack (int thread_id, registers *regptr)
522{
523 int j;
524 stack_registers *s = (stack_registers *)stack_list[thread_id];
525 unsigned int *d = (unsigned int *)regptr;
526
527 for (j = 13; j >= 0; j--)
528 *d++ = s->r[j];
529 regptr->sp = (unsigned int)stack_list[thread_id];
530 regptr->pc = s->pc;
531 regptr->dccr = s->dccr;
532 regptr->srp = s->srp;
533}
534
535
536
537static void
538copy_registers_to_stack (int thread_id, registers *regptr)
539{
540 int i;
541 stack_registers *d = (stack_registers *)stack_list[thread_id];
542 unsigned int *s = (unsigned int *)regptr;
543
544 for (i = 0; i < 14; i++) {
545 d->r[i] = *s++;
546 }
547 d->pc = regptr->pc;
548 d->dccr = regptr->dccr;
549 d->srp = regptr->srp;
550}
551#endif
552
553
554
555static int
556write_register (int regno, char *val)
557{
558 int status = SUCCESS;
559 registers *current_reg = ®
560
561 if (regno >= R0 && regno <= PC) {
562
563 hex2mem ((unsigned char *)current_reg + regno * sizeof(unsigned int),
564 val, sizeof(unsigned int));
565 }
566 else if (regno == P0 || regno == VR || regno == P4 || regno == P8) {
567
568 status = E02;
569 }
570 else if (regno == CCR) {
571
572
573 hex2mem ((unsigned char *)&(current_reg->ccr) + (regno-CCR) * sizeof(unsigned short),
574 val, sizeof(unsigned short));
575 }
576 else if (regno >= MOF && regno <= USP) {
577
578 hex2mem ((unsigned char *)&(current_reg->ibr) + (regno-IBR) * sizeof(unsigned int),
579 val, sizeof(unsigned int));
580 }
581 else {
582
583 status = E05;
584 }
585 return status;
586}
587
588#ifdef PROCESS_SUPPORT
589
590
591static int
592write_stack_register (int thread_id, int regno, char *valptr)
593{
594 int status = SUCCESS;
595 stack_registers *d = (stack_registers *)stack_list[thread_id];
596 unsigned int val;
597
598 hex2mem ((unsigned char *)&val, valptr, sizeof(unsigned int));
599 if (regno >= R0 && regno < SP) {
600 d->r[regno] = val;
601 }
602 else if (regno == SP) {
603 stack_list[thread_id] = val;
604 }
605 else if (regno == PC) {
606 d->pc = val;
607 }
608 else if (regno == SRP) {
609 d->srp = val;
610 }
611 else if (regno == DCCR) {
612 d->dccr = val;
613 }
614 else {
615
616 status = E07;
617 }
618 return status;
619}
620#endif
621
622
623
624
625
626static int
627read_register (char regno, unsigned int *valptr)
628{
629 registers *current_reg = ®
630
631 if (regno >= R0 && regno <= PC) {
632
633 *valptr = *(unsigned int *)((char *)current_reg + regno * sizeof(unsigned int));
634 return SUCCESS;
635 }
636 else if (regno == P0 || regno == VR) {
637
638 *valptr = (unsigned int)(*(unsigned char *)
639 ((char *)&(current_reg->p0) + (regno-P0) * sizeof(char)));
640 return SUCCESS;
641 }
642 else if (regno == P4 || regno == CCR) {
643
644 *valptr = (unsigned int)(*(unsigned short *)
645 ((char *)&(current_reg->p4) + (regno-P4) * sizeof(unsigned short)));
646 return SUCCESS;
647 }
648 else if (regno >= MOF && regno <= USP) {
649
650 *valptr = *(unsigned int *)((char *)&(current_reg->p8)
651 + (regno-P8) * sizeof(unsigned int));
652 return SUCCESS;
653 }
654 else {
655
656 consistency_status = E05;
657 return E05;
658 }
659}
660
661
662
663static int
664hex (char ch)
665{
666 if ((ch >= 'a') && (ch <= 'f'))
667 return (ch - 'a' + 10);
668 if ((ch >= '0') && (ch <= '9'))
669 return (ch - '0');
670 if ((ch >= 'A') && (ch <= 'F'))
671 return (ch - 'A' + 10);
672 return (-1);
673}
674
675
676
677
678
679static int do_printk = 0;
680
681static char *
682mem2hex(char *buf, unsigned char *mem, int count)
683{
684 int i;
685 int ch;
686
687 if (mem == NULL) {
688
689 for (i = 0; i < count; i++) {
690 *buf++ = '0';
691 *buf++ = '0';
692 }
693 } else {
694
695 for (i = 0; i < count; i++) {
696 ch = *mem++;
697 buf = hex_byte_pack(buf, ch);
698 }
699 }
700
701
702 *buf = '\0';
703 return (buf);
704}
705
706
707
708
709static unsigned char*
710hex2mem (unsigned char *mem, char *buf, int count)
711{
712 int i;
713 unsigned char ch;
714 for (i = 0; i < count; i++) {
715 ch = hex (*buf++) << 4;
716 ch = ch + hex (*buf++);
717 *mem++ = ch;
718 }
719 return (mem);
720}
721
722
723
724
725
726static unsigned char*
727bin2mem (unsigned char *mem, unsigned char *buf, int count)
728{
729 int i;
730 unsigned char *next;
731 for (i = 0; i < count; i++) {
732
733
734 if (*buf == 0x7d) {
735 next = buf + 1;
736 if (*next == 0x3 || *next == 0x4 || *next == 0x5D)
737 {
738 buf++;
739 *buf += 0x20;
740 }
741 }
742 *mem++ = *buf++;
743 }
744 return (mem);
745}
746
747
748
749static void
750getpacket (char *buffer)
751{
752 unsigned char checksum;
753 unsigned char xmitcsum;
754 int i;
755 int count;
756 char ch;
757 do {
758 while ((ch = getDebugChar ()) != '$')
759 ;
760 checksum = 0;
761 xmitcsum = -1;
762 count = 0;
763
764 while (count < BUFMAX) {
765 ch = getDebugChar ();
766 if (ch == '#')
767 break;
768 checksum = checksum + ch;
769 buffer[count] = ch;
770 count = count + 1;
771 }
772 buffer[count] = '\0';
773
774 if (ch == '#') {
775 xmitcsum = hex (getDebugChar ()) << 4;
776 xmitcsum += hex (getDebugChar ());
777 if (checksum != xmitcsum) {
778
779 putDebugChar ('-');
780 }
781 else {
782
783 putDebugChar ('+');
784
785 if (buffer[2] == ':') {
786 putDebugChar (buffer[0]);
787 putDebugChar (buffer[1]);
788
789 count = gdb_cris_strlen (buffer);
790 for (i = 3; i <= count; i++)
791 buffer[i - 3] = buffer[i];
792 }
793 }
794 }
795 } while (checksum != xmitcsum);
796}
797
798
799
800static void
801putpacket(char *buffer)
802{
803 int checksum;
804 int runlen;
805 int encode;
806
807 do {
808 char *src = buffer;
809 putDebugChar ('$');
810 checksum = 0;
811 while (*src) {
812
813 putDebugChar (*src);
814 checksum += *src;
815 runlen = 0;
816 while (runlen < RUNLENMAX && *src == src[runlen]) {
817 runlen++;
818 }
819 if (runlen > 3) {
820
821 putDebugChar ('*');
822 checksum += '*';
823 encode = runlen + ' ' - 4;
824 putDebugChar (encode);
825 checksum += encode;
826 src += runlen;
827 }
828 else {
829 src++;
830 }
831 }
832 putDebugChar('#');
833 putDebugChar(hex_asc_hi(checksum));
834 putDebugChar(hex_asc_lo(checksum));
835 } while(kgdb_started && (getDebugChar() != '+'));
836}
837
838
839
840void
841putDebugString (const unsigned char *str, int length)
842{
843 remcomOutBuffer[0] = 'O';
844 mem2hex(&remcomOutBuffer[1], (unsigned char *)str, length);
845 putpacket(remcomOutBuffer);
846}
847
848
849
850
851
852
853
854
855
856
857
858
859static void
860stub_is_stopped(int sigval)
861{
862 char *ptr = remcomOutBuffer;
863 int regno;
864
865 unsigned int reg_cont;
866 int status;
867
868
869
870 *ptr++ = 'T';
871 ptr = hex_byte_pack(ptr, sigval);
872
873
874
875
876
877
878 for (regno = R0; regno <= USP; regno++) {
879
880
881 status = read_register (regno, ®_cont);
882
883 if (status == SUCCESS) {
884 ptr = hex_byte_pack(ptr, regno);
885 *ptr++ = ':';
886
887 ptr = mem2hex(ptr, (unsigned char *)®_cont,
888 register_size[regno]);
889 *ptr++ = ';';
890 }
891
892 }
893
894#ifdef PROCESS_SUPPORT
895
896
897
898
899 current_thread_c = executing_task;
900 current_thread_g = executing_task;
901
902
903
904 copy_registers (®_g, ®, sizeof(registers));
905
906
907 gdb_cris_strcpy (&remcomOutBuffer[pos], "thread:");
908 pos += gdb_cris_strlen ("thread:");
909 remcomOutBuffer[pos++] = hex_asc_hi(executing_task);
910 remcomOutBuffer[pos++] = hex_asc_lo(executing_task);
911 gdb_cris_strcpy (&remcomOutBuffer[pos], ";");
912#endif
913
914
915
916 *ptr = 0;
917
918 putpacket (remcomOutBuffer);
919}
920
921
922
923static void
924handle_exception (int sigval)
925{
926
927
928 USEDFUN(handle_exception);
929 USEDVAR(internal_stack[0]);
930
931
932
933 stub_is_stopped (sigval);
934
935 for (;;) {
936 remcomOutBuffer[0] = '\0';
937 getpacket (remcomInBuffer);
938 switch (remcomInBuffer[0]) {
939 case 'g':
940
941
942
943
944
945
946 {
947#ifdef PROCESS_SUPPORT
948
949 copy_registers (®_g, ®, sizeof(registers));
950
951 if (current_thread_g != executing_task) {
952 copy_registers_from_stack (current_thread_g, ®_g);
953 }
954 mem2hex ((unsigned char *)remcomOutBuffer, (unsigned char *)®_g, sizeof(registers));
955#else
956 mem2hex(remcomOutBuffer, (char *)®, sizeof(registers));
957#endif
958 }
959 break;
960
961 case 'G':
962
963
964
965
966#ifdef PROCESS_SUPPORT
967 hex2mem ((unsigned char *)®_g, &remcomInBuffer[1], sizeof(registers));
968 if (current_thread_g == executing_task) {
969 copy_registers (®, ®_g, sizeof(registers));
970 }
971 else {
972 copy_registers_to_stack(current_thread_g, ®_g);
973 }
974#else
975 hex2mem((char *)®, &remcomInBuffer[1], sizeof(registers));
976#endif
977 gdb_cris_strcpy (remcomOutBuffer, "OK");
978 break;
979
980 case 'P':
981
982
983
984
985
986
987
988 {
989 char *suffix;
990 int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16);
991 int status;
992#ifdef PROCESS_SUPPORT
993 if (current_thread_g != executing_task)
994 status = write_stack_register (current_thread_g, regno, suffix+1);
995 else
996#endif
997 status = write_register (regno, suffix+1);
998
999 switch (status) {
1000 case E02:
1001
1002 gdb_cris_strcpy (remcomOutBuffer, error_message[E02]);
1003 break;
1004 case E05:
1005
1006 gdb_cris_strcpy (remcomOutBuffer, error_message[E05]);
1007 break;
1008 case E07:
1009
1010 gdb_cris_strcpy (remcomOutBuffer, error_message[E07]);
1011 break;
1012 default:
1013
1014 gdb_cris_strcpy (remcomOutBuffer, "OK");
1015 break;
1016 }
1017 }
1018 break;
1019
1020 case 'm':
1021
1022
1023
1024
1025
1026
1027 {
1028 char *suffix;
1029 unsigned char *addr = (unsigned char *)gdb_cris_strtol(&remcomInBuffer[1],
1030 &suffix, 16); int length = gdb_cris_strtol(suffix+1, 0, 16);
1031
1032 mem2hex(remcomOutBuffer, addr, length);
1033 }
1034 break;
1035
1036 case 'X':
1037
1038
1039
1040
1041
1042 case 'M':
1043
1044
1045
1046
1047
1048 {
1049 char *lenptr;
1050 char *dataptr;
1051 unsigned char *addr = (unsigned char *)gdb_cris_strtol(&remcomInBuffer[1],
1052 &lenptr, 16);
1053 int length = gdb_cris_strtol(lenptr+1, &dataptr, 16);
1054 if (*lenptr == ',' && *dataptr == ':') {
1055 if (remcomInBuffer[0] == 'M') {
1056 hex2mem(addr, dataptr + 1, length);
1057 }
1058 else {
1059 bin2mem(addr, dataptr + 1, length);
1060 }
1061 gdb_cris_strcpy (remcomOutBuffer, "OK");
1062 }
1063 else {
1064 gdb_cris_strcpy (remcomOutBuffer, error_message[E06]);
1065 }
1066 }
1067 break;
1068
1069 case 'c':
1070
1071
1072
1073
1074
1075 if (remcomInBuffer[1] != '\0') {
1076 reg.pc = gdb_cris_strtol (&remcomInBuffer[1], 0, 16);
1077 }
1078 enableDebugIRQ();
1079 return;
1080
1081 case 's':
1082
1083
1084
1085
1086
1087
1088
1089 gdb_cris_strcpy (remcomOutBuffer, error_message[E04]);
1090 putpacket (remcomOutBuffer);
1091 return;
1092
1093 case '?':
1094
1095
1096
1097 remcomOutBuffer[0] = 'S';
1098 remcomOutBuffer[1] = hex_asc_hi(sigval);
1099 remcomOutBuffer[2] = hex_asc_lo(sigval);
1100 remcomOutBuffer[3] = 0;
1101 break;
1102
1103 case 'D':
1104
1105
1106
1107 putpacket ("OK");
1108 return;
1109
1110 case 'k':
1111 case 'r':
1112
1113
1114
1115 kill_restart ();
1116 break;
1117
1118 case 'C':
1119 case 'S':
1120 case '!':
1121 case 'R':
1122 case 'd':
1123
1124
1125
1126
1127
1128
1129
1130 gdb_cris_strcpy (remcomOutBuffer, error_message[E04]);
1131 break;
1132#ifdef PROCESS_SUPPORT
1133
1134 case 'T':
1135
1136
1137
1138
1139 {
1140 int thread_id = (int)gdb_cris_strtol (&remcomInBuffer[1], 0, 16);
1141
1142 if (thread_id >= 0 && thread_id < number_of_tasks)
1143 gdb_cris_strcpy (remcomOutBuffer, "OK");
1144 }
1145 break;
1146
1147 case 'H':
1148
1149
1150
1151
1152
1153
1154
1155 {
1156 int thread_id = gdb_cris_strtol (&remcomInBuffer[2], 0, 16);
1157 if (remcomInBuffer[1] == 'c') {
1158
1159
1160
1161 gdb_cris_strcpy (remcomOutBuffer, "OK");
1162 }
1163 else if (remcomInBuffer[1] == 'g') {
1164
1165
1166
1167 if (thread_id >= 0 && thread_id < number_of_tasks) {
1168 current_thread_g = thread_id;
1169 gdb_cris_strcpy (remcomOutBuffer, "OK");
1170 }
1171 else {
1172
1173 gdb_cris_strcpy (remcomOutBuffer, error_message[E01]);
1174 }
1175 }
1176 else {
1177
1178 gdb_cris_strcpy (remcomOutBuffer, error_message[E01]);
1179 }
1180 }
1181 break;
1182
1183 case 'q':
1184 case 'Q':
1185
1186
1187 {
1188 int pos;
1189 int nextpos;
1190 int thread_id;
1191
1192 switch (remcomInBuffer[1]) {
1193 case 'C':
1194
1195 gdb_cris_strcpy (&remcomOutBuffer[0], "QC");
1196 remcomOutBuffer[2] = hex_asc_hi(current_thread_c);
1197 remcomOutBuffer[3] = hex_asc_lo(current_thread_c);
1198 remcomOutBuffer[4] = '\0';
1199 break;
1200 case 'L':
1201 gdb_cris_strcpy (&remcomOutBuffer[0], "QM");
1202
1203 if (os_is_started()) {
1204 remcomOutBuffer[2] = hex_asc_hi(number_of_tasks);
1205 remcomOutBuffer[3] = hex_asc_lo(number_of_tasks);
1206 }
1207 else {
1208 remcomOutBuffer[2] = hex_asc_hi(0);
1209 remcomOutBuffer[3] = hex_asc_lo(1);
1210 }
1211
1212 remcomOutBuffer[4] = hex_asc_lo(1);
1213 pos = 5;
1214
1215 for (; pos < (5 + HEXCHARS_IN_THREAD_ID); pos++)
1216 remcomOutBuffer[pos] = remcomInBuffer[pos];
1217
1218 if (os_is_started()) {
1219
1220 for (thread_id = 0; thread_id < number_of_tasks; thread_id++) {
1221 nextpos = pos + HEXCHARS_IN_THREAD_ID - 1;
1222 for (; pos < nextpos; pos ++)
1223 remcomOutBuffer[pos] = hex_asc_lo(0);
1224 remcomOutBuffer[pos++] = hex_asc_lo(thread_id);
1225 }
1226 }
1227 else {
1228
1229 nextpos = pos + HEXCHARS_IN_THREAD_ID - 1;
1230 for (; pos < nextpos; pos ++)
1231 remcomOutBuffer[pos] = hex_asc_lo(0);
1232 remcomOutBuffer[pos++] = hex_asc_lo(current_thread_c);
1233 }
1234 remcomOutBuffer[pos] = '\0';
1235 break;
1236 default:
1237
1238
1239 remcomOutBuffer[0] = 0;
1240 break;
1241 }
1242 }
1243 break;
1244#endif
1245
1246 default:
1247
1248
1249
1250 remcomOutBuffer[0] = 0;
1251 break;
1252 }
1253 putpacket(remcomOutBuffer);
1254 }
1255}
1256
1257
1258static void
1259kill_restart ()
1260{
1261 machine_restart("");
1262}
1263
1264
1265
1266
1267
1268
1269
1270
1271void kgdb_handle_breakpoint(void);
1272
1273asm ("
1274 .global kgdb_handle_breakpoint
1275kgdb_handle_breakpoint:
1276;;
1277;; Response to the break-instruction
1278;;
1279;; Create a register image of the caller
1280;;
1281 move $dccr,[reg+0x5E] ; Save the flags in DCCR before disable interrupts
1282 di ; Disable interrupts
1283 move.d $r0,[reg] ; Save R0
1284 move.d $r1,[reg+0x04] ; Save R1
1285 move.d $r2,[reg+0x08] ; Save R2
1286 move.d $r3,[reg+0x0C] ; Save R3
1287 move.d $r4,[reg+0x10] ; Save R4
1288 move.d $r5,[reg+0x14] ; Save R5
1289 move.d $r6,[reg+0x18] ; Save R6
1290 move.d $r7,[reg+0x1C] ; Save R7
1291 move.d $r8,[reg+0x20] ; Save R8
1292 move.d $r9,[reg+0x24] ; Save R9
1293 move.d $r10,[reg+0x28] ; Save R10
1294 move.d $r11,[reg+0x2C] ; Save R11
1295 move.d $r12,[reg+0x30] ; Save R12
1296 move.d $r13,[reg+0x34] ; Save R13
1297 move.d $sp,[reg+0x38] ; Save SP (R14)
1298;; Due to the old assembler-versions BRP might not be recognized
1299 .word 0xE670 ; move brp,$r0
1300 subq 2,$r0 ; Set to address of previous instruction.
1301 move.d $r0,[reg+0x3c] ; Save the address in PC (R15)
1302 clear.b [reg+0x40] ; Clear P0
1303 move $vr,[reg+0x41] ; Save special register P1
1304 clear.w [reg+0x42] ; Clear P4
1305 move $ccr,[reg+0x44] ; Save special register CCR
1306 move $mof,[reg+0x46] ; P7
1307 clear.d [reg+0x4A] ; Clear P8
1308 move $ibr,[reg+0x4E] ; P9,
1309 move $irp,[reg+0x52] ; P10,
1310 move $srp,[reg+0x56] ; P11,
1311 move $dtp0,[reg+0x5A] ; P12, register BAR, assembler might not know BAR
1312 ; P13, register DCCR already saved
1313;; Due to the old assembler-versions BRP might not be recognized
1314 .word 0xE670 ; move brp,r0
1315;; Static (compiled) breakpoints must return to the next instruction in order
1316;; to avoid infinite loops. Dynamic (gdb-invoked) must restore the instruction
1317;; in order to execute it when execution is continued.
1318 test.b [is_dyn_brkp] ; Is this a dynamic breakpoint?
1319 beq is_static ; No, a static breakpoint
1320 nop
1321 subq 2,$r0 ; rerun the instruction the break replaced
1322is_static:
1323 moveq 1,$r1
1324 move.b $r1,[is_dyn_brkp] ; Set the state variable to dynamic breakpoint
1325 move.d $r0,[reg+0x62] ; Save the return address in BRP
1326 move $usp,[reg+0x66] ; USP
1327;;
1328;; Handle the communication
1329;;
1330 move.d internal_stack+1020,$sp ; Use the internal stack which grows upward
1331 moveq 5,$r10 ; SIGTRAP
1332 jsr handle_exception ; Interactive routine
1333;;
1334;; Return to the caller
1335;;
1336 move.d [reg],$r0 ; Restore R0
1337 move.d [reg+0x04],$r1 ; Restore R1
1338 move.d [reg+0x08],$r2 ; Restore R2
1339 move.d [reg+0x0C],$r3 ; Restore R3
1340 move.d [reg+0x10],$r4 ; Restore R4
1341 move.d [reg+0x14],$r5 ; Restore R5
1342 move.d [reg+0x18],$r6 ; Restore R6
1343 move.d [reg+0x1C],$r7 ; Restore R7
1344 move.d [reg+0x20],$r8 ; Restore R8
1345 move.d [reg+0x24],$r9 ; Restore R9
1346 move.d [reg+0x28],$r10 ; Restore R10
1347 move.d [reg+0x2C],$r11 ; Restore R11
1348 move.d [reg+0x30],$r12 ; Restore R12
1349 move.d [reg+0x34],$r13 ; Restore R13
1350;;
1351;; FIXME: Which registers should be restored?
1352;;
1353 move.d [reg+0x38],$sp ; Restore SP (R14)
1354 move [reg+0x56],$srp ; Restore the subroutine return pointer.
1355 move [reg+0x5E],$dccr ; Restore DCCR
1356 move [reg+0x66],$usp ; Restore USP
1357 jump [reg+0x62] ; A jump to the content in register BRP works.
1358 nop ;
1359");
1360
1361
1362
1363
1364
1365
1366
1367
1368void kgdb_handle_serial(void);
1369
1370asm ("
1371 .global kgdb_handle_serial
1372kgdb_handle_serial:
1373;;
1374;; Response to a serial interrupt
1375;;
1376
1377 move $dccr,[reg+0x5E] ; Save the flags in DCCR
1378 di ; Disable interrupts
1379 move.d $r0,[reg] ; Save R0
1380 move.d $r1,[reg+0x04] ; Save R1
1381 move.d $r2,[reg+0x08] ; Save R2
1382 move.d $r3,[reg+0x0C] ; Save R3
1383 move.d $r4,[reg+0x10] ; Save R4
1384 move.d $r5,[reg+0x14] ; Save R5
1385 move.d $r6,[reg+0x18] ; Save R6
1386 move.d $r7,[reg+0x1C] ; Save R7
1387 move.d $r8,[reg+0x20] ; Save R8
1388 move.d $r9,[reg+0x24] ; Save R9
1389 move.d $r10,[reg+0x28] ; Save R10
1390 move.d $r11,[reg+0x2C] ; Save R11
1391 move.d $r12,[reg+0x30] ; Save R12
1392 move.d $r13,[reg+0x34] ; Save R13
1393 move.d $sp,[reg+0x38] ; Save SP (R14)
1394 move $irp,[reg+0x3c] ; Save the address in PC (R15)
1395 clear.b [reg+0x40] ; Clear P0
1396 move $vr,[reg+0x41] ; Save special register P1,
1397 clear.w [reg+0x42] ; Clear P4
1398 move $ccr,[reg+0x44] ; Save special register CCR
1399 move $mof,[reg+0x46] ; P7
1400 clear.d [reg+0x4A] ; Clear P8
1401 move $ibr,[reg+0x4E] ; P9,
1402 move $irp,[reg+0x52] ; P10,
1403 move $srp,[reg+0x56] ; P11,
1404 move $dtp0,[reg+0x5A] ; P12, register BAR, assembler might not know BAR
1405 ; P13, register DCCR already saved
1406;; Due to the old assembler-versions BRP might not be recognized
1407 .word 0xE670 ; move brp,r0
1408 move.d $r0,[reg+0x62] ; Save the return address in BRP
1409 move $usp,[reg+0x66] ; USP
1410
1411;; get the serial character (from debugport.c) and check if it is a ctrl-c
1412
1413 jsr getDebugChar
1414 cmp.b 3, $r10
1415 bne goback
1416 nop
1417
1418 move.d [reg+0x5E], $r10 ; Get DCCR
1419 btstq 8, $r10 ; Test the U-flag.
1420 bmi goback
1421 nop
1422
1423;;
1424;; Handle the communication
1425;;
1426 move.d internal_stack+1020,$sp ; Use the internal stack
1427 moveq 2,$r10 ; SIGINT
1428 jsr handle_exception ; Interactive routine
1429
1430goback:
1431;;
1432;; Return to the caller
1433;;
1434 move.d [reg],$r0 ; Restore R0
1435 move.d [reg+0x04],$r1 ; Restore R1
1436 move.d [reg+0x08],$r2 ; Restore R2
1437 move.d [reg+0x0C],$r3 ; Restore R3
1438 move.d [reg+0x10],$r4 ; Restore R4
1439 move.d [reg+0x14],$r5 ; Restore R5
1440 move.d [reg+0x18],$r6 ; Restore R6
1441 move.d [reg+0x1C],$r7 ; Restore R7
1442 move.d [reg+0x20],$r8 ; Restore R8
1443 move.d [reg+0x24],$r9 ; Restore R9
1444 move.d [reg+0x28],$r10 ; Restore R10
1445 move.d [reg+0x2C],$r11 ; Restore R11
1446 move.d [reg+0x30],$r12 ; Restore R12
1447 move.d [reg+0x34],$r13 ; Restore R13
1448;;
1449;; FIXME: Which registers should be restored?
1450;;
1451 move.d [reg+0x38],$sp ; Restore SP (R14)
1452 move [reg+0x56],$srp ; Restore the subroutine return pointer.
1453 move [reg+0x5E],$dccr ; Restore DCCR
1454 move [reg+0x66],$usp ; Restore USP
1455 reti ; Return from the interrupt routine
1456 nop
1457");
1458
1459
1460
1461void
1462breakpoint(void)
1463{
1464 kgdb_started = 1;
1465 is_dyn_brkp = 0;
1466 __asm__ volatile ("break 8");
1467}
1468
1469
1470
1471void
1472kgdb_init(void)
1473{
1474
1475
1476
1477 set_int_vector(8, kgdb_handle_serial);
1478
1479 enableDebugIRQ();
1480}
1481
1482
1483