153d2e4b33a6e9520287c5776965b47d1f263ac8
[reactos.git] / reactos / lib / ppcmmu / gdblib.c
1 /****************************************************************************
2
3 THIS SOFTWARE IS NOT COPYRIGHTED
4
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.
8
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.
12
13 ****************************************************************************/
14
15 /****************************************************************************
16 * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
17 *
18 * Module name: remcom.c $
19 * Revision: 1.34 $
20 * Date: 91/03/09 12:29:49 $
21 * Contributor: Lake Stevens Instrument Division$
22 *
23 * Description: low level support for gdb debugger. $
24 *
25 * Considerations: only works on target hardware $
26 *
27 * Written by: Glenn Engel $
28 * ModuleState: Experimental $
29 *
30 * NOTES: See Below $
31 *
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
35 *
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.
41 ER*
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.
45 *
46 *************
47 *
48 * The following gdb commands are supported:
49 *
50 * command function Return value
51 *
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
54 *
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
57 *
58 * c Resume at current address SNN ( signal NN)
59 * cAA..AA Continue at address AA..AA SNN
60 *
61 * s Step one instruction SNN
62 * sAA..AA Step one instruction from AA..AA SNN
63 *
64 * k kill
65 *
66 * ? What was the last sigval ? SNN (signal NN)
67 *
68 * All commands and responses are sent with a packet which includes a
69 * Checksum. A packet consists of
70 *
71 * $<packet info>#<Checksum>.
72 *
73 * where
74 * <packet info> :: <characters representing the command or response>
75 * <Checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
76 *
77 * When a packet is received, it is first acknowledged with either '+' or '-'.
78 * '+' indicates a successful transfer. '-' indicates a failed transfer.
79 *
80 * Example:
81 *
82 * Host: Reply:
83 * $m0,10#2a +$00010203040506070809101112131415#42
84 *
85 ****************************************************************************/
86
87 #include "ppcmmu/mmu.h"
88
89 typedef struct _BREAKPOINT {
90 int OldCode;
91 int *Address;
92 } BREAKPOINT, *PBREAKPOINT;
93
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";
103
104 #define RCV 0
105 #define THR 0
106 #define BAUDLOW 0
107 #define BAUDHIGH 1
108 #define IER 1
109 #define FCR 2
110 #define ISR 2
111 #define LCR 3
112 #define MCR 4
113 #define LSR 5
114 #define MSR 6
115 #define SPR 7
116
117 extern void send(char *serport, char c);
118 extern char recv(char *serport);
119 extern void setup(char *serport, int baud);
120
121 char *serport = (char *)0x800003f8;
122
123 int isxdigit(int ch)
124 {
125 return
126 (ch >= 'A' && ch <= 'F') ||
127 (ch >= 'a' && ch <= 'f') ||
128 (ch >= '0' && ch <= '9');
129 }
130
131 inline void sync() {
132 __asm__("eieio\n\t"
133 "sync");
134 }
135
136 inline void send(char *serport, char c) {
137 /* Wait for Clear to Send */
138 while( !(GetPhysByte((paddr_t)serport+LSR) & 0x20) ) sync();
139
140 SetPhysByte(serport+THR, c);
141 sync();
142 }
143
144 inline int rdy(char *serport)
145 {
146 sync();
147 return (GetPhysByte((paddr_t)serport+LSR) & 0x20);
148 }
149
150 inline int chr(char *serport)
151 {
152 sync();
153 return GetPhysByte((paddr_t)serport+LSR) & 1;
154 }
155
156 inline char recv(char *serport) {
157 char c;
158
159 while( !chr(serport) ) sync();
160
161 c = GetPhysByte((paddr_t)serport+RCV);
162 sync();
163
164 return c;
165 }
166
167 void setup(char *serport, int baud) {
168 int x = 115200 / baud;
169 SetPhysByte((paddr_t)serport+LCR, 128);
170 sync();
171 SetPhysByte((paddr_t)serport+BAUDLOW, x & 255);
172 sync();
173 SetPhysByte((paddr_t)serport+BAUDHIGH, x >> 8);
174 sync();
175 SetPhysByte((paddr_t)serport+LCR, 3);
176 sync();
177 }
178
179 void SerialSetUp(int deviceType, void *deviceAddr, int baud)
180 {
181 int i;
182 serport = deviceAddr;
183 setup(serport, baud);
184 }
185
186 extern int SerialInterrupt(int signal, ppc_trap_frame_t *tf);
187
188 void IntEnable()
189 {
190 SetPhysByte((paddr_t)serport+IER, GetPhysByte((paddr_t)serport+IER) | 1);
191 }
192
193 void SerialWrite(int ch)
194 {
195 send(serport, ch);
196 }
197
198 int SerialRead()
199 {
200 return recv(serport);
201 }
202
203 int hex2int(int ch)
204 {
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';
208 }
209
210 int PacketReadHexNumber(int dig)
211 {
212 int i;
213 int result = 0;
214 for (i = 0; i < dig && isxdigit(DataInBuffer[DataInAddr]); i++)
215 {
216 result <<= 4;
217 result |= hex2int(DataInBuffer[DataInAddr++]);
218 }
219 return result;
220 }
221
222 void PacketWriteChar(int ch)
223 {
224 DataOutCsum += ch;
225 DataOutBuffer[DataOutAddr++] = ch;
226 }
227
228 int PacketWriteHexNumber(int hnum, int dig)
229 {
230 int i;
231 hnum <<= (8 - dig) * 4;
232 for (i = 0; i < dig; i++)
233 {
234 PacketWriteChar(hex[(hnum >> 28) & 15]);
235 hnum <<= 4;
236 }
237 return i;
238 }
239
240 void PacketStart()
241 {
242 DataOutCsum = 0;
243 DataOutAddr = 0;
244 }
245
246 void PacketFinish()
247 {
248 int i, ch, count = 0;
249
250 PacketSent = 0;
251
252 SerialWrite('$');
253 for (i = 0; i < DataOutAddr; i++)
254 {
255 SerialWrite(DataOutBuffer[i]);
256 }
257 SerialWrite('#');
258 SerialWrite(hex[(DataOutCsum >> 4) & 15]);
259 SerialWrite(hex[DataOutCsum & 15]);
260
261 while(!chr(serport) && ((ch = SerialRead()) != '+') && (ch != '$'));
262 if (ch == '$')
263 {
264 ParseState = 0;
265 DataInAddr = 0;
266 ComputedCsum = 0;
267 }
268 }
269
270
271 void PacketWriteString(char *str)
272 {
273 while(*str) PacketWriteChar(*str++);
274 }
275
276 void PacketOk()
277 {
278 PacketStart();
279 PacketWriteString("OK");
280 PacketFinish();
281 }
282
283 void PacketEmpty()
284 {
285 PacketStart();
286 PacketFinish();
287 }
288
289 void PacketWriteSignal(int code)
290 {
291 PacketStart();
292 PacketWriteChar('S');
293 PacketWriteHexNumber(code, 2);
294 PacketFinish();
295 }
296
297 void PacketWriteError(int code)
298 {
299 PacketStart();
300 PacketWriteChar('E');
301 PacketWriteHexNumber(code, 2);
302 PacketFinish();
303 }
304
305 void marker() { }
306
307 void GotPacket()
308 {
309 int i, memaddr, memsize;
310
311 Continue = 0;
312 switch (DataInBuffer[DataInAddr++])
313 {
314 case 'g':
315 PacketStart();
316 for (i = 0; i < sizeof(*RegisterSaveArea) / sizeof(int); i++)
317 {
318 PacketWriteHexNumber(((int *)RegisterSaveArea)[i], 8);
319 }
320 PacketFinish();
321 break;
322
323 case 'G':
324 for (i = 0; i < sizeof(*RegisterSaveArea) / sizeof(int); i++)
325 {
326 ((int *)RegisterSaveArea)[i] = PacketReadHexNumber(8);
327 }
328 PacketOk();
329 break;
330
331 case 'm':
332 memaddr = PacketReadHexNumber(8);
333 DataInAddr++;
334 memsize = PacketReadHexNumber(8);
335 PacketStart();
336 while(memsize-- > 0)
337 {
338 PacketWriteHexNumber(*((char *)memaddr++), 2);
339 }
340 PacketFinish();
341 break;
342
343 case 'M':
344 memaddr = PacketReadHexNumber(8);
345 DataInAddr++;
346 memsize = PacketReadHexNumber(8);
347 DataInAddr++;
348 while(memsize-- > 0)
349 {
350 *((char *)memaddr++) = PacketReadHexNumber(2);
351 }
352 PacketOk();
353 break;
354
355 case '?':
356 PacketWriteSignal(Signal);
357 break;
358
359 case 'c':
360 PacketOk();
361 Continue = 1;
362 break;
363
364 case 'S':
365 PacketOk();
366 Continue = 0;
367 break;
368
369 case 's':
370 RegisterSaveArea->srr1 |= 0x400;
371 PacketOk();
372 Continue = 1;
373 marker();
374 break;
375
376 case 'q':
377 switch (DataInBuffer[1])
378 {
379 case 'S': /*upported => nothing*/
380 PacketEmpty();
381 break;
382
383 case 'O': /*ffsets*/
384 PacketEmpty();
385 break;
386 }
387 break;
388
389 default:
390 PacketEmpty();
391 break;
392 }
393 }
394
395 int SerialInterrupt(int signal, ppc_trap_frame_t *tf)
396 {
397 int ch;
398
399 if (!chr(serport)) return 0;
400
401 Signal = signal;
402 RegisterSaveArea = tf;
403
404 do
405 {
406 ch = SerialRead();
407
408 if (ch == 3) /* Break in - tehe */
409 {
410 Continue = 0;
411 PacketWriteSignal(3);
412 }
413 else if (ch == '-' || ch == '+')
414 {
415 /* Nothing */
416 }
417 else if (ch == '$')
418 {
419 DataInAddr = 0;
420 ParseState = 0;
421 ComputedCsum = 0;
422 ActualCsum = 0;
423 }
424 else if (ch == '#' && ParseState == 0)
425 {
426 ParseState = 2;
427 }
428 else if (ParseState == 0)
429 {
430 ComputedCsum += ch;
431 DataInBuffer[DataInAddr++] = ch;
432 }
433 else if (ParseState == 2)
434 {
435 ActualCsum = ch;
436 ParseState++;
437 }
438 else if (ParseState == 3)
439 {
440 ActualCsum = hex2int(ch) | (hex2int(ActualCsum) << 4);
441 ComputedCsum &= 255;
442 ParseState = -1;
443 if (ComputedCsum == ActualCsum)
444 {
445 ComputedCsum = 0;
446 DataInBuffer[DataInAddr] = 0;
447 DataInAddr = 0;
448 Continue = 0;
449 SerialWrite('+');
450 GotPacket();
451 }
452 else
453 SerialWrite('-');
454 }
455 else if (ParseState == -1)
456 SerialWrite('-');
457 }
458 while (!Continue);
459 return 1;
460 }
461
462 int TakeException(int n, ppc_trap_frame_t *tf)
463 {
464 Signal = n;
465 RegisterSaveArea = tf;
466 PacketWriteSignal(Signal);
467 SendSignal = 0;
468 Continue = 0;
469 while(!Continue) SerialInterrupt(n, tf);
470 return 1;
471 }
472
473 /* EOF */