Update contrib.
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
24 #include <kernel/kern_priv.h>
25 #include "cryptodriver.h"
27 #include <omap_hrp/assp/shared/omap_reg.h>
28 #include <omap_hrp/assp/shared/omap_interrupt.h>
30 #include "cryptoh4aes.h"
35 #warning "h/w disabled"
40 LOCAL_D void dumpBuffer(const char *aName, TUint32 *aBuf, TUint32 aLen);
42 #define dumpBuffer(aName, aBuf, aLen)
45 CryptoH4JobAes::CryptoH4JobAes(DLddChanAes &aLddChanAes)
46 : iLddChanAes(aLddChanAes),
49 iSwWriteByteOffset(0),
57 iFakeDmaToHwQueued(0),
58 iFakeDmaFromHwQueued(0),
60 iDmaToHwCompleteDfc(DmaToHwCompleteDfc, this, 1), // DFC is priority '1'
61 iDmaFromHwCompleteDfc(DmaFromHwCompleteDfc, this, 1)
63 TRACE_FUNCTION("CryptoH4JobAes");
66 CryptoH4JobAes::~CryptoH4JobAes()
68 TRACE_FUNCTION("~CryptoH4JobAes");
73 void CryptoH4JobAes::SetDfcQ(TDfcQue *aDfcQue)
75 TRACE_FUNCTION("SetDfcQ");
76 iDmaToHwCompleteDfc.SetDfcQ(aDfcQue);
77 iDmaFromHwCompleteDfc.SetDfcQ(aDfcQue);
80 TUint8 *CryptoH4JobAes::GetKeyBuffer()
82 TRACE_FUNCTION("GetKeyBuffer");
83 return (TUint8 *) &iKey;
86 TUint8 *CryptoH4JobAes::GetIVBuffer()
88 TRACE_FUNCTION("GetIVBuffer");
89 return (TUint8 *) &iIV;
92 TUint32 CryptoH4JobAes::MaxBytes() const
94 TRACE_FUNCTION("MaxBytes");
95 return sizeof(iAesBuffer); // return size in bytes
98 TUint8 *CryptoH4JobAes::GetIOBuffer()
100 TRACE_FUNCTION("GetIOBuffer");
101 return (TUint8 *) &iAesBuffer;
104 void CryptoH4JobAes::GetToPddBuffer(TUint8 * &aBuf, TUint32 &aBufLen, TBool &aMore)
106 TRACE_FUNCTION("GetToPddBuffer");
108 TUint8 *p = (TUint8 *) iAesBuffer;
109 aBuf = &p[iSwWriteByteOffset];
111 if(iSwReadByteOffset > iSwWriteByteOffset)
113 // Available buffer is contiguous
114 aBufLen = iSwReadByteOffset - iSwWriteByteOffset;
115 if(aBufLen) --aBufLen; // Never use all space to stop index collision
121 // Available data crosses buffer end so return two regions
122 // OR indexes are equal
123 aBufLen = sizeof(iAesBuffer) - iSwWriteByteOffset;
124 if(iSwReadByteOffset == 0)
126 // Do not fill to end of buffer because index would wrap and collid
131 aMore = (iSwReadByteOffset != iSwWriteByteOffset); // Another region to read
137 void CryptoH4JobAes::BytesWrittenToPdd(TUint32 aBytes)
139 TRACE_FUNCTION("BytesWrittenToPdd");
141 iSwWriteByteOffset += aBytes;
142 if(iSwWriteByteOffset >= sizeof(iAesBuffer))
144 iSwWriteByteOffset -= sizeof(iAesBuffer);
150 void CryptoH4JobAes::GetFromPddBuffer(TUint8 * &aBuf, TUint32 &aBufLen, TBool &aMore)
152 TRACE_FUNCTION("GetFromPddBuffer");
154 TInt hwWrite8Index = iHwWriteIndex * 4;
155 TUint8 *p = (TUint8 *) iAesBuffer;
156 aBuf = &p[iSwReadByteOffset];
158 TInt len = hwWrite8Index - iSwReadByteOffset;
166 // Wrap round condition, but can only return contiguous bytes
167 aBufLen = sizeof(iAesBuffer) - iSwReadByteOffset;
168 aMore = (hwWrite8Index != 0);
173 void CryptoH4JobAes::BytesReadFromPdd(TUint32 aBytes)
175 TRACE_FUNCTION("BytesReadFromPdd");
177 iSwReadByteOffset += aBytes;
178 if(iSwReadByteOffset >= sizeof(iAesBuffer))
180 iSwReadByteOffset -= sizeof(iAesBuffer);
183 iReadRequestLength -= aBytes;
188 TInt CryptoH4JobAes::SetDetails(DCryptoJobScheduler *aJobScheduler,
189 MCryptoJobCallbacks *aCallbacks,
191 TInt aKeyLengthBytes,
192 RCryptoDriver::TChainingMode aMode)
194 TRACE_FUNCTION("TChainingMode");
195 // Kern::Printf("AES Details %s: Key len %d, Mode %s (%d)",
196 // aEncrypt?"Encrypt":"Decrypt", aKeyLengthBytes, (aMode == RCryptoDriver::ECbcMode)?"CBC":"ECB", aMode);
198 if(State() != ECreated)
203 iJobScheduler = aJobScheduler;
204 iCallbacks = aCallbacks;
206 iKeyLengthBytes = aKeyLengthBytes;
208 if((aMode != RCryptoDriver::EEcbMode) && (aMode != RCryptoDriver::ECbcMode))
213 if(iMode == RCryptoDriver::ECbcMode)
215 // For CBC we need to save the IV incase we need to
216 // re-initialise the h/w mid-job
221 // For encryption - DoSaveState saves the last encrypted
222 // block. We set this to the IV to handle the case where
223 // we do not encrypt any blocks before being suspended.
225 to = &iAesBuffer[((sizeof(iAesBuffer)-16)/4)];
229 // For decryption - MaybeSetupWriteDmaToHw maintains
230 // iSavedState as a copy of the last ciphertext
231 // (pre-decryption) so DoSaveState does not need to do
234 // To cover the case where we do not decrypt any blocks
235 // before being suspended, we initialise iSavedState to the IV.
237 to = &iSavedState[0];
246 dumpBuffer("SetDetails - end of iAesBuffer", to-4, 4);
250 dumpBuffer("SetDetails - iSavedState", iSavedState, 4);
255 iSwWriteByteOffset = 0;
258 iSwReadByteOffset = 0;
263 void CryptoH4JobAes::DoSlice(TBool aFirstSlice)
265 TRACE_FUNCTION("DoSlice");
266 // Kern::Printf("DoSlice %s", aFirstSlice?"FIRST":"");
272 // Push any available data to user
273 TInt r = iCallbacks->DataAvailable();
276 iJobScheduler->JobComplete(this,r);
279 // Read available data from user
280 r = iCallbacks->DataRequired();
283 iJobScheduler->JobComplete(this,r);
287 // Setup to read data (if enough is available).
288 // Kern::Printf("DoSlice - calling MaybeSetupWriteDmaToHw");
289 MaybeSetupWriteDmaToHw();
293 if(!iDmaToHwPending && !iDmaFromHwPending)
301 TBool CryptoH4JobAes::DoSaveState()
303 TRACE_FUNCTION("DoSaveState");
305 if((iMode == RCryptoDriver::ECbcMode) && iEncrypt)
307 // Doing CBC encryption - Need to save a copy of the last
308 // ciphertext block (after encryption) so we can use it as the
309 // IV if we are later resumed.
311 // Last block processed by h/w just BEFORE iHwWriteIndex. If
312 // we have not processed any data, then SetDetails will have
313 // initialised this to the IV
314 TInt32 fromIndex = (iHwWriteIndex!=0) ? (iHwWriteIndex-4) : ((sizeof(iAesBuffer)-16)/4);
315 TUint32 *from = &iAesBuffer[fromIndex];
316 TUint32 *to = &iSavedState[0];
321 dumpBuffer("DoSaveState - iSavedState", iSavedState, 4);
325 return ETrue; // We want DoRestoreState to be called
328 void CryptoH4JobAes::DoRestoreState()
330 TRACE_FUNCTION("DoRestoreState");
334 void CryptoH4JobAes::DoReleaseHw()
336 TRACE_FUNCTION("DoReleaseHw");
339 // Cancel DFCs - Doesn't work for FAKE_DMA case....
340 iDmaToHwCompleteDfc.Cancel();
341 iDmaFromHwCompleteDfc.Cancel();
345 void CryptoH4JobAes::MaybeSetupWriteDmaToHw()
347 TRACE_FUNCTION("MaybeSetupWriteDmaToHw");
350 // Calculate space between H/W read index and S/W write index or end of buffer
351 TInt hwReadIndex8 = iHwReadIndex*4;
352 TInt avail = (iSwWriteByteOffset >= hwReadIndex8) ? (iSwWriteByteOffset - hwReadIndex8) : (sizeof(iAesBuffer) - hwReadIndex8);
356 // At least another block of data is available.
357 if((avail <= 31) && (iMode == RCryptoDriver::ECbcMode) && !iEncrypt)
359 // Only one complete block is available
361 // Doing CBC decryption, so need to save a copy of the
362 // last ciphertext block (before it is decrypted) so we
363 // can use it as the IV if we are kicked off the h/w
364 // and have to reconfigure.
365 // Last block available for h/w is at hwReadIndex8
366 TUint32 *from = &iAesBuffer[iHwReadIndex];
367 TUint32 *to = &iSavedState[0];
372 dumpBuffer("MaybeSetupWriteDmaToHw - iSavedState", iSavedState, 4);
374 SetupDma((TUint32)&iAesBuffer[iHwReadIndex], ETrue);
381 void CryptoH4JobAes::FakeDma()
383 TRACE_FUNCTION("FakeDma");
384 if(iFakeDmaToHwQueued < iDmaToHwPending)
386 // Calculate number of 32 bit values in the h/w
387 TInt inHw32 = iHwReadIndex - iHwWriteIndex;
390 inHw32 += sizeof(iAesBuffer)/sizeof(iAesBuffer[0]);
392 // Convert to number of 16 byte blocks in h/w
393 TInt inHwBlocks = inHw32/4;
395 if((inHwBlocks + iFakeDmaToHwQueued) < 2)
397 // Pipeline is not full, so the next DMA to complete would be a "to h/w"
398 // Wait for h/w to be ready
400 // Kern::Printf("CryptoH4JobAes::FakeDma - Start waiting for h/w input ready (%x)", TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL));
401 while(! (TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL) & KHtAesCtrlInputReady))
403 Kern::Printf("CryptoH4JobAes::FakeDma - Waiting for h/w input ready (%x)", TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL));
406 // Queue the fake "to dma" complete DFC
407 iDmaToHwCompleteDfc.Enque();
408 ++iFakeDmaToHwQueued;
413 // Either pipeline is full, or we are out of input data.
416 if(iFakeDmaFromHwQueued < iDmaFromHwPending)
419 // Kern::Printf("CryptoH4JobAes::FakeDma - Start waiting for output ready (%x)", TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL));
420 while(! (TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL) & KHtAesCtrlOutputReady))
422 Kern::Printf("CryptoH4JobAes::FakeDma - waiting for output ready (%x)",TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL));
425 // Queue the fake "from dma" complete DFC
426 iDmaFromHwCompleteDfc.Enque();
427 ++iFakeDmaFromHwQueued;
438 void CryptoH4JobAes::SetupHw(TBool aUseSavedState)
440 TRACE_FUNCTION("SetupHw");
441 // Kern::Printf("SetupHw");
445 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_MASK, KHtAesMaskAutoIdle);
447 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_MASK,
448 KHtAesMaskDmaReqIn | KHtAesMaskDmaReqOut | KHtAesMaskAutoIdle);
450 iHwRunning = EFalse; // Previous MASK register write cleared the start bit.
455 ctrl |= KHtAesCtrlDirection;
458 switch(iKeyLengthBytes)
462 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY1_L, iKey[0]);
463 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY1_H, iKey[1]);
464 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY2_L, iKey[2]);
465 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY2_H, iKey[3]);
466 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY3_L, iKey[4]);
467 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY3_H, iKey[5]);
468 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY4_L, iKey[6]);
469 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY4_H, iKey[7]);
470 ctrl |= KHtAesCtrlKeySize256;
474 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY1_L, iKey[0]);
475 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY1_H, iKey[1]);
476 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY2_L, iKey[2]);
477 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY2_H, iKey[3]);
478 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY3_L, iKey[4]);
479 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY3_H, iKey[5]);
480 ctrl |= KHtAesCtrlKeySize192;
484 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY1_L, iKey[0]);
485 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY1_H, iKey[1]);
486 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY2_L, iKey[2]);
487 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_KEY2_H, iKey[3]);
488 ctrl |= KHtAesCtrlKeySize128;
495 if(iMode == RCryptoDriver::ECbcMode)
499 // Kern::Printf("Setting IV");
501 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_IV_1, iIV[0]);
502 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_IV_2, iIV[1]);
503 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_IV_3, iIV[2]);
504 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_IV_4, iIV[3]);
505 dumpBuffer("SetupHw(EFalse) - iIV", iIV, 4);
509 // Set IV to saved state
510 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_IV_1, iSavedState[0]);
511 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_IV_2, iSavedState[1]);
512 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_IV_3, iSavedState[2]);
513 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_IV_4, iSavedState[3]);
514 dumpBuffer("SetupHw(ETrue) - iSavedState", iSavedState, 4);
517 ctrl |= KHsAesCtrlCBC;
521 // Kern::Printf("Setting crtl to %x", ctrl);
522 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_CTRL, ctrl);
524 // AES_MASK START bit to start DMA
525 // This is done by SetupDma
527 (void)aUseSavedState;
532 void CryptoH4JobAes::SetupDma(TUint32 aPtr, TBool aToHw)
534 TRACE_FUNCTION("SetupDma");
535 // Kern::Printf("\t\tSetupDMA - %s, iHwReadIndex %d iHwWriteIndex %d",
536 // aToHw?"toHw":"fromHw", iHwReadIndex, iHwWriteIndex);
540 // Kern::Printf("SetupDma - starting h/w");
542 // If h/w is not enabled yet, then set the start bit. This is
543 // required even when NOT using DMA...
544 TUint32 mask = TOmap::Register32(KHwBaseAesReg + KHoAES_MASK);
545 // Kern::Printf("mask is %x", mask);
546 mask |= KHtDesMaskDmaReqStart;
547 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_MASK, mask);
548 // Kern::Printf("changed to %x", TOmap::Register32(KHwBaseAesReg + KHoAES_MASK));
569 void CryptoH4JobAes::StopHw()
571 TRACE_FUNCTION("StopHw");
574 TUint32 mask = TOmap::Register32(KHwBaseAesReg + KHoAES_MASK);
575 mask &= ~KHtDesMaskDmaReqStart;
576 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_MASK, mask);
584 Called when the current h/w opperation is complete
586 void CryptoH4JobAes::DmaComplete(DDmaRequest::TResult aResult, TAny *aPtr)
588 TRACE_FUNCTION("TResult");
590 // Queue our DFC to action the DMA complete notification in our thread.
591 reinterpret_cast<TDfc *>(aPtr)->Enque();
597 void CryptoH4JobAes::DmaToHwCompleteDfc(TAny* aPtr)
599 ((CryptoH4JobAes*)aPtr)->DoDmaToHwCompleteDfc();
603 void CryptoH4JobAes::DoDmaToHwCompleteDfc()
605 TRACE_FUNCTION("DoDmaToHwCompleteDfc");
606 // Kern::Printf("**DoDmaToHwCompleteDfc iHwReadIndex %d, iHwWriteIndex %d",iHwReadIndex, iHwWriteIndex);
608 if(iDmaToHwPending < 0) Kern::Fault("DoDmaToHwCompleteDfc - iDmaToHwPending is negative",1);
611 --iFakeDmaToHwQueued;
612 if(iFakeDmaToHwQueued < 0) Kern::Fault("DoDmaToHwCompleteDfc - iFakeDmaToHwQueued is negative",2);
618 if(! (TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL) & KHtAesCtrlInputReady))
620 Kern::Fault("DoDmaToHwCompleteDfc - h/w not ready for input!",3);
622 // Kern::Printf("DoDmaToHwCompleteDfc - Writing data into h/w index %d (%x)", iHwReadIndex, TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL));
623 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_DATA_1, iAesBuffer[iHwReadIndex]);
624 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_DATA_2, iAesBuffer[iHwReadIndex+1]);
625 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_DATA_3, iAesBuffer[iHwReadIndex+2]);
626 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_DATA_4, iAesBuffer[iHwReadIndex+3]);
629 // Update index to point at next block to be passed to the h/w
630 iHwReadIndex += 4; // 4x32bit == 16bytes == block length
631 if(iHwReadIndex == sizeof(iAesBuffer)/sizeof(TUint32))
636 if(!iDmaFromHwPending)
638 SetupDma((TUint32)&iAesBuffer[iHwWriteIndex], EFalse);
643 // Setup to read data (if enough is available).
644 MaybeSetupWriteDmaToHw();
649 void CryptoH4JobAes::DmaFromHwCompleteDfc(TAny* aPtr)
651 ((CryptoH4JobAes*)aPtr)->DoDmaFromHwCompleteDfc();
655 void CryptoH4JobAes::DoDmaFromHwCompleteDfc()
657 TRACE_FUNCTION("DoDmaFromHwCompleteDfc");
658 // Kern::Printf("**DoDmaFromHwCompleteDfc iHwReadIndex %d, iHwWriteIndex %d", iHwReadIndex, iHwWriteIndex);
661 if(iDmaFromHwPending < 0) Kern::Fault("DoDmaFromHwCompleteDfc - iDmaFromHwPending is negative",1);
664 --iFakeDmaFromHwQueued;
665 if(iFakeDmaFromHwQueued < 0) Kern::Fault("iFakeDmaFromHwQueued - iFakeDmaFromHwQueued is negative",2);
671 if(! (TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL) & KHtAesCtrlOutputReady))
673 Kern::Fault("DoDmaToHwCompleteDfc - h/w not ready for output!",3);
676 // Kern::Printf("DoDmaFromHwCompleteDfc - Reading data from h/w index %d (%x)", iHwWriteIndex, TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL));
677 iAesBuffer[iHwWriteIndex] = TOmap::Register32(KHwBaseAesReg + KHoAES_DATA_1);
678 iAesBuffer[iHwWriteIndex+1] = TOmap::Register32(KHwBaseAesReg + KHoAES_DATA_2);
679 iAesBuffer[iHwWriteIndex+2] = TOmap::Register32(KHwBaseAesReg + KHoAES_DATA_3);
680 iAesBuffer[iHwWriteIndex+3] = TOmap::Register32(KHwBaseAesReg + KHoAES_DATA_4);
683 // Update index to point at next block to be read from the h/w
684 iHwWriteIndex += 4; // 4x32bit == 16bytes == block length
685 if(iHwWriteIndex == sizeof(iAesBuffer)/sizeof(TUint32))
694 TInt hwWrite8Index = iHwWriteIndex * 4;
695 TInt hwRead8Index = iHwReadIndex * 4;
697 // Check if we either have enough data to finish the current LDD
698 // user read request, or if we are running out of space
700 // Calculate data available for xfer to user
701 TInt availableForUser = hwWrite8Index - iSwReadByteOffset;
702 if(availableForUser < 0)
704 availableForUser += sizeof(iAesBuffer);
707 if((availableForUser >= sizeof(iAesBuffer) - 32) ||
708 (availableForUser >= iReadRequestLength))
710 // Pass available data to user
711 TInt r = iCallbacks->DataAvailable();
714 iJobScheduler->JobComplete(this,r);
719 // Are we running short of data?
720 TInt availableForHw = iSwWriteByteOffset - hwRead8Index;
721 if(availableForHw < 0)
723 availableForHw += sizeof(iAesBuffer);
726 if(availableForHw < 16)
728 TInt r = iCallbacks->DataRequired();
731 iJobScheduler->JobComplete(this,r);
736 // Kick off a new to h/w DMA if one is not already running
737 MaybeSetupWriteDmaToHw();
739 // Current h/w -> iAesBuffer DMA request has completed
740 if(iHwWriteIndex != iHwReadIndex)
742 SetupDma((TUint32)&iAesBuffer[iHwWriteIndex], EFalse);
745 if(!iDmaToHwPending && ! iDmaFromHwPending)
747 // Kern::Printf("\t\tDoDmaFromHwCompleteDfc STALLED (underrun), iHwReadIndex %d iHwWriteIndex %d",
748 // iHwReadIndex, iHwWriteIndex);
749 // Run out of data to process!
750 // Tell the scheduler that we are stalled & therefore this slice is done
761 void CryptoH4JobAes::CheckIndexes() const
763 TRACE_FUNCTION("CheckIndexes");
764 if(iSwWriteByteOffset < 0 || iSwWriteByteOffset > sizeof(iAesBuffer)) Kern::Fault("CryptoH4JobAes::checkIndexes", 1);
766 if(iHwReadIndex < 0 || iHwReadIndex > sizeof(iAesBuffer)/sizeof(iAesBuffer[0])) Kern::Fault("CryptoH4JobAes::checkIndexes", 2);
768 if(iHwWriteIndex < 0 || iHwWriteIndex > sizeof(iAesBuffer)/sizeof(iAesBuffer[0])) Kern::Fault("CryptoH4JobAes::checkIndexes", 3);
770 if(iSwReadByteOffset < 0 || iSwReadByteOffset > sizeof(iAesBuffer)) Kern::Fault("CryptoH4JobAes::checkIndexes", 4);
773 TInt32 d = iSwWriteByteOffset;
774 TInt32 c = iHwReadIndex * 4;
775 TInt32 b = iHwWriteIndex * 4;
776 TInt32 a = iSwReadByteOffset;
778 // Kern::Printf("%d %d %d %d", a, b, c, d);
781 if(b < a) offset = sizeof(iAesBuffer);
783 if(c < b) offset = sizeof(iAesBuffer);
785 if(d < c) offset = sizeof(iAesBuffer);
788 if(a>b) Kern::Fault("CryptoH4JobAes::CheckIndexes", 5);
789 if(b>c) Kern::Fault("CryptoH4JobAes::CheckIndexes", 6);
790 if(c>d) Kern::Fault("CryptoH4JobAes::CheckIndexes", 7);
794 void CryptoH4JobAes::NotifyReadRequestLength(TUint32 aReadRequestLength)
796 TRACE_FUNCTION("NotifyReadRequestLength");
797 iReadRequestLength = aReadRequestLength;
803 This function uses 100% of the CPU power to attempt to drive
804 the AES h/w as fast as possible.
806 This will give some indication of the maximum achievable speed of the h/w
807 excluding the overhead of (almost all of) the driver framework.
809 void CryptoH4JobAes::HwPerfCheck()
811 TRACE_FUNCTION("HwPerfCheck");
816 TUint32 mask = TOmap::Register32(KHwBaseAesReg + KHoAES_MASK);
817 mask |= KHtDesMaskDmaReqStart;
818 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_MASK, mask);
822 iSwWriteByteOffset = 0;
825 iSwReadByteOffset = 0;
828 iCallbacks->DataRequired();
830 while(iHwWriteIndex*4 < iSwWriteByteOffset)
833 // Kern::Printf("Ctrl %08x", TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL));
835 // Have we got more data to write to h/w?
836 if(iHwReadIndex < iSwWriteByteOffset/4)
838 // Yes, but is h/w ready for it?
840 if(TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL) & KHtAesCtrlInputReady)
842 // Kern::Printf("toHw iHwReadIndex=%d", iHwReadIndex);
843 // ok, write data to h/w
844 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_DATA_1, iAesBuffer[iHwReadIndex]);
845 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_DATA_2, iAesBuffer[iHwReadIndex+1]);
846 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_DATA_3, iAesBuffer[iHwReadIndex+2]);
847 TOmap::SetRegister32(KHwBaseAesReg + KHoAES_DATA_4, iAesBuffer[iHwReadIndex+3]);
854 // Do we expect more data from the h/w?
855 if(iHwWriteIndex < iSwWriteByteOffset/4)
857 // Yes, but is h/w ready?
859 if(TOmap::Register32(KHwBaseAesReg + KHoAES_CTRL) & KHtAesCtrlOutputReady)
861 // Kern::Printf("ReadHw to iHwWriteIndex=%d", iHwWriteIndex);
862 iAesBuffer[iHwWriteIndex] = TOmap::Register32(KHwBaseAesReg + KHoAES_DATA_1);
863 iAesBuffer[iHwWriteIndex+1] = TOmap::Register32(KHwBaseAesReg + KHoAES_DATA_2);
864 iAesBuffer[iHwWriteIndex+2] = TOmap::Register32(KHwBaseAesReg + KHoAES_DATA_3);
865 iAesBuffer[iHwWriteIndex+3] = TOmap::Register32(KHwBaseAesReg + KHoAES_DATA_4);
874 // Write data back to user
875 iCallbacks->DataAvailable();
882 TDfcWrapper::TDfcWrapper(const TDfcWrapper &aOrig)
883 : TDfc(DfcWrapperFunc, this, aOrig.iPriority)
885 TRACE_FUNCTION("TDfcWrapper");
886 iRealFunction = aOrig.iRealFunction,
887 iRealPtr = aOrig.iRealPtr;
888 SetDfcQ(aOrig.iDfcQ);
892 TDfcWrapper::TDfcWrapper(TDfcFn aFunction, TAny* aPtr, TInt aPriority)
893 : TDfc(DfcWrapperFunc, this, aPriority),
894 iRealFunction(aFunction),
897 TRACE_FUNCTION("TDfcWrapper");
900 void TDfcWrapper::Enque()
902 TRACE_FUNCTION("Enque");
903 // Clone self and queue the clone
904 TDfcWrapper *p = new TDfcWrapper(*this);
908 void TDfcWrapper::BaseEnque()
910 TRACE_FUNCTION("BaseEnque");
915 void TDfcWrapper::DfcWrapperFunc(TAny* aPtr)
917 TRACE_FUNCTION("DfcWrapperFunc");
918 TDfcWrapper *p = (TDfcWrapper *) aPtr;
919 p->iRealFunction(p->iRealPtr);
925 LOCAL_D void dumpBuffer(const char *aName, TUint32 *aBuf, TUint32 aLen)
927 Kern::Printf("%s =", aName);
928 TUint8 *buf8 = reinterpret_cast<TUint8 *>(aBuf);
929 for(TInt i = 0 ; i < aLen*4; ++i)
935 Kern::Printf("%02x ", buf8[i]);