kerneltest/e32test/nkernsa/diag.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 //
       
    17 
       
    18 #include <nktest/diag.h>
       
    19 
       
    20 #ifdef __cplusplus
       
    21 extern "C" {
       
    22 #endif
       
    23 
       
    24 const DiagIO* TheIoFunctions;
       
    25 
       
    26 int InputAvailable(void)
       
    27 	{
       
    28 	return (*TheIoFunctions->iAvail)();
       
    29 	}
       
    30 
       
    31 char GetC(void)
       
    32 	{
       
    33 	int c;
       
    34 	do	{
       
    35 		c = (*TheIoFunctions->iPoll)();
       
    36 		} while (c<0);
       
    37 	return (char)c;
       
    38 	}
       
    39 
       
    40 void PutC(char c)
       
    41 	{
       
    42 	(*TheIoFunctions->iOut)(c);
       
    43 	}
       
    44 
       
    45 void PutS(const char* s)
       
    46 	{
       
    47 	while (*s)
       
    48 		PutC(*s++);
       
    49 	}
       
    50 
       
    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 	}
       
    68 
       
    69 void PrtHex2(unsigned long x)
       
    70 	{
       
    71 	PrtHex(x, 2);
       
    72 	}
       
    73 
       
    74 void PrtHex4(unsigned long x)
       
    75 	{
       
    76 	PrtHex(x, 4);
       
    77 	}
       
    78 
       
    79 void PrtHex8(unsigned long x)
       
    80 	{
       
    81 	PrtHex(x, 8);
       
    82 	}
       
    83 
       
    84 void NewLine(void)
       
    85 	{
       
    86 	PutC('\r');
       
    87 	PutC('\n');
       
    88 	}
       
    89 
       
    90 void PutSpc(void)
       
    91 	{
       
    92 	PutC(' ');
       
    93 	}
       
    94 
       
    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 	}
       
   126 
       
   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 	}
       
   134 
       
   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 	}
       
   145 
       
   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 	}
       
   161 
       
   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 	}
       
   198 
       
   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 	}
       
   220 
       
   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 	}
       
   237 
       
   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 	}
       
   254 
       
   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 	}
       
   279 
       
   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 	}
       
   321 
       
   322 
       
   323 
       
   324 #ifdef __cplusplus
       
   325 }
       
   326 #endif
       
   327