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

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new fcbd3099aa arch/arm64/imx9: Extend ELE API with RNG support
fcbd3099aa is described below

commit fcbd3099aa83c91e108ac0e0a07cae1184fd4eae
Author: Theodore Karatapanis <tkaratapa...@census-labs.com>
AuthorDate: Tue May 13 16:26:51 2025 +0300

    arch/arm64/imx9: Extend ELE API with RNG support
    
    - Add ELE command to initialize the ELE RNG context.
    - Add ELE command to poll the readiness of the RNG
    - Add ELE command to obtain random numbers.
    - Replace AHAB_ prefixes with ELE_
    - Cleanup header includes
    - Added some explanatory comments on .../hardware/imx9_ele.h
    
    Signed-off-by: Theodore Karatapanis <tkaratapa...@census-labs.com>
---
 arch/arm64/src/imx9/hardware/imx9_ele.h |  33 +++++--
 arch/arm64/src/imx9/imx9_ele.c          | 154 ++++++++++++++++++++++++++------
 arch/arm64/src/imx9/imx9_ele.h          |  50 ++++++++++-
 3 files changed, 203 insertions(+), 34 deletions(-)

diff --git a/arch/arm64/src/imx9/hardware/imx9_ele.h 
b/arch/arm64/src/imx9/hardware/imx9_ele.h
index 7a289aac74..4c6f4a3c58 100644
--- a/arch/arm64/src/imx9/hardware/imx9_ele.h
+++ b/arch/arm64/src/imx9/hardware/imx9_ele.h
@@ -28,24 +28,35 @@
  ****************************************************************************/
 
 #include <hardware/imx9_memorymap.h>
+#include <stdint.h>
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
 #define ELE_MAX_MSG               255U
-#define AHAB_VERSION              0x6
-#define AHAB_CMD_TAG              0x17
-#define AHAB_RESP_TAG             0xe1
-#define ELE_RELEASE_RDC_REQ       0xc4
-#define ELE_READ_FUSE_REQ         0x97
-#define ELE_GET_EVENTS_REQ        0xa2
+
+#define ELE_CMD_TAG               0x17
+#define ELE_VERSION               0x6
+#define ELE_VERSION_FW            0x7
+#define ELE_RESP_TAG              0xe1
+#define ELE_OK                    0xd6
+
+/* ELE commands. */
+
 #define ELE_DERIVE_KEY_REQ        0xa9
+#define ELE_GET_EVENTS_REQ        0xa2
+#define ELE_GET_TRNG_STATE_REQ    0xa4
+#define ELE_GET_RNG_REQ           0xcd
 #define ELE_FWD_LIFECYCLE_UP_REQ  0x95
 #define ELE_OEM_CNTN_AUTH_REQ     0x87
-#define ELE_VERIFY_IMAGE_REQ      0x88
+#define ELE_READ_FUSE_REQ         0x97
 #define ELE_RELEASE_CONTAINER_REQ 0x89
-#define ELE_OK                    0xd6
+#define ELE_RELEASE_RDC_REQ       0xc4
+#define ELE_START_RNG_REQ         0xa3
+#define ELE_VERIFY_IMAGE_REQ      0x88
+
+/* Messaging Unit registers. */
 
 #define ELE_MU_TCR (IMX9_S3MUA_BASE + 0x120)
 #define ELE_MU_TSR (IMX9_S3MUA_BASE + 0x124)
@@ -57,8 +68,14 @@
 #define ELE_MU_TR(i) (IMX9_S3MUA_BASE + 0x200 + (i) * 4)
 #define ELE_MU_RR(i) (IMX9_S3MUA_BASE + 0x280 + (i) * 4)
 
