kernel/eka/memmodel/epoc/direct/mcodeseg.cpp
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/memmodel/epoc/direct/mcodeseg.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,164 @@
+// Copyright (c) 1995-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\direct\mcodeseg.cpp
+// 
+//
+
+#include <memmodel.h>
+#include <kernel/cache.h>
+
+DCodeSeg* M::NewCodeSeg(TCodeSegCreateInfo&)
+	{
+	__KTRACE_OPT(KDLL,Kern::Printf("M::NewCodeSeg"));
+	return new DMemModelCodeSeg;
+	}
+
+
+DEpocCodeSegMemory* DEpocCodeSegMemory::New(DEpocCodeSeg* aCodeSeg)
+	{
+	return new DMemModelCodeSegMemory(aCodeSeg);
+	}
+
+	
+DMemModelCodeSegMemory::DMemModelCodeSegMemory(DEpocCodeSeg* aCodeSeg)
+	: DEpocCodeSegMemory(aCodeSeg)
+	{
+	}
+
+
+DMemModelCodeSeg::DMemModelCodeSeg()
+	{
+	}
+
+
+DMemModelCodeSeg::~DMemModelCodeSeg()
+//
+// Destructor
+//
+	{
+	__KTRACE_OPT(KDLL,Kern::Printf("DMemModelCodeSeg::Destruct %C", this));
+	if (!iXIP && iMemory)
+		{
+		SRamCodeInfo& ri=RamInfo();
+		if (ri.iCodeLoadAddr)
+			{
+			TInt code_size=MM::RoundToBlockSize(ri.iCodeSize+ri.iDataSize);
+			MM::FreeRegion(ri.iCodeLoadAddr, code_size);
+			}
+		if (iDataAlloc)
+			{
+			TInt data_size=MM::RoundToBlockSize(ri.iDataSize+ri.iBssSize);
+			MM::FreeRegion(iDataAlloc, data_size);
+			}
+		}
+	Kern::Free(iKernelData);
+	DEpocCodeSeg::Destruct();
+	}
+
+TInt DMemModelCodeSeg::DoCreateRam(TCodeSegCreateInfo& aInfo, DProcess* aProcess)
+	{
+	__KTRACE_OPT(KDLL,Kern::Printf("DMemModelCodeSeg::DoCreateRam %C proc %O", this, aProcess));
+	DMemModelProcess* p=(DMemModelProcess*)aProcess;
+	TBool kernel=( (iAttr&(ECodeSegAttKernel|ECodeSegAttGlobal)) == ECodeSegAttKernel );
+	SRamCodeInfo& ri=RamInfo();
+	iSize = MM::RoundToBlockSize(ri.iCodeSize+ri.iDataSize);
+	TInt total_data_size=ri.iDataSize+ri.iBssSize;
+	TInt r=MM::AllocRegion(ri.iCodeLoadAddr, iSize);
+	if (r!=KErrNone)
+		return r;
+	ri.iCodeRunAddr=ri.iCodeLoadAddr;
+	if (ri.iDataSize)
+		ri.iDataLoadAddr=ri.iCodeLoadAddr+ri.iCodeSize;
+	if (kernel)
+		{
+		if (total_data_size)
+			{
+			iKernelData=Kern::Alloc(total_data_size);
+			if (!iKernelData)
+				return KErrNoMemory;
+			ri.iDataRunAddr=(TLinAddr)iKernelData;
+			}
+		return KErrNone;
+		}
+	if (total_data_size && p)
+		SetAttachProcess(p);
+	if (total_data_size && !IsExe())
+		{
+		TInt data_alloc_size=MM::RoundToBlockSize(total_data_size);
+		TInt r=MM::AllocRegion(iDataAlloc, data_alloc_size);
+		if (r!=KErrNone)
+			return r;
+		ri.iDataRunAddr=iDataAlloc;
+		}
+	return r;
+	}
+
+TInt DMemModelCodeSeg::DoCreateXIP(DProcess* aProcess)
+	{
+	__KTRACE_OPT(KDLL,Kern::Printf("DMemModelCodeSeg::DoCreateXIP %C proc %O", this, aProcess));
+	DMemModelProcess* p=(DMemModelProcess*)aProcess;
+	TInt r=KErrNone;
+	TBool kernel=( (iAttr&(ECodeSegAttKernel|ECodeSegAttGlobal)) == ECodeSegAttKernel );
+	const TRomImageHeader& rih=RomInfo();
+	if (!kernel && aProcess)
+		{
+		// XIP images with static data are specific to a single process
+		if (rih.iFlags&KRomImageFlagDataPresent)
+			SetAttachProcess(p);
+		}
+	return r;
+	}
+
+TInt DMemModelCodeSeg::Loaded(TCodeSegCreateInfo& aInfo)
+	{
+	if (!iXIP)
+		{
+		// Clean DCache for specified area, Invalidate ICache/BTB for specified area
+		TLinAddr code_base=RamInfo().iCodeRunAddr;
+		Cache::IMB_Range(code_base, RamInfo().iCodeSize);
+		}
+	return DEpocCodeSeg::Loaded(aInfo);
+	}
+
+void DMemModelCodeSeg::ReadExportDir(TUint32* aDest)
+	{
+	__KTRACE_OPT(KDLL,Kern::Printf("DMemModelCodeSeg::ReadExportDir %08x",aDest));
+	if (!iXIP)
+		{
+		SRamCodeInfo& ri=RamInfo();
+		TInt size=(ri.iExportDirCount+1)*sizeof(TLinAddr);
+		kumemput32(aDest, (const TUint32*)(ri.iExportDir-sizeof(TUint32)), size);
+		}
+	}
+
+TBool DMemModelCodeSeg::OpenCheck(DProcess* aProcess)
+	{
+	return FindCheck(aProcess);
+	}
+
+TBool DMemModelCodeSeg::FindCheck(DProcess* aProcess)
+	{
+	__KTRACE_OPT(KDLL,Kern::Printf("CSEG:%08x Compat? proc=%O",this,aProcess));
+	if (!aProcess)
+		return !iAttachProcess;	// can't reuse same code segment for a new instance of the process
+	DMemModelProcess& p=*(DMemModelProcess*)aProcess;
+	DCodeSeg* pPSeg=p.CodeSeg();
+	if (iAttachProcess && iAttachProcess!=aProcess)
+		return EFalse;
+	if (iExeCodeSeg && iExeCodeSeg!=pPSeg)
+		return EFalse;
+	__ASSERT_DEBUG( (iAttachProcess || !(iMark & EMarkDataPresent)), MM::Panic(MM::ECodeSegCheckInconsistent));
+	return ETrue;
+	}
+