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