You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ut...@apache.org on 2021/02/17 13:22:51 UTC

[mynewt-core] 02/05: trng: kinetis: update driver for newer families

This is an automated email from the ASF dual-hosted git repository.

utzig pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit eea15f7f96ccec8238aae30228f4737c493b9ea3
Author: Fabio Utzig <ut...@apache.org>
AuthorDate: Tue Feb 9 09:41:18 2021 -0300

    trng: kinetis: update driver for newer families
    
    Older Kinetis families used the RNGA HW module for random number
    generation, newer models have a slightly different HW module called
    TRNG; this commit adds TRNG API usage compatibility, and adds syscfg
    to allow BSPs to choose from one of the HW modules.
    
    Signed-off-by: Fabio Utzig <ut...@apache.org>
---
 hw/drivers/trng/trng_kinetis/src/trng_kinetis.c | 67 ++++++++++++++++++++-----
 hw/drivers/trng/trng_kinetis/syscfg.yml         | 10 ++++
 2 files changed, 64 insertions(+), 13 deletions(-)

diff --git a/hw/drivers/trng/trng_kinetis/src/trng_kinetis.c b/hw/drivers/trng/trng_kinetis/src/trng_kinetis.c
index 45d914c..4b79d55 100644
--- a/hw/drivers/trng/trng_kinetis/src/trng_kinetis.c
+++ b/hw/drivers/trng/trng_kinetis/src/trng_kinetis.c
@@ -18,7 +18,27 @@
  */
 
 #include <string.h>
+#include "os/mynewt.h"
+
+#if MYNEWT_VAL(KINETIS_TRNG_USE_RNGA)
+#define USE_RNGA 1
 #include "fsl_rnga.h"
+#elif MYNEWT_VAL(KINETIS_TRNG_USE_TRNG)
+#define USE_TRNG 1
+#include "fsl_trng.h"
+#define TRNG_START(base)                                              \
+    do {                                                              \
+        (base)->MCTL &= ~TRNG_MCTL_PRGM_MASK;                         \
+        (base)->MCTL |= TRNG_MCTL_ERR_MASK;                           \
+    } while (0)
+#define TRNG_STOP(base)                                               \
+    do {                                                              \
+        (base)->MCTL |= (TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK);   \
+    } while (0)
+#else
+#error "Unsupported TRNG interface"
+#endif
+
 #include "trng/trng.h"
 #include "trng_kinetis/trng_kinetis.h"
 
@@ -30,16 +50,20 @@ static os_stack_t *pstack;
 static bool running;
 static struct os_eventq rng_evtq;
 
-#define RNGA_POLLER_PRIO (8)
-#define RNGA_POLLER_STACK_SIZE OS_STACK_ALIGN(64)
+#define TRNG_POLLER_PRIO (8)
+#define TRNG_POLLER_STACK_SIZE OS_STACK_ALIGN(64)
 static struct os_task poller_task;
 
 static inline void
-kinetis_rnga_start(void)
+kinetis_trng_start(void)
 {
     struct os_event evt;
 
+#if USE_RNGA
     RNGA_SetMode(RNG, kRNGA_ModeNormal);
+#elif USE_TRNG
+    TRNG_START(TRNG0);
+#endif
     running = true;
 
     evt.ev_queued = 0;
@@ -48,9 +72,14 @@ kinetis_rnga_start(void)
 }
 
 static inline void
-kinetis_rnga_stop(void)
+kinetis_trng_stop(void)
 {
-   RNGA_SetMode(RNG, kRNGA_ModeSleep);
+#if USE_RNGA
+    RNGA_SetMode(RNG, kRNGA_ModeSleep);
+#elif USE_TRNG
+    TRNG_STOP(TRNG0);
+#endif
+
    running = false;
 }
 
@@ -83,7 +112,7 @@ kinetis_trng_read(struct trng_dev *trng, void *ptr, size_t size)
     rng_cache_out = (rng_cache_out + num_read) % sizeof(rng_cache);
 
     if (num_read > 0) {
-        kinetis_rnga_start();
+        kinetis_trng_start();
     }
 
     os_mutex_release(&rng_cache_mu);
