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