169 #include <linux/string.h>
170 #include <linux/signal.h>
171 #include <linux/kernel.h>
173 #include <linux/linkage.h>
174 #include <linux/reboot.h>
176 #include <asm/setup.h>
177 #include <asm/ptrace.h>
182 static int kgdb_started = 0;
236 static char *gdb_cris_strcpy (
char *
s1,
const char *
s2);
239 static int gdb_cris_strlen (
const char *
s);
242 static void *gdb_cris_memchr (
const void *
s,
int c,
int n);
245 static int gdb_cris_strtol (
const char *
s,
char **endptr,
int base);
255 static void copy_registers_from_stack (
int thread_id,
registers *
reg);
259 static void copy_registers_to_stack (
int thread_id,
registers *
reg);
263 static int write_register (
int regno,
char *
val);
267 static int write_stack_register(
int thread_id,
int regno,
char *valptr);
271 static int read_register (
char regno,
unsigned int *valptr);
282 static int hex (
char ch);
287 static char *mem2hex (
char *
buf,
unsigned char *
mem,
int count);
292 static unsigned char *hex2mem (
unsigned char *
mem,
char *
buf,
int count);
297 static unsigned char *bin2mem (
unsigned char *
mem,
unsigned char *
buf,
int count);
301 static void getpacket (
char *
buffer);
304 static void putpacket (
char *
buffer);
308 static void stub_is_stopped (
int sigval);
312 static void handle_exception (
int sigval);
315 static void kill_restart (
void);
337 #define HEXCHARS_IN_THREAD_ID 16
340 #define USEDVAR(name) { if (name) { ; } }
341 #define USEDFUN(name) { void (*pf)(void) = (void *)name; USEDVAR(pf) }
352 static char remcomInBuffer[
BUFMAX];
353 static char remcomOutBuffer[
BUFMAX];
360 static char *error_message[] =
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"
394 static int register_size[] =
413 static int consistency_status =
SUCCESS;
425 static int current_thread_c = 0;
426 static int current_thread_g = 0;
434 #define INTERNAL_STACK_SIZE 1024
442 static unsigned char is_dyn_brkp = 0;
449 gdb_cris_strcpy (
char *
s1,
const char *
s2)
453 for (s = s1; (*s++ = *s2++) !=
'\0'; )
460 gdb_cris_strlen (
const char *
s)
464 for (sc = s; *sc !=
'\0'; sc++)
471 gdb_cris_memchr (
const void *s,
int c,
int n)
473 const unsigned char uc =
c;
474 const unsigned char *
su;
476 for (su = s; 0 <
n; ++
su, --
n)
485 gdb_cris_strtol (
const char *s,
char **endptr,
int base)
491 for (s1 = (
char*)s; (sd = gdb_cris_memchr(
hex_asc, *s1, base)) !=
NULL; ++
s1)
513 for (dreg = (
unsigned char*)dptr, sreg = (
unsigned char*)sptr; n > 0; n--)
517 #ifdef PROCESS_SUPPORT
524 stack_registers *s = (stack_registers *)stack_list[thread_id];
525 unsigned int *
d = (
unsigned int *)regptr;
527 for (j = 13; j >= 0; j--)
529 regptr->
sp = (
unsigned int)stack_list[thread_id];
531 regptr->
dccr = s->dccr;
532 regptr->
srp = s->srp;
538 copy_registers_to_stack (
int thread_id,
registers *regptr)
541 stack_registers *d = (stack_registers *)stack_list[thread_id];
542 unsigned int *s = (
unsigned int *)regptr;
544 for (i = 0; i < 14; i++) {
548 d->dccr = regptr->
dccr;
549 d->srp = regptr->
srp;
556 write_register (
int regno,
char *
val)
561 if (regno >=
R0 && regno <=
PC) {
563 hex2mem ((
unsigned char *)current_reg + regno *
sizeof(
unsigned int),
564 val,
sizeof(
unsigned int));
566 else if (regno ==
P0 || regno ==
VR || regno ==
P4 || regno ==
P8) {
570 else if (regno ==
CCR) {
573 hex2mem ((
unsigned char *)&(current_reg->
ccr) + (regno-
CCR) *
sizeof(
unsigned short),
574 val,
sizeof(
unsigned short));
576 else if (regno >=
MOF && regno <=
USP) {
578 hex2mem ((
unsigned char *)&(current_reg->
ibr) + (regno-
IBR) *
sizeof(
unsigned int),
579 val,
sizeof(
unsigned int));
588 #ifdef PROCESS_SUPPORT
592 write_stack_register (
int thread_id,
int regno,
char *valptr)
595 stack_registers *d = (stack_registers *)stack_list[thread_id];
598 hex2mem ((
unsigned char *)&val, valptr,
sizeof(
unsigned int));
599 if (regno >=
R0 && regno <
SP) {
602 else if (regno ==
SP) {
603 stack_list[thread_id] =
val;
605 else if (regno ==
PC) {
608 else if (regno ==
SRP) {
611 else if (regno ==
DCCR) {
627 read_register (
char regno,
unsigned int *valptr)
631 if (regno >=
R0 && regno <=
PC) {
633 *valptr = *(
unsigned int *)((
char *)current_reg + regno *
sizeof(
unsigned int));
636 else if (regno ==
P0 || regno ==
VR) {
638 *valptr = (
unsigned int)(*(
unsigned char *)
639 ((
char *)&(current_reg->
p0) + (regno-
P0) *
sizeof(
char)));
642 else if (regno ==
P4 || regno ==
CCR) {
644 *valptr = (
unsigned int)(*(
unsigned short *)
645 ((
char *)&(current_reg->
p4) + (regno-
P4) *
sizeof(
unsigned short)));
648 else if (regno >=
MOF && regno <=
USP) {
650 *valptr = *(
unsigned int *)((
char *)&(current_reg->
p8)
651 + (regno-
P8) *
sizeof(
unsigned int));
656 consistency_status =
E05;
666 if ((ch >=
'a') && (ch <=
'f'))
667 return (ch -
'a' + 10);
668 if ((ch >=
'0') && (ch <=
'9'))
670 if ((ch >=
'A') && (ch <=
'F'))
671 return (ch -
'A' + 10);
679 static int do_printk = 0;
689 for (i = 0; i <
count; i++) {
695 for (i = 0; i <
count; i++) {
697 buf = hex_byte_pack(buf, ch);
709 static unsigned char*
710 hex2mem (
unsigned char *mem,
char *buf,
int count)
714 for (i = 0; i <
count; i++) {
715 ch = hex (*buf++) << 4;
716 ch = ch + hex (*buf++);
726 static unsigned char*
727 bin2mem (
unsigned char *mem,
unsigned char *buf,
int count)
731 for (i = 0; i <
count; i++) {
736 if (*next == 0x3 || *next == 0x4 || *next == 0x5D)
753 unsigned char xmitcsum;
768 checksum = checksum + ch;
772 buffer[
count] =
'\0';
777 if (checksum != xmitcsum) {
785 if (buffer[2] ==
':') {
789 count = gdb_cris_strlen (buffer);
790 for (i = 3; i <=
count; i++)
791 buffer[i - 3] = buffer[i];
795 }
while (checksum != xmitcsum);
801 putpacket(
char *buffer)
816 while (runlen <
RUNLENMAX && *src == src[runlen]) {
823 encode = runlen +
' ' - 4;
843 remcomOutBuffer[0] =
'O';
844 mem2hex(&remcomOutBuffer[1], (
unsigned char *)str, length);
845 putpacket(remcomOutBuffer);
860 stub_is_stopped(
int sigval)
862 char *
ptr = remcomOutBuffer;
865 unsigned int reg_cont;
871 ptr = hex_byte_pack(ptr, sigval);
878 for (regno =
R0; regno <=
USP; regno++) {
881 status = read_register (regno, ®_cont);
884 ptr = hex_byte_pack(ptr, regno);
887 ptr = mem2hex(ptr, (
unsigned char *)®_cont,
888 register_size[regno]);
894 #ifdef PROCESS_SUPPORT
904 copy_registers (®_g, ®,
sizeof(
registers));
907 gdb_cris_strcpy (&remcomOutBuffer[
pos],
"thread:");
908 pos += gdb_cris_strlen (
"thread:");
911 gdb_cris_strcpy (&remcomOutBuffer[
pos],
";");
918 putpacket (remcomOutBuffer);
924 handle_exception (
int sigval)
933 stub_is_stopped (sigval);
936 remcomOutBuffer[0] =
'\0';
937 getpacket (remcomInBuffer);
938 switch (remcomInBuffer[0]) {
947 #ifdef PROCESS_SUPPORT
949 copy_registers (®_g, ®,
sizeof(
registers));
951 if (current_thread_g != executing_task) {
952 copy_registers_from_stack (current_thread_g, ®_g);
954 mem2hex ((
unsigned char *)remcomOutBuffer, (
unsigned char *)®_g,
sizeof(
registers));
956 mem2hex(remcomOutBuffer, (
char *)®,
sizeof(
registers));
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));
972 copy_registers_to_stack(current_thread_g, ®_g);
975 hex2mem((
char *)®, &remcomInBuffer[1],
sizeof(
registers));
977 gdb_cris_strcpy (remcomOutBuffer,
"OK");
990 int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16);
992 #ifdef PROCESS_SUPPORT
993 if (current_thread_g != executing_task)
994 status = write_stack_register (current_thread_g, regno, suffix+1);
997 status = write_register (regno, suffix+1);
1002 gdb_cris_strcpy (remcomOutBuffer, error_message[
E02]);
1006 gdb_cris_strcpy (remcomOutBuffer, error_message[
E05]);
1010 gdb_cris_strcpy (remcomOutBuffer, error_message[
E07]);
1014 gdb_cris_strcpy (remcomOutBuffer,
"OK");
1029 unsigned char *
addr = (
unsigned char *)gdb_cris_strtol(&remcomInBuffer[1],
1030 &suffix, 16);
int length = gdb_cris_strtol(suffix+1, 0, 16);
1032 mem2hex(remcomOutBuffer, addr, length);
1051 unsigned char *addr = (
unsigned char *)gdb_cris_strtol(&remcomInBuffer[1],
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);
1059 bin2mem(addr, dataptr + 1, length);
1061 gdb_cris_strcpy (remcomOutBuffer,
"OK");
1064 gdb_cris_strcpy (remcomOutBuffer, error_message[
E06]);
1075 if (remcomInBuffer[1] !=
'\0') {
1076 reg.
pc = gdb_cris_strtol (&remcomInBuffer[1], 0, 16);
1089 gdb_cris_strcpy (remcomOutBuffer, error_message[
E04]);
1090 putpacket (remcomOutBuffer);
1097 remcomOutBuffer[0] =
'S';
1100 remcomOutBuffer[3] = 0;
1130 gdb_cris_strcpy (remcomOutBuffer, error_message[
E04]);
1132 #ifdef PROCESS_SUPPORT
1140 int thread_id = (
int)gdb_cris_strtol (&remcomInBuffer[1], 0, 16);
1142 if (thread_id >= 0 && thread_id < number_of_tasks)
1143 gdb_cris_strcpy (remcomOutBuffer,
"OK");
1156 int thread_id = gdb_cris_strtol (&remcomInBuffer[2], 0, 16);
1157 if (remcomInBuffer[1] ==
'c') {
1161 gdb_cris_strcpy (remcomOutBuffer,
"OK");
1163 else if (remcomInBuffer[1] ==
'g') {
1167 if (thread_id >= 0 && thread_id < number_of_tasks) {
1168 current_thread_g = thread_id;
1169 gdb_cris_strcpy (remcomOutBuffer,
"OK");
1173 gdb_cris_strcpy (remcomOutBuffer, error_message[
E01]);
1178 gdb_cris_strcpy (remcomOutBuffer, error_message[
E01]);
1192 switch (remcomInBuffer[1]) {
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';
1201 gdb_cris_strcpy (&remcomOutBuffer[0],
"QM");
1203 if (os_is_started()) {
1204 remcomOutBuffer[2] =
hex_asc_hi(number_of_tasks);
1205 remcomOutBuffer[3] =
hex_asc_lo(number_of_tasks);
1216 remcomOutBuffer[pos] = remcomInBuffer[pos];
1218 if (os_is_started()) {
1220 for (thread_id = 0; thread_id < number_of_tasks; thread_id++) {
1222 for (; pos < nextpos; pos ++)
1224 remcomOutBuffer[pos++] =
hex_asc_lo(thread_id);
1229 nextpos = pos + HEXCHARS_IN_THREAD_ID - 1;
1230 for (; pos < nextpos; pos ++)
1232 remcomOutBuffer[pos++] =
hex_asc_lo(current_thread_c);
1234 remcomOutBuffer[
pos] =
'\0';
1239 remcomOutBuffer[0] = 0;
1250 remcomOutBuffer[0] = 0;
1253 putpacket(remcomOutBuffer);
1274 .global kgdb_handle_breakpoint
1275 kgdb_handle_breakpoint:
1277 ;; Response to the break-instruction
1279 ;; Create a register image of the caller
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
1321 subq 2,$r0 ; rerun the instruction the break replaced
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
1328 ;; Handle the communication
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
1334 ;; Return to the caller
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
1351 ;; FIXME: Which registers should be restored?
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.
1371 .global kgdb_handle_serial
1374 ;; Response to a serial interrupt
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
1411 ;; get the serial character (from debugport.c) and check if it is a ctrl-c
1418 move.d [reg+0x5E], $r10 ; Get DCCR
1419 btstq 8, $r10 ; Test the U-flag.
1424 ;; Handle the communication
1426 move.d internal_stack+1020,$sp ; Use the internal stack
1427 moveq 2,$r10 ; SIGINT
1428 jsr handle_exception ; Interactive routine
1432 ;; Return to the caller
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
1449 ;; FIXME: Which registers should be restored?
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