1 // OBSOLETE /****************************************************************************
3 // OBSOLETE THIS SOFTWARE IS NOT COPYRIGHTED
5 // OBSOLETE HP offers the following for use in the public domain. HP makes no
6 // OBSOLETE warranty with regard to the software or it's performance and the
7 // OBSOLETE user accepts the software "AS IS" with all faults.
9 // OBSOLETE HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
10 // OBSOLETE TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
11 // OBSOLETE OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13 // OBSOLETE ****************************************************************************/
15 // OBSOLETE /****************************************************************************
16 // OBSOLETE * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
18 // OBSOLETE * Module name: remcom.c $
19 // OBSOLETE * Revision: 1.34 $
20 // OBSOLETE * Date: 91/03/09 12:29:49 $
21 // OBSOLETE * Contributor: Lake Stevens Instrument Division$
23 // OBSOLETE * Description: low level support for gdb debugger. $
25 // OBSOLETE * Considerations: only works on target hardware $
27 // OBSOLETE * Written by: Glenn Engel $
28 // OBSOLETE * ModuleState: Experimental $
30 // OBSOLETE * NOTES: See Below $
32 // OBSOLETE * Modified for SPARC by Stu Grossman, Cygnus Support.
33 // OBSOLETE * Based on sparc-stub.c, it's modified for SPARClite Debug Unit hardware
34 // OBSOLETE * breakpoint support to create sparclite-stub.c, by Kung Hsu, Cygnus Support.
36 // OBSOLETE * This code has been extensively tested on the Fujitsu SPARClite demo board.
38 // OBSOLETE * To enable debugger support, two things need to happen. One, a
39 // OBSOLETE * call to set_debug_traps() is necessary in order to allow any breakpoints
40 // OBSOLETE * or error conditions to be properly intercepted and reported to gdb.
41 // OBSOLETE * Two, a breakpoint needs to be generated to begin communication. This
42 // OBSOLETE * is most easily accomplished by a call to breakpoint(). Breakpoint()
43 // OBSOLETE * simulates a breakpoint by executing a trap #1.
45 // OBSOLETE *************
47 // OBSOLETE * The following gdb commands are supported:
49 // OBSOLETE * command function Return value
51 // OBSOLETE * g return the value of the CPU registers hex data or ENN
52 // OBSOLETE * G set the value of the CPU registers OK or ENN
53 // OBSOLETE * P set the value of a single CPU register OK or ENN
55 // OBSOLETE * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
56 // OBSOLETE * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
58 // OBSOLETE * c Resume at current address SNN ( signal NN)
59 // OBSOLETE * cAA..AA Continue at address AA..AA SNN
61 // OBSOLETE * s Step one instruction SNN
62 // OBSOLETE * sAA..AA Step one instruction from AA..AA SNN
66 // OBSOLETE * ? What was the last sigval ? SNN (signal NN)
68 // OBSOLETE * All commands and responses are sent with a packet which includes a
69 // OBSOLETE * checksum. A packet consists of
71 // OBSOLETE * $<packet info>#<checksum>.
74 // OBSOLETE * <packet info> :: <characters representing the command or response>
75 // OBSOLETE * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
77 // OBSOLETE * When a packet is received, it is first acknowledged with either '+' or '-'.
78 // OBSOLETE * '+' indicates a successful transfer. '-' indicates a failed transfer.
80 // OBSOLETE * Example:
82 // OBSOLETE * Host: Reply:
83 // OBSOLETE * $m0,10#2a +$00010203040506070809101112131415#42
85 // OBSOLETE ****************************************************************************/
87 // OBSOLETE #include <string.h>
88 // OBSOLETE #include <signal.h>
89 // OBSOLETE #include <sparclite.h>
91 // OBSOLETE /************************************************************************
93 // OBSOLETE * external low-level support routines
96 // OBSOLETE extern void putDebugChar (int c); /* write a single character */
97 // OBSOLETE extern int getDebugChar (void); /* read and return a single char */
99 // OBSOLETE /************************************************************************/
100 // OBSOLETE /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
101 // OBSOLETE /* at least NUMREGBYTES*2 are needed for register packets */
102 // OBSOLETE #define BUFMAX 2048
104 // OBSOLETE static int initialized = 0; /* !0 means we've been initialized */
106 // OBSOLETE extern void breakinst ();
107 // OBSOLETE static void set_mem_fault_trap (int enable);
108 // OBSOLETE static void get_in_break_mode (void);
110 // OBSOLETE static const char hexchars[]="0123456789abcdef";
112 // OBSOLETE #define NUMREGS 80
114 // OBSOLETE /* Number of bytes of registers. */
115 // OBSOLETE #define NUMREGBYTES (NUMREGS * 4)
116 // OBSOLETE enum regnames {G0, G1, G2, G3, G4, G5, G6, G7,
117 // OBSOLETE O0, O1, O2, O3, O4, O5, SP, O7,
118 // OBSOLETE L0, L1, L2, L3, L4, L5, L6, L7,
119 // OBSOLETE I0, I1, I2, I3, I4, I5, FP, I7,
121 // OBSOLETE F0, F1, F2, F3, F4, F5, F6, F7,
122 // OBSOLETE F8, F9, F10, F11, F12, F13, F14, F15,
123 // OBSOLETE F16, F17, F18, F19, F20, F21, F22, F23,
124 // OBSOLETE F24, F25, F26, F27, F28, F29, F30, F31,
125 // OBSOLETE Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR,
126 // OBSOLETE DIA1, DIA2, DDA1, DDA2, DDV1, DDV2, DCR, DSR };
128 // OBSOLETE /*************************** ASSEMBLY CODE MACROS *************************/
131 // OBSOLETE extern void trap_low();
133 // OBSOLETE /* Create private copies of common functions used by the stub. This prevents
134 // OBSOLETE nasty interactions between app code and the stub (for instance if user steps
135 // OBSOLETE into strlen, etc..) */
137 // OBSOLETE static char *
138 // OBSOLETE strcpy (char *dst, const char *src)
140 // OBSOLETE char *retval = dst;
142 // OBSOLETE while ((*dst++ = *src++) != '\000');
144 // OBSOLETE return retval;
147 // OBSOLETE static void *
148 // OBSOLETE memcpy (void *vdst, const void *vsrc, int n)
150 // OBSOLETE char *dst = vdst;
151 // OBSOLETE const char *src = vsrc;
152 // OBSOLETE char *retval = dst;
154 // OBSOLETE while (n-- > 0)
155 // OBSOLETE *dst++ = *src++;
157 // OBSOLETE return retval;
161 // OBSOLETE .reserve trapstack, 1000 * 4, \"bss\", 8
166 // OBSOLETE in_trap_handler:
172 // OBSOLETE ! This function is called when any SPARC trap (except window overflow or
173 // OBSOLETE ! underflow) occurs. It makes sure that the invalid register window is still
174 // OBSOLETE ! available before jumping into C code. It will also restore the world if you
175 // OBSOLETE ! return from handle_exception.
177 // OBSOLETE ! On entry, trap_low expects l1 and l2 to contain pc and npc respectivly.
178 // OBSOLETE ! Register usage throughout the routine is as follows:
180 // OBSOLETE ! l0 - psr
181 // OBSOLETE ! l1 - pc
182 // OBSOLETE ! l2 - npc
183 // OBSOLETE ! l3 - wim
184 // OBSOLETE ! l4 - scratch and y reg
185 // OBSOLETE ! l5 - scratch and tbr
186 // OBSOLETE ! l6 - unused
187 // OBSOLETE ! l7 - unused
189 // OBSOLETE .globl _trap_low
190 // OBSOLETE _trap_low:
191 // OBSOLETE mov %psr, %l0
192 // OBSOLETE mov %wim, %l3
194 // OBSOLETE srl %l3, %l0, %l4 ! wim >> cwp
195 // OBSOLETE cmp %l4, 1
196 // OBSOLETE bne window_fine ! Branch if not in the invalid window
199 // OBSOLETE ! Handle window overflow
201 // OBSOLETE mov %g1, %l4 ! Save g1, we use it to hold the wim
202 // OBSOLETE srl %l3, 1, %g1 ! Rotate wim right
204 // OBSOLETE bg good_wim ! Branch if new wim is non-zero
207 // OBSOLETE ! At this point, we need to bring a 1 into the high order bit of the wim.
208 // OBSOLETE ! Since we don't want to make any assumptions about the number of register
209 // OBSOLETE ! windows, we figure it out dynamically so as to setup the wim correctly.
211 // OBSOLETE not %g1 ! Fill g1 with ones
212 // OBSOLETE mov %g1, %wim ! Fill the wim with ones
216 // OBSOLETE mov %wim, %g1 ! Read back the wim
217 // OBSOLETE inc %g1 ! Now g1 has 1 just to left of wim
218 // OBSOLETE srl %g1, 1, %g1 ! Now put 1 at top of wim
219 // OBSOLETE mov %g0, %wim ! Clear wim so that subsequent save
220 // OBSOLETE nop ! won't trap
224 // OBSOLETE good_wim:
225 // OBSOLETE save %g0, %g0, %g0 ! Slip into next window
226 // OBSOLETE mov %g1, %wim ! Install the new wim
228 // OBSOLETE std %l0, [%sp + 0 * 4] ! save L & I registers
229 // OBSOLETE std %l2, [%sp + 2 * 4]
230 // OBSOLETE std %l4, [%sp + 4 * 4]
231 // OBSOLETE std %l6, [%sp + 6 * 4]
233 // OBSOLETE std %i0, [%sp + 8 * 4]
234 // OBSOLETE std %i2, [%sp + 10 * 4]
235 // OBSOLETE std %i4, [%sp + 12 * 4]
236 // OBSOLETE std %i6, [%sp + 14 * 4]
238 // OBSOLETE restore ! Go back to trap window.
239 // OBSOLETE mov %l4, %g1 ! Restore %g1
241 // OBSOLETE window_fine:
242 // OBSOLETE sethi %hi(in_trap_handler), %l4
243 // OBSOLETE ld [%lo(in_trap_handler) + %l4], %l5
245 // OBSOLETE bg recursive_trap
248 // OBSOLETE set trapstack+1000*4, %sp ! Switch to trap stack
250 // OBSOLETE recursive_trap:
251 // OBSOLETE st %l5, [%lo(in_trap_handler) + %l4]
252 // OBSOLETE sub %sp,(16+1+6+1+80)*4,%sp ! Make room for input & locals
253 // OBSOLETE ! + hidden arg + arg spill
254 // OBSOLETE ! + doubleword alignment
255 // OBSOLETE ! + registers[72] local var
257 // OBSOLETE std %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
258 // OBSOLETE std %g2, [%sp + (24 + 2) * 4]
259 // OBSOLETE std %g4, [%sp + (24 + 4) * 4]
260 // OBSOLETE std %g6, [%sp + (24 + 6) * 4]
262 // OBSOLETE std %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
263 // OBSOLETE std %i2, [%sp + (24 + 10) * 4]
264 // OBSOLETE std %i4, [%sp + (24 + 12) * 4]
265 // OBSOLETE std %i6, [%sp + (24 + 14) * 4]
267 // OBSOLETE mov %y, %l4
268 // OBSOLETE mov %tbr, %l5
269 // OBSOLETE st %l4, [%sp + (24 + 64) * 4] ! Y
270 // OBSOLETE st %l0, [%sp + (24 + 65) * 4] ! PSR
271 // OBSOLETE st %l3, [%sp + (24 + 66) * 4] ! WIM
272 // OBSOLETE st %l5, [%sp + (24 + 67) * 4] ! TBR
273 // OBSOLETE st %l1, [%sp + (24 + 68) * 4] ! PC
274 // OBSOLETE st %l2, [%sp + (24 + 69) * 4] ! NPC
276 // OBSOLETE or %l0, 0xf20, %l4
277 // OBSOLETE mov %l4, %psr ! Turn on traps, disable interrupts
279 // OBSOLETE set 0x1000, %l1
280 // OBSOLETE btst %l1, %l0 ! FP enabled?
281 // OBSOLETE be no_fpstore
284 // OBSOLETE ! Must save fsr first, to flush the FQ. This may cause a deferred fp trap, so
285 // OBSOLETE ! traps must be enabled to allow the trap handler to clean things up.
287 // OBSOLETE st %fsr, [%sp + (24 + 70) * 4]
289 // OBSOLETE std %f0, [%sp + (24 + 32) * 4]
290 // OBSOLETE std %f2, [%sp + (24 + 34) * 4]
291 // OBSOLETE std %f4, [%sp + (24 + 36) * 4]
292 // OBSOLETE std %f6, [%sp + (24 + 38) * 4]
293 // OBSOLETE std %f8, [%sp + (24 + 40) * 4]
294 // OBSOLETE std %f10, [%sp + (24 + 42) * 4]
295 // OBSOLETE std %f12, [%sp + (24 + 44) * 4]
296 // OBSOLETE std %f14, [%sp + (24 + 46) * 4]
297 // OBSOLETE std %f16, [%sp + (24 + 48) * 4]
298 // OBSOLETE std %f18, [%sp + (24 + 50) * 4]
299 // OBSOLETE std %f20, [%sp + (24 + 52) * 4]
300 // OBSOLETE std %f22, [%sp + (24 + 54) * 4]
301 // OBSOLETE std %f24, [%sp + (24 + 56) * 4]
302 // OBSOLETE std %f26, [%sp + (24 + 58) * 4]
303 // OBSOLETE std %f28, [%sp + (24 + 60) * 4]
304 // OBSOLETE std %f30, [%sp + (24 + 62) * 4]
305 // OBSOLETE no_fpstore:
307 // OBSOLETE call _handle_exception
308 // OBSOLETE add %sp, 24 * 4, %o0 ! Pass address of registers
310 // OBSOLETE ! Reload all of the registers that aren't on the stack
312 // OBSOLETE ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
313 // OBSOLETE ldd [%sp + (24 + 2) * 4], %g2
314 // OBSOLETE ldd [%sp + (24 + 4) * 4], %g4
315 // OBSOLETE ldd [%sp + (24 + 6) * 4], %g6
317 // OBSOLETE ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
318 // OBSOLETE ldd [%sp + (24 + 10) * 4], %i2
319 // OBSOLETE ldd [%sp + (24 + 12) * 4], %i4
320 // OBSOLETE ldd [%sp + (24 + 14) * 4], %i6
323 // OBSOLETE ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR
324 // OBSOLETE ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC
326 // OBSOLETE set 0x1000, %l5
327 // OBSOLETE btst %l5, %l1 ! FP enabled?
328 // OBSOLETE be no_fpreload
331 // OBSOLETE ldd [%sp + (24 + 32) * 4], %f0
332 // OBSOLETE ldd [%sp + (24 + 34) * 4], %f2
333 // OBSOLETE ldd [%sp + (24 + 36) * 4], %f4
334 // OBSOLETE ldd [%sp + (24 + 38) * 4], %f6
335 // OBSOLETE ldd [%sp + (24 + 40) * 4], %f8
336 // OBSOLETE ldd [%sp + (24 + 42) * 4], %f10
337 // OBSOLETE ldd [%sp + (24 + 44) * 4], %f12
338 // OBSOLETE ldd [%sp + (24 + 46) * 4], %f14
339 // OBSOLETE ldd [%sp + (24 + 48) * 4], %f16
340 // OBSOLETE ldd [%sp + (24 + 50) * 4], %f18
341 // OBSOLETE ldd [%sp + (24 + 52) * 4], %f20
342 // OBSOLETE ldd [%sp + (24 + 54) * 4], %f22
343 // OBSOLETE ldd [%sp + (24 + 56) * 4], %f24
344 // OBSOLETE ldd [%sp + (24 + 58) * 4], %f26
345 // OBSOLETE ldd [%sp + (24 + 60) * 4], %f28
346 // OBSOLETE ldd [%sp + (24 + 62) * 4], %f30
348 // OBSOLETE ld [%sp + (24 + 70) * 4], %fsr
349 // OBSOLETE no_fpreload:
351 // OBSOLETE restore ! Ensure that previous window is valid
352 // OBSOLETE save %g0, %g0, %g0 ! by causing a window_underflow trap
354 // OBSOLETE mov %l0, %y
355 // OBSOLETE mov %l1, %psr ! Make sure that traps are disabled
356 // OBSOLETE ! for rett
357 // OBSOLETE sethi %hi(in_trap_handler), %l4
358 // OBSOLETE ld [%lo(in_trap_handler) + %l4], %l5
360 // OBSOLETE st %l5, [%lo(in_trap_handler) + %l4]
362 // OBSOLETE jmpl %l2, %g0 ! Restore old PC
363 // OBSOLETE rett %l3 ! Restore old nPC
366 // OBSOLETE /* Convert ch from a hex digit to an int */
368 // OBSOLETE static int
369 // OBSOLETE hex (unsigned char ch)
371 // OBSOLETE if (ch >= 'a' && ch <= 'f')
372 // OBSOLETE return ch-'a'+10;
373 // OBSOLETE if (ch >= '0' && ch <= '9')
374 // OBSOLETE return ch-'0';
375 // OBSOLETE if (ch >= 'A' && ch <= 'F')
376 // OBSOLETE return ch-'A'+10;
377 // OBSOLETE return -1;
380 // OBSOLETE static char remcomInBuffer[BUFMAX];
381 // OBSOLETE static char remcomOutBuffer[BUFMAX];
383 // OBSOLETE /* scan for the sequence $<data>#<checksum> */
385 // OBSOLETE unsigned char *
386 // OBSOLETE getpacket (void)
388 // OBSOLETE unsigned char *buffer = &remcomInBuffer[0];
389 // OBSOLETE unsigned char checksum;
390 // OBSOLETE unsigned char xmitcsum;
391 // OBSOLETE int count;
394 // OBSOLETE while (1)
396 // OBSOLETE /* wait around for the start character, ignore all other characters */
397 // OBSOLETE while ((ch = getDebugChar ()) != '$')
401 // OBSOLETE checksum = 0;
402 // OBSOLETE xmitcsum = -1;
403 // OBSOLETE count = 0;
405 // OBSOLETE /* now, read until a # or end of buffer is found */
406 // OBSOLETE while (count < BUFMAX)
408 // OBSOLETE ch = getDebugChar ();
409 // OBSOLETE if (ch == '$')
410 // OBSOLETE goto retry;
411 // OBSOLETE if (ch == '#')
413 // OBSOLETE checksum = checksum + ch;
414 // OBSOLETE buffer[count] = ch;
415 // OBSOLETE count = count + 1;
417 // OBSOLETE buffer[count] = 0;
419 // OBSOLETE if (ch == '#')
421 // OBSOLETE ch = getDebugChar ();
422 // OBSOLETE xmitcsum = hex (ch) << 4;
423 // OBSOLETE ch = getDebugChar ();
424 // OBSOLETE xmitcsum += hex (ch);
426 // OBSOLETE if (checksum != xmitcsum)
428 // OBSOLETE putDebugChar ('-'); /* failed checksum */
432 // OBSOLETE putDebugChar ('+'); /* successful transfer */
434 // OBSOLETE /* if a sequence char is present, reply the sequence ID */
435 // OBSOLETE if (buffer[2] == ':')
437 // OBSOLETE putDebugChar (buffer[0]);
438 // OBSOLETE putDebugChar (buffer[1]);
440 // OBSOLETE return &buffer[3];
443 // OBSOLETE return &buffer[0];
449 // OBSOLETE /* send the packet in buffer. */
451 // OBSOLETE static void
452 // OBSOLETE putpacket (unsigned char *buffer)
454 // OBSOLETE unsigned char checksum;
455 // OBSOLETE int count;
456 // OBSOLETE unsigned char ch;
458 // OBSOLETE /* $<packet info>#<checksum>. */
461 // OBSOLETE putDebugChar('$');
462 // OBSOLETE checksum = 0;
463 // OBSOLETE count = 0;
465 // OBSOLETE while (ch = buffer[count])
467 // OBSOLETE putDebugChar (ch);
468 // OBSOLETE checksum += ch;
469 // OBSOLETE count += 1;
472 // OBSOLETE putDebugChar('#');
473 // OBSOLETE putDebugChar(hexchars[checksum >> 4]);
474 // OBSOLETE putDebugChar(hexchars[checksum & 0xf]);
477 // OBSOLETE while (getDebugChar() != '+');
480 // OBSOLETE /* Indicate to caller of mem2hex or hex2mem that there has been an
481 // OBSOLETE error. */
482 // OBSOLETE static volatile int mem_err = 0;
484 // OBSOLETE /* Convert the memory pointed to by mem into hex, placing result in buf.
485 // OBSOLETE * Return a pointer to the last char put in buf (null), in case of mem fault,
486 // OBSOLETE * return 0.
487 // OBSOLETE * If MAY_FAULT is non-zero, then we will handle memory faults by returning
488 // OBSOLETE * a 0, else treat a fault like any other fault in the stub.
491 // OBSOLETE static unsigned char *
492 // OBSOLETE mem2hex (unsigned char *mem, unsigned char *buf, int count, int may_fault)
494 // OBSOLETE unsigned char ch;
496 // OBSOLETE set_mem_fault_trap(may_fault);
498 // OBSOLETE while (count-- > 0)
500 // OBSOLETE ch = *mem++;
501 // OBSOLETE if (mem_err)
502 // OBSOLETE return 0;
503 // OBSOLETE *buf++ = hexchars[ch >> 4];
504 // OBSOLETE *buf++ = hexchars[ch & 0xf];
507 // OBSOLETE *buf = 0;
509 // OBSOLETE set_mem_fault_trap(0);
511 // OBSOLETE return buf;
514 // OBSOLETE /* convert the hex array pointed to by buf into binary to be placed in mem
515 // OBSOLETE * return a pointer to the character AFTER the last byte written */
517 // OBSOLETE static char *
518 // OBSOLETE hex2mem (unsigned char *buf, unsigned char *mem, int count, int may_fault)
521 // OBSOLETE unsigned char ch;
523 // OBSOLETE set_mem_fault_trap(may_fault);
525 // OBSOLETE for (i=0; i<count; i++)
527 // OBSOLETE ch = hex(*buf++) << 4;
528 // OBSOLETE ch |= hex(*buf++);
529 // OBSOLETE *mem++ = ch;
530 // OBSOLETE if (mem_err)
531 // OBSOLETE return 0;
534 // OBSOLETE set_mem_fault_trap(0);
536 // OBSOLETE return mem;
539 // OBSOLETE /* This table contains the mapping between SPARC hardware trap types, and
540 // OBSOLETE signals, which are primarily what GDB understands. It also indicates
541 // OBSOLETE which hardware traps we need to commandeer when initializing the stub. */
543 // OBSOLETE static struct hard_trap_info
545 // OBSOLETE unsigned char tt; /* Trap type code for SPARClite */
546 // OBSOLETE unsigned char signo; /* Signal that we map this trap into */
547 // OBSOLETE } hard_trap_info[] = {
548 // OBSOLETE {0x01, SIGSEGV}, /* instruction access error */
549 // OBSOLETE {0x02, SIGILL}, /* privileged instruction */
550 // OBSOLETE {0x03, SIGILL}, /* illegal instruction */
551 // OBSOLETE {0x04, SIGEMT}, /* fp disabled */
552 // OBSOLETE {0x07, SIGBUS}, /* mem address not aligned */
553 // OBSOLETE {0x09, SIGSEGV}, /* data access exception */
554 // OBSOLETE {0x0a, SIGEMT}, /* tag overflow */
555 // OBSOLETE {0x20, SIGBUS}, /* r register access error */
556 // OBSOLETE {0x21, SIGBUS}, /* instruction access error */
557 // OBSOLETE {0x24, SIGEMT}, /* cp disabled */
558 // OBSOLETE {0x29, SIGBUS}, /* data access error */
559 // OBSOLETE {0x2a, SIGFPE}, /* divide by zero */
560 // OBSOLETE {0x2b, SIGBUS}, /* data store error */
561 // OBSOLETE {0x80+1, SIGTRAP}, /* ta 1 - normal breakpoint instruction */
562 // OBSOLETE {0xff, SIGTRAP}, /* hardware breakpoint */
563 // OBSOLETE {0, 0} /* Must be last */
566 // OBSOLETE /* Set up exception handlers for tracing and breakpoints */
569 // OBSOLETE set_debug_traps (void)
571 // OBSOLETE struct hard_trap_info *ht;
573 // OBSOLETE /* Only setup fp traps if the FP is disabled. */
575 // OBSOLETE for (ht = hard_trap_info;
576 // OBSOLETE ht->tt != 0 && ht->signo != 0;
578 // OBSOLETE if (ht->tt != 4 || ! (read_psr () & 0x1000))
579 // OBSOLETE exceptionHandler(ht->tt, trap_low);
581 // OBSOLETE initialized = 1;
585 // OBSOLETE ! Trap handler for memory errors. This just sets mem_err to be non-zero. It
586 // OBSOLETE ! assumes that %l1 is non-zero. This should be safe, as it is doubtful that
587 // OBSOLETE ! 0 would ever contain code that could mem fault. This routine will skip
588 // OBSOLETE ! past the faulting instruction after setting mem_err.
593 // OBSOLETE _fltr_set_mem_err:
594 // OBSOLETE sethi %hi(_mem_err), %l0
595 // OBSOLETE st %l1, [%l0 + %lo(_mem_err)]
596 // OBSOLETE jmpl %l2, %g0
597 // OBSOLETE rett %l2+4
600 // OBSOLETE static void
601 // OBSOLETE set_mem_fault_trap (int enable)
603 // OBSOLETE extern void fltr_set_mem_err();
604 // OBSOLETE mem_err = 0;
606 // OBSOLETE if (enable)
607 // OBSOLETE exceptionHandler(9, fltr_set_mem_err);
609 // OBSOLETE exceptionHandler(9, trap_low);
616 // OBSOLETE _dummy_hw_breakpoint:
617 // OBSOLETE jmpl %l2, %g0
618 // OBSOLETE rett %l2+4
623 // OBSOLETE static void
624 // OBSOLETE get_in_break_mode (void)
626 // OBSOLETE extern void dummy_hw_breakpoint();
628 // OBSOLETE exceptionHandler (255, dummy_hw_breakpoint);
630 // OBSOLETE asm ("ta 255");
632 // OBSOLETE exceptionHandler (255, trap_low);
635 // OBSOLETE /* Convert the SPARC hardware trap type code to a unix signal number. */
637 // OBSOLETE static int
638 // OBSOLETE computeSignal (int tt)
640 // OBSOLETE struct hard_trap_info *ht;
642 // OBSOLETE for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
643 // OBSOLETE if (ht->tt == tt)
644 // OBSOLETE return ht->signo;
646 // OBSOLETE return SIGHUP; /* default for things we don't know about */
650 // OBSOLETE * While we find nice hex chars, build an int.
651 // OBSOLETE * Return number of chars processed.
654 // OBSOLETE static int
655 // OBSOLETE hexToInt(char **ptr, int *intValue)
657 // OBSOLETE int numChars = 0;
658 // OBSOLETE int hexValue;
660 // OBSOLETE *intValue = 0;
662 // OBSOLETE while (**ptr)
664 // OBSOLETE hexValue = hex(**ptr);
665 // OBSOLETE if (hexValue < 0)
668 // OBSOLETE *intValue = (*intValue << 4) | hexValue;
669 // OBSOLETE numChars ++;
671 // OBSOLETE (*ptr)++;
674 // OBSOLETE return (numChars);
678 // OBSOLETE * This function does all command procesing for interfacing to gdb. It
679 // OBSOLETE * returns 1 if you should skip the instruction at the trap address, 0
680 // OBSOLETE * otherwise.
683 // OBSOLETE static void
684 // OBSOLETE handle_exception (unsigned long *registers)
686 // OBSOLETE int tt; /* Trap type */
687 // OBSOLETE int sigval;
688 // OBSOLETE int addr;
689 // OBSOLETE int length;
690 // OBSOLETE char *ptr;
691 // OBSOLETE unsigned long *sp;
692 // OBSOLETE unsigned long dsr;
694 // OBSOLETE /* First, we must force all of the windows to be spilled out */
696 // OBSOLETE asm(" save %sp, -64, %sp
697 // OBSOLETE save %sp, -64, %sp
698 // OBSOLETE save %sp, -64, %sp
699 // OBSOLETE save %sp, -64, %sp
700 // OBSOLETE save %sp, -64, %sp
701 // OBSOLETE save %sp, -64, %sp
702 // OBSOLETE save %sp, -64, %sp
703 // OBSOLETE save %sp, -64, %sp
714 // OBSOLETE get_in_break_mode (); /* Enable DSU register writes */
716 // OBSOLETE registers[DIA1] = read_asi (1, 0xff00);
717 // OBSOLETE registers[DIA2] = read_asi (1, 0xff04);
718 // OBSOLETE registers[DDA1] = read_asi (1, 0xff08);
719 // OBSOLETE registers[DDA2] = read_asi (1, 0xff0c);
720 // OBSOLETE registers[DDV1] = read_asi (1, 0xff10);
721 // OBSOLETE registers[DDV2] = read_asi (1, 0xff14);
722 // OBSOLETE registers[DCR] = read_asi (1, 0xff18);
723 // OBSOLETE registers[DSR] = read_asi (1, 0xff1c);
725 // OBSOLETE if (registers[PC] == (unsigned long)breakinst)
727 // OBSOLETE registers[PC] = registers[NPC];
728 // OBSOLETE registers[NPC] += 4;
730 // OBSOLETE sp = (unsigned long *)registers[SP];
732 // OBSOLETE dsr = (unsigned long)registers[DSR];
733 // OBSOLETE if (dsr & 0x3c)
734 // OBSOLETE tt = 255;
736 // OBSOLETE tt = (registers[TBR] >> 4) & 0xff;
738 // OBSOLETE /* reply to host that an exception has occurred */
739 // OBSOLETE sigval = computeSignal(tt);
740 // OBSOLETE ptr = remcomOutBuffer;
742 // OBSOLETE *ptr++ = 'T';
743 // OBSOLETE *ptr++ = hexchars[sigval >> 4];
744 // OBSOLETE *ptr++ = hexchars[sigval & 0xf];
746 // OBSOLETE *ptr++ = hexchars[PC >> 4];
747 // OBSOLETE *ptr++ = hexchars[PC & 0xf];
748 // OBSOLETE *ptr++ = ':';
749 // OBSOLETE ptr = mem2hex((char *)®isters[PC], ptr, 4, 0);
750 // OBSOLETE *ptr++ = ';';
752 // OBSOLETE *ptr++ = hexchars[FP >> 4];
753 // OBSOLETE *ptr++ = hexchars[FP & 0xf];
754 // OBSOLETE *ptr++ = ':';
755 // OBSOLETE ptr = mem2hex(sp + 8 + 6, ptr, 4, 0); /* FP */
756 // OBSOLETE *ptr++ = ';';
758 // OBSOLETE *ptr++ = hexchars[SP >> 4];
759 // OBSOLETE *ptr++ = hexchars[SP & 0xf];
760 // OBSOLETE *ptr++ = ':';
761 // OBSOLETE ptr = mem2hex((char *)&sp, ptr, 4, 0);
762 // OBSOLETE *ptr++ = ';';
764 // OBSOLETE *ptr++ = hexchars[NPC >> 4];
765 // OBSOLETE *ptr++ = hexchars[NPC & 0xf];
766 // OBSOLETE *ptr++ = ':';
767 // OBSOLETE ptr = mem2hex((char *)®isters[NPC], ptr, 4, 0);
768 // OBSOLETE *ptr++ = ';';
770 // OBSOLETE *ptr++ = hexchars[O7 >> 4];
771 // OBSOLETE *ptr++ = hexchars[O7 & 0xf];
772 // OBSOLETE *ptr++ = ':';
773 // OBSOLETE ptr = mem2hex((char *)®isters[O7], ptr, 4, 0);
774 // OBSOLETE *ptr++ = ';';
776 // OBSOLETE *ptr++ = 0;
778 // OBSOLETE putpacket(remcomOutBuffer);
780 // OBSOLETE while (1)
782 // OBSOLETE remcomOutBuffer[0] = 0;
784 // OBSOLETE ptr = getpacket();
785 // OBSOLETE switch (*ptr++)
787 // OBSOLETE case '?':
788 // OBSOLETE remcomOutBuffer[0] = 'S';
789 // OBSOLETE remcomOutBuffer[1] = hexchars[sigval >> 4];
790 // OBSOLETE remcomOutBuffer[2] = hexchars[sigval & 0xf];
791 // OBSOLETE remcomOutBuffer[3] = 0;
794 // OBSOLETE case 'd':
795 // OBSOLETE /* toggle debug flag */
798 // OBSOLETE case 'g': /* return the value of the CPU registers */
799 // OBSOLETE memcpy (®isters[L0], sp, 16 * 4); /* Copy L & I regs from stack */
800 // OBSOLETE mem2hex ((char *)registers, remcomOutBuffer, NUMREGBYTES, 0);
803 // OBSOLETE case 'G': /* Set the value of all registers */
804 // OBSOLETE case 'P': /* Set the value of one register */
806 // OBSOLETE unsigned long *newsp, psr;
808 // OBSOLETE psr = registers[PSR];
810 // OBSOLETE if (ptr[-1] == 'P')
812 // OBSOLETE int regno;
814 // OBSOLETE if (hexToInt (&ptr, ®no)
815 // OBSOLETE && *ptr++ == '=')
816 // OBSOLETE if (regno >= L0 && regno <= I7)
817 // OBSOLETE hex2mem (ptr, sp + regno - L0, 4, 0);
819 // OBSOLETE hex2mem (ptr, (char *)®isters[regno], 4, 0);
822 // OBSOLETE strcpy (remcomOutBuffer, "E01");
828 // OBSOLETE hex2mem (ptr, (char *)registers, NUMREGBYTES, 0);
829 // OBSOLETE memcpy (sp, ®isters[L0], 16 * 4); /* Copy L & I regs to stack */
832 // OBSOLETE /* See if the stack pointer has moved. If so, then copy the saved
833 // OBSOLETE locals and ins to the new location. This keeps the window
834 // OBSOLETE overflow and underflow routines happy. */
836 // OBSOLETE newsp = (unsigned long *)registers[SP];
837 // OBSOLETE if (sp != newsp)
838 // OBSOLETE sp = memcpy(newsp, sp, 16 * 4);
840 // OBSOLETE /* Don't allow CWP to be modified. */
842 // OBSOLETE if (psr != registers[PSR])
843 // OBSOLETE registers[PSR] = (psr & 0x1f) | (registers[PSR] & ~0x1f);
845 // OBSOLETE strcpy(remcomOutBuffer,"OK");
849 // OBSOLETE case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
850 // OBSOLETE /* Try to read %x,%x. */
852 // OBSOLETE if (hexToInt(&ptr, &addr)
853 // OBSOLETE && *ptr++ == ','
854 // OBSOLETE && hexToInt(&ptr, &length))
856 // OBSOLETE if (mem2hex((char *)addr, remcomOutBuffer, length, 1))
859 // OBSOLETE strcpy (remcomOutBuffer, "E03");
862 // OBSOLETE strcpy(remcomOutBuffer,"E01");
865 // OBSOLETE case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
866 // OBSOLETE /* Try to read '%x,%x:'. */
868 // OBSOLETE if (hexToInt(&ptr, &addr)
869 // OBSOLETE && *ptr++ == ','
870 // OBSOLETE && hexToInt(&ptr, &length)
871 // OBSOLETE && *ptr++ == ':')
873 // OBSOLETE if (hex2mem(ptr, (char *)addr, length, 1))
874 // OBSOLETE strcpy(remcomOutBuffer, "OK");
876 // OBSOLETE strcpy(remcomOutBuffer, "E03");
879 // OBSOLETE strcpy(remcomOutBuffer, "E02");
882 // OBSOLETE case 'c': /* cAA..AA Continue at address AA..AA(optional) */
883 // OBSOLETE /* try to read optional parameter, pc unchanged if no parm */
884 // OBSOLETE if (hexToInt(&ptr, &addr))
886 // OBSOLETE registers[PC] = addr;
887 // OBSOLETE registers[NPC] = addr + 4;
890 // OBSOLETE /* Need to flush the instruction cache here, as we may have deposited a
891 // OBSOLETE breakpoint, and the icache probably has no way of knowing that a data ref to
892 // OBSOLETE some location may have changed something that is in the instruction cache.
895 // OBSOLETE flush_i_cache ();
897 // OBSOLETE if (!(registers[DSR] & 0x1) /* DSU enabled? */
898 // OBSOLETE && !(registers[DCR] & 0x200)) /* Are we in break state? */
899 // OBSOLETE { /* Yes, set the DSU regs */
900 // OBSOLETE write_asi (1, 0xff00, registers[DIA1]);
901 // OBSOLETE write_asi (1, 0xff04, registers[DIA2]);
902 // OBSOLETE write_asi (1, 0xff08, registers[DDA1]);
903 // OBSOLETE write_asi (1, 0xff0c, registers[DDA2]);
904 // OBSOLETE write_asi (1, 0xff10, registers[DDV1]);
905 // OBSOLETE write_asi (1, 0xff14, registers[DDV2]);
906 // OBSOLETE write_asi (1, 0xff1c, registers[DSR]);
907 // OBSOLETE write_asi (1, 0xff18, registers[DCR] | 0x200); /* Clear break */
912 // OBSOLETE /* kill the program */
913 // OBSOLETE case 'k' : /* do nothing */
916 // OBSOLETE case 't': /* Test feature */
917 // OBSOLETE asm (" std %f30,[%sp]");
920 // OBSOLETE case 'r': /* Reset */
921 // OBSOLETE asm ("call 0
924 // OBSOLETE } /* switch */
926 // OBSOLETE /* reply to the request */
927 // OBSOLETE putpacket(remcomOutBuffer);
931 // OBSOLETE /* This function will generate a breakpoint exception. It is used at the
932 // OBSOLETE beginning of a program to sync up with a debugger and can be used
933 // OBSOLETE otherwise as a quick means to stop program execution and "break" into
934 // OBSOLETE the debugger. */
937 // OBSOLETE breakpoint (void)
939 // OBSOLETE if (!initialized)
942 // OBSOLETE asm(" .globl _breakinst
944 // OBSOLETE _breakinst: ta 1