diff options
Diffstat (limited to 'arch/cris')
-rw-r--r-- | arch/cris/arch-v10/kernel/kgdb.c | 257 |
1 files changed, 2 insertions, 255 deletions
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c index 0e799073498d..22d846bfc570 100644 --- a/arch/cris/arch-v10/kernel/kgdb.c +++ b/arch/cris/arch-v10/kernel/kgdb.c | |||
@@ -341,16 +341,6 @@ static int consistency_status = SUCCESS; | |||
341 | in order to provide access mainly for 'g', 'G' and 'P'. | 341 | in order to provide access mainly for 'g', 'G' and 'P'. |
342 | */ | 342 | */ |
343 | 343 | ||
344 | #ifdef PROCESS_SUPPORT | ||
345 | /* Need two task id pointers in order to handle Hct and Hgt commands. */ | ||
346 | static int current_thread_c = 0; | ||
347 | static int current_thread_g = 0; | ||
348 | |||
349 | /* Need two register images in order to handle Hct and Hgt commands. The | ||
350 | variable reg_g is in addition to cris_reg above. */ | ||
351 | static registers reg_g; | ||
352 | #endif /* PROCESS_SUPPORT */ | ||
353 | |||
354 | /********************************** Breakpoint *******************************/ | 344 | /********************************** Breakpoint *******************************/ |
355 | /* Use an internal stack in the breakpoint and interrupt response routines */ | 345 | /* Use an internal stack in the breakpoint and interrupt response routines */ |
356 | #define INTERNAL_STACK_SIZE 1024 | 346 | #define INTERNAL_STACK_SIZE 1024 |
@@ -608,55 +598,6 @@ putDebugString (const unsigned char *str, int length) | |||
608 | } | 598 | } |
609 | 599 | ||
610 | /********************************* Register image ****************************/ | 600 | /********************************* Register image ****************************/ |
611 | #ifdef PROCESS_SUPPORT | ||
612 | /* Copy the content of a register image into another. The size n is | ||
613 | the size of the register image. Due to struct assignment generation of | ||
614 | memcpy in libc. */ | ||
615 | static void | ||
616 | copy_registers (registers *dptr, registers *sptr, int n) | ||
617 | { | ||
618 | unsigned char *dreg; | ||
619 | unsigned char *sreg; | ||
620 | |||
621 | for (dreg = (unsigned char*)dptr, sreg = (unsigned char*)sptr; n > 0; n--) | ||
622 | *dreg++ = *sreg++; | ||
623 | } | ||
624 | |||
625 | /* Copy the stored registers from the stack. Put the register contents | ||
626 | of thread thread_id in the struct reg. */ | ||
627 | static void | ||
628 | copy_registers_from_stack (int thread_id, registers *regptr) | ||
629 | { | ||
630 | int j; | ||
631 | stack_registers *s = (stack_registers *)stack_list[thread_id]; | ||
632 | unsigned int *d = (unsigned int *)regptr; | ||
633 | |||
634 | for (j = 13; j >= 0; j--) | ||
635 | *d++ = s->r[j]; | ||
636 | regptr->sp = (unsigned int)stack_list[thread_id]; | ||
637 | regptr->pc = s->pc; | ||
638 | regptr->dccr = s->dccr; | ||
639 | regptr->srp = s->srp; | ||
640 | } | ||
641 | |||
642 | /* Copy the registers to the stack. Put the register contents of thread | ||
643 | thread_id from struct reg to the stack. */ | ||
644 | static void | ||
645 | copy_registers_to_stack (int thread_id, registers *regptr) | ||
646 | { | ||
647 | int i; | ||
648 | stack_registers *d = (stack_registers *)stack_list[thread_id]; | ||
649 | unsigned int *s = (unsigned int *)regptr; | ||
650 | |||
651 | for (i = 0; i < 14; i++) { | ||
652 | d->r[i] = *s++; | ||
653 | } | ||
654 | d->pc = regptr->pc; | ||
655 | d->dccr = regptr->dccr; | ||
656 | d->srp = regptr->srp; | ||
657 | } | ||
658 | #endif | ||
659 | |||
660 | /* Write a value to a specified register in the register image of the current | 601 | /* Write a value to a specified register in the register image of the current |
661 | thread. Returns status code SUCCESS, E02 or E05. */ | 602 | thread. Returns status code SUCCESS, E02 or E05. */ |
662 | static int | 603 | static int |
@@ -692,40 +633,6 @@ write_register (int regno, char *val) | |||
692 | return status; | 633 | return status; |
693 | } | 634 | } |
694 | 635 | ||
695 | #ifdef PROCESS_SUPPORT | ||
696 | /* Write a value to a specified register in the stack of a thread other | ||
697 | than the current thread. Returns status code SUCCESS or E07. */ | ||
698 | static int | ||
699 | write_stack_register (int thread_id, int regno, char *valptr) | ||
700 | { | ||
701 | int status = SUCCESS; | ||
702 | stack_registers *d = (stack_registers *)stack_list[thread_id]; | ||
703 | unsigned int val; | ||
704 | |||
705 | hex2mem ((unsigned char *)&val, valptr, sizeof(unsigned int)); | ||
706 | if (regno >= R0 && regno < SP) { | ||
707 | d->r[regno] = val; | ||
708 | } | ||
709 | else if (regno == SP) { | ||
710 | stack_list[thread_id] = val; | ||
711 | } | ||
712 | else if (regno == PC) { | ||
713 | d->pc = val; | ||
714 | } | ||
715 | else if (regno == SRP) { | ||
716 | d->srp = val; | ||
717 | } | ||
718 | else if (regno == DCCR) { | ||
719 | d->dccr = val; | ||
720 | } | ||
721 | else { | ||
722 | /* Do not support registers in the current thread. */ | ||
723 | status = E07; | ||
724 | } | ||
725 | return status; | ||
726 | } | ||
727 | #endif | ||
728 | |||
729 | /* Read a value from a specified register in the register image. Returns the | 636 | /* Read a value from a specified register in the register image. Returns the |
730 | value in the register or -1 for non-implemented registers. | 637 | value in the register or -1 for non-implemented registers. |
731 | Should check consistency_status after a call which may be E05 after changes | 638 | Should check consistency_status after a call which may be E05 after changes |
@@ -811,26 +718,6 @@ stub_is_stopped(int sigval) | |||
811 | 718 | ||
812 | } | 719 | } |
813 | 720 | ||
814 | #ifdef PROCESS_SUPPORT | ||
815 | /* Store the registers of the executing thread. Assume that both step, | ||
816 | continue, and register content requests are with respect to this | ||
817 | thread. The executing task is from the operating system scheduler. */ | ||
818 | |||
819 | current_thread_c = executing_task; | ||
820 | current_thread_g = executing_task; | ||
821 | |||
822 | /* A struct assignment translates into a libc memcpy call. Avoid | ||
823 | all libc functions in order to prevent recursive break points. */ | ||
824 | copy_registers (®_g, &cris_reg, sizeof(registers)); | ||
825 | |||
826 | /* Store thread:r...; with the executing task TID. */ | ||
827 | gdb_cris_strcpy (&remcomOutBuffer[pos], "thread:"); | ||
828 | pos += gdb_cris_strlen ("thread:"); | ||
829 | remcomOutBuffer[pos++] = hex_asc_hi(executing_task); | ||
830 | remcomOutBuffer[pos++] = hex_asc_lo(executing_task); | ||
831 | gdb_cris_strcpy (&remcomOutBuffer[pos], ";"); | ||
832 | #endif | ||
833 | |||
834 | /* null-terminate and send it off */ | 721 | /* null-terminate and send it off */ |
835 | 722 | ||
836 | *ptr = 0; | 723 | *ptr = 0; |
@@ -865,19 +752,7 @@ handle_exception (int sigval) | |||
865 | in a register are in the same order the machine uses. | 752 | in a register are in the same order the machine uses. |
866 | Failure: void. */ | 753 | Failure: void. */ |
867 | 754 | ||
868 | { | 755 | mem2hex(remcomOutBuffer, (char *)&cris_reg, sizeof(registers)); |
869 | #ifdef PROCESS_SUPPORT | ||
870 | /* Use the special register content in the executing thread. */ | ||
871 | copy_registers (®_g, &cris_reg, sizeof(registers)); | ||
872 | /* Replace the content available on the stack. */ | ||
873 | if (current_thread_g != executing_task) { | ||
874 | copy_registers_from_stack (current_thread_g, ®_g); | ||
875 | } | ||
876 | mem2hex ((unsigned char *)remcomOutBuffer, (unsigned char *)®_g, sizeof(registers)); | ||
877 | #else | ||
878 | mem2hex(remcomOutBuffer, (char *)&cris_reg, sizeof(registers)); | ||
879 | #endif | ||
880 | } | ||
881 | break; | 756 | break; |
882 | 757 | ||
883 | case 'G': | 758 | case 'G': |
@@ -885,17 +760,7 @@ handle_exception (int sigval) | |||
885 | Each byte of register data is described by two hex digits. | 760 | Each byte of register data is described by two hex digits. |
886 | Success: OK | 761 | Success: OK |
887 | Failure: void. */ | 762 | Failure: void. */ |
888 | #ifdef PROCESS_SUPPORT | ||
889 | hex2mem ((unsigned char *)®_g, &remcomInBuffer[1], sizeof(registers)); | ||
890 | if (current_thread_g == executing_task) { | ||
891 | copy_registers (&cris_reg, ®_g, sizeof(registers)); | ||
892 | } | ||
893 | else { | ||
894 | copy_registers_to_stack(current_thread_g, ®_g); | ||
895 | } | ||
896 | #else | ||
897 | hex2mem((char *)&cris_reg, &remcomInBuffer[1], sizeof(registers)); | 763 | hex2mem((char *)&cris_reg, &remcomInBuffer[1], sizeof(registers)); |
898 | #endif | ||
899 | gdb_cris_strcpy (remcomOutBuffer, "OK"); | 764 | gdb_cris_strcpy (remcomOutBuffer, "OK"); |
900 | break; | 765 | break; |
901 | 766 | ||
@@ -911,12 +776,7 @@ handle_exception (int sigval) | |||
911 | char *suffix; | 776 | char *suffix; |
912 | int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16); | 777 | int regno = gdb_cris_strtol (&remcomInBuffer[1], &suffix, 16); |
913 | int status; | 778 | int status; |
914 | #ifdef PROCESS_SUPPORT | 779 | status = write_register (regno, suffix+1); |
915 | if (current_thread_g != executing_task) | ||
916 | status = write_stack_register (current_thread_g, regno, suffix+1); | ||
917 | else | ||
918 | #endif | ||
919 | status = write_register (regno, suffix+1); | ||
920 | 780 | ||
921 | switch (status) { | 781 | switch (status) { |
922 | case E02: | 782 | case E02: |
@@ -1051,119 +911,6 @@ handle_exception (int sigval) | |||
1051 | Not supported: E04 */ | 911 | Not supported: E04 */ |
1052 | gdb_cris_strcpy (remcomOutBuffer, error_message[E04]); | 912 | gdb_cris_strcpy (remcomOutBuffer, error_message[E04]); |
1053 | break; | 913 | break; |
1054 | #ifdef PROCESS_SUPPORT | ||
1055 | |||
1056 | case 'T': | ||
1057 | /* Thread alive. TXX | ||
1058 | Is thread XX alive? | ||
1059 | Success: OK, thread XX is alive. | ||
1060 | Failure: E03, thread XX is dead. */ | ||
1061 | { | ||
1062 | int thread_id = (int)gdb_cris_strtol (&remcomInBuffer[1], 0, 16); | ||
1063 | /* Cannot tell whether it is alive or not. */ | ||
1064 | if (thread_id >= 0 && thread_id < number_of_tasks) | ||
1065 | gdb_cris_strcpy (remcomOutBuffer, "OK"); | ||
1066 | } | ||
1067 | break; | ||
1068 | |||
1069 | case 'H': | ||
1070 | /* Set thread for subsequent operations: Hct | ||
1071 | c = 'c' for thread used in step and continue; | ||
1072 | t can be -1 for all threads. | ||
1073 | c = 'g' for thread used in other operations. | ||
1074 | t = 0 means pick any thread. | ||
1075 | Success: OK | ||
1076 | Failure: E01 */ | ||
1077 | { | ||
1078 | int thread_id = gdb_cris_strtol (&remcomInBuffer[2], 0, 16); | ||
1079 | if (remcomInBuffer[1] == 'c') { | ||
1080 | /* c = 'c' for thread used in step and continue */ | ||
1081 | /* Do not change current_thread_c here. It would create a mess in | ||
1082 | the scheduler. */ | ||
1083 | gdb_cris_strcpy (remcomOutBuffer, "OK"); | ||
1084 | } | ||
1085 | else if (remcomInBuffer[1] == 'g') { | ||
1086 | /* c = 'g' for thread used in other operations. | ||
1087 | t = 0 means pick any thread. Impossible since the scheduler does | ||
1088 | not allow that. */ | ||
1089 | if (thread_id >= 0 && thread_id < number_of_tasks) { | ||
1090 | current_thread_g = thread_id; | ||
1091 | gdb_cris_strcpy (remcomOutBuffer, "OK"); | ||
1092 | } | ||
1093 | else { | ||
1094 | /* Not expected - send an error message. */ | ||
1095 | gdb_cris_strcpy (remcomOutBuffer, error_message[E01]); | ||
1096 | } | ||
1097 | } | ||
1098 | else { | ||
1099 | /* Not expected - send an error message. */ | ||
1100 | gdb_cris_strcpy (remcomOutBuffer, error_message[E01]); | ||
1101 | } | ||
1102 | } | ||
1103 | break; | ||
1104 | |||
1105 | case 'q': | ||
1106 | case 'Q': | ||
1107 | /* Query of general interest. qXXXX | ||
1108 | Set general value XXXX. QXXXX=yyyy */ | ||
1109 | { | ||
1110 | int pos; | ||
1111 | int nextpos; | ||
1112 | int thread_id; | ||
1113 | |||
1114 | switch (remcomInBuffer[1]) { | ||
1115 | case 'C': | ||
1116 | /* Identify the remote current thread. */ | ||
1117 | gdb_cris_strcpy (&remcomOutBuffer[0], "QC"); | ||
1118 | remcomOutBuffer[2] = hex_asc_hi(current_thread_c); | ||
1119 | remcomOutBuffer[3] = hex_asc_lo(current_thread_c); | ||
1120 | remcomOutBuffer[4] = '\0'; | ||
1121 | break; | ||
1122 | case 'L': | ||
1123 | gdb_cris_strcpy (&remcomOutBuffer[0], "QM"); | ||
1124 | /* Reply with number of threads. */ | ||
1125 | if (os_is_started()) { | ||
1126 | remcomOutBuffer[2] = hex_asc_hi(number_of_tasks); | ||
1127 | remcomOutBuffer[3] = hex_asc_lo(number_of_tasks); | ||
1128 | } | ||
1129 | else { | ||
1130 | remcomOutBuffer[2] = hex_asc_hi(0); | ||
1131 | remcomOutBuffer[3] = hex_asc_lo(1); | ||
1132 | } | ||
1133 | /* Done with the reply. */ | ||
1134 | remcomOutBuffer[4] = hex_asc_lo(1); | ||
1135 | pos = 5; | ||
1136 | /* Expects the argument thread id. */ | ||
1137 | for (; pos < (5 + HEXCHARS_IN_THREAD_ID); pos++) | ||
1138 | remcomOutBuffer[pos] = remcomInBuffer[pos]; | ||
1139 | /* Reply with the thread identifiers. */ | ||
1140 | if (os_is_started()) { | ||
1141 | /* Store the thread identifiers of all tasks. */ | ||
1142 | for (thread_id = 0; thread_id < number_of_tasks; thread_id++) { | ||
1143 | nextpos = pos + HEXCHARS_IN_THREAD_ID - 1; | ||
1144 | for (; pos < nextpos; pos ++) | ||
1145 | remcomOutBuffer[pos] = hex_asc_lo(0); | ||
1146 | remcomOutBuffer[pos++] = hex_asc_lo(thread_id); | ||
1147 | } | ||
1148 | } | ||
1149 | else { | ||
1150 | /* Store the thread identifier of the boot task. */ | ||
1151 | nextpos = pos + HEXCHARS_IN_THREAD_ID - 1; | ||
1152 | for (; pos < nextpos; pos ++) | ||
1153 | remcomOutBuffer[pos] = hex_asc_lo(0); | ||
1154 | remcomOutBuffer[pos++] = hex_asc_lo(current_thread_c); | ||
1155 | } | ||
1156 | remcomOutBuffer[pos] = '\0'; | ||
1157 | break; | ||
1158 | default: | ||
1159 | /* Not supported: "" */ | ||
1160 | /* Request information about section offsets: qOffsets. */ | ||
1161 | remcomOutBuffer[0] = 0; | ||
1162 | break; | ||
1163 | } | ||
1164 | } | ||
1165 | break; | ||
1166 | #endif /* PROCESS_SUPPORT */ | ||
1167 | 914 | ||
1168 | default: | 915 | default: |
1169 | /* The stub should ignore other request and send an empty | 916 | /* The stub should ignore other request and send an empty |