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 386 by Jim Kingdon, Cygnus Support.
33 * Modified for ReactOS by Casper S. Hornstrup <chorns@users.sourceforge.net>
34 * Modified heavily for PowerPC ReactOS by arty
36 * To enable debugger support, two things need to happen. One, setting
37 * up a routine so that it is in the exception path, is necessary in order
38 * to allow any breakpoints or error conditions to be properly intercepted
39 * and reported to gdb.
40 * Two, a breakpoint needs to be generated to begin communication.
42 * Because gdb will sometimes write to the stack area to execute function
43 * calls, this program cannot rely on using the supervisor stack so it
44 * uses it's own stack area.
48 * The following gdb commands are supported:
50 * command function Return value
52 * g return the value of the CPU Registers hex data or ENN
53 * G set the value of the CPU Registers OK or ENN
55 * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
56 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
58 * c Resume at current address SNN ( signal NN)
59 * cAA..AA Continue at address AA..AA SNN
61 * s Step one instruction SNN
62 * sAA..AA Step one instruction from AA..AA SNN
66 * ? What was the last sigval ? SNN (signal NN)
68 * All commands and responses are sent with a packet which includes a
69 * Checksum. A packet consists of
71 * $<packet info>#<Checksum>.
74 * <packet info> :: <characters representing the command or response>
75 * <Checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
77 * When a packet is received, it is first acknowledged with either '+' or '-'.
78 * '+' indicates a successful transfer. '-' indicates a failed transfer.
83 * $m0,10#2a +$00010203040506070809101112131415#42
85 ****************************************************************************/
87 #include "ppcmmu/mmu.h"
89 typedef struct _BREAKPOINT
{
92 } BREAKPOINT
, *PBREAKPOINT
;
94 BREAKPOINT BreakPoints
[64];
95 char DataOutBuffer
[1024];
96 volatile int DataOutAddr
, DataOutCsum
;
97 char DataInBuffer
[128];
98 volatile int DataInAddr
, ParseState
= 0, ComputedCsum
, ActualCsum
;
99 volatile int PacketSent
= 0, SendSignal
= 0;
100 volatile int Continue
= 0, Signal
= 0;
101 volatile ppc_trap_frame_t RegisterSaves
, *RegisterSaveArea
= &RegisterSaves
;
102 char *hex
= "0123456789abcdef";
117 extern void send(char *serport
, char c
);
118 extern char recv(char *serport
);
119 extern void setup(char *serport
, int baud
);
121 char *serport
= (char *)0x800003f8;
126 (ch
>= 'A' && ch
<= 'F') ||
127 (ch
>= 'a' && ch
<= 'f') ||
128 (ch
>= '0' && ch
<= '9');
136 inline void send(char *serport
, char c
) {
137 /* Wait for Clear to Send */
138 while( !(GetPhysByte((paddr_t
)serport
+LSR
) & 0x20) ) sync();
140 SetPhysByte(serport
+THR
, c
);
144 inline int rdy(char *serport
)
147 return (GetPhysByte((paddr_t
)serport
+LSR
) & 0x20);
150 inline int chr(char *serport
)
153 return GetPhysByte((paddr_t
)serport
+LSR
) & 1;
156 inline char recv(char *serport
) {
159 while( !chr(serport
) ) sync();
161 c
= GetPhysByte((paddr_t
)serport
+RCV
);
167 void setup(char *serport
, int baud
) {
168 int x
= 115200 / baud
;
169 SetPhysByte((paddr_t
)serport
+LCR
, 128);
171 SetPhysByte((paddr_t
)serport
+BAUDLOW
, x
& 255);
173 SetPhysByte((paddr_t
)serport
+BAUDHIGH
, x
>> 8);
175 SetPhysByte((paddr_t
)serport
+LCR
, 3);
179 void SerialSetUp(int deviceType
, void *deviceAddr
, int baud
)
182 serport
= deviceAddr
;
183 setup(serport
, baud
);
186 extern int SerialInterrupt(int signal
, ppc_trap_frame_t
*tf
);
190 SetPhysByte((paddr_t
)serport
+IER
, GetPhysByte((paddr_t
)serport
+IER
) | 1);
193 void SerialWrite(int ch
)
200 return recv(serport
);
205 if (ch
>= 'a' && ch
<= 'f') return ch
+ 10 - 'a';
206 else if (ch
>= 'A' && ch
<= 'F') return ch
+ 10 - 'A';
207 else return ch
- '0';
210 int PacketReadHexNumber(int dig
)
214 for (i
= 0; i
< dig
&& isxdigit(DataInBuffer
[DataInAddr
]); i
++)
217 result
|= hex2int(DataInBuffer
[DataInAddr
++]);
222 void PacketWriteChar(int ch
)
225 DataOutBuffer
[DataOutAddr
++] = ch
;
228 int PacketWriteHexNumber(int hnum
, int dig
)
231 hnum
<<= (8 - dig
) * 4;
232 for (i
= 0; i
< dig
; i
++)
234 PacketWriteChar(hex
[(hnum
>> 28) & 15]);
248 int i
, ch
, count
= 0;
253 for (i
= 0; i
< DataOutAddr
; i
++)
255 SerialWrite(DataOutBuffer
[i
]);
258 SerialWrite(hex
[(DataOutCsum
>> 4) & 15]);
259 SerialWrite(hex
[DataOutCsum
& 15]);
261 while(!chr(serport
) && ((ch
= SerialRead()) != '+') && (ch
!= '$'));
271 void PacketWriteString(char *str
)
273 while(*str
) PacketWriteChar(*str
++);
279 PacketWriteString("OK");
289 void PacketWriteSignal(int code
)
292 PacketWriteChar('S');
293 PacketWriteHexNumber(code
, 2);
297 void PacketWriteError(int code
)
300 PacketWriteChar('E');
301 PacketWriteHexNumber(code
, 2);
309 int i
, memaddr
, memsize
;
312 switch (DataInBuffer
[DataInAddr
++])
316 for (i
= 0; i
< sizeof(*RegisterSaveArea
) / sizeof(int); i
++)
318 PacketWriteHexNumber(((int *)RegisterSaveArea
)[i
], 8);
324 for (i
= 0; i
< sizeof(*RegisterSaveArea
) / sizeof(int); i
++)
326 ((int *)RegisterSaveArea
)[i
] = PacketReadHexNumber(8);
332 memaddr
= PacketReadHexNumber(8);
334 memsize
= PacketReadHexNumber(8);
338 PacketWriteHexNumber(*((char *)memaddr
++), 2);
344 memaddr
= PacketReadHexNumber(8);
346 memsize
= PacketReadHexNumber(8);
350 *((char *)memaddr
++) = PacketReadHexNumber(2);
356 PacketWriteSignal(Signal
);
370 RegisterSaveArea
->srr1
|= 0x400;
377 switch (DataInBuffer
[1])
379 case 'S': /*upported => nothing*/
395 int SerialInterrupt(int signal
, ppc_trap_frame_t
*tf
)
399 if (!chr(serport
)) return 0;
402 RegisterSaveArea
= tf
;
408 if (ch
== 3) /* Break in - tehe */
411 PacketWriteSignal(3);
413 else if (ch
== '-' || ch
== '+')
424 else if (ch
== '#' && ParseState
== 0)
428 else if (ParseState
== 0)
431 DataInBuffer
[DataInAddr
++] = ch
;
433 else if (ParseState
== 2)
438 else if (ParseState
== 3)
440 ActualCsum
= hex2int(ch
) | (hex2int(ActualCsum
) << 4);
443 if (ComputedCsum
== ActualCsum
)
446 DataInBuffer
[DataInAddr
] = 0;
455 else if (ParseState
== -1)
462 int TakeException(int n
, ppc_trap_frame_t
*tf
)
465 RegisterSaveArea
= tf
;
466 PacketWriteSignal(Signal
);
469 while(!Continue
) SerialInterrupt(n
, tf
);