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". |
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 = ¤t; |
|
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 |