os/kernelhwsrv/kernel/eka/memmodel/epoc/direct/mprocess.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32\memmodel\epoc\direct\mprocess.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <memmodel.h>
sl@0
    19
#include <kernel/cache.h>
sl@0
    20
sl@0
    21
#define iMState		iWaitLink.iSpare1
sl@0
    22
sl@0
    23
_LIT(KDollarDat,"$DAT");
sl@0
    24
sl@0
    25
/********************************************
sl@0
    26
 * Process
sl@0
    27
 ********************************************/
sl@0
    28
void DMemModelProcess::Destruct()
sl@0
    29
	{
sl@0
    30
	DProcess::Destruct();
sl@0
    31
	}
sl@0
    32
sl@0
    33
TInt DMemModelProcess::NewChunk(DChunk*& aChunk, SChunkCreateInfo& aInfo, TLinAddr& aRunAddr)
sl@0
    34
	{
sl@0
    35
	aChunk=NULL;
sl@0
    36
	DMemModelChunk* pC=new DMemModelChunk;
sl@0
    37
	if (!pC)
sl@0
    38
		return KErrNoMemory;
sl@0
    39
	pC->iChunkType=aInfo.iType;
sl@0
    40
	if (!aInfo.iGlobal && (iAttributes & DMemModelProcess::EPrivate)!=0)
sl@0
    41
		pC->iAttributes |= DMemModelChunk::EPrivate;
sl@0
    42
	pC->iOwningProcess=(aInfo.iGlobal)?NULL:this;
sl@0
    43
	TInt r=pC->Create(aInfo);
sl@0
    44
	if (r==KErrNone && (aInfo.iOperations & SChunkCreateInfo::EAdjust))
sl@0
    45
		{
sl@0
    46
		if (aInfo.iRunAddress!=0)
sl@0
    47
			pC->SetFixedAddress(aInfo.iRunAddress,aInfo.iPreallocated);
sl@0
    48
		if (aInfo.iPreallocated==0)
sl@0
    49
			{
sl@0
    50
			if (pC->iAttributes & DChunk::EDisconnected)
sl@0
    51
				{
sl@0
    52
				r=pC->Commit(aInfo.iInitialBottom,aInfo.iInitialTop-aInfo.iInitialBottom);
sl@0
    53
				}
sl@0
    54
			else if (pC->iAttributes & DChunk::EDoubleEnded)
sl@0
    55
				{
sl@0
    56
				r=pC->AdjustDoubleEnded(aInfo.iInitialBottom,aInfo.iInitialTop);
sl@0
    57
				}
sl@0
    58
			else
sl@0
    59
				{
sl@0
    60
				r=pC->Adjust(aInfo.iInitialTop);
sl@0
    61
				}
sl@0
    62
			}
sl@0
    63
		if (r==KErrNone)
sl@0
    64
			{
sl@0
    65
			aRunAddr=(TLinAddr)pC->Base();
sl@0
    66
			}
sl@0
    67
		}
sl@0
    68
	if (r==KErrNone)
sl@0
    69
		{
sl@0
    70
		pC->iDestroyedDfc = aInfo.iDestroyedDfc;
sl@0
    71
		aChunk=(DChunk*)pC;
sl@0
    72
		}
sl@0
    73
	else
sl@0
    74
		pC->Close(NULL);	// NULL since chunk can't have been added to process
sl@0
    75
	return r;
sl@0
    76
	}
sl@0
    77
sl@0
    78
TInt DMemModelProcess::DoCreate(TBool aKernelProcess, TProcessCreateInfo&)
sl@0
    79
	{
sl@0
    80
	__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess::DoCreate %O",this))
sl@0
    81
	if (aKernelProcess)
sl@0
    82
		iAttributes=ESupervisor|EPrivate;
sl@0
    83
	else
sl@0
    84
		iAttributes=0;
sl@0
    85
	return KErrNone;
sl@0
    86
	}
