os/kernelhwsrv/kernel/eka/memmodel/epoc/moving/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 // e32\memmodel\epoc\moving\mkernel.cpp
    15 // 
    16 //
    17 
    18 #include "memmodel.h"
    19 
    20 /********************************************
    21  * Thread
    22  ********************************************/
    23 
    24 TInt DThread::AllocateSupervisorStack()
    25 	{
    26 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateSupervisorStack %O %x",this,iSupervisorStackSize));
    27 	iSupervisorStackSize=Mmu::RoundToPageSize(iSupervisorStackSize);
    28 	if (iThreadType!=EThreadInitial)
    29 		{
    30 		TInt offset=MM::SvStackChunk->Allocate(iSupervisorStackSize,PP::SupervisorThreadStackGuard);
    31 		if (offset<0)
    32 			{
    33 			__KTRACE_FAIL(KErrNoMemory,Kern::Printf("ASS: %d",KErrNoMemory));
    34 			return KErrNoMemory;
    35 			}
    36 		iSupervisorStack=MM::SvStackChunk->Base()+offset+PP::SupervisorThreadStackGuard;
    37 		iSupervisorStackAllocated = TRUE;
    38 		__KTRACE_OPT(KTHREAD,Kern::Printf("Supervisor stack at %x, size %x",iSupervisorStack,iSupervisorStackSize));
    39 		}
    40 	return KErrNone;
    41 	}
    42 
    43 void DThread::FreeSupervisorStack()
    44 	{
    45 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeSupervisorStack %O",this));
    46 	if (iSupervisorStackAllocated)
    47 		{
    48 		TAny* pStack = __e32_atomic_swp_ord_ptr(&iSupervisorStack, 0);
    49 		if (pStack && iThreadType!=EThreadInitial)
    50 			{
    51 			__KTRACE_OPT(KTHREAD,Kern::Printf("Freeing supervisor stack at %08x, size %x",pStack,iSupervisorStackSize));
    52 			TInt offset=(TUint8*)pStack-MM::SvStackChunk->Base();
    53 			MM::SvStackChunk->Decommit(offset-PP::SupervisorThreadStackGuard,iSupervisorStackSize+PP::SupervisorThreadStackGuard);
    54 			}
    55 		}
    56 	iSupervisorStackAllocated = FALSE;
    57 	}
    58 
    59 TInt DThread::AllocateUserStack(TInt aSize, TBool /*aPaged*/)
    60 	{
    61 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateUserStack %O %x",this,aSize));
    62 
    63 	aSize=Mmu::RoundToPageSize(aSize);
    64 	if (aSize>PP::MaxUserThreadStack)
    65 		return KErrTooBig;
    66 	TInt guard=PP::UserThreadStackGuard;
    67 	DProcess* pP=iOwningProcess;
    68 	NKern::LockSystem();
    69 	DChunk* pC=pP->iDataBssStackChunk;
    70 	if (!pC || pC->Open()!=KErrNone)	// so chunk doesn't disappear during Allocate()
    71 		{
    72 		NKern::UnlockSystem();
    73 		__KTRACE_FAIL(KErrDied,Kern::Printf("AUS1: %d",KErrDied));
    74 		return KErrDied;
    75 		}
    76 	NKern::UnlockSystem();
    77 	TInt r=pC->Allocate(aSize,guard);
    78 	TInt s=pC->Close(NULL);				// NULL since we didn't add chunk to process again
    79 	if (s & EObjectDeleted)
    80 		{
    81 		__KTRACE_FAIL(KErrDied,Kern::Printf("AUS2: %d",KErrDied));
    82 		return KErrDied;
    83 		}
    84 	if (r<0)
    85 		{
    86 		__KTRACE_FAIL(r,Kern::Printf("AUS3: %d",r));
    87 		return r;
    88 		}
    89 	iUserStackSize=aSize;
    90 	iUserStackRunAddress=pP->iDataBssRunAddress+r+guard;
    91 	__KTRACE_OPT(KTHREAD,Kern::Printf("User stack run address at %x",iUserStackRunAddress));
    92 	return KErrNone;
    93 	}
    94 
    95 void DThread::FreeUserStack()
    96 	{
    97 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeUserStack %O",this));
    98 	TLinAddr usr_stack = (TLinAddr)__e32_atomic_swp_ord_ptr(&iUserStackRunAddress, 0);
    99 	if (usr_stack)
   100 		{
   101 		__KTRACE_OPT(KTHREAD,Kern::Printf("Freeing user stack at %x",usr_stack));
   102 		DMemModelProcess* pP=(DMemModelProcess*)iOwningProcess;
   103 		NKern::LockSystem();
   104 		DMemModelChunk* pC=(DMemModelChunk*)pP->iDataBssStackChunk;
   105 		if (!pC || pC->Open()!=KErrNone)	// so chunk doesn't disappear during Decommit()
   106 			{
   107 			NKern::UnlockSystem();
   108 			__KTRACE_FAIL(KErrDied,Kern::Printf("FUS"));
   109 			return;
   110 			}
   111 		NKern::UnlockSystem();
   112 		TInt offset=usr_stack-pP->iDataBssRunAddress;
   113 		pC->Decommit(offset-PP::UserThreadStackGuard,iUserStackSize+PP::UserThreadStackGuard);
   114 		pC->Close(NULL);			// NULL since we didn't add chunk to process again
   115 		}
   116 	}
   117 
   118 void DThread::IpcExcHandler(TExcTrap* aTrap, DThread* aThread, TAny* aContext)
   119 	{
   120 	aThread->iIpcClient = 0;
   121 	TIpcExcTrap& xt=*(TIpcExcTrap*)aTrap;
   122 	switch (xt.ExcLocation(aThread, aContext))
   123 		{
   124 		case TIpcExcTrap::EExcRemote:
   125 			// problem accessing remote address - 'leave' so an error code will be returned
   126 			xt.Exception(KErrBadDescriptor);  // does not return
   127 
   128 		case TIpcExcTrap::EExcLocal:
   129 			// problem accessing local address - return and panic current thread as usual
   130 			NKern::UnlockSystem();
   131 			return;
   132 
   133 		default:
   134 			// otherwise return and fault kernel
   135 			return;
   136 		}
   137 	}