Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygengdblib.c
Go to the documentation of this file.
00001 /**************************************************************************** 00002 00003 THIS SOFTWARE IS NOT COPYRIGHTED 00004 00005 HP offers the following for use in the public domain. HP makes no 00006 warranty with regard to the software or it's performance and the 00007 user accepts the software "AS IS" with all faults. 00008 00009 HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD 00010 TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES 00011 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 ****************************************************************************/ 00014 00015 /**************************************************************************** 00016 * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ 00017 * 00018 * Module name: remcom.c $ 00019 * Revision: 1.34 $ 00020 * Date: 91/03/09 12:29:49 $ 00021 * Contributor: Lake Stevens Instrument Division$ 00022 * 00023 * Description: low level support for gdb debugger. $ 00024 * 00025 * Considerations: only works on target hardware $ 00026 * 00027 * Written by: Glenn Engel $ 00028 * ModuleState: Experimental $ 00029 * 00030 * NOTES: See Below $ 00031 * 00032 * Modified for 386 by Jim Kingdon, Cygnus Support. 00033 * Modified for ReactOS by Casper S. Hornstrup <chorns@users.sourceforge.net> 00034 * Modified heavily for PowerPC ReactOS by arty 00035 * 00036 * To enable debugger support, two things need to happen. One, setting 00037 * up a routine so that it is in the exception path, is necessary in order 00038 * to allow any breakpoints or error conditions to be properly intercepted 00039 * and reported to gdb. 00040 * Two, a breakpoint needs to be generated to begin communication. 00041 ER* 00042 * Because gdb will sometimes write to the stack area to execute function 00043 * calls, this program cannot rely on using the supervisor stack so it 00044 * uses it's own stack area. 00045 * 00046 ************* 00047 * 00048 * The following gdb commands are supported: 00049 * 00050 * command function Return value 00051 * 00052 * g return the value of the CPU Registers hex data or ENN 00053 * G set the value of the CPU Registers OK or ENN 00054 * 00055 * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN 00056 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN 00057 * 00058 * c Resume at current address SNN ( signal NN) 00059 * cAA..AA Continue at address AA..AA SNN 00060 * 00061 * s Step one instruction SNN 00062 * sAA..AA Step one instruction from AA..AA SNN 00063 * 00064 * k kill 00065 * 00066 * ? What was the last sigval ? SNN (signal NN) 00067 * 00068 * All commands and responses are sent with a packet which includes a 00069 * Checksum. A packet consists of 00070 * 00071 * $<packet info>#<Checksum>. 00072 * 00073 * where 00074 * <packet info> :: <characters representing the command or response> 00075 * <Checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>> 00076 * 00077 * When a packet is received, it is first acknowledged with either '+' or '-'. 00078 * '+' indicates a successful transfer. '-' indicates a failed transfer. 00079 * 00080 * Example: 00081 * 00082 * Host: Reply: 00083 * $m0,10#2a +$00010203040506070809101112131415#42 00084 * 00085 ****************************************************************************/ 00086 00087 #include "ppcmmu/mmu.h" 00088 00089 #define GDB_SAVE_SIZE 0x66 00090 00091 typedef struct _BREAKPOINT { 00092 int OldCode; 00093 int *Address; 00094 } BREAKPOINT, *PBREAKPOINT; 00095 00096 BREAKPOINT BreakPoints[64]; 00097 char DataOutBuffer[1024]; 00098 volatile int DataOutAddr, DataOutCsum; 00099 char DataInBuffer[128]; 00100 volatile int DataInAddr, ParseState = 0, ComputedCsum, ActualCsum; 00101 volatile int PacketSent = 0, SendSignal = 0; 00102 volatile int Continue = 0, Signal = 0; 00103 volatile ppc_trap_frame_t RegisterSaves, *RegisterSaveArea = &RegisterSaves; 00104 char *hex = "0123456789abcdef"; 00105 00106 #define RCV 0 00107 #define THR 0 00108 #define BAUDLOW 0 00109 #define BAUDHIGH 1 00110 #define IER 1 00111 #define FCR 2 00112 #define ISR 2 00113 #define LCR 3 00114 #define MCR 4 00115 #define LSR 5 00116 #define MSR 6 00117 #define SPR 7 00118 00119 extern void send(char *serport, char c); 00120 extern char recv(char *serport); 00121 extern void setup(char *serport, int baud); 00122 00123 char *serport = (char *)0x800003f8; 00124 00125 int isxdigit(int ch) 00126 { 00127 return 00128 (ch >= 'A' && ch <= 'F') || 00129 (ch >= 'a' && ch <= 'f') || 00130 (ch >= '0' && ch <= '9'); 00131 } 00132 00133 inline void sync() { 00134 __asm__("eieio\n\t" 00135 "sync"); 00136 } 00137 00138 inline void send(char *serport, char c) { 00139 /* Wait for Clear to Send */ 00140 while( !(GetPhysByte((paddr_t)serport+LSR) & 0x20) ) sync(); 00141 00142 SetPhysByte((paddr_t)serport+THR, c); 00143 sync(); 00144 } 00145 00146 inline int rdy(char *serport) 00147 { 00148 sync(); 00149 return (GetPhysByte((paddr_t)serport+LSR) & 0x20); 00150 } 00151 00152 inline int chr(char *serport) 00153 { 00154 sync(); 00155 return GetPhysByte((paddr_t)serport+LSR) & 1; 00156 } 00157 00158 inline char recv(char *serport) { 00159 char c; 00160 00161 while( !chr(serport) ) sync(); 00162 00163 c = GetPhysByte((paddr_t)serport+RCV); 00164 sync(); 00165 00166 return c; 00167 } 00168 00169 void setup(char *serport, int baud) { 00170 int x = 115200 / baud; 00171 SetPhysByte((paddr_t)serport+LCR, 128); 00172 sync(); 00173 SetPhysByte((paddr_t)serport+BAUDLOW, x & 255); 00174 sync(); 00175 SetPhysByte((paddr_t)serport+BAUDHIGH, x >> 8); 00176 sync(); 00177 SetPhysByte((paddr_t)serport+LCR, 3); 00178 sync(); 00179 } 00180 00181 void SerialSetUp(int deviceType, void *deviceAddr, int baud) 00182 { 00183 int i; 00184 serport = deviceAddr; 00185 setup(serport, baud); 00186 } 00187 00188 extern int SerialInterrupt(int signal, ppc_trap_frame_t *tf); 00189 00190 void IntEnable() 00191 { 00192 SetPhysByte((paddr_t)serport+IER, GetPhysByte((paddr_t)serport+IER) | 1); 00193 } 00194 00195 void SerialWrite(int ch) 00196 { 00197 send(serport, ch); 00198 } 00199 00200 int SerialRead() 00201 { 00202 return recv(serport); 00203 } 00204 00205 int hex2int(int ch) 00206 { 00207 if (ch >= 'a' && ch <= 'f') return ch + 10 - 'a'; 00208 else if (ch >= 'A' && ch <= 'F') return ch + 10 - 'A'; 00209 else return ch - '0'; 00210 } 00211 00212 int PacketReadHexNumber(int dig) 00213 { 00214 int i; 00215 int result = 0; 00216 for (i = 0; i < dig && isxdigit(DataInBuffer[DataInAddr]); i++) 00217 { 00218 result <<= 4; 00219 result |= hex2int(DataInBuffer[DataInAddr++]); 00220 } 00221 return result; 00222 } 00223 00224 void PacketWriteChar(int ch) 00225 { 00226 DataOutCsum += ch; 00227 DataOutBuffer[DataOutAddr++] = ch; 00228 } 00229 00230 int PacketWriteHexNumber(int hnum, int dig) 00231 { 00232 int i; 00233 hnum <<= (8 - dig) * 4; 00234 for (i = 0; i < dig; i++) 00235 { 00236 PacketWriteChar(hex[(hnum >> 28) & 15]); 00237 hnum <<= 4; 00238 } 00239 return i; 00240 } 00241 00242 void PacketStart() 00243 { 00244 DataOutCsum = 0; 00245 DataOutAddr = 0; 00246 } 00247 00248 void PacketFinish() 00249 { 00250 int i, ch, count = 0; 00251 00252 PacketSent = 0; 00253 00254 SerialWrite('$'); 00255 for (i = 0; i < DataOutAddr; i++) 00256 { 00257 SerialWrite(DataOutBuffer[i]); 00258 } 00259 SerialWrite('#'); 00260 SerialWrite(hex[(DataOutCsum >> 4) & 15]); 00261 SerialWrite(hex[DataOutCsum & 15]); 00262 00263 while(!chr(serport) && ((ch = SerialRead()) != '+') && (ch != '$')); 00264 if (ch == '$') 00265 { 00266 ParseState = 0; 00267 DataInAddr = 0; 00268 ComputedCsum = 0; 00269 } 00270 } 00271 00272 00273 void PacketWriteString(char *str) 00274 { 00275 while(*str) PacketWriteChar(*str++); 00276 } 00277 00278 void PacketOk() 00279 { 00280 PacketStart(); 00281 PacketWriteString("OK"); 00282 PacketFinish(); 00283 } 00284 00285 void PacketEmpty() 00286 { 00287 PacketStart(); 00288 PacketFinish(); 00289 } 00290 00291 void PacketWriteSignal(int code) 00292 { 00293 PacketStart(); 00294 PacketWriteChar('S'); 00295 PacketWriteHexNumber(code, 2); 00296 PacketFinish(); 00297 } 00298 00299 void PacketWriteError(int code) 00300 { 00301 PacketStart(); 00302 PacketWriteChar('E'); 00303 PacketWriteHexNumber(code, 2); 00304 PacketFinish(); 00305 } 00306 00307 void marker() { } 00308 00309 void GotPacket() 00310 { 00311 int i, memaddr, memsize; 00312 00313 Continue = 0; 00314 switch (DataInBuffer[DataInAddr++]) 00315 { 00316 case 'g': 00317 PacketStart(); 00318 for (i = 0; i < GDB_SAVE_SIZE; i++) 00319 { 00320 PacketWriteHexNumber(((int *)RegisterSaveArea)[i], 8); 00321 } 00322 PacketFinish(); 00323 break; 00324 00325 case 'G': 00326 for (i = 0; i < sizeof(*RegisterSaveArea) / sizeof(int); i++) 00327 { 00328 ((int *)RegisterSaveArea)[i] = PacketReadHexNumber(8); 00329 } 00330 PacketOk(); 00331 break; 00332 00333 case 'm': 00334 memaddr = PacketReadHexNumber(8); 00335 DataInAddr++; 00336 memsize = PacketReadHexNumber(8); 00337 PacketStart(); 00338 while(memsize-- > 0) 00339 { 00340 PacketWriteHexNumber(*((char *)memaddr++), 2); 00341 } 00342 PacketFinish(); 00343 break; 00344 00345 case 'M': 00346 memaddr = PacketReadHexNumber(8); 00347 DataInAddr++; 00348 memsize = PacketReadHexNumber(8); 00349 DataInAddr++; 00350 while(memsize-- > 0) 00351 { 00352 *((char *)memaddr++) = PacketReadHexNumber(2); 00353 } 00354 PacketOk(); 00355 break; 00356 00357 case '?': 00358 PacketWriteSignal(Signal); 00359 break; 00360 00361 case 'c': 00362 PacketOk(); 00363 Continue = 1; 00364 break; 00365 00366 case 'S': 00367 PacketOk(); 00368 Continue = 0; 00369 break; 00370 00371 case 's': 00372 RegisterSaveArea->srr1 |= 0x400; 00373 PacketOk(); 00374 Continue = 1; 00375 marker(); 00376 break; 00377 00378 case 'q': 00379 switch (DataInBuffer[1]) 00380 { 00381 case 'S': /*upported => nothing*/ 00382 PacketEmpty(); 00383 break; 00384 00385 case 'O': /*ffsets*/ 00386 PacketEmpty(); 00387 break; 00388 } 00389 break; 00390 00391 default: 00392 PacketEmpty(); 00393 break; 00394 } 00395 } 00396 00397 int SerialInterrupt(int signal, ppc_trap_frame_t *tf) 00398 { 00399 int ch; 00400 00401 if (!chr(serport)) return 0; 00402 00403 Signal = signal; 00404 RegisterSaveArea = tf; 00405 00406 do 00407 { 00408 ch = SerialRead(); 00409 00410 if (ch == 3) /* Break in - tehe */ 00411 { 00412 Continue = 0; 00413 PacketWriteSignal(3); 00414 } 00415 else if (ch == '+') 00416 { 00417 /* Nothing */ 00418 } 00419 else if (ch == '$') 00420 { 00421 DataInAddr = 0; 00422 ParseState = 0; 00423 ComputedCsum = 0; 00424 ActualCsum = 0; 00425 } 00426 else if (ch == '#' && ParseState == 0) 00427 { 00428 ParseState = 2; 00429 } 00430 else if (ParseState == 0) 00431 { 00432 ComputedCsum += ch; 00433 DataInBuffer[DataInAddr++] = ch; 00434 } 00435 else if (ParseState == 2) 00436 { 00437 ActualCsum = ch; 00438 ParseState++; 00439 } 00440 else if (ParseState == 3) 00441 { 00442 ActualCsum = hex2int(ch) | (hex2int(ActualCsum) << 4); 00443 ComputedCsum &= 255; 00444 ParseState = -1; 00445 if (ComputedCsum == ActualCsum) 00446 { 00447 ComputedCsum = 0; 00448 DataInBuffer[DataInAddr] = 0; 00449 DataInAddr = 0; 00450 Continue = 0; 00451 SerialWrite('+'); 00452 GotPacket(); 00453 } 00454 else 00455 SerialWrite('-'); 00456 } 00457 else if (ParseState == -1) 00458 SerialWrite('-'); 00459 } 00460 while (!Continue); 00461 return 1; 00462 } 00463 00464 int TakeException(int n, ppc_trap_frame_t *tf) 00465 { 00466 Signal = n; 00467 RegisterSaveArea = tf; 00468 PacketWriteSignal(Signal); 00469 SendSignal = 0; 00470 Continue = 0; 00471 while(!Continue) SerialInterrupt(n, tf); 00472 return 1; 00473 } 00474 00475 /* EOF */ Generated on Sun May 27 2012 04:36:15 for ReactOS by
1.7.6.1
|