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