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 #define GDB_SAVE_SIZE 0x66
91 typedef struct _BREAKPOINT
{
94 } BREAKPOINT
, *PBREAKPOINT
;
96 BREAKPOINT BreakPoints
[64];
97 char DataOutBuffer
[1024];
98 volatile int DataOutAddr
, DataOutCsum
;
99 char DataInBuffer
[128];
100 volatile int DataInAddr
, ParseState
= 0, ComputedCsum
, ActualCsum
;
101 volatile int PacketSent
= 0, SendSignal
= 0;
102 volatile int Continue
= 0, Signal
= 0;
103 volatile ppc_trap_frame_t RegisterSaves
, *RegisterSaveArea
= &RegisterSaves
;
104 char *hex
= "0123456789abcdef";
119 extern void send(char *serport
, char c
);
120 extern char recv(char *serport
);
121 extern void setup(char *serport
, int baud
);
123 char *serport
= (char *)0x800003f8;
128 (ch
>= 'A' && ch
<= 'F') ||
129 (ch
>= 'a' && ch
<= 'f') ||
130 (ch
>= '0' && ch
<= '9');
138 inline void send(char *serport
, char c
) {
139 /* Wait for Clear to Send */
140 while( !(GetPhysByte((paddr_t
)serport
+LSR
) & 0x20) ) sync();
142 SetPhysByte((paddr_t
)serport
+THR
, c
);
146 inline int rdy(char *serport
)
149 return (GetPhysByte((paddr_t
)serport
+LSR
) & 0x20);
152 inline int chr(char *serport
)
155 return GetPhysByte((paddr_t
)serport
+LSR
) & 1;
158 inline char recv(char *serport
) {
161 while( !chr(serport
) ) sync();
163 c
= GetPhysByte((paddr_t
)serport
+RCV
);
169 void setup(char *serport
, int baud
) {
170 int x
= 115200 / baud
;
171 SetPhysByte((paddr_t
)serport
+LCR
, 128);
173 SetPhysByte((paddr_t
)serport
+BAUDLOW
, x
& 255);
175 SetPhysByte((paddr_t
)serport
+BAUDHIGH
, x
>> 8);
177 SetPhysByte((paddr_t
)serport
+LCR
, 3);
181 void SerialSetUp(int deviceType
, void *deviceAddr
, int baud
)
184 serport
= deviceAddr
;
185 setup(serport
, baud
);
188 extern int SerialInterrupt(int signal
, ppc_trap_frame_t
*tf
);
192 SetPhysByte((paddr_t
)serport
+IER
, GetPhysByte((paddr_t
)serport
+IER
) | 1);
195 void SerialWrite(int ch
)
202 return recv(serport
);
207 if (ch
>= 'a' && ch
<= 'f') return ch
+ 10 - 'a';
208 else if (ch
>= 'A' && ch
<= 'F') return ch
+ 10 - 'A';
209 else return ch
- '0';
212 int PacketReadHexNumber(int dig
)
216 for (i
= 0; i
< dig
&& isxdigit(DataInBuffer
[DataInAddr
]); i
++)
219 result
|= hex2int(DataInBuffer
[DataInAddr
++]);
224 void PacketWriteChar(int ch
)
227 DataOutBuffer
[DataOutAddr
++] = ch
;
230 int PacketWriteHexNumber(int hnum
, int dig
)
233 hnum
<<= (8 - dig
) * 4;
234 for (i
= 0; i
< dig
; i
++)
236 PacketWriteChar(hex
[(hnum
>> 28) & 15]);
250 int i
, ch
, count
= 0;
255 for (i
= 0; i
< DataOutAddr
; i
++)
257 SerialWrite(DataOutBuffer
[i
]);
260 SerialWrite(hex
[(DataOutCsum
>> 4) & 15]);
261 SerialWrite(hex
[DataOutCsum
& 15]);
263 while(!chr(serport
) && ((ch
= SerialRead()) != '+') && (ch
!= '$'));
273 void PacketWriteString(char *str
)
275 while(*str
) PacketWriteChar(*str
++);
281 PacketWriteString("OK");
291 void PacketWriteSignal(int code
)
294 PacketWriteChar('S');
295 PacketWriteHexNumber(code
, 2);
299 void PacketWriteError(int code
)
302 PacketWriteChar('E');
303 PacketWriteHexNumber(code
, 2);
311 int i
, memaddr
, memsize
;
314 switch (DataInBuffer
[DataInAddr
++])
318 for (i
= 0; i
< GDB_SAVE_SIZE
; i
++)
320 PacketWriteHexNumber(((int *)RegisterSaveArea
)[i
], 8);
326 for (i
= 0; i
< sizeof(*RegisterSaveArea
) / sizeof(int); i
++)
328 ((int *)RegisterSaveArea
)[i
] = PacketReadHexNumber(8);
334 memaddr
= PacketReadHexNumber(8);
336 memsize
= PacketReadHexNumber(8);
340 PacketWriteHexNumber(*((char *)memaddr
++), 2);
346 memaddr
= PacketReadHexNumber(8);
348 memsize
= PacketReadHexNumber(8);
352 *((char *)memaddr
++) = PacketReadHexNumber(2);
358 PacketWriteSignal(Signal
);
372 RegisterSaveArea
->srr1
|= 0x400;
379 switch (DataInBuffer
[1])
381 case 'S': /*upported => nothing*/
397 int SerialInterrupt(int signal
, ppc_trap_frame_t
*tf
)
401 if (!chr(serport
)) return 0;
404 RegisterSaveArea
= tf
;
410 if (ch
== 3) /* Break in - tehe */
413 PacketWriteSignal(3);
426 else if (ch
== '#' && ParseState
== 0)
430 else if (ParseState
== 0)
433 DataInBuffer
[DataInAddr
++] = ch
;
435 else if (ParseState
== 2)
440 else if (ParseState
== 3)
442 ActualCsum
= hex2int(ch
) | (hex2int(ActualCsum
) << 4);
445 if (ComputedCsum
== ActualCsum
)
448 DataInBuffer
[DataInAddr
] = 0;
457 else if (ParseState
== -1)
464 int TakeException(int n
, ppc_trap_frame_t
*tf
)
467 RegisterSaveArea
= tf
;
468 PacketWriteSignal(Signal
);
471 while(!Continue
) SerialInterrupt(n
, tf
);