author | sl |
Tue, 10 Jun 2014 14:32:02 +0200 | |
changeset 1 | 260cb5ec6c19 |
permissions | -rw-r--r-- |
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
7 //
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
10 //
11 // Contributors:
12 //
13 // Description:
14 // e32test\nkernsa\diag.cpp
15 //
16 //
18 #include <nktest/diag.h>
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
24 const DiagIO* TheIoFunctions;
26 int InputAvailable(void)
27 {
28 return (*TheIoFunctions->iAvail)();
29 }
31 char GetC(void)
32 {
33 int c;
34 do {
35 c = (*TheIoFunctions->iPoll)();
36 } while (c<0);
37 return (char)c;
38 }
40 void PutC(char c)
41 {
42 (*TheIoFunctions->iOut)(c);
43 }
45 void PutS(const char* s)
46 {
47 while (*s)
48 PutC(*s++);
49 }
51 void PrtHex(unsigned long x, int n)
52 {
53 if (n>8)
54 n=8;
55 if (n<1)
56 n=1;
57 x <<= (32-4*n);
58 while (n--)
59 {
60 char c = (char)(x>>28);
61 x<<=4;
62 c += '0';
63 if (c > '9')
64 c += ('a'-'9'-1);
65 PutC(c);
66 }
67 }
69 void PrtHex2(unsigned long x)
70 {
71 PrtHex(x, 2);
72 }
74 void PrtHex4(unsigned long x)
75 {
76 PrtHex(x, 4);
77 }
79 void PrtHex8(unsigned long x)
80 {
81 PrtHex(x, 8);
82 }
84 void NewLine(void)
85 {
86 PutC('\r');
87 PutC('\n');
88 }
90 void PutSpc(void)
91 {
92 PutC(' ');
93 }
95 int GetAndEchoLine(char* buf, int max, const char* prompt)
96 {
97 int n = 0;
98 PutS(prompt);
99 for (;;)
100 {
101 int c;
102 do {
103 c = GetC();
104 } while (c==0x0a); // ignore LF
105 if (c==0x0d || c==0x18 || c==0x03)
106 {
107 if (c!=0x0d)
108 n = 0;
109 NewLine();
110 break;
111 }
112 else if (c==0x08)
113 {
114 if (n>0)
115 --n;
116 }
117 else if (n<max-1)
118 {
119 buf[n++] = (char)c;
120 }
121 PutC((char)c);
122 }
123 buf[n] = 0;
124 return n;
125 }
127 int SkipSpc(const char* s)
128 {
129 const char* s0 = s;
130 while (*s==32 || *s==9)
131 ++s;
132 return s - s0;
133 }
135 int CharToHex(char c)
136 {
137 if (c>='0' && c<='9')
138 return c - '0';
139 else if (c>='A' && c<='F')
140 return c - 'A' + 10;
141 else if (c>='a' && c<='f')
142 return c - 'a' + 10;
143 return -1;
144 }
146 int ReadHex(const char* s, unsigned long* d)
147 {
148 const char* s0 = s;
149 unsigned long x = 0;
150 for (;;)
151 {
152 int digit = CharToHex(*s);
153 if (digit < 0)
154 break;
155 ++s;
156 x = (x<<4) | ((unsigned long)digit);
157 }
158 *d = x;
159 return s - s0;
160 }
162 int ReadRangeHex(const char* s, unsigned long* base, unsigned long* length)
163 {
164 unsigned long b = 0;
165 unsigned long l = 0;
166 const char* s0 = s;
167 char c;
168 int i;
169 s += SkipSpc(s);
170 i = ReadHex(s, &b);
171 if (i == 0)
172 return 0;
173 s += i;
174 s += SkipSpc(s);
175 c = *s;
176 if (c!='+' && CharToHex(c)<0)
177 return 0;
178 if (c=='+')
179 {
180 ++s;
181 s += SkipSpc(s);
182 }
183 i = ReadHex(s, &l);
184 if (i == 0)
185 return 0;
186 s += i;
187 if (c!='+')
188 {
189 if (l >= b) // inclusive end address given
190 l -= (b-1); // calculate length
191 else
192 l = 1; // end < base so assume length of 1
193 }
194 *base = b;
195 *length = l;
196 return s - s0;
197 }
199 void DumpMemory1(const void* mem, const void* disp)
200 {
201 int i;
202 const unsigned char* s = (const unsigned char*)mem;
203 PrtHex8((unsigned long)disp);
204 PutC(':');
205 for (i=0; i<16; ++i)
206 {
207 PutSpc();
208 PrtHex2(s[i]);
209 }
210 PutSpc();
211 for (i=0; i<16; ++i)
212 {
213 char c = s[i];
214 if (c<32 || c>=127)
215 c = '.';
216 PutC(c);
217 }
218 NewLine();
219 }
221 void DumpMemoryRange1(const void* base, unsigned long length, const void* disp)
222 {
223 const char* s = (const char*)base;
224 const char* sd = (const char*)disp;
225 do {
226 DumpMemory1(s, sd);
227 s += 16;
228 sd += 16;
229 if (length < 16)
230 length = 0;
231 else
232 length -= 16;
233 if ((*TheIoFunctions->iPoll)() == 3)
234 break;
235 } while (length > 0);
236 }
238 unsigned long _readdata(const void** pp, unsigned long bytes, int align)
239 {
240 unsigned long x = 0;
241 unsigned long addr = (unsigned long)(*pp);
242 const unsigned char* s;
243 if (align)
244 {
245 addr += (bytes - 1);
246 addr &= ~(bytes - 1);
247 }
248 s = (const unsigned char*)(addr + bytes);
249 *pp = s;
250 while (bytes--)
251 x = (x<<8) | (*--s);
252 return x;
253 }
255 void DumpStruct(const char* s, const void* p)
256 {
257 for (;;)
258 {
259 char c = *s++;
260 if (c == 0)
261 break;
262 if (c == '\n')
263 PutC('\r');
264 if (c != '%')
265 {
266 PutC(c);
267 continue;
268 }
269 c = *s++;
270 switch (c)
271 {
272 case '%': PutC(c); break;
273 case 'b': PrtHex2(_readdata(&p, 1, 1)); break;
274 case 'h': PrtHex4(_readdata(&p, 2, 1)); break;
275 case 'w': PrtHex8(_readdata(&p, 4, 1)); break;
276 }
277 }
278 }
280 void RunCrashDebugger()
281 {
282 char buf[128];
283 for (;;)
284 {
285 int len = GetAndEchoLine(buf, 128, ".");
286 (void)len;
287 int i = 0;
288 int err = 0;
289 const char* s = buf;
290 char cmd = *s++;
291 switch (cmd)
292 {
293 case 'x':
294 case 'X':
295 return;
296 case '\0':
297 break;
298 case 'm':
299 {
300 unsigned long mbase = 0;
301 unsigned long mlen = 0;
302 i = ReadRangeHex(s, &mbase, &mlen);
303 if (i)
304 DumpMemoryRange1((void*)mbase, mlen, (void*)mbase);
305 else
306 err = 2;
307 break;
308 }
309 default:
310 err = 1;
311 break;
312 }
313 switch (err)
314 {
315 case 1: PutS("\r\nUnknown command\r\n"); break;
316 case 2: PutS("\r\nSyntax error\r\n"); break;
317 default: break;
318 }
319 }
320 }
324 #ifdef __cplusplus
325 }
326 #endif