aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-03-08 03:33:24 -0500
committerPaul Mundt <lethal@hera.kernel.org>2007-05-06 22:10:51 -0400
commitfc31b80957a14a60513d953cc67a55519a2b09c7 (patch)
tree0ec4b686bc0f05dc26dd46c8f38866818775ca86 /arch
parentfa5da2f7bdcf885efe65a37df13907c7d72296f6 (diff)
sh: Rip out broken kgdb thread support.
The kgdb thread support is woefully out of date (it predates the pidhash), and needs a complete rewrite before it's useful again. Just rip it out entirely. Updating the unified kgdb stub is a more worthwhile endeavour for anyone that happens to be interested in this, at present it's just limping along. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/sh/Kconfig.debug4
-rw-r--r--arch/sh/kernel/kgdb_stub.c386
2 files changed, 4 insertions, 386 deletions
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 6be2385c1ad2..931c620dbc24 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -104,10 +104,6 @@ config KGDB_NMI
104 bool "Enter KGDB on NMI" 104 bool "Enter KGDB on NMI"
105 default n 105 default n
106 106
107config KGDB_THREAD
108 bool "Include KGDB thread support"
109 default y
110
111config SH_KGDB_CONSOLE 107config SH_KGDB_CONSOLE
112 bool "Console messages through GDB" 108 bool "Console messages through GDB"
113 depends on !SERIAL_SH_SCI_CONSOLE 109 depends on !SERIAL_SH_SCI_CONSOLE
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index 737eadc8ce0f..a5323364cbca 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -243,14 +243,6 @@ static char out_buffer[OUTBUFMAX];
243 243
244static void kgdb_to_gdb(const char *s); 244static void kgdb_to_gdb(const char *s);
245 245
246#ifdef CONFIG_KGDB_THREAD
247static struct task_struct *trapped_thread;
248static struct task_struct *current_thread;
249typedef unsigned char threadref[8];
250#define BUF_THREAD_ID_SIZE 16
251#endif
252
253
254/* Convert ch to hex */ 246/* Convert ch to hex */
255static int hex(const char ch) 247static int hex(const char ch)
256{ 248{
@@ -346,66 +338,6 @@ static char *pack_hex_byte(char *pkt, int byte)
346 return pkt; 338 return pkt;
347} 339}
348 340
349#ifdef CONFIG_KGDB_THREAD
350
351/* Pack a thread ID */
352static char *pack_threadid(char *pkt, threadref * id)
353{
354 char *limit;
355 unsigned char *altid;
356
357 altid = (unsigned char *) id;
358
359 limit = pkt + BUF_THREAD_ID_SIZE;
360 while (pkt < limit)
361 pkt = pack_hex_byte(pkt, *altid++);
362 return pkt;
363}
364
365/* Convert an integer into our threadref */
366static void int_to_threadref(threadref * id, const int value)
367{
368 unsigned char *scan = (unsigned char *) id;
369 int i = 4;
370
371 while (i--)
372 *scan++ = 0;
373
374 *scan++ = (value >> 24) & 0xff;
375 *scan++ = (value >> 16) & 0xff;
376 *scan++ = (value >> 8) & 0xff;
377 *scan++ = (value & 0xff);
378}
379
380/* Return a task structure ptr for a particular pid */
381static struct task_struct *get_thread(int pid)
382{
383 struct task_struct *thread;
384
385 /* Use PID_MAX w/gdb for pid 0 */
386 if (pid == PID_MAX) pid = 0;
387
388 /* First check via PID */
389 thread = find_task_by_pid(pid);
390
391 if (thread)
392 return thread;
393
394 /* Start at the start */
395 thread = init_tasks[0];
396
397 /* Walk along the linked list of tasks */
398 do {
399 if (thread->pid == pid)
400 return thread;
401 thread = thread->next_task;
402 } while (thread != init_tasks[0]);
403
404 return NULL;
405}
406
407#endif /* CONFIG_KGDB_THREAD */
408
409/* Scan for the start char '$', read the packet and check the checksum */ 341/* Scan for the start char '$', read the packet and check the checksum */
410static void get_packet(char *buffer, int buflen) 342static void get_packet(char *buffer, int buflen)
411{ 343{
@@ -608,74 +540,6 @@ static void gdb_regs_to_kgdb_regs(const int *gdb_regs,
608 regs->vbr = gdb_regs[VBR]; 540 regs->vbr = gdb_regs[VBR];
609} 541}
610 542
611#ifdef CONFIG_KGDB_THREAD
612/* Make a local copy of registers from the specified thread */
613asmlinkage void ret_from_fork(void);
614static void thread_regs_to_gdb_regs(const struct task_struct *thread,
615 int *gdb_regs)
616{
617 int regno;
618 int *tregs;
619
620 /* Initialize to zero */
621 for (regno = 0; regno < MAXREG; regno++)
622 gdb_regs[regno] = 0;
623
624 /* Just making sure... */
625 if (thread == NULL)
626 return;
627
628 /* A new fork has pt_regs on the stack from a fork() call */
629 if (thread->thread.pc == (unsigned long)ret_from_fork) {
630
631 int vbr_val;
632 struct pt_regs *kregs;
633 kregs = (struct pt_regs*)thread->thread.sp;
634
635 gdb_regs[R0] = kregs->regs[R0];
636 gdb_regs[R1] = kregs->regs[R1];
637 gdb_regs[R2] = kregs->regs[R2];
638 gdb_regs[R3] = kregs->regs[R3];
639 gdb_regs[R4] = kregs->regs[R4];
640 gdb_regs[R5] = kregs->regs[R5];
641 gdb_regs[R6] = kregs->regs[R6];
642 gdb_regs[R7] = kregs->regs[R7];
643 gdb_regs[R8] = kregs->regs[R8];
644 gdb_regs[R9] = kregs->regs[R9];
645 gdb_regs[R10] = kregs->regs[R10];
646 gdb_regs[R11] = kregs->regs[R11];
647 gdb_regs[R12] = kregs->regs[R12];
648 gdb_regs[R13] = kregs->regs[R13];
649 gdb_regs[R14] = kregs->regs[R14];
650 gdb_regs[R15] = kregs->regs[R15];
651 gdb_regs[PC] = kregs->pc;
652 gdb_regs[PR] = kregs->pr;
653 gdb_regs[GBR] = kregs->gbr;
654 gdb_regs[MACH] = kregs->mach;
655 gdb_regs[MACL] = kregs->macl;
656 gdb_regs[SR] = kregs->sr;
657
658 asm("stc vbr, %0":"=r"(vbr_val));
659 gdb_regs[VBR] = vbr_val;
660 return;
661 }
662
663 /* Otherwise, we have only some registers from switch_to() */
664 tregs = (int *)thread->thread.sp;
665 gdb_regs[R15] = (int)tregs;
666 gdb_regs[R14] = *tregs++;
667 gdb_regs[R13] = *tregs++;
668 gdb_regs[R12] = *tregs++;
669 gdb_regs[R11] = *tregs++;
670 gdb_regs[R10] = *tregs++;
671 gdb_regs[R9] = *tregs++;
672 gdb_regs[R8] = *tregs++;
673 gdb_regs[PR] = *tregs++;
674 gdb_regs[GBR] = *tregs++;
675 gdb_regs[PC] = thread->thread.pc;
676}
677#endif /* CONFIG_KGDB_THREAD */
678
679/* Calculate the new address for after a step */ 543/* Calculate the new address for after a step */
680static short *get_step_address(void) 544static short *get_step_address(void)
681{ 545{
@@ -794,37 +658,11 @@ static void undo_single_step(void)
794/* Send a signal message */ 658/* Send a signal message */
795static void send_signal_msg(const int signum) 659static void send_signal_msg(const int signum)
796{ 660{
797#ifndef CONFIG_KGDB_THREAD
798 out_buffer[0] = 'S'; 661 out_buffer[0] = 'S';
799 out_buffer[1] = highhex(signum); 662 out_buffer[1] = highhex(signum);
800 out_buffer[2] = lowhex(signum); 663 out_buffer[2] = lowhex(signum);
801 out_buffer[3] = 0; 664 out_buffer[3] = 0;
802 put_packet(out_buffer); 665 put_packet(out_buffer);
803#else /* CONFIG_KGDB_THREAD */
804 int threadid;
805 threadref thref;
806 char *out = out_buffer;
807 const char *tstring = "thread";
808
809 *out++ = 'T';
810 *out++ = highhex(signum);
811 *out++ = lowhex(signum);
812
813 while (*tstring) {
814 *out++ = *tstring++;
815 }
816 *out++ = ':';
817
818 threadid = trapped_thread->pid;
819 if (threadid == 0) threadid = PID_MAX;
820 int_to_threadref(&thref, threadid);
821 pack_threadid(out, &thref);
822 out += BUF_THREAD_ID_SIZE;
823 *out++ = ';';
824
825 *out = 0;
826 put_packet(out_buffer);
827#endif /* CONFIG_KGDB_THREAD */
828} 666}
829 667
830/* Reply that all was well */ 668/* Reply that all was well */
@@ -959,15 +797,7 @@ static void step_with_sig_msg(void)
959/* Send register contents */ 797/* Send register contents */
960static void send_regs_msg(void) 798static void send_regs_msg(void)
961{ 799{
962#ifdef CONFIG_KGDB_THREAD
963 if (!current_thread)
964 kgdb_regs_to_gdb_regs(&trap_registers, registers);
965 else
966 thread_regs_to_gdb_regs(current_thread, registers);
967#else
968 kgdb_regs_to_gdb_regs(&trap_registers, registers); 800 kgdb_regs_to_gdb_regs(&trap_registers, registers);
969#endif
970
971 mem_to_hex((char *) registers, out_buffer, NUMREGBYTES); 801 mem_to_hex((char *) registers, out_buffer, NUMREGBYTES);
972 put_packet(out_buffer); 802 put_packet(out_buffer);
973} 803}
@@ -975,198 +805,11 @@ static void send_regs_msg(void)
975/* Set register contents - currently can't set other thread's registers */ 805/* Set register contents - currently can't set other thread's registers */
976static void set_regs_msg(void) 806static void set_regs_msg(void)
977{ 807{
978#ifdef CONFIG_KGDB_THREAD 808 kgdb_regs_to_gdb_regs(&trap_registers, registers);
979 if (!current_thread) { 809 hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
980#endif 810 gdb_regs_to_kgdb_regs(registers, &trap_registers);
981 kgdb_regs_to_gdb_regs(&trap_registers, registers); 811 send_ok_msg();
982 hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES);
983 gdb_regs_to_kgdb_regs(registers, &trap_registers);
984 send_ok_msg();
985#ifdef CONFIG_KGDB_THREAD
986 } else
987 send_err_msg();
988#endif
989}
990
991
992#ifdef CONFIG_KGDB_THREAD
993
994/* Set the status for a thread */
995void set_thread_msg(void)
996{
997 int threadid;
998 struct task_struct *thread = NULL;
999 char *ptr;
1000
1001 switch (in_buffer[1]) {
1002 /* To select which thread for gG etc messages, i.e. supported */
1003 case 'g':
1004 ptr = &in_buffer[2];
1005 hex_to_int(&ptr, &threadid);
1006 thread = get_thread(threadid);
1007
1008 /* If we haven't found it */
1009 if (!thread) {
1010 send_err_msg();
1011 break;
1012 }
1013
1014 /* Set current_thread (or not) */
1015 if (thread == trapped_thread)
1016 current_thread = NULL;
1017 else
1018 current_thread = thread;
1019 send_ok_msg();
1020 break;
1021
1022 /* To select which thread for cCsS messages, i.e. unsupported */
1023 case 'c':
1024 send_ok_msg();
1025 break;
1026
1027 default:
1028 send_empty_msg();
1029 break;
1030 }
1031}
1032
1033/* Is a thread alive? */
1034static void thread_status_msg(void)
1035{
1036 char *ptr;
1037 int threadid;
1038 struct task_struct *thread = NULL;
1039
1040 ptr = &in_buffer[1];
1041 hex_to_int(&ptr, &threadid);
1042 thread = get_thread(threadid);
1043 if (thread)
1044 send_ok_msg();
1045 else
1046 send_err_msg();
1047}
1048/* Send the current thread ID */
1049static void thread_id_msg(void)
1050{
1051 int threadid;
1052 threadref thref;
1053
1054 out_buffer[0] = 'Q';
1055 out_buffer[1] = 'C';
1056
1057 if (current_thread)
1058 threadid = current_thread->pid;
1059 else if (trapped_thread)
1060 threadid = trapped_thread->pid;
1061 else /* Impossible, but just in case! */
1062 {
1063 send_err_msg();
1064 return;
1065 }
1066
1067 /* Translate pid 0 to PID_MAX for gdb */
1068 if (threadid == 0) threadid = PID_MAX;
1069
1070 int_to_threadref(&thref, threadid);
1071 pack_threadid(out_buffer + 2, &thref);
1072 out_buffer[2 + BUF_THREAD_ID_SIZE] = '\0';
1073 put_packet(out_buffer);
1074}
1075
1076/* Send thread info */
1077static void thread_info_msg(void)
1078{
1079 struct task_struct *thread = NULL;
1080 int threadid;
1081 char *pos;
1082 threadref thref;
1083
1084 /* Start with 'm' */
1085 out_buffer[0] = 'm';
1086 pos = &out_buffer[1];
1087
1088 /* For all possible thread IDs - this will overrun if > 44 threads! */
1089 /* Start at 1 and include PID_MAX (since GDB won't use pid 0...) */
1090 for (threadid = 1; threadid <= PID_MAX; threadid++) {
1091
1092 read_lock(&tasklist_lock);
1093 thread = get_thread(threadid);
1094 read_unlock(&tasklist_lock);
1095
1096 /* If it's a valid thread */
1097 if (thread) {
1098 int_to_threadref(&thref, threadid);
1099 pack_threadid(pos, &thref);
1100 pos += BUF_THREAD_ID_SIZE;
1101 *pos++ = ',';
1102 }
1103 }
1104 *--pos = 0; /* Lose final comma */
1105 put_packet(out_buffer);
1106
1107}
1108
1109/* Return printable info for gdb's 'info threads' command */
1110static void thread_extra_info_msg(void)
1111{
1112 int threadid;
1113 struct task_struct *thread = NULL;
1114 char buffer[20], *ptr;
1115 int i;
1116
1117 /* Extract thread ID */
1118 ptr = &in_buffer[17];
1119 hex_to_int(&ptr, &threadid);
1120 thread = get_thread(threadid);
1121
1122 /* If we don't recognise it, say so */
1123 if (thread == NULL)
1124 strcpy(buffer, "(unknown)");
1125 else
1126 strcpy(buffer, thread->comm);
1127
1128 /* Construct packet */
1129 for (i = 0, ptr = out_buffer; buffer[i]; i++)
1130 ptr = pack_hex_byte(ptr, buffer[i]);
1131
1132 if (thread->thread.pc == (unsigned long)ret_from_fork) {
1133 strcpy(buffer, "<new fork>");
1134 for (i = 0; buffer[i]; i++)
1135 ptr = pack_hex_byte(ptr, buffer[i]);
1136 }
1137
1138 *ptr = '\0';
1139 put_packet(out_buffer);
1140}
1141
1142/* Handle all qFooBarBaz messages - have to use an if statement as
1143 opposed to a switch because q messages can have > 1 char id. */
1144static void query_msg(void)
1145{
1146 const char *q_start = &in_buffer[1];
1147
1148 /* qC = return current thread ID */
1149 if (strncmp(q_start, "C", 1) == 0)
1150 thread_id_msg();
1151
1152 /* qfThreadInfo = query all threads (first) */
1153 else if (strncmp(q_start, "fThreadInfo", 11) == 0)
1154 thread_info_msg();
1155
1156 /* qsThreadInfo = query all threads (subsequent). We know we have sent
1157 them all after the qfThreadInfo message, so there are no to send */
1158 else if (strncmp(q_start, "sThreadInfo", 11) == 0)
1159 put_packet("l"); /* el = last */
1160
1161 /* qThreadExtraInfo = supply printable information per thread */
1162 else if (strncmp(q_start, "ThreadExtraInfo", 15) == 0)
1163 thread_extra_info_msg();
1164
1165 /* Unsupported - empty message as per spec */
1166 else
1167 send_empty_msg();
1168} 812}
1169#endif /* CONFIG_KGDB_THREAD */
1170 813
1171#ifdef CONFIG_SH_KGDB_CONSOLE 814#ifdef CONFIG_SH_KGDB_CONSOLE
1172/* 815/*
@@ -1206,12 +849,6 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
1206 if (!kgdb_enabled) 849 if (!kgdb_enabled)
1207 return; 850 return;
1208 851
1209#ifdef CONFIG_KGDB_THREAD
1210 /* Until GDB specifies a thread */
1211 current_thread = NULL;
1212 trapped_thread = current;
1213#endif
1214
1215 /* Enter GDB mode (e.g. after detach) */ 852 /* Enter GDB mode (e.g. after detach) */
1216 if (!kgdb_in_gdb_mode) { 853 if (!kgdb_in_gdb_mode) {
1217 /* Do serial setup, notify user, issue preemptive ack */ 854 /* Do serial setup, notify user, issue preemptive ack */
@@ -1284,21 +921,6 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value)
1284 step_msg(); 921 step_msg();
1285 return; 922 return;
1286 923
1287#ifdef CONFIG_KGDB_THREAD
1288
1289 case 'H': /* Task related */
1290 set_thread_msg();
1291 break;
1292
1293 case 'T': /* Query thread status */
1294 thread_status_msg();
1295 break;
1296
1297 case 'q': /* Handle query - currently thread-related */
1298 query_msg();
1299 break;
1300#endif
1301
1302 case 'k': /* 'Kill the program' with a kernel ? */ 924 case 'k': /* 'Kill the program' with a kernel ? */
1303 break; 925 break;
1304 926