1 /****************************************************************************
3 THIS SOFTWARE IS NOT COPYRIGHTED
5 HP offers the following for use in the public domain. HP makes no
6 warranty with regard to the software or it's performance and the
7 user accepts the software "AS IS" with all faults.
9 HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD
10 TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES
11 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13 ****************************************************************************/
15 /****************************************************************************
16 * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
18 * Module name: remcom.c $
20 * Date: 91/03/09 12:29:49 $
21 * Contributor: Lake Stevens Instrument Division$
23 * Description: low level support for gdb debugger. $
25 * Considerations: only works on target hardware $
27 * Written by: Glenn Engel $
28 * ModuleState: Experimental $
32 * Modified for SPARC by Stu Grossman, Cygnus Support.
33 * Based on sparc-stub.c, it's modified for SPARClite Debug Unit hardware
34 * breakpoint support to create sparclite-stub.c, by Kung Hsu, Cygnus Support.
36 * This code has been extensively tested on the Fujitsu SPARClite demo board.
38 * To enable debugger support, two things need to happen. One, a
39 * call to set_debug_traps() is necessary in order to allow any breakpoints
40 * or error conditions to be properly intercepted and reported to gdb.
41 * Two, a breakpoint needs to be generated to begin communication. This
42 * is most easily accomplished by a call to breakpoint(). Breakpoint()
43 * simulates a breakpoint by executing a trap #1.
47 * The following gdb commands are supported:
49 * command function Return value
51 * g return the value of the CPU registers hex data or ENN
52 * G set the value of the CPU registers OK or ENN
54 * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
55 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
57 * c Resume at current address SNN ( signal NN)
58 * cAA..AA Continue at address AA..AA SNN
60 * s Step one instruction SNN
61 * sAA..AA Step one instruction from AA..AA SNN
65 * ? What was the last sigval ? SNN (signal NN)
67 * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
70 * All commands and responses are sent with a packet which includes a
71 * checksum. A packet consists of
73 * $<packet info>#<checksum>.
76 * <packet info> :: <characters representing the command or response>
77 * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
79 * When a packet is received, it is first acknowledged with either '+' or '-'.
80 * '+' indicates a successful transfer. '-' indicates a failed transfer.
85 * $m0,10#2a +$00010203040506070809101112131415#42
87 ****************************************************************************/
91 #include <sparclite.h>
93 /************************************************************************
95 * external low-level support routines
98 extern void putDebugChar (int c
); /* write a single character */
99 extern int getDebugChar (void); /* read and return a single char */
101 /************************************************************************/
102 /* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
103 /* at least NUMREGBYTES*2 are needed for register packets */
106 static int initialized
= 0; /* !0 means we've been initialized */
108 extern void breakinst ();
109 static void set_mem_fault_trap (int enable
);
110 static void get_in_break_mode (void);
112 static const char hexchars
[]="0123456789abcdef";
116 /* Number of bytes of registers. */
117 #define NUMREGBYTES (NUMREGS * 4)
118 enum regnames
{G0
, G1
, G2
, G3
, G4
, G5
, G6
, G7
,
119 O0
, O1
, O2
, O3
, O4
, O5
, SP
, O7
,
120 L0
, L1
, L2
, L3
, L4
, L5
, L6
, L7
,
121 I0
, I1
, I2
, I3
, I4
, I5
, FP
, I7
,
123 F0
, F1
, F2
, F3
, F4
, F5
, F6
, F7
,
124 F8
, F9
, F10
, F11
, F12
, F13
, F14
, F15
,
125 F16
, F17
, F18
, F19
, F20
, F21
, F22
, F23
,
126 F24
, F25
, F26
, F27
, F28
, F29
, F30
, F31
,
127 Y
, PSR
, WIM
, TBR
, PC
, NPC
, FPSR
, CPSR
,
128 DIA1
, DIA2
, DDA1
, DDA2
, DDV1
, DDV2
, DCR
, DSR
};
130 /*************************** ASSEMBLY CODE MACROS *************************/
133 extern void trap_low();
135 /* Create private copies of common functions used by the stub. This prevents
136 nasty interactions between app code and the stub (for instance if user steps
137 into strlen, etc..) */
140 strcpy (char *dst
, const char *src
)
144 while ((*dst
++ = *src
++) != '\000');
150 memcpy (void *vdst
, const void *vsrc
, int n
)
153 const char *src
= vsrc
;
163 .reserve trapstack, 1000 * 4, \"bss\", 8
174 ! This function is called when any SPARC trap (except window overflow or
175 ! underflow) occurs. It makes sure that the invalid register window is still
176 ! available before jumping into C code. It will also restore the world if you
177 ! return from handle_exception.
179 ! On entry, trap_low expects l1 and l2 to contain pc and npc respectivly.
180 ! Register usage throughout the routine is as follows:
186 ! l4 - scratch and y reg
187 ! l5 - scratch and tbr
196 srl %l3, %l0, %l4 ! wim >> cwp
198 bne window_fine ! Branch if not in the invalid window
201 ! Handle window overflow
203 mov %g1, %l4 ! Save g1, we use it to hold the wim
204 srl %l3, 1, %g1 ! Rotate wim right
206 bg good_wim ! Branch if new wim is non-zero
209 ! At this point, we need to bring a 1 into the high order bit of the wim.
210 ! Since we don't want to make any assumptions about the number of register
211 ! windows, we figure it out dynamically so as to setup the wim correctly.
213 not %g1 ! Fill g1 with ones
214 mov %g1, %wim ! Fill the wim with ones
218 mov %wim, %g1 ! Read back the wim
219 inc %g1 ! Now g1 has 1 just to left of wim
220 srl %g1, 1, %g1 ! Now put 1 at top of wim
221 mov %g0, %wim ! Clear wim so that subsequent save
227 save %g0, %g0, %g0 ! Slip into next window
228 mov %g1, %wim ! Install the new wim
230 std %l0, [%sp + 0 * 4] ! save L & I registers
231 std %l2, [%sp + 2 * 4]
232 std %l4, [%sp + 4 * 4]
233 std %l6, [%sp + 6 * 4]
235 std %i0, [%sp + 8 * 4]
236 std %i2, [%sp + 10 * 4]
237 std %i4, [%sp + 12 * 4]
238 std %i6, [%sp + 14 * 4]
240 restore ! Go back to trap window.
241 mov %l4, %g1 ! Restore %g1
244 sethi %hi(in_trap_handler), %l4
245 ld [%lo(in_trap_handler) + %l4], %l5
250 set trapstack+1000*4, %sp ! Switch to trap stack
253 st %l5, [%lo(in_trap_handler) + %l4]
254 sub %sp,(16+1+6+1+80)*4,%sp ! Make room for input & locals
255 ! + hidden arg + arg spill
256 ! + doubleword alignment
257 ! + registers[72] local var
259 std %g0, [%sp + (24 + 0) * 4] ! registers[Gx]
260 std %g2, [%sp + (24 + 2) * 4]
261 std %g4, [%sp + (24 + 4) * 4]
262 std %g6, [%sp + (24 + 6) * 4]
264 std %i0, [%sp + (24 + 8) * 4] ! registers[Ox]
265 std %i2, [%sp + (24 + 10) * 4]
266 std %i4, [%sp + (24 + 12) * 4]
267 std %i6, [%sp + (24 + 14) * 4]
271 st %l4, [%sp + (24 + 64) * 4] ! Y
272 st %l0, [%sp + (24 + 65) * 4] ! PSR
273 st %l3, [%sp + (24 + 66) * 4] ! WIM
274 st %l5, [%sp + (24 + 67) * 4] ! TBR
275 st %l1, [%sp + (24 + 68) * 4] ! PC
276 st %l2, [%sp + (24 + 69) * 4] ! NPC
279 mov %l4, %psr ! Turn on traps, disable interrupts
282 btst %l1, %l0 ! FP enabled?
286 ! Must save fsr first, to flush the FQ. This may cause a deferred fp trap, so
287 ! traps must be enabled to allow the trap handler to clean things up.
289 st %fsr, [%sp + (24 + 70) * 4]
291 std %f0, [%sp + (24 + 32) * 4]
292 std %f2, [%sp + (24 + 34) * 4]
293 std %f4, [%sp + (24 + 36) * 4]
294 std %f6, [%sp + (24 + 38) * 4]
295 std %f8, [%sp + (24 + 40) * 4]
296 std %f10, [%sp + (24 + 42) * 4]
297 std %f12, [%sp + (24 + 44) * 4]
298 std %f14, [%sp + (24 + 46) * 4]
299 std %f16, [%sp + (24 + 48) * 4]
300 std %f18, [%sp + (24 + 50) * 4]
301 std %f20, [%sp + (24 + 52) * 4]
302 std %f22, [%sp + (24 + 54) * 4]
303 std %f24, [%sp + (24 + 56) * 4]
304 std %f26, [%sp + (24 + 58) * 4]
305 std %f28, [%sp + (24 + 60) * 4]
306 std %f30, [%sp + (24 + 62) * 4]
309 call _handle_exception
310 add %sp, 24 * 4, %o0 ! Pass address of registers
312 ! Reload all of the registers that aren't on the stack
314 ld [%sp + (24 + 1) * 4], %g1 ! registers[Gx]
315 ldd [%sp + (24 + 2) * 4], %g2
316 ldd [%sp + (24 + 4) * 4], %g4
317 ldd [%sp + (24 + 6) * 4], %g6
319 ldd [%sp + (24 + 8) * 4], %i0 ! registers[Ox]
320 ldd [%sp + (24 + 10) * 4], %i2
321 ldd [%sp + (24 + 12) * 4], %i4
322 ldd [%sp + (24 + 14) * 4], %i6
325 ldd [%sp + (24 + 64) * 4], %l0 ! Y & PSR
326 ldd [%sp + (24 + 68) * 4], %l2 ! PC & NPC
329 btst %l5, %l1 ! FP enabled?
333 ldd [%sp + (24 + 32) * 4], %f0
334 ldd [%sp + (24 + 34) * 4], %f2
335 ldd [%sp + (24 + 36) * 4], %f4
336 ldd [%sp + (24 + 38) * 4], %f6
337 ldd [%sp + (24 + 40) * 4], %f8
338 ldd [%sp + (24 + 42) * 4], %f10
339 ldd [%sp + (24 + 44) * 4], %f12
340 ldd [%sp + (24 + 46) * 4], %f14
341 ldd [%sp + (24 + 48) * 4], %f16
342 ldd [%sp + (24 + 50) * 4], %f18
343 ldd [%sp + (24 + 52) * 4], %f20
344 ldd [%sp + (24 + 54) * 4], %f22
345 ldd [%sp + (24 + 56) * 4], %f24
346 ldd [%sp + (24 + 58) * 4], %f26
347 ldd [%sp + (24 + 60) * 4], %f28
348 ldd [%sp + (24 + 62) * 4], %f30
350 ld [%sp + (24 + 70) * 4], %fsr
353 restore ! Ensure that previous window is valid
354 save %g0, %g0, %g0 ! by causing a window_underflow trap
357 mov %l1, %psr ! Make sure that traps are disabled
359 sethi %hi(in_trap_handler), %l4
360 ld [%lo(in_trap_handler) + %l4], %l5
362 st %l5, [%lo(in_trap_handler) + %l4]
364 jmpl %l2, %g0 ! Restore old PC
365 rett %l3 ! Restore old nPC
368 /* Convert ch from a hex digit to an int */
374 if (ch
>= 'a' && ch
<= 'f')
376 if (ch
>= '0' && ch
<= '9')
378 if (ch
>= 'A' && ch
<= 'F')
383 /* scan for the sequence $<data>#<checksum> */
387 unsigned char *buffer
;
389 unsigned char checksum
;
390 unsigned char xmitcsum
;
396 /* wait around for the start character, ignore all other characters */
397 while ((ch
= getDebugChar ()) != '$')
405 /* now, read until a # or end of buffer is found */
406 while (count
< BUFMAX
)
408 ch
= getDebugChar ();
413 checksum
= checksum
+ ch
;
421 ch
= getDebugChar ();
422 xmitcsum
= hex (ch
) << 4;
423 ch
= getDebugChar ();
424 xmitcsum
+= hex (ch
);
426 if (checksum
!= xmitcsum
)
428 putDebugChar ('-'); /* failed checksum */
432 putDebugChar ('+'); /* successful transfer */
434 /* if a sequence char is present, reply the sequence ID */
435 if (buffer
[2] == ':')
437 putDebugChar (buffer
[0]);
438 putDebugChar (buffer
[1]);
449 /* send the packet in buffer. */
453 unsigned char *buffer
;
455 unsigned char checksum
;
459 /* $<packet info>#<checksum>. */
466 while (ch
= buffer
[count
])
474 putDebugChar(hexchars
[checksum
>> 4]);
475 putDebugChar(hexchars
[checksum
& 0xf]);
478 while (getDebugChar() != '+');
481 static char remcomInBuffer
[BUFMAX
];
482 static char remcomOutBuffer
[BUFMAX
];
484 /* Indicate to caller of mem2hex or hex2mem that there has been an
486 static volatile int mem_err
= 0;
488 /* Convert the memory pointed to by mem into hex, placing result in buf.
489 * Return a pointer to the last char put in buf (null), in case of mem fault,
491 * If MAY_FAULT is non-zero, then we will handle memory faults by returning
492 * a 0, else treat a fault like any other fault in the stub.
495 static unsigned char *
496 mem2hex(mem
, buf
, count
, may_fault
)
504 set_mem_fault_trap(may_fault
);
511 *buf
++ = hexchars
[ch
>> 4];
512 *buf
++ = hexchars
[ch
& 0xf];
517 set_mem_fault_trap(0);
522 /* convert the hex array pointed to by buf into binary to be placed in mem
523 * return a pointer to the character AFTER the last byte written */
526 hex2mem(buf
, mem
, count
, may_fault
)
535 set_mem_fault_trap(may_fault
);
537 for (i
=0; i
<count
; i
++)
539 ch
= hex(*buf
++) << 4;
546 set_mem_fault_trap(0);
551 /* This table contains the mapping between SPARC hardware trap types, and
552 signals, which are primarily what GDB understands. It also indicates
553 which hardware traps we need to commandeer when initializing the stub. */
555 static struct hard_trap_info
557 unsigned char tt
; /* Trap type code for SPARClite */
558 unsigned char signo
; /* Signal that we map this trap into */
559 } hard_trap_info
[] = {
560 {0x01, SIGSEGV
}, /* instruction access error */
561 {0x02, SIGILL
}, /* privileged instruction */
562 {0x03, SIGILL
}, /* illegal instruction */
563 {0x04, SIGEMT
}, /* fp disabled */
564 {0x07, SIGBUS
}, /* mem address not aligned */
565 {0x09, SIGSEGV
}, /* data access exception */
566 {0x0a, SIGEMT
}, /* tag overflow */
567 {0x20, SIGBUS
}, /* r register access error */
568 {0x21, SIGBUS
}, /* instruction access error */
569 {0x24, SIGEMT
}, /* cp disabled */
570 {0x29, SIGBUS
}, /* data access error */
571 {0x2a, SIGFPE
}, /* divide by zero */
572 {0x2b, SIGBUS
}, /* data store error */
573 {0x80+1, SIGTRAP
}, /* ta 1 - normal breakpoint instruction */
574 {0xff, SIGTRAP
}, /* hardware breakpoint */
575 {0, 0} /* Must be last */
578 /* Set up exception handlers for tracing and breakpoints */
583 struct hard_trap_info
*ht
;
585 /* Only setup fp traps if the FP is disabled. */
587 for (ht
= hard_trap_info
;
588 ht
->tt
!= 0 && ht
->signo
!= 0;
590 if (ht
->tt
!= 4 || ! (read_psr () & 0x1000))
591 exceptionHandler(ht
->tt
, trap_low
);
597 ! Trap handler for memory errors. This just sets mem_err to be non-zero. It
598 ! assumes that %l1 is non-zero. This should be safe, as it is doubtful that
599 ! 0 would ever contain code that could mem fault. This routine will skip
600 ! past the faulting instruction after setting mem_err.
606 sethi %hi(_mem_err), %l0
607 st %l1, [%l0 + %lo(_mem_err)]
613 set_mem_fault_trap(enable
)
616 extern void fltr_set_mem_err();
620 exceptionHandler(9, fltr_set_mem_err
);
622 exceptionHandler(9, trap_low
);
629 _dummy_hw_breakpoint:
639 extern void dummy_hw_breakpoint();
641 exceptionHandler (255, dummy_hw_breakpoint
);
645 exceptionHandler (255, trap_low
);
648 /* Convert the SPARC hardware trap type code to a unix signal number. */
654 struct hard_trap_info
*ht
;
656 for (ht
= hard_trap_info
; ht
->tt
&& ht
->signo
; ht
++)
660 return SIGHUP
; /* default for things we don't know about */
664 * While we find nice hex chars, build an int.
665 * Return number of chars processed.
669 hexToInt(char **ptr
, int *intValue
)
678 hexValue
= hex(**ptr
);
682 *intValue
= (*intValue
<< 4) | hexValue
;
692 * This function does all command procesing for interfacing to gdb. It
693 * returns 1 if you should skip the instruction at the trap address, 0
698 handle_exception (registers
)
699 unsigned long *registers
;
701 int tt
; /* Trap type */
709 /* First, we must force all of the windows to be spilled out */
711 asm(" save %sp, -64, %sp
729 get_in_break_mode (); /* Enable DSU register writes */
731 registers
[DIA1
] = read_asi (1, 0xff00);
732 registers
[DIA2
] = read_asi (1, 0xff04);
733 registers
[DDA1
] = read_asi (1, 0xff08);
734 registers
[DDA2
] = read_asi (1, 0xff0c);
735 registers
[DDV1
] = read_asi (1, 0xff10);
736 registers
[DDV2
] = read_asi (1, 0xff14);
737 registers
[DCR
] = read_asi (1, 0xff18);
738 registers
[DSR
] = read_asi (1, 0xff1c);
740 if (registers
[PC
] == (unsigned long)breakinst
)
742 registers
[PC
] = registers
[NPC
];
745 sp
= (unsigned long *)registers
[SP
];
747 dsr
= (unsigned long)registers
[DSR
];
751 tt
= (registers
[TBR
] >> 4) & 0xff;
753 /* reply to host that an exception has occurred */
754 sigval
= computeSignal(tt
);
755 ptr
= remcomOutBuffer
;
758 *ptr
++ = hexchars
[sigval
>> 4];
759 *ptr
++ = hexchars
[sigval
& 0xf];
761 *ptr
++ = hexchars
[PC
>> 4];
762 *ptr
++ = hexchars
[PC
& 0xf];
764 ptr
= mem2hex((char *)®isters
[PC
], ptr
, 4, 0);
767 *ptr
++ = hexchars
[FP
>> 4];
768 *ptr
++ = hexchars
[FP
& 0xf];
770 ptr
= mem2hex(sp
+ 8 + 6, ptr
, 4, 0); /* FP */
773 *ptr
++ = hexchars
[SP
>> 4];
774 *ptr
++ = hexchars
[SP
& 0xf];
776 ptr
= mem2hex((char *)&sp
, ptr
, 4, 0);
779 *ptr
++ = hexchars
[NPC
>> 4];
780 *ptr
++ = hexchars
[NPC
& 0xf];
782 ptr
= mem2hex((char *)®isters
[NPC
], ptr
, 4, 0);
785 *ptr
++ = hexchars
[O7
>> 4];
786 *ptr
++ = hexchars
[O7
& 0xf];
788 ptr
= mem2hex((char *)®isters
[O7
], ptr
, 4, 0);
793 putpacket(remcomOutBuffer
);
797 remcomOutBuffer
[0] = 0;
799 ptr
= getpacket(remcomInBuffer
);
803 remcomOutBuffer
[0] = 'S';
804 remcomOutBuffer
[1] = hexchars
[sigval
>> 4];
805 remcomOutBuffer
[2] = hexchars
[sigval
& 0xf];
806 remcomOutBuffer
[3] = 0;
810 /* toggle debug flag */
813 case 'g': /* return the value of the CPU registers */
814 memcpy (®isters
[L0
], sp
, 16 * 4); /* Copy L & I regs from stack */
815 mem2hex ((char *)registers
, remcomOutBuffer
, NUMREGBYTES
, 0);
818 case 'G': /* Set the value of all registers */
819 case 'P': /* Set the value of one register */
821 unsigned long *newsp
, psr
;
823 psr
= registers
[PSR
];
829 if (hexToInt (&ptr
, ®no
)
831 if (regno
>= L0
&& regno
<= I7
)
832 hex2mem (ptr
, sp
+ regno
- L0
, 4, 0);
834 hex2mem (ptr
, (char *)®isters
[regno
], 4, 0);
837 strcpy (remcomOutBuffer
, "P01");
843 hex2mem (ptr
, (char *)registers
, NUMREGBYTES
, 0);
844 memcpy (sp
, ®isters
[L0
], 16 * 4); /* Copy L & I regs to stack */
847 /* See if the stack pointer has moved. If so, then copy the saved
848 locals and ins to the new location. This keeps the window
849 overflow and underflow routines happy. */
851 newsp
= (unsigned long *)registers
[SP
];
853 sp
= memcpy(newsp
, sp
, 16 * 4);
855 /* Don't allow CWP to be modified. */
857 if (psr
!= registers
[PSR
])
858 registers
[PSR
] = (psr
& 0x1f) | (registers
[PSR
] & ~0x1f);
860 strcpy(remcomOutBuffer
,"OK");
864 case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
865 /* Try to read %x,%x. */
867 if (hexToInt(&ptr
, &addr
)
869 && hexToInt(&ptr
, &length
))
871 if (mem2hex((char *)addr
, remcomOutBuffer
, length
, 1))
874 strcpy (remcomOutBuffer
, "E03");
877 strcpy(remcomOutBuffer
,"E01");
880 case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
881 /* Try to read '%x,%x:'. */
883 if (hexToInt(&ptr
, &addr
)
885 && hexToInt(&ptr
, &length
)
888 if (hex2mem(ptr
, (char *)addr
, length
, 1))
889 strcpy(remcomOutBuffer
, "OK");
891 strcpy(remcomOutBuffer
, "E03");
894 strcpy(remcomOutBuffer
, "E02");
897 case 'c': /* cAA..AA Continue at address AA..AA(optional) */
898 /* try to read optional parameter, pc unchanged if no parm */
899 if (hexToInt(&ptr
, &addr
))
901 registers
[PC
] = addr
;
902 registers
[NPC
] = addr
+ 4;
905 /* Need to flush the instruction cache here, as we may have deposited a
906 breakpoint, and the icache probably has no way of knowing that a data ref to
907 some location may have changed something that is in the instruction cache.
912 if (!(registers
[DSR
] & 0x1) /* DSU enabled? */
913 && !(registers
[DCR
] & 0x200)) /* Are we in break state? */
914 { /* Yes, set the DSU regs */
915 write_asi (1, 0xff00, registers
[DIA1
]);
916 write_asi (1, 0xff04, registers
[DIA2
]);
917 write_asi (1, 0xff08, registers
[DDA1
]);
918 write_asi (1, 0xff0c, registers
[DDA2
]);
919 write_asi (1, 0xff10, registers
[DDV1
]);
920 write_asi (1, 0xff14, registers
[DDV2
]);
921 write_asi (1, 0xff1c, registers
[DSR
]);
922 write_asi (1, 0xff18, registers
[DCR
] | 0x200); /* Clear break */
927 /* kill the program */
928 case 'k' : /* do nothing */
931 case 't': /* Test feature */
932 asm (" std %f30,[%sp]");
935 case 'r': /* Reset */
941 Disabled until we can unscrew
this properly
943 case 'b': /* bBB... Set baud rate to BB... */
946 extern void set_timer_3();
948 if (!hexToInt(&ptr
, &baudrate
))
950 strcpy(remcomOutBuffer
,"B01");
954 /* Convert baud rate to uart clock divider */
967 strcpy(remcomOutBuffer
,"B02");
971 putpacket("OK"); /* Ack before changing speed */
972 set_timer_3(baudrate
); /* Set it */
978 /* reply to the request */
979 putpacket(remcomOutBuffer
);
983 /* This function will generate a breakpoint exception. It is used at the
984 beginning of a program to sync up with a debugger and can be used
985 otherwise as a quick means to stop program execution and "break" into
994 asm(" .globl _breakinst