Fix for Bug 2984 - [GCCE] Illegal inline assembler in kernel/eka/debug/utrace/src/e32utrace.cpp
// Copyright (c) 2006-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\mmu\t_kblockmap.cpp
// Unit tests for TKernBlockMap
// 002 Test Initialise error checking
// 003 Test processing of user-side block map into extent list
// 004 Test processing of user-side block map into extent list, block size > read unit size
// 005 Test Read error checking
// 006 Test Read
//
//
//! @SYMTestCaseID KBASE-T_KBLOCKMAP-0338
//! @SYMTestType UT
//! @SYMPREQ PREQ1110
//! @SYMTestCaseDesc Demand Paging Kernel Blockmap tests
//! @SYMTestActions 001 Unit tests the TKernBlockMap class
//! @SYMTestExpectedResults All tests should pass.
//! @SYMTestPriority High
//! @SYMTestStatus Implemented
#include <e32test.h>
#include <e32debug.h>
#include <memmodel/epoc/mmubase/kblockmap.h>
RTest test(_L("T_KBLOCKMAP"));
#define test_noError(x) { TInt _r = (x); if (_r < 0) HandleError(_r, __LINE__); }
#define test_notNull(x) { TAny* _a = (TAny*)(x); if (_a == NULL) HandleNull(__LINE__); }
#define test_equal(e, a) { TInt _e = (e); TInt _a = (a); if (_e != _a) HandleNotEqual(_e, _a, __LINE__); }
void HandleError(TInt aError, TInt aLine)
{
test.Printf(_L("Error %d\n"), aError);
test.operator()(EFalse, aLine);
}
void HandleNull(TInt aLine)
{
test.Printf(_L("Null value\n"));
test.operator()(EFalse, aLine);
}
void HandleNotEqual(TInt aExpected, TInt aActual, TInt aLine)
{
test.Printf(_L("Expected 0x%x but got 0x%x\n"), aExpected, aActual);
test.operator()(EFalse, aLine);
}
/// An list of "pod" objects which can be initialised by passing a variable number of TUints to its
/// constructor
template <class T>
class CList
{
public:
CList();
CList(TInt aCount, ...);
virtual ~CList();
inline TInt Count() const { return iCount; }
const T* Entries() const { return iEntries; }
const T& operator[](TInt aIndex) const;
protected:
void Set(TInt aCount, VA_LIST aList);
private:
const CList<T>& operator=(const CList<T>&);
TInt iCount;
T* iEntries;
};
template <class T>
CList<T>::CList()
: iCount(0), iEntries(NULL)
{
__ASSERT_COMPILE(sizeof(T) % sizeof(TUint32) == 0);
}
template <class T>
CList<T>::CList(TInt aCount, ...)
: iCount(aCount)
{
VA_LIST list;
VA_START(list, aCount);
Set(aCount, list);
}
template <class T>
CList<T>::~CList()
{
User::Free(iEntries);
iEntries = NULL;
}
template <class T>
void CList<T>::Set(TInt aCount, VA_LIST aList)
{
iCount = aCount;
test(iEntries == NULL);
iEntries = (T*)User::Alloc(sizeof(T) * iCount);
test_notNull(iEntries);
TInt argCount = iCount * (sizeof(T) / sizeof(TUint32));
for (TInt i = 0 ; i < argCount ; ++i)
((TUint32*)iEntries)[i] = VA_ARG(aList, TUint32);
}
template <class T>
const T& CList<T>::operator[](TInt aIndex) const
{
test(aIndex < iCount);
return iEntries[aIndex];
}
/// Holds all the data associated with the user-side representation of a block map
class CBlockMap : public CList<TBlockMapEntryBase>
{
public:
CBlockMap(TUint aBlockGranularity,
TUint aBlockStartOffset,
TInt64 aStartBlockAddress,
TUint aReadUnitShift,
TUint aCodeLengthInFile,
TUint aEntriesSize,
...);
inline const SBlockMapInfoBase& Info() const { return iInfo; }
inline TInt ReadUnitShift() const { return iReadUnitShift; }
inline TInt CodeLengthInFile() const { return iCodeLengthInFile; }
inline TInt EntriesSize() const { return iEntriesSize; }
private:
SBlockMapInfoBase iInfo;
TBlockMapEntryBase* iEntries;
TUint iReadUnitShift;
TUint iCodeLengthInFile;
TUint iEntriesSize;
};
CBlockMap::CBlockMap(TUint aBlockGranularity,
TUint aBlockStartOffset,
TInt64 aStartBlockAddress,
TUint aReadUnitShift,
TUint aCodeLengthInFile,
TUint aEntriesSize,
...)
{
iInfo.iBlockGranularity = aBlockGranularity;
iInfo.iBlockStartOffset = aBlockStartOffset;
iInfo.iStartBlockAddress = aStartBlockAddress;
// don't care about iInfo.iLocalDriveNumber for test purposes
iReadUnitShift = aReadUnitShift;
iCodeLengthInFile = aCodeLengthInFile;
iEntriesSize = aEntriesSize;
iEntries = (TBlockMapEntryBase*)User::Alloc(iEntriesSize);
VA_LIST list;
VA_START(list, aEntriesSize);
Set(iEntriesSize / sizeof(TBlockMapEntryBase), list);
}
/// A list of extents, for comparison with those generated by the kernel block map processing code
class CExtentList : public CList<TBlockMap::SExtent>
{
public:
typedef TBlockMap::SExtent SExtent;
CExtentList(TInt aCount, ...);
void Dump() const;
};
CExtentList::CExtentList(TInt aCount, ...)
{
VA_LIST list;
VA_START(list, aCount);
Set(aCount, list);
}
void CExtentList::Dump() const
{
RDebug::Printf("CExtentList:\n");
const CExtentList& self = *this;
for (TInt i = 0 ; i < Count() ; ++i)
RDebug::Printf(" %d: %08x -> %08x: %08x\n", i, self[i].iDataOffset, self[i+1].iDataOffset, self[i].iBlockNumber);
}
TBool operator==(const TBlockMap::SExtent& a, const TBlockMap::SExtent& b)
{
return a.iDataOffset == b.iDataOffset && a.iBlockNumber == b.iBlockNumber;
}
TBool operator!=(const TBlockMap::SExtent& a, const TBlockMap::SExtent& b)
{
return !(a == b);
}
TBool CompareExtentsEqual(const TBlockMap& aBlockMap, const CExtentList& aExtentList)
{
if (aBlockMap.Count() != aExtentList.Count())
return EFalse;
for (TInt i = 0 ; i < aBlockMap.Count() ; ++i)
{
if (aBlockMap.Extent(i) != aExtentList[i])
return EFalse;
}
return ETrue;
}
TInt MakeKernBlockMap(TBlockMap& aKbm, const CBlockMap& aUbm)
{
TBlockMapEntryBase* buffer = (TBlockMapEntryBase*)User::Alloc(aUbm.EntriesSize());
test_notNull(buffer);
Mem::Copy(buffer, aUbm.Entries(), aUbm.EntriesSize());
return aKbm.Initialise(aUbm.Info(),
buffer,
aUbm.EntriesSize(),
aUbm.ReadUnitShift(),
aUbm.CodeLengthInFile());
}
void MakeKernBlockMapAndTestExtents(const CBlockMap& aUbm, const CExtentList& aExpectedExtentList)
{
TBlockMap kbm;
test_noError(MakeKernBlockMap(kbm, aUbm));
TBool equal = CompareExtentsEqual(kbm, aExpectedExtentList);
if (!equal)
{
aExpectedExtentList.Dump();
#ifdef _DEBUG
kbm.Dump();
#endif
}
test(equal);
}
// Tests
void TestInitialiseErrors()
{
test.Next(_L("Test Initialise error checking"));
TBlockMap kbm;
// Block size must be a power of two
test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(513, 0, 0, 9, 1, 8, 1, 0)));
// Block size must be greater than or equal to the read unit size
test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 10, 1, 8, 1, 0)));
// Block start offset must be less than or equal to block size
test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 513, 0, 9, 1, 8, 1, 0)));
// Block zero address must be a multiple of the block size
test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 1, 9, 1, 8, 1, 0)));
// Code length in file must be greater than zero
test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 0, 8, 1, 0)));
// Size of entries array must be multiple of the size of one entry
test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1, 9, 1, 0)));
// Size of entries must be non-zero
test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1, 0)));
// Size of block map must be greater or equal to size of data in file
test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 513, 8, 1, 0)));
}
// blockGranularity, startOffset, blockZeroAddress, readUnitShift, codeLengthInFile, entriesSize, (numberOfBlocks, startBlock)+
void TestExtentList()
{
test.Next(_L("Test processing of user-side block map into extent list"));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// |= | | | | | | | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 0, 9, 1, 8, 1, 0),
CExtentList(1, 0, 0));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | |= | | | | | | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 512, 9, 1, 8, 1, 0),
CExtentList(1, 0, 1));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | | = | | | | | | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1, 8, 1, 0),
CExtentList(1, -23, 1));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | | | | = | | | | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1, 8, 1, 2),
CExtentList(1, -23, 3));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | | | | ======| | | | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 489, 8, 1, 2),
CExtentList(1, -23, 3));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | | | | ======== | | | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 600, 8, 2, 2),
CExtentList(1, -23, 3));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | | | | ==============| |== | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1100, 16, 2, 2, 1, 5),
CExtentList(2, -23, 3, 1001, 6));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | | | | ==============| |=======| | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1513, 16, 2, 2, 1, 5),
CExtentList(2, -23, 3, 1001, 6));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | | | | ==============| |=======|= | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1540, 16, 2, 2, 2, 5),
CExtentList(2, -23, 3, 1001, 6));
}
void TestExtentListScaled()
{
test.Next(_L("Test processing of user-side block map into extent list, block size > read unit size"));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// |= : | : | : | : | : | : | : | : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 0, 8, 1, 8, 1, 0),
CExtentList(1, 0, 0));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : |= : | : | : | : | : | : | : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 512, 8, 1, 8, 1, 0),
CExtentList(1, 0, 2));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | = : | : | : | : | : | : | : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 8, 1, 8, 1, 0),
CExtentList(1, -23, 2));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | : = | : | : | : | : | : | : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1, 8, 1, 0),
CExtentList(1, -24, 3));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | : | : | : = | : | : | : | : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1, 8, 1, 2),
CExtentList(1, -24, 7));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | : | : | : ==| : | : | : | : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 232, 8, 1, 2),
CExtentList(1, -24, 7));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | : | : | : ==== : | : | : | : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 333, 8, 2, 2),
CExtentList(1, -24, 7));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | : | : | : ======== | : | : | : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 666, 8, 2, 2),
CExtentList(1, -24, 7));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | : | : | : ==========| : | : | : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 744, 8, 2, 2),
CExtentList(1, -24, 7));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | : | : | : ==========| : |== : | : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 888, 16, 2, 2, 1, 5),
CExtentList(2, -24, 7, 744, 12));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | : | : | : ==========| : |=======| : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1256, 16, 2, 2, 1, 5),
CExtentList(2, -24, 7, 744, 12));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | : | : | : ==========| : |========= : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1350, 16, 2, 2, 2, 5),
CExtentList(2, -24, 7, 744, 12));
}
/// Holds the expected arguments for one call to the read function
struct SReadEntry
{
TLinAddr iBuffer;
TInt iBlockNumber;
TInt iBlockCount;
};
/// Holds a list of expected arguments for all calls to the read function
class CReadInfo : public CList<SReadEntry>
{
public:
CReadInfo(TInt aReturnVal, TInt aCount, ...);
const SReadEntry& Next();
void Done() const;
TInt ReturnVal() const { return iReturnVal; }
private:
TInt iPos;
TInt iReturnVal;
};
CReadInfo::CReadInfo(TInt aReturnVal, TInt aCount, ...)
: iPos(0), iReturnVal(aReturnVal)
{
VA_LIST list;
VA_START(list, aCount);
Set(aCount, list);
}
const SReadEntry& CReadInfo::Next()
{
const CList<SReadEntry>& self = *this;
return self[iPos++];
}
void CReadInfo::Done() const
{
test_equal(Count(), iPos);
}
TInt ReadFunc(TAny* aArg, TAny*, TLinAddr aBuffer, TInt aBlockNumber, TInt aBlockCount)
{
CReadInfo& info = *(CReadInfo*)aArg;
const SReadEntry& expected = info.Next();
test_equal(expected.iBuffer, aBuffer);
test_equal(expected.iBlockNumber, aBlockNumber);
test_equal(expected.iBlockCount, aBlockCount);
return KErrNone;
}
void TestRead(const TBlockMap& aBlockMap,
TLinAddr aBuffer,
TInt aPos,
TInt aLength,
TInt aReadUnitShift,
const CReadInfo& aExpected)
{
test_equal(aExpected.ReturnVal(),
aBlockMap.Read(aBuffer, aPos, aLength, aReadUnitShift, ReadFunc, (TAny*)&aExpected, (TAny*)NULL));
aExpected.Done();
}
void TestReadErrors()
{
test.Next(_L("Test Read error checking"));
TBlockMap kbm, kbm2;
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// |= | | | | | | | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
test_noError(MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1, 8, 1, 0)));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | : | : | : | : ==========| : |========= : | : |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
test_noError(MakeKernBlockMap(kbm2, CBlockMap(512, 280, 512, 8, 1350, 16, 2, 2, 2, 5)));
// Test read start position is outside block map
TestRead(kbm, 0, 1, 1, 9, CReadInfo(KErrArgument, 0));
TestRead(kbm2, 0, 1350, 1, 8, CReadInfo(KErrArgument, 0));
// Test read start position is negative
TestRead(kbm, 0, -1, 1, 9, CReadInfo(KErrArgument, 0));
TestRead(kbm2, 0, -1, 1, 8, CReadInfo(KErrArgument, 0));
// Test read length exceeds block map length
TestRead(kbm, 0, 0, 2, 9, CReadInfo(KErrArgument, 1, 0, 0, 1));
TestRead(kbm2, 0, 1349, 2, 8, CReadInfo(KErrArgument, 1, 0, 14, 1));
}
void TestReads()
{
test.Next(_L("Test Read"));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// |=======================| | | | | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
TBlockMap kbm2;
test_noError(MakeKernBlockMap(kbm2, CBlockMap(512, 0, 0, 9, 1536, 8, 3, 0)));
// Test correct number of blocks read
TestRead(kbm2, 0, 0, 512, 9, CReadInfo(0, 1, 0, 0, 1));
TestRead(kbm2, 0, 0, 513, 9, CReadInfo(0, 1, 0, 0, 2));
TestRead(kbm2, 0, 0, 1024, 9, CReadInfo(0, 1, 0, 0, 2));
TestRead(kbm2, 0, 0, 1025, 9, CReadInfo(0, 1, 0, 0, 3));
TestRead(kbm2, 0, 0, 1536, 9, CReadInfo(0, 1, 0, 0, 3));
// Test start offset not aligned to read unit
TestRead(kbm2, 0, 1, 511, 9, CReadInfo(1, 1, 0, 0, 1));
TestRead(kbm2, 0, 256, 256, 9, CReadInfo(256, 1, 0, 0, 1));
TestRead(kbm2, 0, 511, 1, 9, CReadInfo(511, 1, 0, 0, 1));
TestRead(kbm2, 0, 513, 511, 9, CReadInfo(1, 1, 0, 1, 1));
TestRead(kbm2, 0, 1023, 1, 9, CReadInfo(511, 1, 0, 1, 1));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// |=======| |=======| |=======| | | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
TBlockMap kbm;
test_noError(MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1536, 24, 1, 0, 1, 3, 1, 5)));
// Test correct block selected for read
TestRead(kbm, 0, 0, 1, 9, CReadInfo(0, 1, 0, 0, 1));
TestRead(kbm, 0, 256, 1, 9, CReadInfo(256, 1, 0, 0, 1));
TestRead(kbm, 0, 511, 1, 9, CReadInfo(511, 1, 0, 0, 1));
TestRead(kbm, 0, 512, 1, 9, CReadInfo(0, 1, 0, 3, 1));
TestRead(kbm, 0, 768, 1, 9, CReadInfo(256, 1, 0, 3, 1));
TestRead(kbm, 0, 1023, 1, 9, CReadInfo(511, 1, 0, 3, 1));
TestRead(kbm, 0, 1535, 1, 9, CReadInfo(511, 1, 0, 5, 1));
// Test reading multiple blocks
TestRead(kbm, 0, 0, 513, 9, CReadInfo(0, 2, 0, 0, 1, 512, 3, 1));
TestRead(kbm, 0, 0, 1024, 9, CReadInfo(0, 2, 0, 0, 1, 512, 3, 1));
TestRead(kbm, 0, 0, 1025, 9, CReadInfo(0, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
TestRead(kbm, 0, 0, 1536, 9, CReadInfo(0, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
// | ====| |=======| |=======| | | | |
// +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
TBlockMap kbm3;
test_noError(MakeKernBlockMap(kbm3, CBlockMap(512, 256, 0, 9, 1280, 24, 1, 0, 1, 3, 1, 5)));
// Test correct block selected for read
TestRead(kbm3, 0, 0, 1, 9, CReadInfo(256, 1, 0, 0, 1));
TestRead(kbm3, 0, 255, 1, 9, CReadInfo(511, 1, 0, 0, 1));
TestRead(kbm3, 0, 256, 1, 9, CReadInfo(0, 1, 0, 3, 1));
TestRead(kbm3, 0, 767, 1, 9, CReadInfo(511, 1, 0, 3, 1));
TestRead(kbm3, 0, 768, 1, 9, CReadInfo(0, 1, 0, 5, 1));
// Test reading multiple blocks
TestRead(kbm3, 0, 0, 256, 9, CReadInfo(256, 1, 0, 0, 1));
TestRead(kbm3, 0, 0, 257, 9, CReadInfo(256, 2, 0, 0, 1, 512, 3, 1));
TestRead(kbm3, 0, 0, 768, 9, CReadInfo(256, 2, 0, 0, 1, 512, 3, 1));
TestRead(kbm3, 0, 0, 769, 9, CReadInfo(256, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
TestRead(kbm3, 0, 0, 1280, 9, CReadInfo(256, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
}
TInt E32Main()
{
test.Title();
test.Start(_L("Unit tests the TKernBlockMap class"));
TestInitialiseErrors();
TestExtentList();
TestExtentListScaled();
TestReadErrors();
TestReads();
test.End();
return KErrNone;
}