os/kernelhwsrv/kerneltest/e32test/mmu/d_shadow.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32test\mmu\d_shadow.cpp
sl@0
    15
// LDD for testing ROM shadowing
sl@0
    16
// 
sl@0
    17
//
sl@0
    18
sl@0
    19
#include <kernel/kern_priv.h>
sl@0
    20
#include "platform.h"
sl@0
    21
#include <kernel/cache.h>
sl@0
    22
#include "d_shadow.h"
sl@0
    23
sl@0
    24
const TInt KMajorVersionNumber=0;
sl@0
    25
const TInt KMinorVersionNumber=1;
sl@0
    26
const TInt KBuildVersionNumber=1;
sl@0
    27
sl@0
    28
_LIT(KLddName,"Shadow");
sl@0
    29
sl@0
    30
class DShadow;
sl@0
    31
sl@0
    32
class DShadowFactory : public DLogicalDevice
sl@0
    33
//
sl@0
    34
// Shadow ROM LDD factory
sl@0
    35
//
sl@0
    36
	{
sl@0
    37
public:
sl@0
    38
	DShadowFactory();
sl@0
    39
	virtual TInt Install();						//overriding pure virtual
sl@0
    40
	virtual void GetCaps(TDes8& aDes) const;	//overriding pure virtual
sl@0
    41
	virtual TInt Create(DLogicalChannelBase*& aChannel);	//overriding pure virtual
sl@0
    42
	};
sl@0
    43
sl@0
    44
class DShadow : public DLogicalChannelBase
sl@0
    45
//
sl@0
    46
// Shadow ROM logical channel
sl@0
    47
//
sl@0
    48
	{
sl@0
    49
public:
sl@0
    50
	DShadow();
sl@0
    51
	~DShadow();
sl@0
    52
protected:
sl@0
    53
	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
sl@0
    54
	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
sl@0
    55
	};
sl@0
    56
sl@0
    57
DECLARE_STANDARD_LDD()
sl@0
    58
	{
sl@0
    59
    return new DShadowFactory;
sl@0
    60
    }
sl@0
    61
sl@0
    62
DShadowFactory::DShadowFactory()
sl@0
    63
//
sl@0
    64
// Constructor
sl@0
    65
//
sl@0
    66
    {
sl@0
    67
    iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
sl@0
    68
    //iParseMask=0;//No units, no info, no PDD
sl@0
    69
    //iUnitsMask=0;//Only one thing
sl@0
    70
    }
sl@0
    71
sl@0
    72
TInt DShadowFactory::Create(DLogicalChannelBase*& aChannel)
sl@0
    73
//
sl@0
    74
// Create a new DShadow on this logical device
sl@0
    75
//
sl@0
    76
    {
sl@0
    77
	aChannel=new DShadow;
sl@0
    78
	return aChannel?KErrNone:KErrNoMemory;
sl@0
    79
    }
sl@0
    80
sl@0
    81
TInt DShadowFactory::Install()
sl@0
    82
//
sl@0
    83
// Install the LDD - overriding pure virtual
sl@0
    84
//
sl@0
    85
    {
sl@0
    86
    return SetName(&KLddName);
sl@0
    87
    }
sl@0
    88
sl@0
    89
void DShadowFactory::GetCaps(TDes8& aDes) const
sl@0
    90
//
sl@0
    91
// Get capabilities - overriding pure virtual
sl@0
    92
//
sl@0
    93
    {
sl@0
    94
    TCapsShadowV01 b;
sl@0
    95
    b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
sl@0
    96
    Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
sl@0
    97
    }
sl@0
    98
sl@0
    99
DShadow::DShadow()
sl@0
   100
//
sl@0
   101
// Constructor
sl@0
   102
//
sl@0
   103
    {
sl@0
   104
    }
sl@0
   105
sl@0
   106
TInt DShadow::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
sl@0
   107
//
sl@0
   108
// Create channel
sl@0
   109
//
sl@0
   110
    {
sl@0
   111
sl@0
   112
    if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
sl@0
   113
    	return KErrNotSupported;
sl@0
   114
	return KErrNone;
sl@0
   115
	}
sl@0
   116
sl@0
   117
DShadow::~DShadow()
sl@0
   118
//
sl@0
   119
// Destructor
sl@0
   120
//
sl@0
   121
    {
sl@0
   122
    }
