1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/drivers/crashflash/crashflashnor.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,259 @@
1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\drivers\crashflashnor.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include <crashflashnor.h>
1.22 +
1.23 +void CrashFlashNor::StartTransaction()
1.24 + {
1.25 + }
1.26 +
1.27 +void CrashFlashNor::EndTransaction()
1.28 + {
1.29 +#ifdef _CRASHLOG_COMPR
1.30 + // Ensure any buffered data is output not all the data will be valid but
1.31 + // iWriteTotal should reflect this by only increasing by no of valid/buffered bytes
1.32 + if (iWriteBufBytes)
1.33 + {
1.34 + DoWrite(iWriteBuf);
1.35 + }
1.36 +#endif //_CRASHLOG_COMPR
1.37 + }
1.38 +
1.39 +TUint CrashFlashNor::BytesWritten()
1.40 + {
1.41 + return iWriteTotal + iWriteBufBytes;
1.42 + }
1.43 +
1.44 +void CrashFlashNor::SetReadPos(TUint aPos)
1.45 + {
1.46 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Setting read position to %d", aPos));
1.47 + if( (aPos%sizeof(TCFIWord)) == 0)
1.48 + {
1.49 + iReadPos = aPos;
1.50 + iReadBufBytes = 0;
1.51 + iReadBuf = 0;
1.52 + }
1.53 + else
1.54 + {
1.55 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Invalid read position requested, ignoring."));
1.56 + }
1.57 + }
1.58 +
1.59 +
1.60 +TInt CrashFlashNor::Initialise()
1.61 + {
1.62 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("CrashFlashNor::Initialise()"));
1.63 + TInt ret = VariantInitialise();
1.64 + if(ret)
1.65 + {
1.66 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("CrashFlashNor::VariantInitialise() failed"));
1.67 + return ret;
1.68 + }
1.69 + // start writing after the crash log header
1.70 +
1.71 +#ifdef CDS_CRASH_LOGGER
1.72 + iWritePos = 0;
1.73 +#else
1.74 + iWritePos = KCrashLogHeaderSize;
1.75 +#endif //CDS_CRASH_LOGGER
1.76 +
1.77 + SetReadPos(0);
1.78 + iWriteTotal = 0;
1.79 +
1.80 + return KErrNone;
1.81 + }
1.82 +
1.83 +void CrashFlashNor::SetWritePos(TUint aPos)
1.84 + {
1.85 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("CrashFlashNor::SetWritePos"));
1.86 + if( (aPos%sizeof(TCFIWord)) == 0)
1.87 + {
1.88 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Setting write position to %d", aPos));
1.89 + iWritePos = aPos;
1.90 + iWriteTotal = 0;
1.91 + iWriteBufBytes = 0;
1.92 + iWriteBuf = 0;
1.93 + }
1.94 + else
1.95 + {
1.96 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Invalid read position requested, ignoring."));
1.97 + }
1.98 + }
1.99 +void CrashFlashNor::Write(const TDesC8& aDes)
1.100 + {
1.101 + if (iWritePos >= KMaxCrashLogSize)
1.102 + {
1.103 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Write: log limit already exceeded"));
1.104 + return;
1.105 + }
1.106 +
1.107 + TInt size = aDes.Size();
1.108 +#ifndef _CRASHLOG_COMPR
1.109 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Write: %S, size: %d",&aDes,size));
1.110 +#else
1.111 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Write: writing %d bytes",size));
1.112 +#endif
1.113 + const TUint8* ptr8 = aDes.Ptr();
1.114 +
1.115 + TInt truncated = EFalse;
1.116 +#ifndef _CRASHLOG_COMPR
1.117 + // If this will take us too close to (or past) the end of the crash log, discard the current string
1.118 + // and write the truncation notice instead
1.119 + if (iWritePos+size > KMaxCrashLogSize-KCrashLogTruncated().Size())
1.120 + {
1.121 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Write: truncating log"));
1.122 + size = KCrashLogTruncated().Size();
1.123 + ptr8 = KCrashLogTruncated().Ptr();
1.124 + truncated = ETrue;
1.125 + }
1.126 +#else
1.127 + // If this will take us past the end of the crash log, then truncate it
1.128 + if (iWritePos+size > KMaxCrashLogSize)
1.129 + {
1.130 + // no. of bytes left in crash log sector
1.131 + TUint tmp=KMaxCrashLogSize - iWritePos;
1.132 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Write: truncating log, limiting output to %d bytes as iWritePos=%d",tmp,iWritePos));
1.133 + size = tmp;
1.134 + truncated = ETrue;
1.135 + }
1.136 +#endif
1.137 +
1.138 + const TUint8* end = ptr8 + size;
1.139 +
1.140 + for(; ptr8<end; ptr8++)
1.141 + {
1.142 + switch(iWriteBufBytes)
1.143 + {
1.144 + case 0:
1.145 + iWriteBuf |= (*ptr8);
1.146 + break;
1.147 +#if defined(TCFI_2BYTE_WORD) || defined(TCFI_4BYTE_WORD)
1.148 + case 1:
1.149 + iWriteBuf |= (*ptr8)<<8;
1.150 + break;
1.151 +#if defined(TCFI_4BYTE_WORD)
1.152 + case 2:
1.153 + iWriteBuf |= (*ptr8)<<16;
1.154 + break;
1.155 + case 3:
1.156 + iWriteBuf |= (*ptr8)<<24;
1.157 + break;
1.158 +#endif
1.159 +#endif
1.160 + }
1.161 + iWriteBufBytes++;
1.162 + if(iWriteBufBytes == (sizeof(TCFIWord)))
1.163 + {
1.164 + DoWrite(iWriteBuf);
1.165 + iWritePos+=sizeof(TCFIWord);
1.166 + iWriteTotal+=sizeof(TCFIWord);
1.167 + iWriteBuf = 0;
1.168 + }
1.169 + //equiv to iWriteBufBytes%=sizeof(TCFIWord) as long as TCFIWord is
1.170 + //a power of 2
1.171 + iWriteBufBytes&=sizeof(TCFIWord)-1;
1.172 + }
1.173 +
1.174 + // If the log was truncated, skip the write position ahead so we don't try to write any more
1.175 + if (truncated)
1.176 + {
1.177 + iWritePos = KMaxCrashLogSize;
1.178 + }
1.179 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Write: total %d, position %d", iWriteTotal, iWritePos));
1.180 + }
1.181 +
1.182 +void CrashFlashNor::WriteSignature(const TDesC8& aDes)
1.183 + {
1.184 + if (iWriteBufBytes > 0)
1.185 + {
1.186 + DoWrite(iWriteBuf);
1.187 + iWriteBufBytes=0;
1.188 + iWriteBuf=0;
1.189 + }
1.190 + iWritePos = 0;
1.191 + Write(aDes);
1.192 + }
1.193 +
1.194 +void CrashFlashNor::Read(TDes8& aDes)
1.195 + {
1.196 + TUint8* ptr8 = const_cast<TUint8*>(aDes.Ptr());
1.197 + const TUint8* end = ptr8 + aDes.Size();
1.198 + for( ; ptr8<end; ptr8++)
1.199 + {
1.200 + switch(iReadBufBytes)
1.201 + {
1.202 + case 0:
1.203 + iReadBuf = DoRead();
1.204 + iReadPos+=sizeof(TCFIWord);
1.205 + *ptr8 = (TUint8)(iReadBuf);
1.206 + break;
1.207 +#if defined(TCFI_2BYTE_WORD) || defined(TCFI_4BYTE_WORD)
1.208 + case 1:
1.209 + *ptr8 = (TUint8)(iReadBuf>>8);
1.210 + break;
1.211 +#if defined(TCFI_4BYTE_WORD)
1.212 + case 2:
1.213 + *ptr8 = (TUint8)(iReadBuf>>16);
1.214 + break;
1.215 + case 3:
1.216 + *ptr8 = (TUint8)(iReadBuf>>24);
1.217 + break;
1.218 +#endif
1.219 +#endif
1.220 + }
1.221 + iReadBufBytes++;
1.222 + //equiv to iReadBufBytes%=sizeof(TCFIWord) as long as TCFIWord is
1.223 + //a power of 2
1.224 + iReadBufBytes&=sizeof(TCFIWord)-1;
1.225 + }
1.226 + }
1.227 +
1.228 +void CrashFlashNor::EraseLogArea()
1.229 + {
1.230 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Erasing crash log area..."));
1.231 + for(TUint erased = 0; erased < KMaxCrashLogSize; erased += iEraseBlockSize)
1.232 + {
1.233 + DoEraseBlock(erased);
1.234 + }
1.235 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Finished erasing area for crash log."));
1.236 + }
1.237 +
1.238 +void CrashFlashNor::EraseFlashBlock(TUint aBlock)
1.239 + {
1.240 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("CrashFlashNor::Erasing crash flash block offset [0x%X]", aBlock));
1.241 +
1.242 + if(aBlock%iEraseBlockSize != 0 || aBlock > KMaxCrashLogSize)
1.243 + {
1.244 + __KTRACE_OPT(KDEBUGGER,Kern::Printf("Invalid Block Address - Not deleting [0x%X]", aBlock));
1.245 + return;
1.246 + }
1.247 +
1.248 + DoEraseBlock(aBlock);
1.249 + }
1.250 +
1.251 +#ifdef _CRASHLOG_COMPR
1.252 +TUint CrashFlashNor::GetOutputLimit()
1.253 + {
1.254 + return KMaxCrashLogSize-KCrashLogHeaderSize;
1.255 + }
1.256 +
1.257 +TUint CrashFlashNor::GetLogOffset(void)
1.258 + {
1.259 + return 0;
1.260 + }
1.261 +#endif
1.262 +