Skip to content

Commit 0c10984

Browse files
committed
[NUC472/M487] Refine flow control code between crypto start and crypto ISR
1 parent e1fbf0f commit 0c10984

File tree

8 files changed

+153
-52
lines changed

8 files changed

+153
-52
lines changed

features/mbedtls/targets/TARGET_NUVOTON/TARGET_M480/aes/aes_alt.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,9 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
176176

177177
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
178178

179-
g_AES_done = 0;
180-
/* Ensure memory accesses above are completed before DMA is started
181-
*
182-
* Replacing __DSB() with __DMB() is also OK in this case.
183-
*
184-
* Refer to "multi-master systems" section with DMA in:
185-
* https://static.docs.arm.com/dai0321/a/DAI0321A_programming_guide_memory_barriers_for_m_profile.pdf
186-
*/
187-
__DSB();
179+
crypto_aes_prestart();
188180
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
189-
while (!g_AES_done);
181+
crypto_aes_wait();
190182

191183
if( pOut != output ) {
192184
memcpy(output, au8OutputData, dataSize);

features/mbedtls/targets/TARGET_NUVOTON/TARGET_NUC472/aes/aes_alt.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,17 +176,9 @@ static void __nvt_aes_crypt( mbedtls_aes_context *ctx,
176176

177177
AES_SetDMATransfer(0, (uint32_t)pIn, (uint32_t)pOut, dataSize);
178178

179-
g_AES_done = 0;
180-
/* Ensure memory accesses above are completed before DMA is started
181-
*
182-
* Replacing __DSB() with __DMB() is also OK in this case.
183-
*
184-
* Refer to "multi-master systems" section with DMA in:
185-
* https://static.docs.arm.com/dai0321/a/DAI0321A_programming_guide_memory_barriers_for_m_profile.pdf
186-
*/
187-
__DSB();
179+
crypto_aes_prestart();
188180
AES_Start(0, CRYPTO_DMA_ONE_SHOT);
189-
while (!g_AES_done);
181+
crypto_aes_wait();
190182

191183
if( pOut != output ) {
192184
memcpy(output, au8OutputData, dataSize);

targets/TARGET_NUVOTON/TARGET_M480/crypto/crypto-misc.c

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
#include "nu_bitutil.h"
2525
#include "crypto-misc.h"
2626

27-
volatile int g_PRNG_done;
28-
volatile int g_AES_done;
29-
3027
/* Track if AES H/W is available */
3128
static uint16_t crypto_aes_avail = 1;
3229
/* Track if DES H/W is available */
@@ -40,6 +37,14 @@ static uint16_t crypto_init_counter = 0U;
4037
static bool crypto_submodule_acquire(uint16_t *submodule_avail);
4138
static void crypto_submodule_release(uint16_t *submodule_avail);
4239

40+
/* Track if PRNG H/W operation is done */
41+
static volatile uint16_t crypto_prng_done;
42+
/* Track if AES H/W operation is done */
43+
static volatile uint16_t crypto_aes_done;
44+
45+
static void crypto_submodule_prestart(volatile uint16_t *submodule_done);
46+
static bool crypto_submodule_wait(volatile uint16_t *submodule_done);
47+
4348
/* As crypto init counter changes from 0 to 1:
4449
*
4550
* 1. Enable crypto clock
@@ -125,6 +130,26 @@ void crypto_sha_release(void)
125130
crypto_submodule_release(&crypto_sha_avail);
126131
}
127132

133+
void crypto_prng_prestart(void)
134+
{
135+
crypto_submodule_prestart(&crypto_prng_done);
136+
}
137+
138+
bool crypto_prng_wait(void)
139+
{
140+
return crypto_submodule_wait(&crypto_prng_done);
141+
}
142+
143+
void crypto_aes_prestart(void)
144+
{
145+
crypto_submodule_prestart(&crypto_aes_done);
146+
}
147+
148+
bool crypto_aes_wait(void)
149+
{
150+
return crypto_submodule_wait(&crypto_aes_done);
151+
}
152+
128153
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to)
129154
{
130155
uint32_t buff_ = (uint32_t) buff;
@@ -146,14 +171,35 @@ static void crypto_submodule_release(uint16_t *submodule_avail)
146171
while (! core_util_atomic_cas_u16(submodule_avail, &expectedCurrentValue, 1));
147172
}
148173

174+
static void crypto_submodule_prestart(volatile uint16_t *submodule_done)
175+
{
176+
*submodule_done = 0;
177+
178+
/* Ensure memory accesses above are completed before DMA is started
179+
*
180+
* Replacing __DSB() with __DMB() is also OK in this case.
181+
*
182+
* Refer to "multi-master systems" section with DMA in:
183+
* https://static.docs.arm.com/dai0321/a/DAI0321A_programming_guide_memory_barriers_for_m_profile.pdf
184+
*/
185+
__DSB();
186+
}
187+
188+
static bool crypto_submodule_wait(volatile uint16_t *submodule_done)
189+
{
190+
while (! *submodule_done);
191+
192+
return true;
193+
}
194+
149195
/* Crypto interrupt handler */
150196
void CRYPTO_IRQHandler()
151197
{
152198
if (PRNG_GET_INT_FLAG()) {
153-
g_PRNG_done = 1;
199+
crypto_prng_done = 1;
154200
PRNG_CLR_INT_FLAG();
155201
} else if (AES_GET_INT_FLAG()) {
156-
g_AES_done = 1;
202+
crypto_aes_done = 1;
157203
AES_CLR_INT_FLAG();
158204
}
159205
}

targets/TARGET_NUVOTON/TARGET_M480/crypto/crypto-misc.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,6 @@
2323
extern "C" {
2424
#endif
2525

26-
/* Flags to indicate crypto H/W operation has done
27-
*
28-
* Crypto driver would clear it before trigger and wait for it.
29-
* Crypto interrupt handler would set it on done or error.
30-
*/
31-
extern volatile int g_PRNG_done;
32-
extern volatile int g_AES_done;
33-
3426
/* Init/Uninit crypto module */
3527
void crypto_init(void);
3628
void crypto_uninit(void);
@@ -54,6 +46,27 @@ void crypto_des_release(void);
5446
bool crypto_sha_acquire(void);
5547
void crypto_sha_release(void);
5648

49+
/* Flow control between crypto/xxx start and crypto/xxx ISR
50+
*
51+
* crypto_xxx_prestart/crypto_xxx_wait encapsulate control flow between crypto/xxx start and crypto/xxx ISR.
52+
*
53+
* crypto_xxx_prestart will also address synchronization issue with memory barrier instruction.
54+
*
55+
* On finish, return of crypto_xxx_wait indicates success or not:
56+
* true if successful
57+
* false if failed
58+
*
59+
* Example: Start AES H/W and wait for its finish
60+
* crypto_aes_prestart();
61+
* AES_Start();
62+
* crypto_aes_wait();
63+
*/
64+
void crypto_prng_prestart(void);
65+
bool crypto_prng_wait(void);
66+
void crypto_aes_prestart(void);
67+
bool crypto_aes_wait(void);
68+
69+
5770
/* Check if buffer can be used for crypto DMA. It has the following requirements:
5871
* (1) Word-aligned buffer base address
5972
* (2) Crypto submodule (AES, DES, SHA, etc.) dependent buffer size alignment. Must be 2 power.

targets/TARGET_NUVOTON/TARGET_M480/trng_api.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ static void trng_get(unsigned char *pConversionData)
3636
p32ConversionData = (uint32_t *)pConversionData;
3737

3838
PRNG_Open(PRNG_KEY_SIZE_256, 1, us_ticker_read());
39+
crypto_prng_prestart();
3940
PRNG_Start();
40-
while (!g_PRNG_done);
41+
crypto_prng_wait();
4142

4243
PRNG_Read(p32ConversionData);
4344
}
@@ -85,4 +86,3 @@ int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_l
8586
}
8687

8788
#endif
88-

targets/TARGET_NUVOTON/TARGET_NUC472/crypto/crypto-misc.c

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
#include "nu_bitutil.h"
2525
#include "crypto-misc.h"
2626

27-
volatile int g_PRNG_done;
28-
volatile int g_AES_done;
29-
3027
/* Track if AES H/W is available */
3128
static uint16_t crypto_aes_avail = 1;
3229
/* Track if DES H/W is available */
@@ -40,6 +37,14 @@ static uint16_t crypto_init_counter = 0U;
4037
static bool crypto_submodule_acquire(uint16_t *submodule_avail);
4138
static void crypto_submodule_release(uint16_t *submodule_avail);
4239

40+
/* Track if PRNG H/W operation is done */
41+
static volatile uint16_t crypto_prng_done;
42+
/* Track if AES H/W operation is done */
43+
static volatile uint16_t crypto_aes_done;
44+
45+
static void crypto_submodule_prestart(volatile uint16_t *submodule_done);
46+
static bool crypto_submodule_wait(volatile uint16_t *submodule_done);
47+
4348
/* As crypto init counter changes from 0 to 1:
4449
*
4550
* 1. Enable crypto clock
@@ -125,6 +130,26 @@ void crypto_sha_release(void)
125130
crypto_submodule_release(&crypto_sha_avail);
126131
}
127132

133+
void crypto_prng_prestart(void)
134+
{
135+
crypto_submodule_prestart(&crypto_prng_done);
136+
}
137+
138+
bool crypto_prng_wait(void)
139+
{
140+
return crypto_submodule_wait(&crypto_prng_done);
141+
}
142+
143+
void crypto_aes_prestart(void)
144+
{
145+
crypto_submodule_prestart(&crypto_aes_done);
146+
}
147+
148+
bool crypto_aes_wait(void)
149+
{
150+
return crypto_submodule_wait(&crypto_aes_done);
151+
}
152+
128153
bool crypto_dma_buff_compat(const void *buff, size_t buff_size, size_t size_aligned_to)
129154
{
130155
uint32_t buff_ = (uint32_t) buff;
@@ -146,14 +171,35 @@ static void crypto_submodule_release(uint16_t *submodule_avail)
146171
while (! core_util_atomic_cas_u16(submodule_avail, &expectedCurrentValue, 1));
147172
}
148173

174+
static void crypto_submodule_prestart(volatile uint16_t *submodule_done)
175+
{
176+
*submodule_done = 0;
177+
178+
/* Ensure memory accesses above are completed before DMA is started
179+
*
180+
* Replacing __DSB() with __DMB() is also OK in this case.
181+
*
182+
* Refer to "multi-master systems" section with DMA in:
183+
* https://static.docs.arm.com/dai0321/a/DAI0321A_programming_guide_memory_barriers_for_m_profile.pdf
184+
*/
185+
__DSB();
186+
}
187+
188+
static bool crypto_submodule_wait(volatile uint16_t *submodule_done)
189+
{
190+
while (! *submodule_done);
191+
192+
return true;
193+
}
194+
149195
/* Crypto interrupt handler */
150196
void CRYPTO_IRQHandler()
151197
{
152198
if (PRNG_GET_INT_FLAG()) {
153-
g_PRNG_done = 1;
199+
crypto_prng_done = 1;
154200
PRNG_CLR_INT_FLAG();
155201
} else if (AES_GET_INT_FLAG()) {
156-
g_AES_done = 1;
202+
crypto_aes_done = 1;
157203
AES_CLR_INT_FLAG();
158204
}
159205
}

targets/TARGET_NUVOTON/TARGET_NUC472/crypto/crypto-misc.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,6 @@
2323
extern "C" {
2424
#endif
2525

26-
/* Flags to indicate crypto H/W operation has done
27-
*
28-
* Crypto driver would clear it before trigger and wait for it.
29-
* Crypto interrupt handler would set it on done or error.
30-
*/
31-
extern volatile int g_PRNG_done;
32-
extern volatile int g_AES_done;
33-
3426
/* Init/Uninit crypto module */
3527
void crypto_init(void);
3628
void crypto_uninit(void);
@@ -54,6 +46,27 @@ void crypto_des_release(void);
5446
bool crypto_sha_acquire(void);
5547
void crypto_sha_release(void);
5648

49+
/* Flow control between crypto/xxx start and crypto/xxx ISR
50+
*
51+
* crypto_xxx_prestart/crypto_xxx_wait encapsulate control flow between crypto/xxx start and crypto/xxx ISR.
52+
*
53+
* crypto_xxx_prestart will also address synchronization issue with memory barrier instruction.
54+
*
55+
* On finish, return of crypto_xxx_wait indicates success or not:
56+
* true if successful
57+
* false if failed
58+
*
59+
* Example: Start AES H/W and wait for its finish
60+
* crypto_aes_prestart();
61+
* AES_Start();
62+
* crypto_aes_wait();
63+
*/
64+
void crypto_prng_prestart(void);
65+
bool crypto_prng_wait(void);
66+
void crypto_aes_prestart(void);
67+
bool crypto_aes_wait(void);
68+
69+
5770
/* Check if buffer can be used for crypto DMA. It has the following requirements:
5871
* (1) Word-aligned buffer base address
5972
* (2) Crypto submodule (AES, DES, SHA, etc.) dependent buffer size alignment. Must be 2 power.

targets/TARGET_NUVOTON/TARGET_NUC472/trng_api.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include <stdlib.h>
2424
#include <string.h>
2525
#include "cmsis.h"
26-
#include "NUC472_442.h"
2726
#include "us_ticker_api.h"
2827
#include "trng_api.h"
2928
#include "crypto-misc.h"
@@ -41,8 +40,9 @@ static void trng_get(unsigned char *pConversionData)
4140
p32ConversionData = (uint32_t *)pConversionData;
4241

4342
PRNG_Open(PRNG_KEY_SIZE_256, 1, us_ticker_read());
43+
crypto_prng_prestart();
4444
PRNG_Start();
45-
while (!g_PRNG_done);
45+
crypto_prng_wait();
4646

4747
PRNG_Read(p32ConversionData);
4848
}
@@ -88,6 +88,5 @@ int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_l
8888
*output_length = cur_length;
8989
return 0;
9090
}
91-
92-
#endif
9391

92+
#endif

0 commit comments

Comments
 (0)