os/kernelhwsrv/kernel/eka/memmodel/epoc/multiple/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\multiple\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 DMemModelThread::DoExit1()
    44 	{
    45 	// Regularize the thread state before main exit processing.
    46 	// We must remove any existing alias before we do any operation 
    47 	// which requires aliasing (e.g. logon completion).
    48 	__KTRACE_OPT(KTHREAD,Kern::Printf("DMemModelThread %O DoExit1",this));
    49 	NKern::LockSystem();
    50 	RemoveAlias();
    51 	NKern::UnlockSystem();
    52 	}
    53 
    54 void DThread::FreeSupervisorStack()
    55 	{
    56 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeSupervisorStack %O",this));
    57 	if (iSupervisorStackAllocated)
    58 		{
    59 		TAny* pStack = __e32_atomic_swp_ord_ptr(&iSupervisorStack, 0);
    60 		if (pStack && iThreadType!=EThreadInitial)
    61 			{
    62 			__KTRACE_OPT(KTHREAD,Kern::Printf("Freeing supervisor stack at %08x, size %x",pStack,iSupervisorStackSize));
    63 			TInt offset=(TUint8*)pStack-MM::SvStackChunk->Base();
    64 			TInt r=MM::SvStackChunk->Decommit(offset-PP::SupervisorThreadStackGuard,iSupervisorStackSize+PP::SupervisorThreadStackGuard);
    65 			__ASSERT_DEBUG(r==KErrNone, MM::Panic(MM::EDecommitFailed));
    66 			(void)r; //Supress the warning in urel build
    67 			}
    68 		}
    69 	iSupervisorStackAllocated = FALSE;
    70 	}
    71 
    72 TInt DThread::AllocateUserStack(TInt aSize, TBool /*aPaged*/)
    73 	{
    74 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateUserStack %O %x",this,aSize));
    75 
    76 	aSize=Mmu::RoundToPageSize(aSize);
    77 	if (aSize>PP::MaxUserThreadStack)
    78 		return KErrTooBig;
    79 	TInt guard=PP::UserThreadStackGuard;
    80 	DProcess* pP=iOwningProcess;
    81 	NKern::LockSystem();
    82 	DChunk* pC=pP->iDataBssStackChunk;
    83 	if (!pC || pC->Open()!=KErrNone)	// so chunk doesn't disappear during Allocate()
    84 		{
    85 		NKern::UnlockSystem();
    86 		__KTRACE_FAIL(KErrDied,Kern::Printf("AUS1: %d",KErrDied));
    87 		return KErrDied;
    88 		}
    89 	NKern::UnlockSystem();
    90 	TInt r=pC->Allocate(aSize,guard);
    91 	TInt s=pC->Close(NULL);				// NULL since we didn't add chunk to process again
    92 	if (s & EObjectDeleted)
    93 		{
    94 		__KTRACE_FAIL(KErrDied,Kern::Printf("AUS2: %d",KErrDied));
    95 		return KErrDied;
    96 		}
    97 	if (r<0)
    98 		{
    99 		__KTRACE_FAIL(r,Kern::Printf("AUS3: %d",r));
   100 		return r;
   101 		}
   102 	iUserStackSize=aSize;
   103 	iUserStackRunAddress=pP->iDataBssRunAddress+r+guard;
   104 	__KTRACE_OPT(KTHREAD,Kern::Printf("User stack run address at %x",iUserStackRunAddress));
   105 	return KErrNone;
   106 	}
   107 
   108 void DThread::FreeUserStack()
   109 	{
   110 	__KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeUserStack %O",this));
   111 	TLinAddr usr_stack = (TLinAddr)__e32_atomic_swp_ord_ptr(&iUserStackRunAddress, 0);
   112 	if (usr_stack)
   113 		{
   114 		__KTRACE_OPT(KTHREAD,Kern::Printf("Freeing user stack at %x",usr_stack));
   115 		DMemModelProcess* pP=(DMemModelProcess*)iOwningProcess;
   116 		NKern::LockSystem();
   117 		DMemModelChunk* pC=(DMemModelChunk*)pP->iDataBssStackChunk;
   118 		if (!pC || pC->Open()!=KErrNone)	// so chunk doesn't disappear during Decommit()
   119 			{
   120 			NKern::UnlockSystem();
   121 			__KTRACE_FAIL(KErrDied,Kern::Printf("FUS"));
   122 			return;
   123 			}
   124 		NKern::UnlockSystem();
   125 		TInt offset=usr_stack-pP->iDataBssRunAddress;
   126 		TInt r=pC->Decommit(offset-PP::UserThreadStackGuard,iUserStackSize+PP::UserThreadStackGuard);
   127 		__ASSERT_DEBUG(r==KErrNone, MM::Panic(MM::EDecommitFailed));
   128 		pC->Close(NULL);			// NULL since we didn't add chunk to process again
   129 		(void)r; //Supress the warning in urel build
   130 		}
   131 	}
   132 
   133 void DThread::IpcExcHandler(TExcTrap* aTrap, DThread* aThread, TAny* aContext)
   134 	{
   135 	aThread->iIpcClient = 0;
   136 	TIpcExcTrap& xt=*(TIpcExcTrap*)aTrap;
   137 	switch (xt.ExcLocation(aThread, aContext))
   138 		{
   139 		case TIpcExcTrap::EExcRemote:
   140 			// problem accessing remote address - 'leave' so an error code will be returned
   141 			NKern::LockSystem();
   142 			((DMemModelThread*)aThread)->RemoveAlias();
   143 			xt.Exception(KErrBadDescriptor);  // does not return
   144 
   145 		case TIpcExcTrap::EExcLocal:
   146 			// problem accessing local address - return and panic current thread as usual
   147 			NKern::LockSystem();
   148 			((DMemModelThread*)aThread)->RemoveAlias();
   149 			NKern::UnlockSystem();
   150 			return;
   151 
   152 		default:
   153 			// otherwise return and fault kernel
   154 			NKern::LockSystem();
   155 			return;
   156 		}
   157 	}