sl@0
   123
sl@0
   124
#ifdef __MARM__
sl@0
   125
extern TInt DoRead(TAny*);
sl@0
   126
extern TInt GetMmuId();
sl@0
   127
extern TInt GetCacheType();
sl@0
   128
extern TUint GetTTBCR();
sl@0
   129
extern TUint GetControlRegister();
sl@0
   130
#endif
sl@0
   131
sl@0
   132
LOCAL_C TInt KernStackSize()
sl@0
   133
	{
sl@0
   134
	TRomEntry* pE=(TRomEntry*)Kern::SuperPage().iPrimaryEntry;
sl@0
   135
	TRomImageHeader* pI=(TRomImageHeader*)pE->iAddressLin;
sl@0
   136
	return pI->iStackSize;
sl@0
   137
	}
sl@0
   138
sl@0
   139
LOCAL_C TInt MeasureKernStackUse()
sl@0
   140
	{
sl@0
   141
	TLinAddr kstack=Kern::RoundToPageSize(Epoc::RomHeader().iKernDataAddress + Epoc::RomHeader().iTotalSvDataSize);
sl@0
   142
	TLinAddr kstackEnd=kstack+KernStackSize();
sl@0
   143
	TUint32 *pS=(TUint32*)kstack;
sl@0
   144
	while(*pS==0xffffffff) pS++;
sl@0
   145
	TUint used=kstackEnd-TLinAddr(pS);
sl@0
   146
	return (TInt)used;
sl@0
   147
	}
sl@0
   148
sl@0
   149
#if !defined(__WINS__)
sl@0
   150