sl@0
    87
sl@0
    88
TInt DMemModelProcess::CreateDataBssStackArea(TProcessCreateInfo& aInfo)
sl@0
    89
	{
sl@0
    90
	__KTRACE_OPT(KPROC,Kern::Printf("DMemModelProcess::CreateDataBssStackArea %O",this));
sl@0
    91
	TInt dataBssSize=MM::RoundToBlockSize(aInfo.iTotalDataSize);
sl@0
    92
	TInt r=KErrNone;
sl@0
    93
	DMemModelCodeSeg* cs=(DMemModelCodeSeg*)iTempCodeSeg;
sl@0
    94
	if (!cs->iXIP && dataBssSize)
sl@0
    95
		{
sl@0
    96
		// only RAM loaded processes need data chunks
sl@0
    97
		// ROM processes have their .data/.bss areas reserved by ROMBUILD
sl@0
    98
		SChunkCreateInfo cinfo;
sl@0
    99
		cinfo.iGlobal=EFalse;
sl@0
   100
		cinfo.iAtt=TChunkCreate::ENormal;
sl@0
   101
		cinfo.iForceFixed=EFalse;
sl@0
   102
		cinfo.iOperations=SChunkCreateInfo::EAdjust|SChunkCreateInfo::EAdd;
sl@0
   103
		cinfo.iType=EUserData;
sl@0
   104
		cinfo.iMaxSize=dataBssSize;
sl@0
   105
		cinfo.iInitialBottom=0;
sl@0
   106
		cinfo.iInitialTop=dataBssSize;
sl@0
   107
		cinfo.iPreallocated=0;
sl@0
   108
		cinfo.iName.Set(KDollarDat);
sl@0
   109
		cinfo.iOwner=this;
sl@0
   110
		cinfo.iRunAddress=0;
sl@0
   111
		r=NewChunk((DChunk*&)iDataBssStackChunk, cinfo, iDataBssRunAddress);
sl@0
   112
		__KTRACE_OPT(KPROC,Kern::Printf("RAM process, ret=%d, data at %08x+%x",r,iDataBssRunAddress,dataBssSize));
sl@0
   113
		}
sl@0
   114
	else if (cs->iXIP)
sl@0
   115
		{
sl@0
   116
		iDataBssRunAddress=cs->RomInfo().iDataBssLinearBase;
sl@0
   117
		__KTRACE_OPT(KPROC,Kern::Printf("ROM process, data at %08x+%x",iDataBssRunAddress,dataBssSize));
sl@0
   118
		}
sl@0
   119
	return r;
sl@0
   120
	}
sl@0
   121
sl@0
   122
TInt DMemModelProcess::AddChunk(DChunk* aChunk,TBool isReadOnly)
sl@0
   123
	{
sl@0
   124
	return KErrNone;
sl@0
   125
	}
sl@0
   126
sl@0
   127
void DMemModelProcess::FinalRelease()
sl@0
   128
	{
sl@0
   129
	}
sl@0
   130
sl@0
   131
void DMemModelProcess::RemoveDllData()
sl@0
   132
//
sl@0
   133
// Call with CodeSegLock held
sl@0
   134
//
sl@0
   135
	{
sl@0
   136
	}
sl@0
   137
sl@0
   138
TInt DMemModelProcess::MapCodeSeg(DCodeSeg*)
sl@0
   139
	{
sl@0
   140
	return KErrNone;
sl@0
   141
	}
sl@0
   142
sl@0
   143
void DMemModelProcess::UnmapCodeSeg(DCodeSeg*)
sl@0
   144
	{
sl@0
   145
	}
sl@0
   146
sl@0
   147
TInt DMemModelProcess::NewShPool(DShPool*& /* aPool */, TShPoolCreateInfo& /* aInfo */)
sl@0
   148
	{
sl@0
   149
	return KErrNotSupported;
sl@0
   150
	}