+/* Fuse and Status Block lifecycle register. */
+
 #define FSB_LC_REG              0x4751041cUL
 
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
 struct ele_header_t
 {
   union
diff --git a/arch/arm64/src/imx9/imx9_ele.c b/arch/arm64/src/imx9/imx9_ele.c
index e53df86eb1..35880ce4e3 100644
--- a/arch/arm64/src/imx9/imx9_ele.c
+++ b/arch/arm64/src/imx9/imx9_ele.c
@@ -24,16 +24,8 @@
  * Included Files
  ****************************************************************************/
 
-#include <nuttx/config.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <nuttx/arch.h>
-#include <nuttx/clock.h>
 #include <debug.h>
-
-#include <arch/board/board.h>
+#include <errno.h>
 
 #include "chip.h"
 #include "arm64_internal.h"
@@ -52,12 +44,24 @@
 #define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
 #define lower_32_bits(n) ((uint32_t)(n))
 
+#define ELE_RNG_TIMEOUT_US    5000
+#define ELE_RNG_SLEEP_US      100
+#define ELE_TRNG_STATUS_READY 0x3
+#define ELE_CSAL_STATUS_READY 0x2
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
 struct ele_msg msg;
 
+struct ele_trng_state
+{
+  uint8_t  trng_state;
+  uint8_t  csal_state;
+  uint16_t reserved;
+};
+
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -154,8 +158,8 @@ void imx9_ele_init(void)
 
 int imx9_ele_release_rdc(uint32_t rdc_id)
 {
-  msg.header.version = AHAB_VERSION;
-  msg.header.tag = AHAB_CMD_TAG;
+  msg.header.version = ELE_VERSION;
+  msg.header.tag = ELE_CMD_TAG;
   msg.header.size = 2;
   msg.header.command = ELE_RELEASE_RDC_REQ;
   msg.data[0] = rdc_id;
@@ -175,8 +179,8 @@ uint32_t imx9_ele_read_common_fuse(uint32_t fuse_id)
 {
   uint32_t value = 0;
 
-  msg.header.version = AHAB_VERSION;
-  msg.header.tag = AHAB_CMD_TAG;
+  msg.header.version = ELE_VERSION;
+  msg.header.tag = ELE_CMD_TAG;
   msg.header.size = 2;
   msg.header.command = ELE_READ_FUSE_REQ;
   msg.data[0] = fuse_id;
@@ -225,8 +229,8 @@ int imx9_ele_get_key(uint8_t *key, size_t key_size,
       return -EINVAL;
     }
 
-  msg.header.version = AHAB_VERSION;
-  msg.header.tag = AHAB_CMD_TAG;
+  msg.header.version = ELE_VERSION;
+  msg.header.tag = ELE_CMD_TAG;
   msg.header.size = 7;
   msg.header.command = ELE_DERIVE_KEY_REQ;
   msg.data[0] = upper_32_bits((ulong)key);
@@ -264,8 +268,8 @@ int imx9_ele_get_events(uint32_t *buffer, size_t 
buffer_size)
   size_t events_num;
   size_t i;
 
-  msg.header.version = AHAB_VERSION;
-  msg.header.tag = AHAB_CMD_TAG;
+  msg.header.version = ELE_VERSION;
+  msg.header.tag = ELE_CMD_TAG;
   msg.header.size = 1;
   msg.header.command = ELE_GET_EVENTS_REQ;
 
@@ -295,8 +299,8 @@ int imx9_ele_get_events(uint32_t *buffer, size_t 
buffer_size)
 
 int imx9_ele_close_device(void)
 {
-  msg.header.version = AHAB_VERSION;
-  msg.header.tag = AHAB_CMD_TAG;
+  msg.header.version = ELE_VERSION;
+  msg.header.tag = ELE_CMD_TAG;
   msg.header.size = 2;
   msg.header.command = ELE_FWD_LIFECYCLE_UP_REQ;
   msg.data[0] = 0x08;
@@ -319,8 +323,8 @@ uint32_t imx9_ele_get_lifecycle(void)
 
 int imx9_ele_auth_oem_ctnr(unsigned long ctnr_addr, uint32_t *response)
 {
-  msg.header.version = AHAB_VERSION;
-  msg.header.tag = AHAB_CMD_TAG;
+  msg.header.version = ELE_VERSION;
+  msg.header.tag = ELE_CMD_TAG;
   msg.header.size = 3;
   msg.header.command = ELE_OEM_CNTN_AUTH_REQ;
   msg.data[0] = upper_32_bits(ctnr_addr);
@@ -343,8 +347,8 @@ int imx9_ele_auth_oem_ctnr(unsigned long ctnr_addr, 
uint32_t *response)
 
 int imx9_ele_release_container(uint32_t *response)
 {
-  msg.header.version = AHAB_VERSION;
-  msg.header.tag = AHAB_CMD_TAG;
+  msg.header.version = ELE_VERSION;
+  msg.header.tag = ELE_CMD_TAG;
   msg.header.size = 1;
   msg.header.command = ELE_RELEASE_CONTAINER_REQ;
 
@@ -366,8 +370,8 @@ int imx9_ele_release_container(uint32_t *response)
 
 int imx9_ele_verify_image(uint32_t img_id, uint32_t *response)
 {
-  msg.header.version = AHAB_VERSION;
-  msg.header.tag = AHAB_CMD_TAG;
+  msg.header.version = ELE_VERSION;
+  msg.header.tag = ELE_CMD_TAG;
   msg.header.size = 2;
   msg.header.command = ELE_VERIFY_IMAGE_REQ;
   msg.data[0] = 1 << img_id;
@@ -387,3 +391,103 @@ int imx9_ele_verify_image(uint32_t img_id, uint32_t 
*response)
 
   return -EIO;
 }
+
+int imx9_ele_start_rng(void)
+{
+  msg.header.version = ELE_VERSION;
+  msg.header.tag = ELE_CMD_TAG;
+  msg.header.size = 1;
+  msg.header.command = ELE_START_RNG_REQ;
+
+  imx9_ele_sendmsg(&msg);
+  imx9_ele_receivemsg(&msg);
+
+  if ((msg.data[0] & 0xff) == ELE_OK)
+    {
+      return 0;
+    }
+
+  return -EIO;
+}
+
+int imx9_ele_get_trng_state(void)
+{
+  msg.header.version = ELE_VERSION;
+  msg.header.tag = ELE_CMD_TAG;
+  msg.header.size = 1;
+  msg.header.command = ELE_GET_TRNG_STATE_REQ;
+
+  imx9_ele_sendmsg(&msg);
+  imx9_ele_receivemsg(&msg);
+
+  if ((msg.data[0] & 0xff) == ELE_OK)
+    {
+      struct ele_trng_state *ele_trng =
+        (struct ele_trng_state *)(msg.data + 1);
+      if (ele_trng->trng_state != ELE_TRNG_STATUS_READY ||
+          ele_trng->csal_state != ELE_CSAL_STATUS_READY)
+        {
+          /* Ensure imx9_ele_start_rng() was called earlier or we will
+           * end up here.
+           */
+
+          return -EBUSY;
+        }
+      else
+        {
+          return 0;
+        }
+    }
+
+  return -EIO;
+}
+
+int imx9_ele_get_random(uint32_t paddr, size_t len)
+{
+  uint16_t counter = 0;
+  uint16_t max_tries = ELE_RNG_TIMEOUT_US / ELE_RNG_SLEEP_US;
+
+  if (paddr == 0 || len == 0)
+    {
+      _err("Wrong input parameters!\n");
+      return -EINVAL;
+    }
+
+  while ((imx9_ele_get_trng_state() != 0))
+    {
+      if (counter > max_tries)
+        {
+          _err("Timed out after %hu iterations!\n", counter);
+          return -EBUSY;
+        }
+
+      usleep(ELE_RNG_SLEEP_US);
+      counter++;
+    }
+
+  /* Flush the cache before sending the request to ELE. */
+
+  up_flush_dcache((uintptr_t)paddr, (uintptr_t)(paddr + len));
+
+  msg.header.version = ELE_VERSION_FW;
+  msg.header.tag = ELE_CMD_TAG;
+  msg.header.size = 4;
+  msg.header.command = ELE_GET_RNG_REQ;
+  msg.data[0] = 0;
+  msg.data[1] = paddr;
+  msg.data[2] = len;
+
+  imx9_ele_sendmsg(&msg);
+  imx9_ele_receivemsg(&msg);
+
+  if ((msg.data[0] & 0xff) == ELE_OK)
+    {
+      /* Invalidate the cache so we can read the result from RAM. */
+
+      up_invalidate_dcache((uintptr_t)paddr,
+                           (uintptr_t)(paddr + len));
+      return 0;
+    }
+
+  return -EIO;
+}
diff --git a/arch/arm64/src/imx9/imx9_ele.h b/arch/arm64/src/imx9/imx9_ele.h
index fa48cd9014..5f192070b2 100644
--- a/arch/arm64/src/imx9/imx9_ele.h
+++ b/arch/arm64/src/imx9/imx9_ele.h
@@ -27,8 +27,9 @@
  * Included Files
  ****************************************************************************/
 
-#include <nuttx/config.h>
 #include "hardware/imx9_ele.h"
+#include <sys/types.h>
+#include <stdint.h>
 
 /****************************************************************************
  * Public Function Prototypes
@@ -219,4 +220,51 @@ int imx9_ele_release_container(uint32_t *response);
  ****************************************************************************/
 
 int imx9_ele_verify_image(uint32_t img_id, uint32_t *response);
+
+/****************************************************************************
+ * Name: imx9_ele_start_rng
+ *
+ * Description:
+ *   Sends command to initialize the ELE RNG context.
+ *
+ * Returned Value:
+ *   Zero (OK) is returned for success. A negated errno value is returned on
+ *   failure.
+ *
+ ****************************************************************************/
+
+int imx9_ele_start_rng(void);
+
+/****************************************************************************
+ * Name: imx9_ele_get_trng_state
+ *
+ * Description:
+ *   Query the state of the True Random Number Generator.
+ *
+ * Returned Value:
+ *   Zero is returned if the Random Number Generator (RNG) is ready for use.
+ *   A negated errno value (-EBUSY) or another is returned on failure.
+ *
+ ****************************************************************************/
+
+int imx9_ele_get_trng_state(void);
+
+/****************************************************************************
+ * Name: imx9_ele_get_random
+ *
+ * Description:
+ *   Request from the ELE the generation of a random number of specified
+ *   length.
+ *
+ * Input Parameters:
+ *   paddr  -  32bit physical address to store the random number.
+ *   len    -  Length in bytes of the random number.
+ *
+ * Returned Value:
+ *   Zero is returned if ELE successfully generated the random number.
+ *   A negated errno value (-EBUSY) or another is returned on failure.
+ *
+ ****************************************************************************/
+
+int imx9_ele_get_random(uint32_t paddr, size_t len);
 #endif /* __ARCH_ARM64_SRC_IMX9_IMX9_ELE_H */

Reply via email to