diff -r 000000000000 -r 96e5fb8b040d kernel/eka/memmodel/epoc/flexible/mkernel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/memmodel/epoc/flexible/mkernel.cpp Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,223 @@ +// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include "mmu/mm.h" +#include "mmboot.h" + + +/******************************************** + * Thread + ********************************************/ + +TInt DThread::AllocateSupervisorStack() + { + __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateSupervisorStack %O %x",this,iSupervisorStackSize)); + iSupervisorStackSize = MM::RoundToPageSize(iSupervisorStackSize); + if(iThreadType==EThreadInitial) + return KErrNone; + + TUint guardSize = PP::SupervisorThreadStackGuard; + TUint virtualSize = guardSize+iSupervisorStackSize; + DMemoryObject* memory; + TInt r = MM::MemoryNew(memory,EMemoryObjectUnpaged,MM::BytesToPages(virtualSize)); + if(r==KErrNone) + { + r = MM::MemoryAlloc(memory,MM::BytesToPages(guardSize),MM::BytesToPages(iSupervisorStackSize)); + if(r==KErrNone) + { + DMemoryMapping* mapping; + r = MM::MappingNew(mapping,memory,ESupervisorReadWrite,KKernelOsAsid); + if(r==KErrNone) + { + __NK_ASSERT_DEBUG(!((DMemModelThread*)this)->iKernelStackMapping); + ((DMemModelThread*)this)->iKernelStackMapping = mapping; + iSupervisorStack = (TAny*)(MM::MappingBase(mapping)+guardSize); + __KTRACE_OPT(KTHREAD,Kern::Printf("Supervisor stack at %x, size %x",iSupervisorStack,iSupervisorStackSize)); + } + } + if(r!=KErrNone) + MM::MemoryDestroy(memory); + else + { +#ifdef BTRACE_FLEXIBLE_MEM_MODEL + BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsSupervisorStack,memory,&iNThread); +#endif + } + } + return r; + } + + +void DThread::FreeSupervisorStack() + { + __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeSupervisorStack %O",this)); + if(iThreadType==EThreadInitial) // !!!??? + return; + MM::MappingAndMemoryDestroy(((DMemModelThread*)this)->iKernelStackMapping); + } + + +TInt DThread::AllocateUserStack(TInt aSize, TBool aPaged) + { + __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateUserStack %O %x",this,aSize)); + aSize = MM::RoundToPageSize(aSize); + if(aSize>PP::MaxUserThreadStack) + return KErrTooBig; + + TMemoryObjectType memoryType = (aPaged)? EMemoryObjectPaged : EMemoryObjectMovable; + TUint guardSize = PP::UserThreadStackGuard; + TUint virtualSize = guardSize+aSize; + // wipe user thread stack with 0x29292929 + TMemoryCreateFlags flags = (TMemoryCreateFlags)(EMemoryCreateDefault | EMemoryCreateUseCustomWipeByte | (0x29 << EMemoryCreateWipeByteShift)); + DMemoryObject* memory; + TInt r = MM::MemoryNew(memory, memoryType, MM::BytesToPages(virtualSize),flags); + if(r==KErrNone) + { + r = MM::MemoryAlloc(memory,MM::BytesToPages(guardSize),MM::BytesToPages(aSize)); + if(r==KErrNone) + { + DMemoryMapping* mapping; + // Get os asid, no need to open a reference as this only invoked where + // the current thread is owned by iOwningProcess, iOwningProcess is + // the kernel process or this is the first thread of a process that + // isn't fully created yet. + TUint osAsid = ((DMemModelProcess*)iOwningProcess)->OsAsid(); + r = MM::MappingNew(mapping,memory,EUserReadWrite,osAsid); + if(r==KErrNone) + { + __NK_ASSERT_DEBUG(!((DMemModelThread*)this)->iUserStackMapping); + ((DMemModelThread*)this)->iUserStackMapping = mapping; + iUserStackSize = aSize; + iUserStackRunAddress = MM::MappingBase(mapping)+guardSize; + __KTRACE_OPT(KTHREAD,Kern::Printf("User stack at %x, size %x",iUserStackRunAddress,iUserStackSize)); + } + } + if(r!=KErrNone) + MM::MemoryDestroy(memory); + else + { +#ifdef BTRACE_FLEXIBLE_MEM_MODEL + BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsUserStack,memory,&iNThread); +#endif + } + } + return r; + } + + +void DThread::FreeUserStack() + { + __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeUserStack %O",this)); + MM::MappingAndMemoryDestroy(((DMemModelThread*)this)->iUserStackMapping); + } + + +void DMemModelThread::SetPaging(TUint& aCreateFlags) + { + TUint pagingAtt = aCreateFlags & EThreadCreateFlagPagingMask; + TUint dataPolicy = TheSuperPage().KernelConfigFlags() & EKernelConfigDataPagingPolicyMask; + if (dataPolicy == EKernelConfigDataPagingPolicyNoPaging || + !(K::MemModelAttributes & EMemModelAttrDataPaging)) + {// No paging policy set or no data paging device installed. + pagingAtt = EThreadCreateFlagUnpaged; + } + else if (dataPolicy == EKernelConfigDataPagingPolicyAlwaysPage) + { + pagingAtt = EThreadCreateFlagPaged; + } + else if (pagingAtt == EThreadCreateFlagPagingUnspec) + {// No data paging attribute specified for this chunk so use the process's. + if (iOwningProcess->iAttributes & DProcess::EDataPaged) + pagingAtt = EThreadCreateFlagPaged; + else + pagingAtt = EThreadCreateFlagUnpaged; + } +#ifdef _DEBUG + else + { + __NK_ASSERT_DEBUG( pagingAtt == EThreadCreateFlagPaged || + pagingAtt == EThreadCreateFlagUnpaged); + } +#endif + // Save the paging attributes for when the stack and heap are created later. + aCreateFlags &= ~EThreadCreateFlagPagingMask; + aCreateFlags |= pagingAtt; + } + + +void DMemModelThread::DoExit1() + { + // Regularize the thread state before main exit processing. + // We must remove any existing alias before we do any operation + // which requires aliasing (e.g. logon completion). + __KTRACE_OPT(KTHREAD,Kern::Printf("DMemModelThread %O DoExit1",this)); + RemoveAlias(); + } + + +void DThread::IpcExcHandler(TExcTrap* aTrap, DThread* aThread, TAny* aContext) + { + aThread->iIpcClient = 0; + TIpcExcTrap& xt=*(TIpcExcTrap*)aTrap; + switch (xt.ExcLocation(aThread, aContext)) + { + case TIpcExcTrap::EExcRemote: + // problem accessing remote address - 'leave' so an error code will be returned + ((DMemModelThread*)aThread)->RemoveAlias(); + xt.Exception(KErrBadDescriptor); // does not return + + case TIpcExcTrap::EExcLocal: + // problem accessing local address - return and panic current thread as usual + ((DMemModelThread*)aThread)->RemoveAlias(); + return; + + default: + // otherwise return and fault kernel + NKern::LockSystem(); + return; + } + } + + +void DMemModelThread::BTracePrime(TInt aCategory) + { + DThread::BTracePrime(aCategory); +#ifdef BTRACE_FLEXIBLE_MEM_MODEL + if(aCategory==BTrace::EFlexibleMemModel || aCategory==-1) + { + if (iKernelStackMapping) + { + DMemoryObject* memory = MM::MappingGetAndOpenMemory(iKernelStackMapping); + if (memory) + { + MM::MemoryBTracePrime(memory); + BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsSupervisorStack,memory,&iNThread); + MM::MemoryClose(memory); + } + } + if (iUserStackMapping) + { + DMemoryObject* memory = MM::MappingGetAndOpenMemory(iUserStackMapping); + if (memory) + { + MM::MemoryBTracePrime(memory); + BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsUserStack,memory,&iNThread); + MM::MemoryClose(memory); + } + } + } +#endif + }