Exemple #1
0
U32 static_Hash_HwPerform64bDigest(U32* pData, U32 nProcessedBytes, U32 control)
{
   /*
    * Restore the DIGCNT register first
    */
   OUTREG32(&g_pSha1Md5Reg_t->DIGCNT, nProcessedBytes);

   /*
    * Then set the register control to start the operation
    */
   OUTREG32(&g_pSha1Md5Reg_t->CTRL, control);

	if (scxPublicCryptoWaitForReadyBit((VU32 *) &g_pSha1Md5Reg_t->IRQSTAT, DIGEST_IRQSTAT_INPUT_READY_BIT) != PUBLIC_CRYPTO_OPERATION_SUCCESS) {
      return PUBLIC_CRYPTO_ERR_TIMEOUT;
   }

   /*
    * The pData buffer is a buffer of at least 64 bytes.
    * For an update operation, we are always processing a 64-bytes buffer.
    * Only the final operation might process a smaller buffer.
    * Let's make it simple, and always write all registers.
    */
   OUTREG32(&g_pSha1Md5Reg_t->DIN_0, pData[0]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_1, pData[1]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_2, pData[2]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_3, pData[3]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_4, pData[4]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_5, pData[5]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_6, pData[6]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_7, pData[7]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_8, pData[8]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_9, pData[9]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_10, pData[10]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_11, pData[11]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_12, pData[12]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_13, pData[13]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_14, pData[14]);
   OUTREG32(&g_pSha1Md5Reg_t->DIN_15, pData[15]);

   /*
    * Wait until the hash operation is finished.
    */
	if (scxPublicCryptoWaitForReadyBit((VU32 *) &g_pSha1Md5Reg_t->IRQSTAT, DIGEST_IRQSTAT_OUTPUT_READY_BIT) != PUBLIC_CRYPTO_OPERATION_SUCCESS) {
      return PUBLIC_CRYPTO_ERR_TIMEOUT;
   }

   return PUBLIC_CRYPTO_OPERATION_SUCCESS;
}
Exemple #2
0
U32 PDrvCryptoUpdateDES(PUBLIC_CRYPTO_DES_DES3_CONTEXT * pDesDes3Ctx,
                        U8 * pSrc,
                        U8 * pDest,
                        U32 nbBlocks,
                        U32 dmaUse)
{
   U32 nbr_of_blocks;
   U8 * pProcessSrc;
   U8 * pProcessDest;
   U32 vTemp;

   pProcessSrc  = pSrc;
   pProcessDest = pDest;

	if ((dmaUse == PUBLIC_CRYPTO_DMA_USE_POLLING) || (dmaUse == PUBLIC_CRYPTO_DMA_USE_IRQ)) {
      return PDrvCryptoUpdateDESWithDMA(pDesDes3Ctx, pSrc, pDest, nbBlocks, dmaUse);
   }

	for (nbr_of_blocks = 0; nbr_of_blocks < nbBlocks ; nbr_of_blocks++) {
      /* (2) : We wait for the input ready */
		if (scxPublicCryptoWaitForReadyBit((VU32 *) &g_pDESReg_t->DES_CTRL, DES_CTRL_INPUT_READY_BIT) != PUBLIC_CRYPTO_OPERATION_SUCCESS) {
         return PUBLIC_CRYPTO_ERR_TIMEOUT;
      }

      /* (3) : We copy the 8 bytes of data src->reg */
      vTemp = (U32) BYTES_TO_LONG(pProcessSrc);
      OUTREG32(&g_pDESReg_t->DES_DATA_L, vTemp);
      pProcessSrc += 4;
      vTemp = (U32) BYTES_TO_LONG(pProcessSrc);
      OUTREG32(&g_pDESReg_t->DES_DATA_H, vTemp);
      pProcessSrc += 4;

      /* (4) : We wait for the output ready */
		if (scxPublicCryptoWaitForReadyBit((VU32 *) &g_pDESReg_t->DES_CTRL, DES_CTRL_OUTPUT_READY_BIT) != PUBLIC_CRYPTO_OPERATION_SUCCESS) {
         return PUBLIC_CRYPTO_ERR_TIMEOUT;
      }

      /* (5) : We copy the 8 bytes of data reg->dest */
      vTemp = INREG32(&g_pDESReg_t->DES_DATA_L);
      LONG_TO_BYTE(pProcessDest, vTemp);
      pProcessDest += 4;
      vTemp = INREG32(&g_pDESReg_t->DES_DATA_H);
      LONG_TO_BYTE(pProcessDest, vTemp);
      pProcessDest += 4;
   }

   return PUBLIC_CRYPTO_OPERATION_SUCCESS;
}
Exemple #3
0
U32 static_Hash_HwPerformDmaDigest(U32* pData, U32 nProcessedBytes, U32 control, U32 dmaUse)
{
   U32 bufIn_phys = virt_to_phys(pData);
   U32 dma_ch0 = OMAP3430_SMC_DMA_CH_0;   /* Hard Coded Tx Data */
   SCX_DMA_CHANNEL_PARAM ch0_parameters;
   U32 returnCode = PUBLIC_CRYPTO_OPERATION_SUCCESS;
   int sizeToProcess;

   sizeToProcess = (control & 0xFFFFFFE0)>>5;

   /* Makes sure that if the dma channels that will need to be used are currently active,
   one can reprogram it (them)  */
   scxPublicDMADisableChannel(dma_ch0);

	if (dmaUse == PUBLIC_CRYPTO_DMA_USE_IRQ) {
      /* Reset DMA int (DMA CTRL) - The DMA int (INT CTRL) is reset by the OS */
      scxPublicDMADisableL3IRQ();
      scxPublicDMAClearL3IRQ();
   }

   /* DMA1: Mem -> HASH */
   ch0_parameters.data_type =   DMA_CSDP_Srce_Endian_little
      | DMA_CSDP_Srce_Endian_Lock_off
      | DMA_CSDP_Dest_Endian_little
      | DMA_CSDP_Dest_Endian_Lock_off
      | DMA_CSDP_Write_Mode_none_posted
      | DMA_CSDP_Dest_Burst_64B
      | DMA_CSDP_Dest_packed_off
      | DMA_CSDP_WR_Add_Trslt
      | DMA_CSDP_Src_Burst_64B
      | DMA_CSDP_Src_packed_off
      | DMA_CSDP_RD_Add_Trslt
      | DMA_CSDP_Data_32b;
   ch0_parameters.elem_count = DMA_CEN_Elts_per_Frame_SHA;
   ch0_parameters.frame_count = sizeToProcess / HASH_BLOCK_BYTES_LENGTH;

   ch0_parameters.src_amode = 1; /* post increment */
   ch0_parameters.src_start = bufIn_phys;
   ch0_parameters.src_ei = DMA_CSEI_Default;
   ch0_parameters.src_fi = DMA_CSFI_Default;

   ch0_parameters.dst_amode = 0; /* const */
   ch0_parameters.dst_start = DIGEST1_REGS_HW_ADDR + 0x30;
   ch0_parameters.dst_ei = DMA_CDEI_Default;
   ch0_parameters.dst_fi = DMA_CDFI_Default; /* source frame index */

   ch0_parameters.trigger = DMA_CCR_Mask_Channel(DMA_CCR_Channel_Mem2SHA);
   ch0_parameters.sync_mode = 0x2; /* FS =1, BS=0 => An entire frame is
                                      transferred once a DMA request is made */
   ch0_parameters.src_or_dst_synch = 0; /* Transfert is triggered by the Dest */

   dprintk(KERN_INFO "PDrvCryptoUpdateHASHWithDMA: scxPublicDMASetParams(ch0)\n");
   scxPublicDMASetParams(dma_ch0, &ch0_parameters);

	if (nProcessedBytes == 0) {
      // Reset the digest hw => Because DIGCNT should be reset : it's the only way to do so
      OUTREG32(&g_pSha1Md5Reg_t->MASK, DIGEST_MASK_SOFTRESET_BIT);

		if (scxPublicCryptoWaitForReadyBit((VU32 *) &g_pSha1Md5Reg_t->SYSSTATUS, DIGEST_SYSTATUS_RESET_DONE) != PUBLIC_CRYPTO_OPERATION_SUCCESS) {
         return PUBLIC_CRYPTO_ERR_TIMEOUT;
      }
   }

   dprintk(KERN_INFO "PDrvCryptoUpdateHASHWithDMA: Start DMA channel %d\n", (unsigned int)dma_ch0);

   /*
    * Set the register control to start the operation
    */
   OUTREG32(&g_pSha1Md5Reg_t->CTRL, control);


   /*
    * Set the DIGCNT register
    */
   OUTREG32(&g_pSha1Md5Reg_t->DIGCNT, nProcessedBytes);


	if (dmaUse == PUBLIC_CRYPTO_DMA_USE_IRQ) {
      scxPublicDMAEnableL3IRQ();
   }

   dprintk(KERN_INFO "PDrvCryptoUpdateHASHWithDMA: Start DMA channel %d\n", (unsigned int)dma_ch0);

   v7_dma_flush_range((int) pData, (int) pData + sizeToProcess);

   /* Start operation */
   /* Triggers operation - Interrupt, Free Running + GO (DMA on)  */
   OUTREG32(&g_pSha1Md5Reg_t->MASK,
            INREG32(&g_pSha1Md5Reg_t->MASK)|DIGEST_MASK_DMA_EN_BIT|DIGEST_MASK_IT_EN_BIT);

   scxPublicDMAStart(dma_ch0, OMAP_DMA_DROP_IRQ|OMAP_DMA_BLOCK_IRQ);

	if (dmaUse == PUBLIC_CRYPTO_DMA_USE_IRQ) {
      /* Suspends the process until the DMA IRQ occurs */
      dprintk(KERN_INFO "PDrvCryptoUpdateHASHWithDMA: Waiting for IRQ\n");
      returnCode = scxPublicDMAWait();
	} else {
      dprintk(KERN_INFO "PDrvCryptoUpdateHASHWithDMA: Polling DMA\n");
      returnCode = scxPublicDMAPoll(dma_ch0);
   }

	if (returnCode != PUBLIC_CRYPTO_OPERATION_SUCCESS) {
      dprintk(KERN_ERR "PDrvCryptoUpdateHASHWithDMA: Timeout\n");
      /* Do not exit function but clear properly the operation */
   }

	if (dmaUse == PUBLIC_CRYPTO_DMA_USE_IRQ) {
      /* Acknoledge DMA interrupt */
      scxPublicDMADisableL3IRQ();
   }

   scxPublicDMAClearChannel(dma_ch0);

   /* The dma transfert is finished, now wait until the hash operation is finished. */
	if (scxPublicCryptoWaitForReadyBit((VU32 *) &g_pSha1Md5Reg_t->IRQSTAT, DIGEST_IRQSTAT_OUTPUT_READY_BIT) != PUBLIC_CRYPTO_OPERATION_SUCCESS) {
      return PUBLIC_CRYPTO_ERR_TIMEOUT;
   }

   /* Stop clocks */
   OUTREG32(&g_pSha1Md5Reg_t->MASK,
           INREG32(&g_pSha1Md5Reg_t->MASK)&(~DIGEST_MASK_DMA_EN_BIT)&(~DIGEST_MASK_IT_EN_BIT));

    /* Clear the interrupt */
   OUTREG32(&g_pSha1Md5Reg_t->CTRL, INREG32(&g_pSha1Md5Reg_t->CTRL)&0x0000001F);/* clear length field */

   return PUBLIC_CRYPTO_OPERATION_SUCCESS;
}