Create the AHCI branch for Aman's work
[reactos.git] / sdk / 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 #define GDB_SAVE_SIZE 0x66
90
91 typedef struct _BREAKPOINT {
92 int OldCode;
93 int *Address;
94 } BREAKPOINT, *PBREAKPOINT;
95
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";
105
106 #define RCV 0
107 #define THR 0
108 #define BAUDLOW 0
109 #define BAUDHIGH 1
110 #define IER 1
111 #define FCR 2
112 #define ISR 2
113 #define LCR 3
114 #define MCR 4
115 #define LSR 5
116 #define MSR 6
117 #define SPR 7
118
119 extern void send(char *serport, char c);
120 extern char recv(char *serport);
121 extern void setup(char *serport, int baud);
122
123 char *serport = (char *)0x800003f8;
124
125 int isxdigit(int ch)
126 {
127 return
128 (ch >= 'A' && ch <= 'F') ||
129 (ch >= 'a' && ch <= 'f') ||
130 (ch >= '0' && ch <= '9');
131 }
132
133 inline void sync() {
134 __asm__("eieio\n\t"
135 "sync");
136 }
137
138 inline void send(char *serport, char c) {
139 /* Wait for Clear to Send */
140 while( !(GetPhysByte((paddr_t)serport+LSR) & 0x20) ) sync();
141
142 SetPhysByte((paddr_t)serport+THR, c);
143 sync();
144 }
145
146 inline int rdy(char *serport)
147 {
148 sync();
149 return (GetPhysByte((paddr_t)serport+LSR) & 0x20);
150 }
151
152 inline int chr(char *serport)
153 {
154 sync();
155 return GetPhysByte((paddr_t)serport+LSR) & 1;
156 }
157
158 inline char recv(char *serport) {
159 char c;
160
161 while( !chr(serport) ) sync();
162
163 c = GetPhysByte((paddr_t)serport+RCV);
164 sync();
165
166 return c;
167 }
168
169 void setup(char *serport, int baud) {
170 int x = 115200 / baud;
171 SetPhysByte((paddr_t)serport+LCR, 128);
172 sync();
173 SetPhysByte((paddr_t)serport+BAUDLOW, x & 255);
174 sync();
175 SetPhysByte((paddr_t)serport+BAUDHIGH, x >> 8);
176 sync();
177 SetPhysByte((paddr_t)serport+LCR, 3);
178 sync();
179 }
180
181 void SerialSetUp(int deviceType, void *deviceAddr, int baud)
182 {
183 int i;
184 serport = deviceAddr;
185 setup(serport, baud);
186 }
187
188 extern int SerialInterrupt(int signal, ppc_trap_frame_t *tf);
189
190 void IntEnable()
191 {
192 SetPhysByte((paddr_t)serport+IER, GetPhysByte((paddr_t)serport+IER) | 1);
193 }
194
195 void SerialWrite(int ch)
196 {
197 send(serport, ch);
198 }
199
200 int SerialRead()
201 {
202 return recv(serport);
203 }
204
205 int hex2int(int ch)
206 {
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';
210 }
211
212 int PacketReadHexNumber(int dig)
213 {
214 int i;
215 int result = 0;
216 for (i = 0; i < dig && isxdigit(DataInBuffer[DataInAddr]); i++)
217 {
218 result <<= 4;
219 result |= hex2int(DataInBuffer[DataInAddr++]);
220 }
221 return result;
222 }
223
224 void PacketWriteChar(int ch)
225 {
226 DataOutCsum += ch;
227 DataOutBuffer[DataOutAddr++] = ch;
228 }
229
230 int PacketWriteHexNumber(int hnum, int dig)
231 {
232 int i;
233 hnum <<= (8 - dig) * 4;
234 for (i = 0; i < dig; i++)
235 {
236 PacketWriteChar(hex[(hnum >> 28) & 15]);
237 hnum <<= 4;
238 }
239 return i;
240 }
241
242 void PacketStart()
243 {
244 DataOutCsum = 0;
245 DataOutAddr = 0;
246 }
247
248 void PacketFinish()
249 {
250 int i, ch, count = 0;
251
252 PacketSent = 0;
253
254 SerialWrite('$');
255 for (i = 0; i < DataOutAddr; i++)
256 {
257 SerialWrite(DataOutBuffer[i]);
258 }
259 SerialWrite('#');
260 SerialWrite(hex[(DataOutCsum >> 4) & 15]);
261 SerialWrite(hex[DataOutCsum & 15]);
262
263 while(!chr(serport) && ((ch = SerialRead()) != '+') && (ch != '$'));
264 if (ch == '$')
265 {
266 ParseState = 0;
267 DataInAddr = 0;
268 ComputedCsum = 0;
269 }
270 }
271
272
273 void PacketWriteString(char *str)
274 {
275 while(*str) PacketWriteChar(*str++);
276 }
277
278 void PacketOk()
279 {
280 PacketStart();
281 PacketWriteString("OK");
282 PacketFinish();
283 }
284
285 void PacketEmpty()
286 {
287 PacketStart();
288 PacketFinish();
289 }
290
291 void PacketWriteSignal(int code)
292 {
293 PacketStart();
294 PacketWriteChar('S');
295 PacketWriteHexNumber(code, 2);
296 PacketFinish();
297 }
298
299 void PacketWriteError(int code)
300 {
301 PacketStart();
302 PacketWriteChar('E');
303 PacketWriteHexNumber(code, 2);
304 PacketFinish();
305 }
306
307 void marker() { }
308
309 void GotPacket()
310 {
311 int i, memaddr, memsize;
312
313 Continue = 0;
314 switch (DataInBuffer[DataInAddr++])
315 {
316 case 'g':
317 PacketStart();
318 for (i = 0; i < GDB_SAVE_SIZE; i++)
319 {
320 PacketWriteHexNumber(((int *)RegisterSaveArea)[i], 8);
321 }
322 PacketFinish();
323 break;
324
325 case 'G':
326 for (i = 0; i < sizeof(*RegisterSaveArea) / sizeof(int); i++)
327 {
328 ((int *)RegisterSaveArea)[i] = PacketReadHexNumber(8);
329 }
330 PacketOk();
331 break;
332
333 case 'm':
334 memaddr = PacketReadHexNumber(8);
335 DataInAddr++;
336 memsize = PacketReadHexNumber(8);
337 PacketStart();
338 while(memsize-- > 0)
339 {
340 PacketWriteHexNumber(*((char *)memaddr++), 2);
341 }
342 PacketFinish();
343 break;
344
345 case 'M':
346 memaddr = PacketReadHexNumber(8);
347 DataInAddr++;
348 memsize = PacketReadHexNumber(8);
349 DataInAddr++;
350 while(memsize-- > 0)
351 {
352 *((char *)memaddr++) = PacketReadHexNumber(2);
353 }
354 PacketOk();
355 break;
356
357 case '?':
358 PacketWriteSignal(Signal);
359 break;
360
361 case 'c':
362 PacketOk();
363 Continue = 1;
364 break;
365
366 case 'S':
367 PacketOk();
368 Continue = 0;
369 break;
370
371 case 's':
372 RegisterSaveArea->srr1 |= 0x400;
373 PacketOk();
374 Continue = 1;
375 marker();
376 break;
377
378 case 'q':
379 switch (DataInBuffer[1])
380 {
381 case 'S': /*upported => nothing*/
382 PacketEmpty();
383 break;
384
385 case 'O': /*ffsets*/
386 PacketEmpty();
387 break;
388 }
389 break;
390
391 default:
392 PacketEmpty();
393 break;
394 }
395 }
396
397 int SerialInterrupt(int signal, ppc_trap_frame_t *tf)
398 {
399 int ch;
400
401 if (!chr(serport)) return 0;
402
403 Signal = signal;
404 RegisterSaveArea = tf;
405
406 do
407 {
408 ch = SerialRead();
409
410 if (ch == 3) /* Break in - tehe */
411 {
412 Continue = 0;
413 PacketWriteSignal(3);
414 }
415 else if (ch == '+')
416 {
417 /* Nothing */
418 }
419 else if (ch == '$')
420 {
421 DataInAddr = 0;
422 ParseState = 0;
423 ComputedCsum = 0;
424 ActualCsum = 0;
425 }
426 else if (ch == '#' && ParseState == 0)
427 {
428 ParseState = 2;
429 }
430 else if (ParseState == 0)
431 {
432 ComputedCsum += ch;
433 DataInBuffer[DataInAddr++] = ch;
434 }
435 else if (ParseState == 2)
436 {
437 ActualCsum = ch;
438 ParseState++;
439 }
440 else if (ParseState == 3)
441 {
442 ActualCsum = hex2int(ch) | (hex2int(ActualCsum) << 4);
443 ComputedCsum &= 255;
444 ParseState = -1;
445 if (ComputedCsum == ActualCsum)
446 {
447 ComputedCsum = 0;
448 DataInBuffer[DataInAddr] = 0;
449 DataInAddr = 0;
450 Continue = 0;
451 SerialWrite('+');
452 GotPacket();
453 }
454 else
455 SerialWrite('-');
456 }
457 else if (ParseState == -1)
458 SerialWrite('-');
459 }
460 while (!Continue);
461 return 1;
462 }
463
464 int TakeException(int n, ppc_trap_frame_t *tf)
465 {
466 Signal = n;
467 RegisterSaveArea = tf;
468 PacketWriteSignal(Signal);
469 SendSignal = 0;
470 Continue = 0;
471 while(!Continue) SerialInterrupt(n, tf);
472 return 1;
473 }
474
475 /* EOF */