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