sl@0
   151
sl@0
   152
TInt DThread::RawRead(const TAny* aSrc, TAny* aDest, TInt aLength, TInt aFlags, TIpcExcTrap* /*aExcTrap*/)
sl@0
   153
//
sl@0
   154
// Read from the thread's process.
sl@0
   155
// aSrc is run address of memory to read
sl@0
   156
// aDest is current address of destination
sl@0
   157
// Enter and leave with system locked
sl@0
   158
//
sl@0
   159
	{
sl@0
   160
	const TUint8* pS=(const TUint8*)aSrc;
sl@0
   161
	TUint8* pD=(TUint8*)aDest;
sl@0
   162
	TBool check=ETrue;
sl@0
   163
	while (aLength)
sl@0
   164
		{
sl@0
   165
		if (check)
sl@0
   166
			{
sl@0
   167
			if (iMState==EDead)
sl@0
   168
				return KErrDied;
sl@0
   169
			__KTRACE_OPT(KTHREAD2,Kern::Printf("DThread::Read %08x",pS));
sl@0
   170
			}
sl@0
   171
		TInt l=Min(aLength,K::MaxMemCopyInOneGo);
sl@0
   172
		memcpy(pD,pS,l);
sl@0
   173
		pD+=l;
sl@0
   174
		pS+=l;
sl@0
   175
		aLength-=l;
sl@0
   176
		if (aLength)
sl@0
   177
			check=NKern::FlashSystem();
sl@0
   178
		}
sl@0
   179
	return KErrNone;
sl@0
   180
	}
sl@0
   181
sl@0
   182
TInt DThread::RawWrite(const TAny* aDest, const TAny* aSrc, TInt aLength, TInt aFlags, DThread* anOriginatingThread, TIpcExcTrap* /*aExcTrap*/)
sl@0
   183
//
sl@0
   184
// Write to the thread's process.
sl@0
   185
// aDest is run address of memory to write
sl@0
   186
// aSrc is current address of destination
sl@0
   187
// anOriginatingThread is the thread on behalf of which this operation is performed (eg client of device driver).
sl@0
   188
// Enter and leave with system locked
sl@0
   189
//
sl@0
   190
	{
sl@0
   191
	TUint8* pD=(TUint8*)aDest;
sl@0
   192
	const TUint8* pS=(const TUint8*)aSrc;
sl@0
   193
	TBool check=ETrue;
sl@0
   194
	while (aLength)
sl@0
   195
		{
sl@0
   196
		if (check)
sl@0
   197
			{
sl@0
   198
			if (iMState==EDead)
sl@0
   199
				return KErrDied;
sl@0
   200
			__KTRACE_OPT(KTHREAD2,Kern::Printf("DThread::Write %08x",pD));
sl@0
   201
			}
sl@0
   202
		TInt l=Min(aLength,K::MaxMemCopyInOneGo);
sl@0
   203
		memcpy(pD,pS,l);
sl@0
   204
		pD+=l;
sl@0
   205
		pS+=l;
sl@0
   206
		aLength-=l;
sl@0
   207
		if (aLength)
sl@0
   208
			check=NKern::FlashSystem();
sl@0
   209
		}
sl@0
   210
	return KErrNone;
sl@0
   211
	}
sl@0
   212
sl@0
   213
#ifdef __DEBUGGER_SUPPORT__
sl@0
   214
TInt CodeModifier::SafeWriteCode(DProcess* /*aProcess*/, TLinAddr /*aAddress*/, TInt /*aSize*/, TUint /*aValue*/, void* /*aOldValue*/)
sl@0
   215
	{
sl@0
   216
	return KErrNotSupported;
sl@0
   217
	}
sl@0
   218
TInt CodeModifier::WriteCode(TLinAddr /*aAddress*/, TInt /*aSize*/, TUint /*aValue*/, void* /*aOldValue*/)
sl@0
   219
	{
sl@0
   220
	return KErrNotSupported;
sl@0
   221
	}
