kerneltest/e32test/dmav2/d_dma2_cmn.cpp
changeset 139 95f71bcdcdb7
parent 36 538db54a451d
child 199 189ece41fa29
equal deleted inserted replaced
109:b3a1d9898418 139:95f71bcdcdb7
     1 /*
     1 /*
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
   131 		{
   131 		{
   132 	case NKern::EThread:
   132 	case NKern::EThread:
   133 		return EThread;
   133 		return EThread;
   134 	case NKern::EInterrupt:
   134 	case NKern::EInterrupt:
   135 		return EIsr;
   135 		return EIsr;
   136 	case NKern::EIDFC: //fall-through
   136 	//Fall-through: If context is IDFC or the EEscaped marker occur
       
   137 	//it is an error
       
   138 	case NKern::EIDFC:
   137 	case NKern::EEscaped:
   139 	case NKern::EEscaped:
   138 	default:
   140 	default:
   139 		return EInvalid;
   141 		return EInvalid;
   140 		}
   142 		}
   141 #else
   143 #else
   173 	{}
   175 	{}
   174 
   176 
   175 TAddrRange::TAddrRange(TUint aStart, TUint aLength)
   177 TAddrRange::TAddrRange(TUint aStart, TUint aLength)
   176 	:iStart(aStart), iLength(aLength)
   178 	:iStart(aStart), iLength(aLength)
   177 	{
   179 	{
   178 	TEST_ASSERT(iLength > 0);
       
   179 	}
   180 	}
   180 
   181 
   181 TBool TAddrRange::Contains(TAddrRange aRange) const
   182 TBool TAddrRange::Contains(TAddrRange aRange) const
   182 	{
   183 	{
   183 	return Contains(aRange.Start()) && Contains(aRange.End());
   184 	return Contains(aRange.Start()) && Contains(aRange.End());
   186 TBool TAddrRange::Overlaps(const TAddrRange& aRange) const
   187 TBool TAddrRange::Overlaps(const TAddrRange& aRange) const
   187 	{
   188 	{
   188 	return (aRange.Contains(iStart) || aRange.Contains(End()) ||
   189 	return (aRange.Contains(iStart) || aRange.Contains(End()) ||
   189 			Contains(aRange.Start()) || Contains(aRange.End()));
   190 			Contains(aRange.Start()) || Contains(aRange.End()));
   190 	}
   191 	}
       
   192 
       
   193 TBool TAddrRange::IsFilled(TUint8 aValue) const
       
   194 	{
       
   195 	TUint8* buffer = reinterpret_cast<TUint8*>(iStart);
       
   196 	for(TUint i = 0; i < iLength; i++)
       
   197 		{
       
   198 		if(buffer[i] != aValue)
       
   199 			return EFalse;
       
   200 		}
       
   201 	return ETrue;
       
   202 	}
       
   203 
   191 /**
   204 /**
   192 If addresses have been left as KPhysAddrInvalid or the count as 0
   205 If addresses have been left as KPhysAddrInvalid or the count as 0 (ie. the
   193 (ie. the default values used for IsrRedoRequest)
   206 default values used for IsrRedoRequest) then substitute the values from
   194 then substitute the values from aTransferArgs.
   207 aTransferArgs.
   195 */
   208 */
   196 void TAddressParms::Substitute(const TDmaTransferArgs& aTransferArgs)
   209 void TAddressParms::Substitute(const TDmaTransferArgs& aTransferArgs)
   197 	{
   210 	{
       
   211 	Substitute(GetAddrParms(aTransferArgs));
       
   212 	}
       
   213 
       
   214 /**
       
   215 If addresses have been left as KPhysAddrInvalid or the count as 0 (ie. the
       
   216 default values used for IsrRedoRequest) then substitute the values from
       
   217 aTransferArgs.
       
   218 */
       
   219 void TAddressParms::Substitute(const TAddressParms& aAddrParams)
       
   220 	{
   198 	if(iSrcAddr == KPhysAddrInvalidUser)
   221 	if(iSrcAddr == KPhysAddrInvalidUser)
   199 		iSrcAddr = aTransferArgs.iSrcConfig.iAddr;
   222 		iSrcAddr = aAddrParams.iSrcAddr;
   200 
   223 
   201 	if(iDstAddr == KPhysAddrInvalidUser)
   224 	if(iDstAddr == KPhysAddrInvalidUser)
   202 		iDstAddr = aTransferArgs.iDstConfig.iAddr;
   225 		iDstAddr = aAddrParams.iDstAddr;
   203 
   226 
   204 	if(iTransferCount == 0)
   227 	if(iTransferCount == 0)
   205 		iTransferCount = aTransferArgs.iTransferCount;
   228 		iTransferCount = aAddrParams.iTransferCount;
   206 	}
   229 	}
   207 
   230 
   208 /**
   231 /**
   209 Addresses are converted into absolute,
   232 Addresses are converted into absolute,
   210 addresses (virtual in user mode, physical in kernel)
   233 addresses (virtual in user mode, physical in kernel)
   291 	}
   314 	}
   292 
   315 
   293 TAddrRange TAddressParms::DestRange() const
   316 TAddrRange TAddressParms::DestRange() const
   294 	{
   317 	{
   295 	return TAddrRange(iDstAddr, iTransferCount);
   318 	return TAddrRange(iDstAddr, iTransferCount);
       
   319 	}
       
   320 
       
   321 void TAddressParms::MakePhysical()
       
   322 	{
       
   323 #ifdef __KERNEL_MODE__
       
   324 	iSrcAddr = Epoc::LinearToPhysical(iSrcAddr);
       
   325 	TEST_ASSERT(iSrcAddr != KPhysAddrInvalid);
       
   326 	iDstAddr = Epoc::LinearToPhysical(iDstAddr);
       
   327 	TEST_ASSERT(iDstAddr != KPhysAddrInvalid);
       
   328 #else
       
   329 	TEST_FAULT;
       
   330 #endif
   296 	}
   331 	}
   297 
   332 
   298 void SetAddrParms(TDmaTransferArgs& aTransferArgs, const TAddressParms& aAddrParams)
   333 void SetAddrParms(TDmaTransferArgs& aTransferArgs, const TAddressParms& aAddrParams)
   299 	{
   334 	{
   300 	aTransferArgs.iSrcConfig.iAddr = aAddrParams.iSrcAddr;
   335 	aTransferArgs.iSrcConfig.iAddr = aAddrParams.iSrcAddr;
   309 	iIndex++;
   344 	iIndex++;
   310 	iCount--;
   345 	iCount--;
   311 	return args;
   346 	return args;
   312 	}
   347 	}
   313 
   348 
   314 
       
   315 void TIsrRequeArgsSet::Substitute(const TDmaTransferArgs& aTransferArgs)
   349 void TIsrRequeArgsSet::Substitute(const TDmaTransferArgs& aTransferArgs)
   316 	{
   350 	{
       
   351 	TAddressParms initial(aTransferArgs);
       
   352 
       
   353 	//if on user side it is assumed that aTransferArgs addresses will be offset
       
   354 	//based (from a virtual address). In kernel mode it is expected that address
       
   355 	//will be absolute virtual addresses, and must therefore be made physical
       
   356 #ifdef __KERNEL_MODE__
       
   357 	initial.MakePhysical();
       
   358 #endif
       
   359 
       
   360 	const TAddressParms* previous = &initial;
       
   361 
   317 	for(TInt i=0; i<iCount; i++)
   362 	for(TInt i=0; i<iCount; i++)
   318 		{
   363 		{
   319 		iRequeArgs[i].Substitute(aTransferArgs);
   364 		TAddressParms& current = iRequeArgs[i];
   320 		}
   365 		current.Substitute(*previous);
   321 	}
   366 		previous = &current;
       
   367 		}
       
   368 	}
       
   369 
   322 void TIsrRequeArgsSet::Fixup(TLinAddr aChunkBase)
   370 void TIsrRequeArgsSet::Fixup(TLinAddr aChunkBase)
   323 	{
   371 	{
   324 	for(TInt i=0; i<iCount; i++)
   372 	for(TInt i=0; i<iCount; i++)
   325 		{
   373 		{
   326 		iRequeArgs[i].Fixup(aChunkBase);
   374 		iRequeArgs[i].Fixup(aChunkBase);
   327 		}
   375 		}
   328 	}
   376 	}
       
   377 
       
   378 /** Check that both source and destination of ISR reque args will lie within the
       
   379 range specified by aStart and aSize.
       
   380 
       
   381 @param aStart The linear base address of the region
       
   382 @param aSize The size of the region
       
   383 */
       
   384 TBool TIsrRequeArgs::CheckRange(TLinAddr aStart, TUint aSize) const
       
   385 	{
       
   386 	TUint chunkStart = 0;
       
   387 #ifdef __KERNEL_MODE__
       
   388 	chunkStart = Epoc::LinearToPhysical(aStart);
       
   389 	TEST_ASSERT(chunkStart != KPhysAddrInvalid);
       
   390 #else
       
   391 	chunkStart = aStart;
       
   392 #endif
       
   393 
       
   394 	// If an address is still KPhysAddrInvalid it means the arguments haven't
       
   395 	// yet been substituted
       
   396 	TAddrRange chunk(chunkStart, aSize);
       
   397 	TBool sourceOk = (iSrcAddr != KPhysAddrInvalid) && chunk.Contains(SourceRange());
       
   398 
       
   399 	TBool destOk = (iDstAddr != KPhysAddrInvalid) && chunk.Contains(DestRange());
       
   400 
       
   401 	TBool ok = sourceOk && destOk;
       
   402 	if(!ok)
       
   403 		{
       
   404 		PRINTF(("Error, re-queue args: "));
       
   405 		TBuf<128> buf;
       
   406 		AppendString(buf);
       
   407 		PRINTF(("%S", &buf));
       
   408 		PRINTF(("overflow buffer base=0x%08x, size=0x%08x", chunkStart, aSize));
       
   409 		}
       
   410 	return ok;
       
   411 	}
       
   412 
       
   413 TBool TIsrRequeArgsSet::CheckRange(TLinAddr aAddr, TUint aSize) const
       
   414 	{
       
   415 	for(TInt i=0; i<iCount; i++)
       
   416 		{
       
   417 		if(!iRequeArgs[i].CheckRange(aAddr, aSize))
       
   418 			return EFalse;
       
   419 		}
       
   420 	return ETrue;
       
   421 	}
       
   422 
       
   423 TBool TIsrRequeArgsSet::CheckRange(TLinAddr aAddr, TUint aSize, const TDmaTransferArgs& aInitialParms) const
       
   424 	{
       
   425 	// apply substitution, without modifying the original
       
   426 	TIsrRequeArgsSet copy(*this);
       
   427 	copy.Substitute(aInitialParms);
       
   428 
       
   429 	return copy.CheckRange(aAddr, aSize);
       
   430 	}
       
   431