@@ -228,53 +228,51 @@ void hal_trng_fini(void)
228228 /* Don't disable ELS, it might be used by other actors */
229229}
230230
231- int hal_trng_get_entropy ( unsigned char * out , unsigned int len )
231+ static int els_rnd_req ( void * out , uint32_t len )
232232{
233- /* Implemented as a RND_REQ command to the ELS */
234-
235- uint32_t aligned_len = len & ~3U ;
236- uint32_t status ;
237-
238- /* Wait for ELS to be ready */
239233 while (ELS -> ELS_STATUS & S50_ELS_STATUS_ELS_BUSY_MASK )
240234 ;
235+ ELS -> ELS_DMA_RES0 = (uint32_t )(uintptr_t )out ;
236+ ELS -> ELS_DMA_RES0_LEN = len ;
237+ ELS -> ELS_CMDCFG0 = 0 ;
238+ ELS -> ELS_CTRL = S50_ELS_CTRL_ELS_EN (1 )
239+ | S50_ELS_CTRL_ELS_START (1 )
240+ | S50_ELS_CTRL_ELS_CMD (ELS_CMD_RND_REQ );
241+ while (ELS -> ELS_STATUS & S50_ELS_STATUS_ELS_BUSY_MASK )
242+ ;
243+ return (ELS -> ELS_STATUS & S50_ELS_STATUS_ELS_ERR_MASK ) ? -1 : 0 ;
244+ }
241245
242- /* Handle the word-aligned portion */
243- if (aligned_len > 0 ) {
244- ELS -> ELS_DMA_RES0 = (uint32_t )(uintptr_t )out ;
245- ELS -> ELS_DMA_RES0_LEN = aligned_len ;
246- ELS -> ELS_CMDCFG0 = 0 ;
247- ELS -> ELS_CTRL = S50_ELS_CTRL_ELS_EN (1 )
248- | S50_ELS_CTRL_ELS_START (1 )
249- | S50_ELS_CTRL_ELS_CMD (ELS_CMD_RND_REQ );
250-
251- while (ELS -> ELS_STATUS & S50_ELS_STATUS_ELS_BUSY_MASK )
252- ;
253-
254- status = ELS -> ELS_STATUS ;
255- if (status & S50_ELS_STATUS_ELS_ERR_MASK )
246+ int hal_trng_get_entropy (unsigned char * out , unsigned int len )
247+ {
248+ uint32_t tmp ;
249+
250+ /* Handle unaligned head (up to 3 bytes) via temporary word */
251+ if ((uintptr_t )out & 3U ) {
252+ uint32_t head = 4U - ((uintptr_t )out & 3U );
253+ if (head > len )
254+ head = len ;
255+ if (els_rnd_req (& tmp , 4 ) != 0 )
256256 return -1 ;
257+ memcpy (out , & tmp , head );
258+ out += head ;
259+ len -= head ;
257260 }
258261
259- /* Handle remaining bytes (1-3) with a temporary word */
260- if (len > aligned_len ) {
261- uint32_t tmp ;
262-
263- ELS -> ELS_DMA_RES0 = (uint32_t )(uintptr_t )& tmp ;
264- ELS -> ELS_DMA_RES0_LEN = 4 ;
265- ELS -> ELS_CMDCFG0 = 0 ;
266- ELS -> ELS_CTRL = S50_ELS_CTRL_ELS_EN (1 )
267- | S50_ELS_CTRL_ELS_START (1 )
268- | S50_ELS_CTRL_ELS_CMD (ELS_CMD_RND_REQ );
269-
270- while (ELS -> ELS_STATUS & S50_ELS_STATUS_ELS_BUSY_MASK )
271- ;
272-
273- status = ELS -> ELS_STATUS ;
274- if (status & S50_ELS_STATUS_ELS_ERR_MASK )
262+ /* Bulk aligned portion in one request */
263+ if (len >= 4 ) {
264+ uint32_t aligned_len = len & ~3U ;
265+ if (els_rnd_req (out , aligned_len ) != 0 )
275266 return -1 ;
267+ out += aligned_len ;
268+ len -= aligned_len ;
269+ }
276270
277- memcpy (out + aligned_len , & tmp , len - aligned_len );
271+ /* Handle remaining tail bytes (1-3) via temporary word */
272+ if (len > 0 ) {
273+ if (els_rnd_req (& tmp , 4 ) != 0 )
274+ return -1 ;
275+ memcpy (out , & tmp , len );
278276 }
279277
280278 return 0 ;
0 commit comments