File: /usr/src/linux/arch/s390x/kernel/gdb-stub.c

1     /*
2      *  arch/s390/kernel/gdb-stub.c
3      *
4      *  S390 version
5      *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
6      *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
7      *
8      *  Originally written by Glenn Engel, Lake Stevens Instrument Division
9      *
10      *  Contributed by HP Systems
11      *
12      *  Modified for SPARC by Stu Grossman, Cygnus Support.
13      *
14      *  Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
15      *  Send complaints, suggestions etc. to <andy@waldorf-gmbh.de>
16      *
17      *  Copyright (C) 1995 Andreas Busse
18      */
19     
20     /*
21      *  To enable debugger support, two things need to happen.  One, a
22      *  call to set_debug_traps() is necessary in order to allow any breakpoints
23      *  or error conditions to be properly intercepted and reported to gdb.
24      *  Two, a breakpoint needs to be generated to begin communication.  This
25      *  is most easily accomplished by a call to breakpoint().  Breakpoint()
26      *  simulates a breakpoint by executing a BREAK instruction.
27      *
28      *
29      *    The following gdb commands are supported:
30      *
31      * command          function                               Return value
32      *
33      *    g             return the value of the CPU registers  hex data or ENN
34      *    G             set the value of the CPU registers     OK or ENN
35      *
36      *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA      hex data or ENN
37      *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA      OK or ENN
38      *
39      *    c             Resume at current address              SNN   ( signal NN)
40      *    cAA..AA       Continue at address AA..AA             SNN
41      *
42      *    s             Step one instruction                   SNN
43      *    sAA..AA       Step one instruction from AA..AA       SNN
44      *
45      *    k             kill
46      *
47      *    ?             What was the last sigval ?             SNN   (signal NN)
48      *
49      *
50      * All commands and responses are sent with a packet which includes a
51      * checksum.  A packet consists of
52      *
53      * $<packet info>#<checksum>.
54      *
55      * where
56      * <packet info> :: <characters representing the command or response>
57      * <checksum>    :: < two hex digits computed as modulo 256 sum of <packetinfo>>
58      *
59      * When a packet is received, it is first acknowledged with either '+' or '-'.
60      * '+' indicates a successful transfer.  '-' indicates a failed transfer.
61      *
62      * Example:
63      *
64      * Host:                  Reply:
65      * $m0,10#2a               +$00010203040506070809101112131415#42
66      *
67      */
68     
69     #include <asm/gdb-stub.h>
70     #include <linux/string.h>
71     #include <linux/kernel.h>
72     #include <linux/signal.h>
73     #include <linux/sched.h>
74     #include <linux/mm.h>
75     #include <asm/pgtable.h>
76     #include <asm/system.h>
77     
78     
79     /*
80      * external low-level support routines
81      */
82     
83     extern int putDebugChar(char c);    /* write a single character      */
84     extern char getDebugChar(void);     /* read and return a single char */
85     extern void fltr_set_mem_err(void);
86     extern void trap_low(void);
87     
88     /*
89      * breakpoint and test functions
90      */
91     extern void breakpoint(void);
92     extern void breakinst(void);
93     
94     /*
95      * local prototypes
96      */
97     
98     static void getpacket(char *buffer);
99     static void putpacket(char *buffer);
100     static int hex(unsigned char ch);
101     static int hexToInt(char **ptr, int *intValue);
102     static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault);
103     
104     
105     /*
106      * BUFMAX defines the maximum number of characters in inbound/outbound buffers
107      * at least NUMREGBYTES*2 are needed for register packets
108      */
109     #define BUFMAX 2048
110     
111     static char input_buffer[BUFMAX];
112     static char output_buffer[BUFMAX];
113     int gdb_stub_initialised = FALSE;	
114     static const char hexchars[]="0123456789abcdef";
115     
116     
117     /*
118      * Convert ch from a hex digit to an int
119      */
120     static int hex(unsigned char ch)
121     {
122     	if (ch >= 'a' && ch <= 'f')
123     		return ch-'a'+10;
124     	if (ch >= '0' && ch <= '9')
125     		return ch-'0';
126     	if (ch >= 'A' && ch <= 'F')
127     		return ch-'A'+10;
128     	return -1;
129     }
130     
131     /*
132      * scan for the sequence $<data>#<checksum>
133      */
134     static void getpacket(char *buffer)
135     {
136     	unsigned char checksum;
137     	unsigned char xmitcsum;
138     	int i;
139     	int count;
140     	unsigned char ch;
141     
142     	do {
143     		/*
144     		 * wait around for the start character,
145     		 * ignore all other characters
146     		 */
147     		while ((ch = (getDebugChar() & 0x7f)) != '$') ;
148     
149     		checksum = 0;
150     		xmitcsum = -1;
151     		count = 0;
152     	
153     		/*
154     		 * now, read until a # or end of buffer is found
155     		 */
156     		while (count < BUFMAX) {
157     			ch = getDebugChar() & 0x7f;
158     			if (ch == '#')
159     				break;
160     			checksum = checksum + ch;
161     			buffer[count] = ch;
162     			count = count + 1;
163     		}
164     
165     		if (count >= BUFMAX)
166     			continue;
167     
168     		buffer[count] = 0;
169     
170     		if (ch == '#') {
171     			xmitcsum = hex(getDebugChar() & 0x7f) << 4;
172     			xmitcsum |= hex(getDebugChar() & 0x7f);
173     
174     			if (checksum != xmitcsum)
175     				putDebugChar('-');	/* failed checksum */
176     			else {
177     				putDebugChar('+'); /* successful transfer */
178     
179     				/*
180     				 * if a sequence char is present,
181     				 * reply the sequence ID
182     				 */
183     				if (buffer[2] == ':') {
184     					putDebugChar(buffer[0]);
185     					putDebugChar(buffer[1]);
186     
187     					/*
188     					 * remove sequence chars from buffer
189     					 */
190     					count = strlen(buffer);
191     					for (i=3; i <= count; i++)
192     						buffer[i-3] = buffer[i];
193     				}
194     			}
195     		}
196     	}
197     	while (checksum != xmitcsum);
198     }
199     
200     /*
201      * send the packet in buffer.
202      */
203     static void putpacket(char *buffer)
204     {
205     	unsigned char checksum;
206     	int count;
207     	unsigned char ch;
208     
209     	/*
210     	 * $<packet info>#<checksum>.
211     	 */
212     
213     	do {
214     		putDebugChar('$');
215     		checksum = 0;
216     		count = 0;
217     
218     		while ((ch = buffer[count]) != 0) {
219     			if (!(putDebugChar(ch)))
220     				return;
221     			checksum += ch;
222     			count += 1;
223     		}
224     
225     		putDebugChar('#');
226     		putDebugChar(hexchars[checksum >> 4]);
227     		putDebugChar(hexchars[checksum & 0xf]);
228     
229     	}
230     	while ((getDebugChar() & 0x7f) != '+');
231     }
232     
233     
234     
235     /*
236      * Convert the memory pointed to by mem into hex, placing result in buf.
237      * Return a pointer to the last char put in buf (null), in case of mem fault,
238      * return 0.
239      * If MAY_FAULT is non-zero, then we will handle memory faults by returning
240      * a 0, else treat a fault like any other fault in the stub.
241      */
242     static unsigned char *mem2hex(char *mem, char *buf, int count, int may_fault)
243     {
244     	unsigned char ch;
245     
246     /*	set_mem_fault_trap(may_fault); */
247     
248     	while (count-- > 0) {
249     		ch = *(mem++);
250     		if (mem_err)
251     			return 0;
252     		*buf++ = hexchars[ch >> 4];
253     		*buf++ = hexchars[ch & 0xf];
254     	}
255     
256     	*buf = 0;
257     
258     /*	set_mem_fault_trap(0); */
259     
260     	return buf;
261     }
262     
263     /*
264      * convert the hex array pointed to by buf into binary to be placed in mem
265      * return a pointer to the character AFTER the last byte written
266      */
267     static char *hex2mem(char *buf, char *mem, int count, int may_fault)
268     {
269     	int i;
270     	unsigned char ch;
271     
272     /*	set_mem_fault_trap(may_fault); */
273     
274     	for (i=0; i<count; i++)
275     	{
276     		ch = hex(*buf++) << 4;
277     		ch |= hex(*buf++);
278     		*(mem++) = ch;
279     		if (mem_err)
280     			return 0;
281     	}
282     
283     /*	set_mem_fault_trap(0); */
284     
285     	return mem;
286     }
287     
288     
289     
290     /*
291      * Set up exception handlers for tracing and breakpoints
292      */
293     void set_debug_traps(void)
294     {
295     //	unsigned long flags;
296     	unsigned char c;
297     
298     //	save_and_cli(flags);
299     	/*
300     	 * In case GDB is started before us, ack any packets
301     	 * (presumably "$?#xx") sitting there.
302     	 */
303     	while((c = getDebugChar()) != '$');
304     	while((c = getDebugChar()) != '#');
305     	c = getDebugChar(); /* eat first csum byte */
306     	c = getDebugChar(); /* eat second csum byte */
307     	putDebugChar('+'); /* ack it */
308     
309     	gdb_stub_initialised = TRUE;
310     //	restore_flags(flags);
311     }
312     
313     
314     /*
315      * Trap handler for memory errors.  This just sets mem_err to be non-zero.  It
316      * assumes that %l1 is non-zero.  This should be safe, as it is doubtful that
317      * 0 would ever contain code that could mem fault.  This routine will skip
318      * past the faulting instruction after setting mem_err.
319      */
320     extern void fltr_set_mem_err(void)
321     {
322       /* FIXME: Needs to be written... */
323     }
324     
325     
326     /*
327      * While we find nice hex chars, build an int.
328      * Return number of chars processed.
329      */
330     static int hexToInt(char **ptr, int *intValue)
331     {
332     	int numChars = 0;
333     	int hexValue;
334     
335     	*intValue = 0;
336     
337     	while (**ptr)
338     	{
339     		hexValue = hex(**ptr);
340     		if (hexValue < 0)
341     			break;
342     
343     		*intValue = (*intValue << 4) | hexValue;
344     		numChars ++;
345     
346     		(*ptr)++;
347     	}
348     
349     	return (numChars);
350     }
351     
352     void gdb_stub_get_non_pt_regs(gdb_pt_regs *regs)
353     {
354     	s390_fp_regs *fpregs=&regs->fp_regs;
355     	int has_ieee=save_fp_regs1(fpregs);
356     
357     	if(!has_ieee)
358     	{
359     		fpregs->fpc=0;
360     		fpregs->fprs[1].d=
361     		fpregs->fprs[3].d=
362     		fpregs->fprs[5].d=
363     		fpregs->fprs[7].d=0;
364     		memset(&fpregs->fprs[8].d,0,sizeof(freg_t)*8);
365     	}
366     }
367     
368     void gdb_stub_set_non_pt_regs(gdb_pt_regs *regs)
369     {
370     	restore_fp_regs1(&regs->fp_regs);
371     }
372     
373     void gdb_stub_send_signal(int sigval)
374     {
375     	char *ptr;
376     	ptr = output_buffer;
377     
378     	/*
379     	 * Send trap type (converted to signal)
380     	 */
381     	*ptr++ = 'S';
382     	*ptr++ = hexchars[sigval >> 4];
383     	*ptr++ = hexchars[sigval & 0xf];
384     	*ptr++ = 0;
385     	putpacket(output_buffer);	/* send it off... */
386     }
387     
388     /*
389      * This function does all command processing for interfacing to gdb.  It
390      * returns 1 if you should skip the instruction at the trap address, 0
391      * otherwise.
392      */
393     void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
394     {
395     	int trap;			/* Trap type */
396     	int addr;
397     	int length;
398     	char *ptr;
399     	unsigned long *stack;
400     
401     	
402     	/*
403     	 * reply to host that an exception has occurred
404     	 */
405     	send_signal(sigval);
406     
407     	/*
408     	 * Wait for input from remote GDB
409     	 */
410     	while (1) {
411     		output_buffer[0] = 0;
412     		getpacket(input_buffer);
413     
414     		switch (input_buffer[0])
415     		{
416     		case '?':
417     			send_signal(sigval);
418     			continue;
419     
420     		case 'd':
421     			/* toggle debug flag */
422     			break;
423     
424     		/*
425     		 * Return the value of the CPU registers
426     		 */
427     		case 'g':
428     			gdb_stub_get_non_pt_regs(regs);
429     			ptr = output_buffer;
430     			ptr=  mem2hex((char *)regs,ptr,sizeof(s390_regs_common),FALSE);
431     			ptr=  mem2hex((char *)&regs->crs[0],ptr,NUM_CRS*CR_SIZE,FALSE);
432     			ptr = mem2hex((char *)&regs->fp_regs, ptr,sizeof(s390_fp_regs));
433     			break;
434     	  
435     		/*
436     		 * set the value of the CPU registers - return OK
437     		 * FIXME: Needs to be written
438     		 */
439     		case 'G':
440     			ptr=input_buffer;
441     			hex2mem (ptr, (char *)regs,sizeof(s390_regs_common), FALSE);
442     			ptr+=sizeof(s390_regs_common)*2;
443     			hex2mem (ptr, (char *)regs->crs[0],NUM_CRS*CR_SIZE, FALSE);
444     			ptr+=NUM_CRS*CR_SIZE*2;
445     			hex2mem (ptr, (char *)regs->fp_regs,sizeof(s390_fp_regs), FALSE);
446     			gdb_stub_set_non_pt_regs(regs);
447     			strcpy(output_buffer,"OK");
448     		break;
449     
450     		/*
451     		 * mAA..AA,LLLL  Read LLLL bytes at address AA..AA
452     		 */
453     		case 'm':
454     			ptr = &input_buffer[1];
455     
456     			if (hexToInt(&ptr, &addr)
457     				&& *ptr++ == ','
458     				&& hexToInt(&ptr, &length)) {
459     				if (mem2hex((char *)addr, output_buffer, length, 1))
460     					break;
461     				strcpy (output_buffer, "E03");
462     			} else
463     				strcpy(output_buffer,"E01");
464     			break;
465     
466     		/*
467     		 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK
468     		 */
469     		case 'M': 
470     			ptr = &input_buffer[1];
471     
472     			if (hexToInt(&ptr, &addr)
473     				&& *ptr++ == ','
474     				&& hexToInt(&ptr, &length)
475     				&& *ptr++ == ':') {
476     				if (hex2mem(ptr, (char *)addr, length, 1))
477     					strcpy(output_buffer, "OK");
478     				else
479     					strcpy(output_buffer, "E03");
480     			}
481     			else
482     				strcpy(output_buffer, "E02");
483     			break;
484     
485     		/*
486     		 * cAA..AA    Continue at address AA..AA(optional)
487     		 */
488     		case 'c':    
489     			/* try to read optional parameter, pc unchanged if no parm */
490     
491     			ptr = &input_buffer[1];
492     			if (hexToInt(&ptr, &addr))
493     				regs->cp0_epc = addr;
494     	  
495     			/*
496     			 * Need to flush the instruction cache here, as we may
497     			 * have deposited a breakpoint, and the icache probably
498     			 * has no way of knowing that a data ref to some location
499     			 * may have changed something that is in the instruction
500     			 * cache.
501     			 * NB: We flush both caches, just to be sure...
502     			 */
503     
504     			flush_cache_all();
505     			return;
506     			/* NOTREACHED */
507     			break;
508     
509     
510     		/*
511     		 * kill the program
512     		 */
513     		case 'k' :
514     			break;		/* do nothing */
515     
516     
517     		/*
518     		 * Reset the whole machine (FIXME: system dependent)
519     		 */
520     		case 'r':
521     			break;
522     
523     
524     		/*
525     		 * Step to next instruction
526     		 */
527     		case 's':
528     			/*
529     			 * There is no single step insn in the MIPS ISA, so we
530     			 * use breakpoints and continue, instead.
531     			 */
532     			single_step(regs);
533     			flush_cache_all();
534     			return;
535     			/* NOTREACHED */
536     
537     		}
538     		break;
539     
540     		}			/* switch */
541     
542     		/*
543     		 * reply to the request
544     		 */
545     
546     		putpacket(output_buffer);
547     
548     	} /* while */
549     }
550     
551     /*
552      * This function will generate a breakpoint exception.  It is used at the
553      * beginning of a program to sync up with a debugger and can be used
554      * otherwise as a quick means to stop program execution and "break" into
555      * the debugger.
556      */
557     void breakpoint(void)
558     {
559     	if (!gdb_stub_initialised)
560     		return;
561     	__asm__ __volatile__(
562     			".globl	breakinst\n"
563     			"breakinst:\t.word   %0\n\t"
564     			:
565     			: "i" (S390_BREAKPOINT_U16)
566     				:
567     				);
568     }
569     
570     
571     
572     
573     
574     
575     
576