TInt DShadow::Request(TInt aFunction, TAny* a1, TAny* a2)
sl@0
   151
	{
sl@0
   152
	TInt pageSize=Kern::RoundToPageSize(1);
sl@0
   153
	TInt r=KErrNone;
sl@0
   154
	switch (aFunction)
sl@0
   155
		{
sl@0
   156
		case RShadow::EControlAllocShadow:
sl@0
   157
			NKern::ThreadEnterCS();
sl@0
   158
			r=Epoc::AllocShadowPage(TLinAddr(a1));
sl@0
   159
			NKern::ThreadLeaveCS();
sl@0
   160
			break;
sl@0
   161
		case RShadow::EControlFreeShadow:
sl@0
   162
			NKern::ThreadEnterCS();
sl@0
   163
			r=Epoc::FreeShadowPage(TLinAddr(a1));
sl@0
   164
			NKern::ThreadLeaveCS();
sl@0
   165
			break;
sl@0
   166
sl@0
   167
		case RShadow::EControlWriteShadow: //copy 4KB(page size) data to shadow page
sl@0
   168
			{
sl@0
   169
			NKern::ThreadEnterCS();
sl@0
   170
			void* alloc = Kern::Alloc(pageSize); //CopyToShadowMemory assumes Kernel adress space. Copy here first
sl@0
   171
			if (alloc)
sl@0
   172
				{
sl@0
   173
				kumemget(alloc,a2,pageSize);//From user space to kernel heap
sl@0
   174
				for (TInt i=0;i<pageSize;i+=32)
sl@0
   175
					Epoc::CopyToShadowMemory((TLinAddr)((TInt)a1+i),(TLinAddr)((TInt)alloc+i),32);
sl@0
   176
				Cache::IMB_Range((TLinAddr)a1,pageSize);
sl@0
   177
				Kern::Free(alloc);
sl@0
   178
				}
sl@0
   179
			else
sl@0
   180
				r = KErrNoMemory;
sl@0
   181
			
sl@0
   182
			NKern::ThreadLeaveCS();
sl@0
   183
			}
sl@0
   184
			break;
sl@0
   185
		case RShadow::EControlFreezeShadow:
sl@0
   186
			NKern::ThreadEnterCS();
sl@0
   187
			r=Epoc::FreezeShadowPage(TLinAddr(a1));
sl@0
   188
			NKern::ThreadLeaveCS();
sl@0
   189
			break;
sl@0
   190
		case RShadow::EControlSetPriority:
sl@0
   191
			{
sl@0
   192
			TInt h=(TInt)a1;
sl@0
   193
			TInt p=(TInt)a2;
sl@0
   194
			NKern::LockSystem();
sl@0
   195
			DThread *pT=(DThread*)Kern::CurrentThread().ObjectFromHandle(h);
sl@0
   196
			pT->SetThreadPriority(p);
sl@0
   197
			NKern::UnlockSystem();
sl@0
   198
			break;
sl@0
   199
			}
sl@0
   200
#ifdef __MARM__
sl@0
   201
		case RShadow::EControlRead:
sl@0
   202
			r=DoRead(a1);
sl@0
   203
			break;
sl@0
   204
		case RShadow::EControlMmuId:
sl@0
   205
			r=GetMmuId();
sl@0
   206
			break;
sl@0
   207
		case RShadow::EControlCacheType:
sl@0
   208
			r=GetCacheType();
sl@0
   209
			break;
sl@0
   210
#endif
sl@0
   211
		case RShadow::EControlMeasureKernStackUse:
sl@0
   212
			r=MeasureKernStackUse();
sl@0
   213
			break;
sl@0
   214
		case RShadow::EControlMeasureKernHeapFree:
sl@0
   215
			r=KErrNotSupported;
sl@0
   216
			break;
sl@0
   217
		case RShadow::EControlCallFunction:
sl@0
   218
			{
sl@0
   219
			TThreadFunction f=(TThreadFunction)a1;
sl@0
   220
			r=(*f)(a2);
sl@0
   221
			break;
sl@0
   222
			}
sl@0
   223
		case RShadow::EControlAllocPhys:
sl@0
   224
			{
sl@0
   225
			
sl@0
   226
			TInt size=(TInt)a1;
sl@0
   227
			TInt align=(TInt)a2;
sl@0
   228
			TPhysAddr pa;
sl@0
   229
		
sl@0
   230
			NKern::ThreadEnterCS();
sl@0
   231
			r=Epoc::AllocPhysicalRam(size,pa,align);
sl@0
   232
			NKern::ThreadLeaveCS();
sl@0
   233
			
sl@0
   234
			if (r==KErrNone)
sl@0
   235
				{
sl@0
   236
				if (pa&0x0f)
sl@0
   237
					r=KErrCorrupt;
sl@0
   238
				else
sl@0
   239
					r=pa>>4;
sl@0
   240
				}
sl@0
   241
			
sl@0
   242
			break;
sl@0
   243
			}
sl@0
   244
		case RShadow::EControlFreePhys:
sl@0
   245
			{
sl@0
   246
			
sl@0
   247
			TPhysAddr pa=(TPhysAddr)a1;
sl@0
   248
			TInt size=(TInt)a2;
sl@0
   249
			NKern::ThreadEnterCS();
sl@0
   250
			r=Epoc::FreePhysicalRam(pa,size);
sl@0
   251
			NKern::ThreadLeaveCS();
sl@0
   252
			break;
sl@0
   253
			}
sl@0
   254
		case RShadow::EControlClaimPhys:
sl@0
   255
			{
sl@0
   256
			
sl@0
   257
			TPhysAddr pa=(TPhysAddr)a1;
sl@0
   258
			TInt size=(TInt)a2;
sl@0
   259
			NKern::ThreadEnterCS();
sl@0
   260
			r=Epoc::ClaimPhysicalRam(pa,size);
sl@0
   261
			NKern::ThreadLeaveCS();
sl@0
   262
			break;
sl@0
   263
			}
sl@0
   264
			
sl@0
   265
		// GetMemoryArchitecture
sl@0
   266
		case RShadow::EControlGetMemoryArchitecture:
sl@0
   267
			{
sl@0
   268
			TCpu* cpu = (TCpu*) a1;
sl@0
   269
			TUint* flags = (TUint*) a2;
sl@0
   270
			
sl@0
   271
#if defined(__CPU_ARM)
sl@0
   272
			*cpu=ECpuArm;
sl@0
   273
			*flags = GetControlRegister();
sl@0
   274
#elif defined(__CPU_X86)
sl@0
   275
			*cpu=ECpuX86;
sl@0
   276
			*flags =0;
sl@0
   277
#else
sl@0
   278
			*cpu=ECpuUnknown;
sl@0
   279
			*flags =0;
sl@0
   280
#endif
sl@0
   281
			
sl@0
   282
			break;
sl@0
   283
			}
sl@0
   284
			
sl@0
   285
			
sl@0
   286
		// GetMemModelInfo
sl@0
   287
		case RShadow::EControlGetMemModelInfo:
sl@0
   288
			{
sl@0
   289
			TUint pageTable;
sl@0
   290
			TUint numPds;
sl@0
   291
						 
sl@0
   292
#ifdef __EPOC32__
sl@0
   293
sl@0
   294
#if defined(__MEMMODEL_MULTIPLE__) || defined(__MEMMODEL_FLEXIBLE__)
sl@0
   295
			numPds = KMaxNumberOfPageDirectories;
sl@0
   296
#else
sl@0
   297
			numPds = 0;								
sl@0
   298
#endif			
sl@0
   299
			r = KMemoryModel;
sl@0
   300
#endif
sl@0
   301
			pageTable = KPageTableBase;			
sl@0
   302
sl@0
   303
			kumemput(a1, &pageTable, sizeof(TUint));
sl@0
   304
			kumemput(a2, &numPds, sizeof(TUint));
sl@0
   305
			break;
sl@0
   306
			}
sl@0
   307
			
sl@0
   308
			
sl@0
   309
		// GetPdInfo
sl@0
   310
		case RShadow::EControlGetPdInfo:
sl@0
   311
			{
sl@0
   312
			TUint pd;
sl@0
   313
			kumemget(&pd, a1, sizeof(TUint));
sl@0
   314
sl@0
   315
			TUint pdSize;
sl@0
   316
			TUint pdBase;
sl@0
   317
sl@0
   318
			r=KErrNoPageTable;
sl@0
   319
sl@0
   320
#if defined(__MEMMODEL_MOVING__)
sl@0
   321
sl@0
   322
			if (pd==KGlobalPageDirectory)
sl@0
   323
				{
sl@0
   324
				pdSize=KPageDirectorySize;
sl@0
   325
				pdBase=KPageDirectoryBase;
sl@0
   326
				r = KErrNone;
sl@0
   327
				}
sl@0
   328
sl@0
   329
#elif defined(__MEMMODEL_MULTIPLE__) || defined(__MEMMODEL_FLEXIBLE__)
sl@0
   330
sl@0
   331
#ifdef __CPU_X86
sl@0
   332
			TUint ttbcr = KPsudoX86TTBCR;
sl@0
   333
#else
sl@0
   334
			TUint ttbcr = KPageDirectorySize >> GetTTBCR();
sl@0
   335
#endif
sl@0
   336
sl@0
   337
			if (pd==KGlobalPageDirectory)
sl@0
   338
				{
sl@0
   339
				pdSize=KPageDirectorySize - ttbcr;
sl@0
   340
				pdBase=KPageDirectoryBase + ttbcr*4;
sl@0
   341
				r = ttbcr & KPageOffsetMask;
sl@0
   342
				}
sl@0
   343
			else
sl@0
   344
				{
sl@0
   345
				pdSize = ttbcr;
sl@0
   346
				pdBase=KPageDirectoryBase + pd * KPageDirectorySize * 4;
sl@0
   347
sl@0
   348
				TPhysAddr phys=Epoc::LinearToPhysical((TLinAddr)pdBase);				
sl@0
   349
				r = (phys==KPhysAddrInvalid) ? KErrNoPageTable : KErrNone;
sl@0
   350
				}
sl@0
   351
			
sl@0
   352
#endif  //memmodel
sl@0
   353
sl@0
   354
			if ((r & KErrNoPageTable) == 0)
sl@0
   355
				{
sl@0
   356
				kumemput(a1, &pdSize, sizeof(TUint));
sl@0
   357
				kumemput(a2, &pdBase, sizeof(TUint));
sl@0
   358
				}
sl@0
   359
			
sl@0
   360
			break;	
sl@0
   361
			}
sl@0
   362
			
sl@0
   363
		default:
sl@0
   364
			r=KErrNotSupported;
sl@0
   365
			break;
sl@0
   366
		}
sl@0
   367
	return r;
sl@0
   368
	}
sl@0
   369
#else
sl@0
   370
TInt DShadow::Request(TInt /*aFunction*/, TAny* /*a1*/, TAny* /*a2*/)
sl@0
   371
	{
sl@0
   372
sl@0
   373
	return KErrNotSupported;
sl@0
   374
	}
sl@0
   375
#endif
sl@0
   376