os/kernelhwsrv/kernel/eka/memmodel/epoc/moving/mkernel.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/memmodel/epoc/moving/mkernel.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,137 @@
     1.4 +// Copyright (c) 1994-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\memmodel\epoc\moving\mkernel.cpp
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include "memmodel.h"
    1.22 +
    1.23 +/********************************************
    1.24 + * Thread
    1.25 + ********************************************/
    1.26 +
    1.27 +TInt DThread::AllocateSupervisorStack()
    1.28 +	{
    1.29 +	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateSupervisorStack %O %x",this,iSupervisorStackSize));
    1.30 +	iSupervisorStackSize=Mmu::RoundToPageSize(iSupervisorStackSize);
    1.31 +	if (iThreadType!=EThreadInitial)
    1.32 +		{
    1.33 +		TInt offset=MM::SvStackChunk->Allocate(iSupervisorStackSize,PP::SupervisorThreadStackGuard);
    1.34 +		if (offset<0)
    1.35 +			{
    1.36 +			__KTRACE_FAIL(KErrNoMemory,Kern::Printf("ASS: %d",KErrNoMemory));
    1.37 +			return KErrNoMemory;
    1.38 +			}
    1.39 +		iSupervisorStack=MM::SvStackChunk->Base()+offset+PP::SupervisorThreadStackGuard;
    1.40 +		iSupervisorStackAllocated = TRUE;
    1.41 +		__KTRACE_OPT(KTHREAD,Kern::Printf("Supervisor stack at %x, size %x",iSupervisorStack,iSupervisorStackSize));
    1.42 +		}
    1.43 +	return KErrNone;
    1.44 +	}
    1.45 +
    1.46 +void DThread::FreeSupervisorStack()
    1.47 +	{
    1.48 +	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeSupervisorStack %O",this));
    1.49 +	if (iSupervisorStackAllocated)
    1.50 +		{
    1.51 +		TAny* pStack = __e32_atomic_swp_ord_ptr(&iSupervisorStack, 0);
    1.52 +		if (pStack && iThreadType!=EThreadInitial)
    1.53 +			{
    1.54 +			__KTRACE_OPT(KTHREAD,Kern::Printf("Freeing supervisor stack at %08x, size %x",pStack,iSupervisorStackSize));
    1.55 +			TInt offset=(TUint8*)pStack-MM::SvStackChunk->Base();
    1.56 +			MM::SvStackChunk->Decommit(offset-PP::SupervisorThreadStackGuard,iSupervisorStackSize+PP::SupervisorThreadStackGuard);
    1.57 +			}
    1.58 +		}
    1.59 +	iSupervisorStackAllocated = FALSE;
    1.60 +	}
    1.61 +
    1.62 +TInt DThread::AllocateUserStack(TInt aSize, TBool /*aPaged*/)
    1.63 +	{
    1.64 +	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateUserStack %O %x",this,aSize));
    1.65 +
    1.66 +	aSize=Mmu::RoundToPageSize(aSize);
    1.67 +	if (aSize>PP::MaxUserThreadStack)
    1.68 +		return KErrTooBig;
    1.69 +	TInt guard=PP::UserThreadStackGuard;
    1.70 +	DProcess* pP=iOwningProcess;
    1.71 +	NKern::LockSystem();
    1.72 +	DChunk* pC=pP->iDataBssStackChunk;
    1.73 +	if (!pC || pC->Open()!=KErrNone)	// so chunk doesn't disappear during Allocate()
    1.74 +		{
    1.75 +		NKern::UnlockSystem();
    1.76 +		__KTRACE_FAIL(KErrDied,Kern::Printf("AUS1: %d",KErrDied));
    1.77 +		return KErrDied;
    1.78 +		}
    1.79 +	NKern::UnlockSystem();
    1.80 +	TInt r=pC->Allocate(aSize,guard);
    1.81 +	TInt s=pC->Close(NULL);				// NULL since we didn't add chunk to process again
    1.82 +	if (s & EObjectDeleted)
    1.83 +		{
    1.84 +		__KTRACE_FAIL(KErrDied,Kern::Printf("AUS2: %d",KErrDied));
    1.85 +		return KErrDied;
    1.86 +		}
    1.87 +	if (r<0)
    1.88 +		{
    1.89 +		__KTRACE_FAIL(r,Kern::Printf("AUS3: %d",r));
    1.90 +		return r;
    1.91 +		}
    1.92 +	iUserStackSize=aSize;
    1.93 +	iUserStackRunAddress=pP->iDataBssRunAddress+r+guard;
    1.94 +	__KTRACE_OPT(KTHREAD,Kern::Printf("User stack run address at %x",iUserStackRunAddress));
    1.95 +	return KErrNone;
    1.96 +	}
    1.97 +
    1.98 +void DThread::FreeUserStack()
    1.99 +	{
   1.100 +	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeUserStack %O",this));
   1.101 +	TLinAddr usr_stack = (TLinAddr)__e32_atomic_swp_ord_ptr(&iUserStackRunAddress, 0);
   1.102 +	if (usr_stack)
   1.103 +		{
   1.104 +		__KTRACE_OPT(KTHREAD,Kern::Printf("Freeing user stack at %x",usr_stack));
   1.105 +		DMemModelProcess* pP=(DMemModelProcess*)iOwningProcess;
   1.106 +		NKern::LockSystem();
   1.107 +		DMemModelChunk* pC=(DMemModelChunk*)pP->iDataBssStackChunk;
   1.108 +		if (!pC || pC->Open()!=KErrNone)	// so chunk doesn't disappear during Decommit()
   1.109 +			{
   1.110 +			NKern::UnlockSystem();
   1.111 +			__KTRACE_FAIL(KErrDied,Kern::Printf("FUS"));
   1.112 +			return;
   1.113 +			}
   1.114 +		NKern::UnlockSystem();
   1.115 +		TInt offset=usr_stack-pP->iDataBssRunAddress;
   1.116 +		pC->Decommit(offset-PP::UserThreadStackGuard,iUserStackSize+PP::UserThreadStackGuard);
   1.117 +		pC->Close(NULL);			// NULL since we didn't add chunk to process again
   1.118 +		}
   1.119 +	}
   1.120 +
   1.121 +void DThread::IpcExcHandler(TExcTrap* aTrap, DThread* aThread, TAny* aContext)
   1.122 +	{
   1.123 +	aThread->iIpcClient = 0;
   1.124 +	TIpcExcTrap& xt=*(TIpcExcTrap*)aTrap;
   1.125 +	switch (xt.ExcLocation(aThread, aContext))
   1.126 +		{
   1.127 +		case TIpcExcTrap::EExcRemote:
   1.128 +			// problem accessing remote address - 'leave' so an error code will be returned
   1.129 +			xt.Exception(KErrBadDescriptor);  // does not return
   1.130 +
   1.131 +		case TIpcExcTrap::EExcLocal:
   1.132 +			// problem accessing local address - return and panic current thread as usual
   1.133 +			NKern::UnlockSystem();
   1.134 +			return;
   1.135 +
   1.136 +		default:
   1.137 +			// otherwise return and fault kernel
   1.138 +			return;
   1.139 +		}
   1.140 +	}