diff -r 000000000000 -r a41df078684a kerneltest/e32test/nkernsa/diag.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/nkernsa/diag.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,327 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\nkernsa\diag.cpp +// +// + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +const DiagIO* TheIoFunctions; + +int InputAvailable(void) + { + return (*TheIoFunctions->iAvail)(); + } + +char GetC(void) + { + int c; + do { + c = (*TheIoFunctions->iPoll)(); + } while (c<0); + return (char)c; + } + +void PutC(char c) + { + (*TheIoFunctions->iOut)(c); + } + +void PutS(const char* s) + { + while (*s) + PutC(*s++); + } + +void PrtHex(unsigned long x, int n) + { + if (n>8) + n=8; + if (n<1) + n=1; + x <<= (32-4*n); + while (n--) + { + char c = (char)(x>>28); + x<<=4; + c += '0'; + if (c > '9') + c += ('a'-'9'-1); + PutC(c); + } + } + +void PrtHex2(unsigned long x) + { + PrtHex(x, 2); + } + +void PrtHex4(unsigned long x) + { + PrtHex(x, 4); + } + +void PrtHex8(unsigned long x) + { + PrtHex(x, 8); + } + +void NewLine(void) + { + PutC('\r'); + PutC('\n'); + } + +void PutSpc(void) + { + PutC(' '); + } + +int GetAndEchoLine(char* buf, int max, const char* prompt) + { + int n = 0; + PutS(prompt); + for (;;) + { + int c; + do { + c = GetC(); + } while (c==0x0a); // ignore LF + if (c==0x0d || c==0x18 || c==0x03) + { + if (c!=0x0d) + n = 0; + NewLine(); + break; + } + else if (c==0x08) + { + if (n>0) + --n; + } + else if (n='0' && c<='9') + return c - '0'; + else if (c>='A' && c<='F') + return c - 'A' + 10; + else if (c>='a' && c<='f') + return c - 'a' + 10; + return -1; + } + +int ReadHex(const char* s, unsigned long* d) + { + const char* s0 = s; + unsigned long x = 0; + for (;;) + { + int digit = CharToHex(*s); + if (digit < 0) + break; + ++s; + x = (x<<4) | ((unsigned long)digit); + } + *d = x; + return s - s0; + } + +int ReadRangeHex(const char* s, unsigned long* base, unsigned long* length) + { + unsigned long b = 0; + unsigned long l = 0; + const char* s0 = s; + char c; + int i; + s += SkipSpc(s); + i = ReadHex(s, &b); + if (i == 0) + return 0; + s += i; + s += SkipSpc(s); + c = *s; + if (c!='+' && CharToHex(c)<0) + return 0; + if (c=='+') + { + ++s; + s += SkipSpc(s); + } + i = ReadHex(s, &l); + if (i == 0) + return 0; + s += i; + if (c!='+') + { + if (l >= b) // inclusive end address given + l -= (b-1); // calculate length + else + l = 1; // end < base so assume length of 1 + } + *base = b; + *length = l; + return s - s0; + } + +void DumpMemory1(const void* mem, const void* disp) + { + int i; + const unsigned char* s = (const unsigned char*)mem; + PrtHex8((unsigned long)disp); + PutC(':'); + for (i=0; i<16; ++i) + { + PutSpc(); + PrtHex2(s[i]); + } + PutSpc(); + for (i=0; i<16; ++i) + { + char c = s[i]; + if (c<32 || c>=127) + c = '.'; + PutC(c); + } + NewLine(); + } + +void DumpMemoryRange1(const void* base, unsigned long length, const void* disp) + { + const char* s = (const char*)base; + const char* sd = (const char*)disp; + do { + DumpMemory1(s, sd); + s += 16; + sd += 16; + if (length < 16) + length = 0; + else + length -= 16; + if ((*TheIoFunctions->iPoll)() == 3) + break; + } while (length > 0); + } + +unsigned long _readdata(const void** pp, unsigned long bytes, int align) + { + unsigned long x = 0; + unsigned long addr = (unsigned long)(*pp); + const unsigned char* s; + if (align) + { + addr += (bytes - 1); + addr &= ~(bytes - 1); + } + s = (const unsigned char*)(addr + bytes); + *pp = s; + while (bytes--) + x = (x<<8) | (*--s); + return x; + } + +void DumpStruct(const char* s, const void* p) + { + for (;;) + { + char c = *s++; + if (c == 0) + break; + if (c == '\n') + PutC('\r'); + if (c != '%') + { + PutC(c); + continue; + } + c = *s++; + switch (c) + { + case '%': PutC(c); break; + case 'b': PrtHex2(_readdata(&p, 1, 1)); break; + case 'h': PrtHex4(_readdata(&p, 2, 1)); break; + case 'w': PrtHex8(_readdata(&p, 4, 1)); break; + } + } + } + +void RunCrashDebugger() + { + char buf[128]; + for (;;) + { + int len = GetAndEchoLine(buf, 128, "."); + (void)len; + int i = 0; + int err = 0; + const char* s = buf; + char cmd = *s++; + switch (cmd) + { + case 'x': + case 'X': + return; + case '\0': + break; + case 'm': + { + unsigned long mbase = 0; + unsigned long mlen = 0; + i = ReadRangeHex(s, &mbase, &mlen); + if (i) + DumpMemoryRange1((void*)mbase, mlen, (void*)mbase); + else + err = 2; + break; + } + default: + err = 1; + break; + } + switch (err) + { + case 1: PutS("\r\nUnknown command\r\n"); break; + case 2: PutS("\r\nSyntax error\r\n"); break; + default: break; + } + } + } + + + +#ifdef __cplusplus +} +#endif +