diff -r 000000000000 -r 96e5fb8b040d kernel/eka/memmodel/epoc/multiple/x86/xkernel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/memmodel/epoc/multiple/x86/xkernel.cpp Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,205 @@ +// 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: +// e32\memmodel\epoc\multiple\x86\xkernel.cpp +// +// + +#include + + +/******************************************** + * Thread + ********************************************/ + +TInt DX86PlatThread::SetupContext(SThreadCreateInfo& aInfo) + { + switch(iThreadType) + { + case EThreadSupervisor: + case EThreadMinimalSupervisor: + case EThreadInitial: + case EThreadAPInitial: + break; + case EThreadUser: + break; + } + iNThread.SetAddressSpace(iOwningProcess); + iNThread.SetAttributes(KThreadAttAddressSpace); +#ifdef __SMP__ + iCpuRestoreCookie = -1; +#else + iAliasPdePtr = &PageDirectory(((DMemModelProcess*)iOwningProcess)->iOsAsid)[KIPCAlias>>KChunkShift]; +#endif + return KErrNone; + } + +/******************************************** + * Process + ********************************************/ + +DX86PlatProcess::DX86PlatProcess() + { + iAddressCheckMaskR=0x000fffffu; // addresses<0xA0000000 OK + iAddressCheckMaskW=0x0000ffffu; // addresses<0x80000000 OK + } + +DX86PlatProcess::~DX86PlatProcess() + { + __KTRACE_OPT(KMMU,Kern::Printf("DX86PlatProcess destruct")); + DMemModelProcess::Destruct(); + } + +TInt DX86PlatProcess::GetNewChunk(DMemModelChunk*& aChunk, SChunkCreateInfo& aInfo) + { + aChunk=NULL; + DX86PlatChunk* pC=new DX86PlatChunk; + if (!pC) + return KErrNoMemory; + aChunk=pC; + TChunkType type = aInfo.iType; + pC->iChunkType=type; + TInt r=pC->SetAttributes(aInfo); + if(r==KErrNone) + { + if(type==ESharedKernelSingle || type==ESharedKernelMultiple || type==ESharedIo) + { + DX86PlatChunk* pM=new DX86PlatChunk; + if (!pM) + return KErrNoMemory; + pC->iKernelMirror = pM; + pM->iChunkType = ESharedKernelMirror; + r=pM->SetAttributes(aInfo); + } + } + return r; + } + +TInt DX86PlatChunk::SetAttributes(SChunkCreateInfo& aInfo) + { + switch(iChunkType) + { + case EKernelData: + iAttributes = EAddressFixed|EMapTypeGlobal|EPrivate; + break; + case ERamDrive: + iAttributes = EAddressFixed|EMapTypeShared|EPrivate; + break; + case EKernelStack: + iAttributes = EAddressKernel|EMapTypeGlobal|EPrivate; + break; + case EKernelCode: + iAttributes = EAddressKernel|EMapTypeGlobal|EPrivate|ECode; + break; + case EDll: + case EUserCode: + if (aInfo.iGlobal) + iAttributes = EAddressUserGlobal|EMapTypeGlobal|ECode; + else + iAttributes = EAddressFixed|EMapTypeLocal|EPrivate|ECode; + break; + case EUserData: + if (aInfo.iGlobal) + iAttributes = EAddressShared|EMapTypeShared; + else + iAttributes = EAddressLocal|EMapTypeLocal|EPrivate; + break; + case EDllData: + iAttributes = EAddressFixed|EMapTypeLocal|EPrivate; + break; + case EUserSelfModCode: + if (aInfo.iGlobal) + iAttributes = EAddressShared|EMapTypeShared|ECode; + else + iAttributes = EAddressLocal|EMapTypeLocal|EPrivate|ECode; + break; + case ESharedKernelSingle: + case ESharedKernelMultiple: + case ESharedIo: + iAttributes = EAddressShared|EMapTypeShared; + break; + case ESharedKernelMirror: + iAttributes = EAddressKernel|EMapTypeGlobal|EPrivate; + break; + case EKernelMessage: + iAttributes = EAddressKernel|EMapTypeGlobal|EPrivate; + break; + default: + FAULT(); + } + return KErrNone; + } + +/******************************************** + * Chunk + ********************************************/ + +DX86PlatChunk::DX86PlatChunk() + {} + +DX86PlatChunk::~DX86PlatChunk() + { + DMemModelChunk::Destruct(); + } + +TInt DX86PlatChunk::SetupPermissions() + { + Mmu& m=Mmu::Get(); + if(iChunkType==ESharedKernelSingle || iChunkType==ESharedKernelMultiple || iChunkType==ESharedIo || iChunkType==ESharedKernelMirror) + { + // override map attributes for shared kernel chunks + TUint ma = (iMapAttr &~ EMapAttrAccessMask) | (iChunkType==ESharedKernelMirror?EMapAttrSupRw:EMapAttrUserRw); + TInt r = m.PdePtePermissions(ma, iPdePermissions, iPtePermissions); + if (r != KErrNone) + return r; + iMapAttr = ma; + } + else + { + iPtePermissions=m.PtePermissions(iChunkType); + iPdePermissions=m.PdePermissions(iChunkType,EFalse); + } + + __KTRACE_OPT(KMMU,Kern::Printf("Chunk permissions PTE=%08x PDE=%08x",iPtePermissions,iPdePermissions)); + return KErrNone; + } + +TIpcExcTrap::TExcLocation TIpcExcTrap::ExcLocation(DThread* aThread, TAny* aContext) + { + TX86ExcInfo& info=*(TX86ExcInfo*)aContext; + if (info.iExcId==EX86VectorPageFault) + { + TLinAddr va=(TLinAddr)info.iFaultAddress; + + TLinAddr aliasAddr = ((DMemModelThread*)aThread)->iAliasLinAddr; + TBool remoteError; + if(aliasAddr) + remoteError = TUint(va^aliasAddr)=iRemoteBase && (va-iRemoteBase)=iLocalBase && (va-iLocalBase) local read -> DS restricted, else ES restricted + if (seg==KRing3DS || seg==KRing3CS) + return EExcLocal; + } + return EExcUnknown; + }