@@ -110,7 +139,7 @@ kinetis_trng_get_u32(struct trng_dev *trng)
 }
 
 static void
-rnga_poller_handler(void *arg)
+trng_poller_handler(void *arg)
 {
     int8_t i;
     uint8_t data[4];
@@ -118,8 +147,12 @@ rnga_poller_handler(void *arg)
 
     while (1) {
         if (running) {
+#if USE_RNGA
             rc = RNGA_GetRandomData(RNG, data, sizeof(uint32_t));
-            if (rc == kStatus_Success) {
+#else
+            rc = TRNG_GetRandomData(TRNG0, data, sizeof(uint32_t));
+#endif
+            if (rc == 0) {
                 os_mutex_pend(&rng_cache_mu, OS_TIMEOUT_NEVER);
                 for (i = 0; i < 4; i++) {
                     rng_cache[rng_cache_in++] = data[i];
@@ -129,7 +162,7 @@ rnga_poller_handler(void *arg)
                     }
 
                     if ((rng_cache_in + 1) % sizeof(rng_cache) == rng_cache_out) {
-                        kinetis_rnga_stop();
+                        kinetis_trng_stop();
                         break;
                     }
                 }
@@ -146,6 +179,9 @@ static int
 kinetis_trng_dev_open(struct os_dev *dev, uint32_t wait, void *arg)
 {
     struct trng_dev *trng;
+#if USE_TRNG
+    trng_config_t default_config;
+#endif
 
     trng = (struct trng_dev *)dev;
     assert(trng);
@@ -154,9 +190,14 @@ kinetis_trng_dev_open(struct os_dev *dev, uint32_t wait, void *arg)
         rng_cache_out = 0;
         rng_cache_in = 0;
 
+#if USE_RNGA
         RNGA_Init(RNG);
+#elif USE_TRNG
+        (void)TRNG_GetDefaultConfig(&default_config);
+        TRNG_Init(TRNG0, &default_config);
+#endif
 
-        kinetis_rnga_start();
+        kinetis_trng_start();
     }
 
     return 0;
@@ -179,11 +220,11 @@ kinetis_trng_dev_init(struct os_dev *dev, void *arg)
     os_eventq_init(&rng_evtq);
     os_mutex_init(&rng_cache_mu);
 
-    pstack = malloc(sizeof(os_stack_t) * RNGA_POLLER_STACK_SIZE);
+    pstack = malloc(sizeof(os_stack_t) * TRNG_POLLER_STACK_SIZE);
     assert(pstack);
 
-    rc = os_task_init(&poller_task, "rnga_poller", rnga_poller_handler, NULL,
-            RNGA_POLLER_PRIO, OS_WAIT_FOREVER, pstack, RNGA_POLLER_STACK_SIZE);
+    rc = os_task_init(&poller_task, "trng_poller", trng_poller_handler, NULL,
+            TRNG_POLLER_PRIO, OS_WAIT_FOREVER, pstack, TRNG_POLLER_STACK_SIZE);
     if (rc) {
         return rc;
     }
diff --git a/hw/drivers/trng/trng_kinetis/syscfg.yml b/hw/drivers/trng/trng_kinetis/syscfg.yml
index 9f8c0cf..7c72a7b 100644
--- a/hw/drivers/trng/trng_kinetis/syscfg.yml
+++ b/hw/drivers/trng/trng_kinetis/syscfg.yml
@@ -20,3 +20,13 @@ syscfg.defs:
     KINETIS_TRNG_CACHE_LEN:
         description: 'Internal cache length, shall be a multiple of 4'
         value: 32
+    KINETIS_TRNG_USE_RNGA:
+        description: 'Use the RNGA HW module (default)'
+        value: 1
+        restrictions:
+            - '!KINETIS_TRNG_USE_TRNG'
+    KINETIS_TRNG_USE_TRNG:
+        description: 'Use the TRNG HW module'
+        value: 0
+        restrictions:
+            - '!KINETIS_TRNG_USE_RNGA'