sl@0
   222
#endif //__DEBUGGER_SUPPORT__
sl@0
   223
sl@0
   224
TInt DThread::ReadAndParseDesHeader(const TAny* aSrc, TDesHeader& aDest)
sl@0
   225
//
sl@0
   226
// Read and parse the header of a remote descriptor.
sl@0
   227
// Enter and leave with system locked.
sl@0
   228
//
sl@0
   229
	{
sl@0
   230
	TRawDesHeader& header = (TRawDesHeader&)aDest;
sl@0
   231
	static const TUint8 LengthLookup[16]={4,8,12,8,12,0,0,0,0,0,0,0,0,0,0,0};
sl@0
   232
	const TUint32* pS=(const TUint32*)aSrc;
sl@0
   233
	if (!pS || (TInt(pS)&3)!=0)
sl@0
   234
		return KErrBadDescriptor;
sl@0
   235
	if (Kern::SafeRead(pS,&header,sizeof(TUint32)))
sl@0
   236
		return KErrBadDescriptor;
sl@0
   237
	TInt type=header[0]>>KShiftDesType8;
sl@0
   238
	TInt l=LengthLookup[type];
sl@0
   239
	if (l==0)
sl@0
   240
		return KErrBadDescriptor;
sl@0
   241
	if (l>(TInt)sizeof(TUint32) && Kern::SafeRead(pS+1,&header[1],l-sizeof(TUint32)))
sl@0
   242
		return KErrBadDescriptor;
sl@0
   243
	return K::ParseDesHeader(aSrc, header, aDest);
sl@0
   244
	}
sl@0
   245
sl@0
   246
DChunk* DThread::OpenSharedChunk(const TAny* aAddress, TBool /*aWrite*/, TInt& aOffset)
sl@0
   247
	{
sl@0
   248
	DMemModelChunk* chunk=0;
sl@0
   249
	DObjectCon& chunks=*K::Containers[EChunk];
sl@0
   250
	NKern::LockSystem();
sl@0
   251
	chunks.Lock()->Wait();
sl@0
   252
	TInt count=chunks.Count();
sl@0
   253
	TInt i;
sl@0
   254
	TUint offset=0;
sl@0
   255
	for(i=0;i<count;i++)
sl@0
   256
		{
sl@0
   257
		DMemModelChunk* pC=(DMemModelChunk*)chunks[i];
sl@0
   258
		offset = (TUint)aAddress-(TUint)pC->Base();
sl@0
   259
		if(offset<TUint(pC->iMaxSize))
sl@0
   260
			{
sl@0
   261
			chunk = pC;
sl@0
   262
			break;
sl@0
   263
			}
sl@0
   264
		}
sl@0
   265
	chunks.Lock()->Signal();
sl@0
   266
sl@0
   267
	if(!chunk)
sl@0
   268
		return 0;
sl@0
   269
sl@0
   270
	if((chunk->iChunkType!=ESharedKernelSingle && chunk->iChunkType!=ESharedKernelMultiple))
sl@0
   271
		return 0;
sl@0
   272
	if(chunk->Open()!=KErrNone)
sl@0
   273
		return 0;
sl@0
   274
	aOffset = offset;
sl@0
   275
	return chunk;
sl@0
   276
	}
sl@0
   277
sl@0
   278
TInt DThread::PrepareMemoryForDMA(const TAny* aLinAddr, TInt aSize, TPhysAddr* aPhysicalPageList)
sl@0
   279
	{
sl@0
   280
	return KErrNotSupported;
sl@0
   281
	}
sl@0
   282
sl@0
   283
TInt DThread::ReleaseMemoryFromDMA(const TAny* aLinAddr, TInt aSize, TPhysAddr* aPhysicalPageList)
sl@0
   284
	{
sl@0
   285
	return KErrNotSupported;
sl@0
   286
	}
sl@0
   287