os/kernelhwsrv/kernel/eka/memmodel/epoc/flexible/mkernel.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1994-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 //
    15 
    16 #include <memmodel.h>
    17 #include "mmu/mm.h"
    18 #include "mmboot.h"
    19 
    20 
    21 /********************************************
    22  * Thread
    23  ********************************************/
    24 
    25 TInt DThread::AllocateSupervisorStack()
    26 	{
    27 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateSupervisorStack %O %x",this,iSupervisorStackSize));
    28 	iSupervisorStackSize = MM::RoundToPageSize(iSupervisorStackSize);
    29 	if(iThreadType==EThreadInitial)
    30 		return KErrNone;
    31 
    32 	TUint guardSize = PP::SupervisorThreadStackGuard;
    33 	TUint virtualSize = guardSize+iSupervisorStackSize;
    34 	DMemoryObject* memory;
    35 	TInt r = MM::MemoryNew(memory,EMemoryObjectUnpaged,MM::BytesToPages(virtualSize));
    36 	if(r==KErrNone)
    37 		{
    38 		r = MM::MemoryAlloc(memory,MM::BytesToPages(guardSize),MM::BytesToPages(iSupervisorStackSize));
    39 		if(r==KErrNone)
    40 			{
    41 			DMemoryMapping* mapping;
    42 			r = MM::MappingNew(mapping,memory,ESupervisorReadWrite,KKernelOsAsid);
    43 			if(r==KErrNone)
    44 				{
    45 				__NK_ASSERT_DEBUG(!((DMemModelThread*)this)->iKernelStackMapping);
    46 				((DMemModelThread*)this)->iKernelStackMapping = mapping;
    47 				iSupervisorStack = (TAny*)(MM::MappingBase(mapping)+guardSize);
    48 				__KTRACE_OPT(KTHREAD,Kern::Printf("Supervisor stack at %x, size %x",iSupervisorStack,iSupervisorStackSize));
    49 				}
    50 			}
    51 		if(r!=KErrNone)
    52 			MM::MemoryDestroy(memory);
    53 		else
    54 			{
    55 #ifdef BTRACE_FLEXIBLE_MEM_MODEL
    56 			BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsSupervisorStack,memory,&iNThread);
    57 #endif
    58 			}
    59 		}
    60 	return r;
    61 	}
    62 
    63 
    64 void DThread::FreeSupervisorStack()
    65 	{
    66 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeSupervisorStack %O",this));
    67 	if(iThreadType==EThreadInitial) // !!!???
    68 		return;
    69 	MM::MappingAndMemoryDestroy(((DMemModelThread*)this)->iKernelStackMapping);
    70 	}
    71 
    72 
    73 TInt DThread::AllocateUserStack(TInt aSize, TBool aPaged)
    74 	{
    75 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateUserStack %O %x",this,aSize));
    76 	aSize = MM::RoundToPageSize(aSize);
    77 	if(aSize>PP::MaxUserThreadStack)
    78 		return KErrTooBig;
    79 
    80 	TMemoryObjectType memoryType = (aPaged)? EMemoryObjectPaged : EMemoryObjectMovable;
    81 	TUint guardSize = PP::UserThreadStackGuard;
    82 	TUint virtualSize = guardSize+aSize;
    83 	// wipe user thread stack with 0x29292929
    84 	TMemoryCreateFlags flags = (TMemoryCreateFlags)(EMemoryCreateDefault | EMemoryCreateUseCustomWipeByte | (0x29 << EMemoryCreateWipeByteShift));
    85 	DMemoryObject* memory;
    86 	TInt r = MM::MemoryNew(memory, memoryType, MM::BytesToPages(virtualSize),flags);
    87 	if(r==KErrNone)
    88 		{
    89 		r = MM::MemoryAlloc(memory,MM::BytesToPages(guardSize),MM::BytesToPages(aSize));
    90 		if(r==KErrNone)
    91 			{
    92 			DMemoryMapping* mapping;
    93 			// Get os asid, no need to open a reference as this only invoked where 
    94 			// the current thread is owned by iOwningProcess, iOwningProcess is 
    95 			// the kernel process or this is the first thread of a process that 
    96 			// isn't fully created yet.
    97 			TUint osAsid = ((DMemModelProcess*)iOwningProcess)->OsAsid();
    98 			r = MM::MappingNew(mapping,memory,EUserReadWrite,osAsid);
    99 			if(r==KErrNone)
   100 				{
   101 				__NK_ASSERT_DEBUG(!((DMemModelThread*)this)->iUserStackMapping);
   102 				((DMemModelThread*)this)->iUserStackMapping = mapping;
   103 				iUserStackSize = aSize;
   104 				iUserStackRunAddress = MM::MappingBase(mapping)+guardSize;
   105 				__KTRACE_OPT(KTHREAD,Kern::Printf("User stack at %x, size %x",iUserStackRunAddress,iUserStackSize));
   106 				}
   107 			}
   108 		if(r!=KErrNone)
   109 			MM::MemoryDestroy(memory);
   110 		else
   111 			{
   112 #ifdef BTRACE_FLEXIBLE_MEM_MODEL
   113 			BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsUserStack,memory,&iNThread);
   114 #endif
   115 			}
   116 		}
   117 	return r;
   118 	}
   119 
   120 
   121 void DThread::FreeUserStack()
   122 	{
   123 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeUserStack %O",this));
   124 	MM::MappingAndMemoryDestroy(((DMemModelThread*)this)->iUserStackMapping);
   125 	}
   126 
   127 
   128 void DMemModelThread::SetPaging(TUint& aCreateFlags)
   129 	{
   130 	TUint pagingAtt = aCreateFlags & EThreadCreateFlagPagingMask;
   131 	TUint dataPolicy = TheSuperPage().KernelConfigFlags() & EKernelConfigDataPagingPolicyMask;
   132 	if (dataPolicy == EKernelConfigDataPagingPolicyNoPaging ||
   133 		!(K::MemModelAttributes & EMemModelAttrDataPaging))
   134 		{// No paging policy set or no data paging device installed.
   135 		pagingAtt = EThreadCreateFlagUnpaged;
   136 		}
   137 	else if (dataPolicy == EKernelConfigDataPagingPolicyAlwaysPage)
   138 		{
   139 		pagingAtt = EThreadCreateFlagPaged;
   140 		}
   141 	else if (pagingAtt == EThreadCreateFlagPagingUnspec)
   142 		{// No data paging attribute specified for this chunk so use the process's.
   143 		if (iOwningProcess->iAttributes & DProcess::EDataPaged)
   144 			pagingAtt = EThreadCreateFlagPaged;
   145 		else
   146 			pagingAtt = EThreadCreateFlagUnpaged;
   147 		}
   148 #ifdef _DEBUG
   149 	else
   150 		{
   151 		__NK_ASSERT_DEBUG(	pagingAtt == EThreadCreateFlagPaged || 
   152 							pagingAtt == EThreadCreateFlagUnpaged);
   153 		}
   154 #endif
   155 	// Save the paging attributes for when the stack and heap are created later.
   156 	aCreateFlags &= ~EThreadCreateFlagPagingMask;
   157 	aCreateFlags |= pagingAtt;
   158 	}
   159 
   160 
   161 void DMemModelThread::DoExit1()
   162 	{
   163 	// Regularize the thread state before main exit processing.
   164 	// We must remove any existing alias before we do any operation 
   165 	// which requires aliasing (e.g. logon completion).
   166 	__KTRACE_OPT(KTHREAD,Kern::Printf("DMemModelThread %O DoExit1",this));
   167 	RemoveAlias();
   168 	}
   169 
   170 
   171 void DThread::IpcExcHandler(TExcTrap* aTrap, DThread* aThread, TAny* aContext)
   172 	{
   173 	aThread->iIpcClient = 0;
   174 	TIpcExcTrap& xt=*(TIpcExcTrap*)aTrap;
   175 	switch (xt.ExcLocation(aThread, aContext))
   176 		{
   177 		case TIpcExcTrap::EExcRemote:
   178 			// problem accessing remote address - 'leave' so an error code will be returned
   179 			((DMemModelThread*)aThread)->RemoveAlias();
   180 			xt.Exception(KErrBadDescriptor);  // does not return
   181 
   182 		case TIpcExcTrap::EExcLocal:
   183 			// problem accessing local address - return and panic current thread as usual
   184 			((DMemModelThread*)aThread)->RemoveAlias();
   185 			return;
   186 
   187 		default:
   188 			// otherwise return and fault kernel
   189 			NKern::LockSystem();
   190 			return;
   191 		}
   192 	}
   193 
   194 
   195 void DMemModelThread::BTracePrime(TInt aCategory)
   196 	{
   197 	DThread::BTracePrime(aCategory);
   198 #ifdef BTRACE_FLEXIBLE_MEM_MODEL
   199 	if(aCategory==BTrace::EFlexibleMemModel || aCategory==-1)
   200 		{
   201 		if (iKernelStackMapping)
   202 			{
   203 			DMemoryObject* memory = MM::MappingGetAndOpenMemory(iKernelStackMapping);
   204 			if (memory)
   205 				{
   206 				MM::MemoryBTracePrime(memory);
   207 				BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsSupervisorStack,memory,&iNThread);
   208 				MM::MemoryClose(memory);
   209 				}
   210 			}
   211 		if (iUserStackMapping)
   212 			{
   213 			DMemoryObject* memory = MM::MappingGetAndOpenMemory(iUserStackMapping);
   214 			if (memory)
   215 				{
   216 				MM::MemoryBTracePrime(memory);
   217 				BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsUserStack,memory,&iNThread);
   218 				MM::MemoryClose(memory);
   219 				}
   220 			}
   221 		}
   222 #endif
   223 	}