From 9485d1e2ff9c713abb9db6128d7986b0ed6b976f Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 26 Dec 2018 09:00:45 +0000 Subject: Settled for a weird DMA use in this driver. Apparently it is working, it needs complete test vectors. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12484 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c | 96 ++++++++++++---------- os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h | 17 ++++ .../CRYPTO/cfg/stm32f756zg_nucleo144/mcuconf.h | 1 + ...Select ELF file)(OpenOCD, Flash and Run).launch | 2 +- testhal/STM32/multi/CRYPTO/main.c | 4 +- 5 files changed, 74 insertions(+), 46 deletions(-) diff --git a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c index 645619d84..156ed5f5f 100644 --- a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c +++ b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c @@ -71,9 +71,6 @@ static void cry_lld_serve_hash_interrupt(CRYDriver *cryp, uint32_t flags) { if ((flags & STM32_DMA_ISR_TCIF) != 0U) { /* End buffer interrupt.*/ - /* Halting processing via DMA.*/ -// HASH->CR &= ~HASH_CR_DMAE; - /* Resuming waiting thread.*/ osalSysLockFromISR(); osalThreadResumeI(&cryp->hash_tr, MSG_OK); @@ -81,6 +78,52 @@ static void cry_lld_serve_hash_interrupt(CRYDriver *cryp, uint32_t flags) { } } +/** + * @brief Pushes a series of words into the hash engine. + * + * @param[in] cryp pointer to the @p CRYDriver object + * @param[in] n the number of words to be pushed + * @param[in] p pointer to the words buffer + */ +static void cry_lld_hash_push(CRYDriver *cryp, uint32_t n, const uint32_t *p) { + + /* Data is processed in 32kB blocks because DMA size limitations.*/ + while (n > 0U) { + uint32_t chunk = n > 0x8000U ? 0x8000U : n; + n -= chunk; + +#if STM32_CRY_HASH_SIZE_THRESHOLD > 0 + if (chunk >= STM32_CRY_HASH_SIZE_THRESHOLD) +#endif + { + /* Setting up transfer.*/ + dmaStreamSetTransactionSize(cryp->dma_hash, chunk); + dmaStreamSetPeripheral(cryp->dma_hash, p); + p += chunk; + + osalSysLock(); + + /* Enabling DMA channel then HASH engine.*/ + dmaStreamEnable(cryp->dma_hash); + + /* Waiting for DMA operation completion.*/ + osalThreadSuspendS(&cryp->hash_tr); + + osalSysUnlock(); + } +#if STM32_CRY_HASH_SIZE_THRESHOLD > 0 + else { + /* Small chunk, just pushing data without touching DMA.*/ + do { + HASH->DIN = *p++; + chunk--; + } while (chunk > 0U); + } +#endif + } + +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ @@ -143,14 +186,12 @@ void cry_lld_start(CRYDriver *cryp) { dmaStreamSetMode(cryp->dma_hash, STM32_DMA_CR_CHSEL(HASH1_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_CRY_HASH1_DMA_PRIORITY) | - STM32_DMA_CR_MINC | STM32_DMA_CR_DIR_M2P | -// STM32_DMA_CR_PINC | STM32_DMA_CR_DIR_M2M | + STM32_DMA_CR_PINC | STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE); - dmaStreamSetPeripheral(cryp->dma_hash, &HASH->DIN); -// dmaStreamSetMemory0(cryp->dma_hash, &HASH->DIN); -// dmaStreamSetFIFO(cryp->dma_hash, STM32_DMA_FCR_DMDIS); + dmaStreamSetMemory0(cryp->dma_hash, &HASH->DIN); + dmaStreamSetFIFO(cryp->dma_hash, STM32_DMA_FCR_DMDIS); #if STM32_DMA_SUPPORTS_DMAMUX dmaSetRequestSource(cryp->dma_hash, STM32_DMAMUX1_HASH); #endif @@ -1160,7 +1201,7 @@ cryerror_t cry_lld_SHA256_init(CRYDriver *cryp, SHA256Context *sha256ctxp) { sha256ctxp->last_size = 0U; /* Initializing operation.*/ - HASH->CR = HASH_CR_MDMAT | HASH_CR_ALGO_1 | HASH_CR_ALGO_0 | + HASH->CR = /*HASH_CR_MDMAT |*/ HASH_CR_ALGO_1 | HASH_CR_ALGO_0 | HASH_CR_DATATYPE_1 | HASH_CR_INIT; return CRY_NOERROR; @@ -1184,6 +1225,7 @@ cryerror_t cry_lld_SHA256_init(CRYDriver *cryp, SHA256Context *sha256ctxp) { */ cryerror_t cry_lld_SHA256_update(CRYDriver *cryp, SHA256Context *sha256ctxp, size_t size, const uint8_t *in) { + const uint32_t *wp = (const uint32_t *)(const void *)in; /* This HW is unable to hash blocks that are not a multiple of 4 bytes except for the last block in the stream which is handled in the @@ -1195,43 +1237,11 @@ cryerror_t cry_lld_SHA256_update(CRYDriver *cryp, SHA256Context *sha256ctxp, /* Any unaligned data is deferred to the "final" function.*/ sha256ctxp->last_size = 8U * (size % sizeof (uint32_t)); if (sha256ctxp->last_size > 0U) { - const uint32_t *wp = (const uint32_t *)(const void *)in; sha256ctxp->last_data = wp[size / sizeof (uint32_t)]; } - /* Removing the unaligned part from the total size.*/ - size = size & ~(sizeof (uint32_t) - 1U); - - /* Data is processed in 32kB blocks because DMA size limitations.*/ - while (size > 0U) { - size_t chunk = size > 0x8000U ? 0x8000U : size; - -#if 1 - osalSysLock(); - - /* Setting up transfer.*/ - dmaStreamSetMemory0(cryp->dma_hash, in); -// dmaStreamSetPeripheral(cryp->dma_hash, in); - dmaStreamSetTransactionSize(cryp->dma_hash, chunk / sizeof (uint32_t)); - - /* Enabling DMA channel then HASH engine.*/ - dmaStreamEnable(cryp->dma_hash); - HASH->CR |= HASH_CR_DMAE; - - /* Waiting for DMA operation completion.*/ - osalThreadSuspendS(&cryp->hash_tr); - - osalSysUnlock(); -#else - const uint32_t *wp = (const uint32_t *)(const void *)in; - for (size_t i = 0; i < chunk / sizeof (uint32_t); i++) { - HASH->DIN = wp[i]; - } -#endif - - size -= chunk; - in += chunk; - } + /* Pushing data.*/ + cry_lld_hash_push(cryp, (uint32_t)(size / sizeof (uint32_t)), wp); return CRY_NOERROR; } diff --git a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h index 46201d570..509206e76 100644 --- a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h +++ b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h @@ -77,6 +77,23 @@ #if !defined(STM32_CRY_HASH1_DMA_PRIORITY) || defined(__DOXYGEN__) #define STM32_CRY_HASH1_DMA_PRIORITY 0 #endif + +/** + * @brief Minimum message size (in words) for DMA use. + * @note If set to zero then DMA is always used. + */ +#if !defined(STM32_CRY_HASH_SIZE_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_CRY_HASH_SIZE_THRESHOLD 1024 +#endif + +/** + * @brief Hash DMA error hook. + * @note The default action for DMA errors is a system halt because DMA + * error can only happen because programming errors. + */ +#if !defined(STM32_CRY_HASH_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define STM32_CRY_HASH_DMA_ERROR_HOOK(cryp) osalSysHalt("DMA failure") +#endif /** @} */ /*===========================================================================*/ diff --git a/testhal/STM32/multi/CRYPTO/cfg/stm32f756zg_nucleo144/mcuconf.h b/testhal/STM32/multi/CRYPTO/cfg/stm32f756zg_nucleo144/mcuconf.h index 1e5e6624a..58315d901 100644 --- a/testhal/STM32/multi/CRYPTO/cfg/stm32f756zg_nucleo144/mcuconf.h +++ b/testhal/STM32/multi/CRYPTO/cfg/stm32f756zg_nucleo144/mcuconf.h @@ -150,6 +150,7 @@ #define STM32_CRY_HASH1_IRQ_PRIORITY 9 #define STM32_CRY_HASH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) #define STM32_CRY_HASH1_DMA_PRIORITY 0 +#define STM32_CRY_HASH_SIZE_THRESHOLD 1024 #define STM32_CRY_HASH_DMA_ERROR_HOOK(cryp) osalSysHalt("DMA failure") /* diff --git a/testhal/STM32/multi/CRYPTO/debug/STM32-CRYPTO (Select ELF file)(OpenOCD, Flash and Run).launch b/testhal/STM32/multi/CRYPTO/debug/STM32-CRYPTO (Select ELF file)(OpenOCD, Flash and Run).launch index bfd40254c..918d40d5e 100644 --- a/testhal/STM32/multi/CRYPTO/debug/STM32-CRYPTO (Select ELF file)(OpenOCD, Flash and Run).launch +++ b/testhal/STM32/multi/CRYPTO/debug/STM32-CRYPTO (Select ELF file)(OpenOCD, Flash and Run).launch @@ -33,7 +33,7 @@ - + diff --git a/testhal/STM32/multi/CRYPTO/main.c b/testhal/STM32/multi/CRYPTO/main.c index 61be877f0..75d5e51e5 100644 --- a/testhal/STM32/multi/CRYPTO/main.c +++ b/testhal/STM32/multi/CRYPTO/main.c @@ -69,7 +69,7 @@ int main(void) { if (palReadLine(PORTAB_LINE_BUTTON) == PORTAB_BUTTON_PRESSED) { SHA256Context ctx256; -#if 0 + crySHA256Init(&CRYD1, &ctx256); crySHA256Update(&CRYD1, &ctx256, 0U, (const uint8_t *)""); crySHA256Final(&CRYD1, &ctx256, digest); @@ -77,7 +77,7 @@ int main(void) { crySHA256Init(&CRYD1, &ctx256); crySHA256Update(&CRYD1, &ctx256, 3U, (const uint8_t *)"abc"); crySHA256Final(&CRYD1, &ctx256, digest); -#endif + crySHA256Init(&CRYD1, &ctx256); crySHA256Update(&CRYD1, &ctx256, 56U, (const uint8_t *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); crySHA256Final(&CRYD1, &ctx256, digest); -- cgit v1.2.3