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
83extern int putDebugChar(char c);    /* write a single character      */
84extern char getDebugChar(void);     /* read and return a single char */
85extern void fltr_set_mem_err(void);
86extern void trap_low(void);
87
88/*
89 * breakpoint and test functions
90 */
91extern void breakpoint(void);
92extern void breakinst(void);
93
94/*
95 * local prototypes
96 */
97
98static void getpacket(char *buffer);
99static void putpacket(char *buffer);
100static int hex(unsigned char ch);
101static int hexToInt(char **ptr, int *intValue);
102static 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
111static char input_buffer[BUFMAX];
112static char output_buffer[BUFMAX];
113int gdb_stub_initialised = FALSE;
114static const char hexchars[]="0123456789abcdef";
115
116
117/*
118 * Convert ch from a hex digit to an int
119 */
120static 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 */
134static 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 */
203static 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 */
242static 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 */
267static 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 */
293void 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 */
320extern void fltr_set_mem_err(void)
321{
322}
323
324
325/*
326 * While we find nice hex chars, build an int.
327 * Return number of chars processed.
328 */
329static int hexToInt(char **ptr, int *intValue)
330{
331	int numChars = 0;
332	int hexValue;
333
334	*intValue = 0;
335
336	while (**ptr)
337	{
338		hexValue = hex(**ptr);
339		if (hexValue < 0)
340			break;
341
342		*intValue = (*intValue << 4) | hexValue;
343		numChars ++;
344
345		(*ptr)++;
346	}
347
348	return (numChars);
349}
350
351void gdb_stub_get_non_pt_regs(gdb_pt_regs *regs)
352{
353	s390_fp_regs *fpregs=&regs->fp_regs;
354	int has_ieee=save_fp_regs1(fpregs);
355
356	if(!has_ieee)
357	{
358		fpregs->fpc=0;
359		fpregs->fprs[1].d=
360		fpregs->fprs[3].d=
361		fpregs->fprs[5].d=
362		fpregs->fprs[7].d=0;
363		memset(&fpregs->fprs[8].d,0,sizeof(freg_t)*8);
364	}
365}
366
367void gdb_stub_set_non_pt_regs(gdb_pt_regs *regs)
368{
369	restore_fp_regs1(&regs->fp_regs);
370}
371
372void gdb_stub_send_signal(int sigval)
373{
374	char *ptr;
375	ptr = output_buffer;
376
377	/*
378	 * Send trap type (converted to signal)
379	 */
380	*ptr++ = 'S';
381	*ptr++ = hexchars[sigval >> 4];
382	*ptr++ = hexchars[sigval & 0xf];
383	*ptr++ = 0;
384	putpacket(output_buffer);	/* send it off... */
385}
386
387/*
388 * This function does all command processing for interfacing to gdb.  It
389 * returns 1 if you should skip the instruction at the trap address, 0
390 * otherwise.
391 */
392void gdb_stub_handle_exception(gdb_pt_regs *regs,int sigval)
393{
394	int trap;			/* Trap type */
395	int addr;
396	int length;
397	char *ptr;
398	unsigned long *stack;
399
400
401	/*
402	 * reply to host that an exception has occurred
403	 */
404	send_signal(sigval);
405
406	/*
407	 * Wait for input from remote GDB
408	 */
409	while (1) {
410		output_buffer[0] = 0;
411		getpacket(input_buffer);
412
413		switch (input_buffer[0])
414		{
415		case '?':
416			send_signal(sigval);
417			continue;
418
419		case 'd':
420			/* toggle debug flag */
421			break;
422
423		/*
424		 * Return the value of the CPU registers
425		 */
426		case 'g':
427			gdb_stub_get_non_pt_regs(regs);
428			ptr = output_buffer;
429			ptr=  mem2hex((char *)regs,ptr,sizeof(s390_regs_common),FALSE);
430			ptr=  mem2hex((char *)&regs->crs[0],ptr,NUM_CRS*CR_SIZE,FALSE);
431			ptr = mem2hex((char *)&regs->fp_regs, ptr,sizeof(s390_fp_regs));
432			break;
433
434		case 'G':
435			ptr=input_buffer;
436			hex2mem (ptr, (char *)regs,sizeof(s390_regs_common), FALSE);
437			ptr+=sizeof(s390_regs_common)*2;
438			hex2mem (ptr, (char *)regs->crs[0],NUM_CRS*CR_SIZE, FALSE);
439			ptr+=NUM_CRS*CR_SIZE*2;
440			hex2mem (ptr, (char *)regs->fp_regs,sizeof(s390_fp_regs), FALSE);
441			gdb_stub_set_non_pt_regs(regs);
442			strcpy(output_buffer,"OK");
443		break;
444
445		/*
446		 * mAA..AA,LLLL  Read LLLL bytes at address AA..AA
447		 */
448		case 'm':
449			ptr = &input_buffer[1];
450
451			if (hexToInt(&ptr, &addr)
452				&& *ptr++ == ','
453				&& hexToInt(&ptr, &length)) {
454				if (mem2hex((char *)addr, output_buffer, length, 1))
455					break;
456				strcpy (output_buffer, "E03");
457			} else
458				strcpy(output_buffer,"E01");
459			break;
460
461		/*
462		 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK
463		 */
464		case 'M':
465			ptr = &input_buffer[1];
466
467			if (hexToInt(&ptr, &addr)
468				&& *ptr++ == ','
469				&& hexToInt(&ptr, &length)
470				&& *ptr++ == ':') {
471				if (hex2mem(ptr, (char *)addr, length, 1))
472					strcpy(output_buffer, "OK");
473				else
474					strcpy(output_buffer, "E03");
475			}
476			else
477				strcpy(output_buffer, "E02");
478			break;
479
480		/*
481		 * cAA..AA    Continue at address AA..AA(optional)
482		 */
483		case 'c':
484			/* try to read optional parameter, pc unchanged if no parm */
485
486			ptr = &input_buffer[1];
487			if (hexToInt(&ptr, &addr))
488				regs->cp0_epc = addr;
489
490			/*
491			 * Need to flush the instruction cache here, as we may
492			 * have deposited a breakpoint, and the icache probably
493			 * has no way of knowing that a data ref to some location
494			 * may have changed something that is in the instruction
495			 * cache.
496			 * NB: We flush both caches, just to be sure...
497			 */
498
499			flush_cache_all();
500			return;
501			/* NOTREACHED */
502			break;
503
504
505		/*
506		 * kill the program
507		 */
508		case 'k' :
509			break;		/* do nothing */
510
511
512		case 'r':
513			break;
514
515
516		/*
517		 * Step to next instruction
518		 */
519		case 's':
520			/*
521			 * There is no single step insn in the MIPS ISA, so we
522			 * use breakpoints and continue, instead.
523			 */
524			single_step(regs);
525			flush_cache_all();
526			return;
527			/* NOTREACHED */
528
529		}
530		break;
531
532		}			/* switch */
533
534		/*
535		 * reply to the request
536		 */
537
538		putpacket(output_buffer);
539
540	} /* while */
541}
542
543/*
544 * This function will generate a breakpoint exception.  It is used at the
545 * beginning of a program to sync up with a debugger and can be used
546 * otherwise as a quick means to stop program execution and "break" into
547 * the debugger.
548 */
549void breakpoint(void)
550{
551	if (!gdb_stub_initialised)
552		return;
553	__asm__ __volatile__(
554			".globl	breakinst\n"
555			"breakinst:\t.word   %0\n\t"
556			:
557			: "i" (S390_BREAKPOINT_U16)
558				:
559				);
560}
561
562
563
564
565
566
567
568