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 + }