[EXT] RE: [PATCH v5 01/16] crypto/fsl: Add support for CAAM Job ring driver model

Gaurav Jain gaurav.jain at nxp.com
Wed Nov 17 12:25:34 CET 2021


Hello Andrey

> -----Original Message-----
> From: ZHIZHIKIN Andrey <andrey.zhizhikin at leica-geosystems.com>
> Sent: Tuesday, November 16, 2021 9:24 PM
> To: Gaurav Jain <gaurav.jain at nxp.com>; u-boot at lists.denx.de
> Cc: Stefano Babic <sbabic at denx.de>; Fabio Estevam <festevam at gmail.com>;
> Peng Fan <peng.fan at nxp.com>; Simon Glass <sjg at chromium.org>; Priyanka
> Jain <priyanka.jain at nxp.com>; Ye Li <ye.li at nxp.com>; Horia Geanta
> <horia.geanta at nxp.com>; Ji Luo <ji.luo at nxp.com>; Franck Lenormand
> <franck.lenormand at nxp.com>; Silvano Di Ninno <silvano.dininno at nxp.com>;
> Sahil Malhotra <sahil.malhotra at nxp.com>; Pankaj Gupta
> <pankaj.gupta at nxp.com>; Varun Sethi <V.Sethi at nxp.com>; dl-uboot-imx
> <uboot-imx at nxp.com>; Shengzhou Liu <shengzhou.liu at nxp.com>; Mingkai Hu
> <mingkai.hu at nxp.com>; Rajesh Bhagat <rajesh.bhagat at nxp.com>; Meenakshi
> Aggarwal <meenakshi.aggarwal at nxp.com>; Wasim Khan
> <wasim.khan at nxp.com>; Alison Wang <alison.wang at nxp.com>; Pramod
> Kumar <pramod.kumar_1 at nxp.com>; Andy Tang <andy.tang at nxp.com>;
> Adrian Alonso <adrian.alonso at nxp.com>; Vladimir Oltean <olteanv at gmail.com>
> Subject: [EXT] RE: [PATCH v5 01/16] crypto/fsl: Add support for CAAM Job ring
> driver model
> 
> Caution: EXT Email
> 
> Hello Gaurav,
> 
> > -----Original Message-----
> > From: U-Boot <u-boot-bounces at lists.denx.de> On Behalf Of Gaurav Jain
> > Sent: Monday, November 15, 2021 8:00 AM
> > To: u-boot at lists.denx.de
> > Cc: Stefano Babic <sbabic at denx.de>; Fabio Estevam
> > <festevam at gmail.com>; Peng Fan <peng.fan at nxp.com>; Simon Glass
> > <sjg at chromium.org>; Priyanka Jain <priyanka.jain at nxp.com>; Ye Li
> > <ye.li at nxp.com>; Horia Geanta <horia.geanta at nxp.com>; Ji Luo
> > <ji.luo at nxp.com>; Franck Lenormand <franck.lenormand at nxp.com>; Silvano
> > Di Ninno <silvano.dininno at nxp.com>; Sahil malhotra
> > <sahil.malhotra at nxp.com>; Pankaj Gupta <pankaj.gupta at nxp.com>; Varun
> > Sethi <V.Sethi at nxp.com>; NXP i . MX U-Boot Team <uboot-imx at nxp.com>;
> > Shengzhou Liu <Shengzhou.Liu at nxp.com>; Mingkai Hu
> > <mingkai.hu at nxp.com>; Rajesh Bhagat <rajesh.bhagat at nxp.com>;
> Meenakshi
> > Aggarwal <meenakshi.aggarwal at nxp.com>; Wasim Khan
> > <wasim.khan at nxp.com>; Alison Wang <alison.wang at nxp.com>; Pramod
> Kumar
> > <pramod.kumar_1 at nxp.com>; Tang Yuantian <andy.tang at nxp.com>; Adrian
> > Alonso <adrian.alonso at nxp.com>; Vladimir Oltean <olteanv at gmail.com>;
> > Gaurav Jain <gaurav.jain at nxp.com>
> > Subject: [PATCH v5 01/16] crypto/fsl: Add support for CAAM Job ring
> > driver model
> >
> >
> > added device tree support for job ring driver.
> > sec is initialized based on job ring information processed from device
> > tree.
> >
> > Signed-off-by: Gaurav Jain <gaurav.jain at nxp.com>
> > Reviewed-by: Ye Li <ye.li at nxp.com>
> > ---
> >  cmd/Kconfig                 |   1 +
> >  drivers/crypto/fsl/Kconfig  |   7 +
> >  drivers/crypto/fsl/Makefile |   4 +-
> >  drivers/crypto/fsl/jr.c     | 316 +++++++++++++++++++++++-------------
> >  drivers/crypto/fsl/jr.h     |  14 ++
> >  5 files changed, 232 insertions(+), 110 deletions(-)
> >
> > diff --git a/cmd/Kconfig b/cmd/Kconfig index 5b30b13e43..2b24672505
> > 100644
> > --- a/cmd/Kconfig
> > +++ b/cmd/Kconfig
> > @@ -2009,6 +2009,7 @@ config CMD_AES
> >
> >  config CMD_BLOB
> >         bool "Enable the 'blob' command"
> > +       select FSL_BLOB
> >         depends on !MX6ULL && !MX6SLL && !MX6SL
> >         select IMX_HAB if ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP ||
> ARCH_IMX8M
> >         help
> > diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig
> > index 94ff540111..ab59d516f8 100644
> > --- a/drivers/crypto/fsl/Kconfig
> > +++ b/drivers/crypto/fsl/Kconfig
> > @@ -66,4 +66,11 @@ config FSL_CAAM_RNG
> >           using the prediction resistance flag which means the DRGB is
> >           reseeded from the TRNG every time random data is generated.
> >
> > +config FSL_BLOB
> > +        bool "Enable Blob Encap/Decap, Blob KEK support"
> > +       help
> > +         Enable support for the hardware based crytographic blob encap/decap
> > +         module of the CAAM. blobs can be safely placed into non-volatile
> > +         storage. blobs can only be decapsulated by the SoC that created it.
> > +         Enable support for blob key encryption key generation.
> >  endif
> > diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
> > index f9c3ccecfc..738535b8e4 100644
> > --- a/drivers/crypto/fsl/Makefile
> > +++ b/drivers/crypto/fsl/Makefile
> > @@ -1,10 +1,12 @@
> >  # SPDX-License-Identifier: GPL-2.0+
> >  #
> >  # Copyright 2014 Freescale Semiconductor, Inc.
> > +# Copyright 2021 NXP
> >
> >  obj-y += sec.o
> >  obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
> > -obj-$(CONFIG_CMD_BLOB)$(CONFIG_IMX_CAAM_DEK_ENCAP) += fsl_blob.o
> > +obj-$(CONFIG_FSL_BLOB) += fsl_blob.o
> > +obj-$(CONFIG_IMX_CAAM_DEK_ENCAP) += fsl_blob.o
> >  obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
> >  obj-$(CONFIG_FSL_CAAM_RNG) += rng.o
> >  obj-$(CONFIG_FSL_MFGPROT) += fsl_mfgprot.o diff --git
> > a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index
> > 22b649219e..eea2225a1e 100644
> > --- a/drivers/crypto/fsl/jr.c
> > +++ b/drivers/crypto/fsl/jr.c
> > @@ -1,7 +1,7 @@
> >  // SPDX-License-Identifier: GPL-2.0+
> >  /*
> >   * Copyright 2008-2014 Freescale Semiconductor, Inc.
> > - * Copyright 2018 NXP
> > + * Copyright 2018, 2021 NXP
> >   *
> >   * Based on CAAM driver in drivers/crypto/caam in Linux
> >   */
> > @@ -11,7 +11,6 @@
> >  #include <linux/kernel.h>
> >  #include <log.h>
> >  #include <malloc.h>
> > -#include "fsl_sec.h"
> >  #include "jr.h"
> >  #include "jobdesc.h"
> >  #include "desc_constr.h"
> > @@ -21,8 +20,11 @@
> >  #include <asm/cache.h>
> >  #include <asm/fsl_pamu.h>
> >  #endif
> > +#include <dm.h>
> >  #include <dm/lists.h>
> >  #include <linux/delay.h>
> > +#include <dm/root.h>
> > +#include <dm/device-internal.h>
> >
> >  #define CIRC_CNT(head, tail, size)     (((head) - (tail)) & (size - 1))
> >  #define CIRC_SPACE(head, tail, size)   CIRC_CNT((tail), (head) + 1, (size))
> > @@ -35,20 +37,30 @@ uint32_t
> sec_offset[CONFIG_SYS_FSL_MAX_NUM_OF_SEC]
> > = {  #endif  };
> >
> > +#if CONFIG_IS_ENABLED(DM)
> > +struct udevice *caam_dev;
> > +#else
> >  #define SEC_ADDR(idx)  \
> >         (ulong)((CONFIG_SYS_FSL_SEC_ADDR + sec_offset[idx]))
> >
> >  #define SEC_JR0_ADDR(idx)      \
> >         (ulong)(SEC_ADDR(idx) + \
> >          (CONFIG_SYS_FSL_JR0_OFFSET - CONFIG_SYS_FSL_SEC_OFFSET))
> > +struct caam_regs caam_st;
> > +#endif
> >
> > -struct jobring jr0[CONFIG_SYS_FSL_MAX_NUM_OF_SEC];
> > +static inline u32 jr_start_reg(u8 jrid) {
> > +       return (1 << jrid);
> > +}
> >
> > -static inline void start_jr0(uint8_t sec_idx)
> > +#ifndef CONFIG_ARCH_IMX8
> > +static inline void start_jr(struct caam_regs *caam)
> >  {
> > -       ccsr_sec_t *sec = (void *)SEC_ADDR(sec_idx);
> > +       ccsr_sec_t *sec = caam->sec;
> >         u32 ctpr_ms = sec_in32(&sec->ctpr_ms);
> >         u32 scfgr = sec_in32(&sec->scfgr);
> > +       u32 jrstart = jr_start_reg(caam->jrid);
> >
> >         if (ctpr_ms & SEC_CTPR_MS_VIRT_EN_INCL) {
> >                 /* VIRT_EN_INCL = 1 & VIRT_EN_POR = 1 or @@ -56,23
> > +68,17 @@ static inline void start_jr0(uint8_t sec_idx)
> >                  */
> >                 if ((ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR) ||
> >                     (scfgr & SEC_SCFGR_VIRT_EN))
> > -                       sec_out32(&sec->jrstartr, CONFIG_JRSTARTR_JR0);
> > +                       sec_out32(&sec->jrstartr, jrstart);
> >         } else {
> >                 /* VIRT_EN_INCL = 0 && VIRT_EN_POR_VALUE = 1 */
> >                 if (ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR)
> > -                       sec_out32(&sec->jrstartr, CONFIG_JRSTARTR_JR0);
> > +                       sec_out32(&sec->jrstartr, jrstart);
> >         }
> >  }
> > +#endif
> >
> > -static inline void jr_reset_liodn(uint8_t sec_idx) -{
> > -       ccsr_sec_t *sec = (void *)SEC_ADDR(sec_idx);
> > -       sec_out32(&sec->jrliodnr[0].ls, 0);
> > -}
> > -
> > -static inline void jr_disable_irq(uint8_t sec_idx)
> > +static inline void jr_disable_irq(struct jr_regs *regs)
> >  {
> > -       struct jr_regs *regs = (struct jr_regs *)SEC_JR0_ADDR(sec_idx);
> >         uint32_t jrcfg = sec_in32(&regs->jrcfg1);
> >
> >         jrcfg = jrcfg | JR_INTMASK;
> > @@ -80,10 +86,10 @@ static inline void jr_disable_irq(uint8_t sec_idx)
> >         sec_out32(&regs->jrcfg1, jrcfg);  }
> >
> > -static void jr_initregs(uint8_t sec_idx)
> > +static void jr_initregs(uint8_t sec_idx, struct caam_regs *caam)
> >  {
> > -       struct jr_regs *regs = (struct jr_regs *)SEC_JR0_ADDR(sec_idx);
> > -       struct jobring *jr = &jr0[sec_idx];
> > +       struct jr_regs *regs = caam->regs;
> > +       struct jobring *jr = &caam->jr[sec_idx];
> >         caam_dma_addr_t ip_base = virt_to_phys((void *)jr->input_ring);
> >         caam_dma_addr_t op_base = virt_to_phys((void
> > *)jr->output_ring);
> >
> > @@ -103,16 +109,16 @@ static void jr_initregs(uint8_t sec_idx)
> >         sec_out32(&regs->irs, JR_SIZE);
> >
> >         if (!jr->irq)
> > -               jr_disable_irq(sec_idx);
> > +               jr_disable_irq(regs);
> >  }
> >
> > -static int jr_init(uint8_t sec_idx)
> > +static int jr_init(uint8_t sec_idx, struct caam_regs *caam)
> >  {
> > -       struct jobring *jr = &jr0[sec_idx];
> > +       struct jobring *jr = &caam->jr[sec_idx];
> >
> >         memset(jr, 0, sizeof(struct jobring));
> >
> > -       jr->jq_id = DEFAULT_JR_ID;
> > +       jr->jq_id = caam->jrid;
> >         jr->irq = DEFAULT_IRQ;
> >
> >  #ifdef CONFIG_FSL_CORENET
> > @@ -134,53 +140,10 @@ static int jr_init(uint8_t sec_idx)
> >         memset(jr->input_ring, 0, JR_SIZE * sizeof(caam_dma_addr_t));
> >         memset(jr->output_ring, 0, jr->op_size);
> >
> > -       start_jr0(sec_idx);
> > -
> > -       jr_initregs(sec_idx);
> > -
> > -       return 0;
> > -}
> > -
> > -static int jr_sw_cleanup(uint8_t sec_idx) -{
> > -       struct jobring *jr = &jr0[sec_idx];
> > -
> > -       jr->head = 0;
> > -       jr->tail = 0;
> > -       jr->read_idx = 0;
> > -       jr->write_idx = 0;
> > -       memset(jr->info, 0, sizeof(jr->info));
> > -       memset(jr->input_ring, 0, jr->size * sizeof(caam_dma_addr_t));
> > -       memset(jr->output_ring, 0, jr->size * sizeof(struct op_ring));
> > -
> > -       return 0;
> > -}
> > -
> > -static int jr_hw_reset(uint8_t sec_idx) -{
> > -       struct jr_regs *regs = (struct jr_regs *)SEC_JR0_ADDR(sec_idx);
> > -       uint32_t timeout = 100000;
> > -       uint32_t jrint, jrcr;
> > -
> > -       sec_out32(&regs->jrcr, JRCR_RESET);
> > -       do {
> > -               jrint = sec_in32(&regs->jrint);
> > -       } while (((jrint & JRINT_ERR_HALT_MASK) ==
> > -                 JRINT_ERR_HALT_INPROGRESS) && --timeout);
> > -
> > -       jrint = sec_in32(&regs->jrint);
> > -       if (((jrint & JRINT_ERR_HALT_MASK) !=
> > -            JRINT_ERR_HALT_INPROGRESS) && timeout == 0)
> > -               return -1;
> > -
> > -       timeout = 100000;
> > -       sec_out32(&regs->jrcr, JRCR_RESET);
> > -       do {
> > -               jrcr = sec_in32(&regs->jrcr);
> > -       } while ((jrcr & JRCR_RESET) && --timeout);
> > -
> > -       if (timeout == 0)
> > -               return -1;
> > +#ifndef CONFIG_ARCH_IMX8
> > +       start_jr(caam);
> > +#endif
> > +       jr_initregs(sec_idx, caam);
> >
> >         return 0;
> >  }
> > @@ -188,10 +151,10 @@ static int jr_hw_reset(uint8_t sec_idx)
> >  /* -1 --- error, can't enqueue -- no space available */  static int
> > jr_enqueue(uint32_t *desc_addr,
> >                void (*callback)(uint32_t status, void *arg),
> > -              void *arg, uint8_t sec_idx)
> > +              void *arg, uint8_t sec_idx, struct caam_regs *caam)
> >  {
> > -       struct jr_regs *regs = (struct jr_regs *)SEC_JR0_ADDR(sec_idx);
> > -       struct jobring *jr = &jr0[sec_idx];
> > +       struct jr_regs *regs = caam->regs;
> > +       struct jobring *jr = &caam->jr[sec_idx];
> >         int head = jr->head;
> >         uint32_t desc_word;
> >         int length = desc_len(desc_addr); @@ -263,10 +226,10 @@ static
> > int jr_enqueue(uint32_t *desc_addr,
> >         return 0;
> >  }
> >
> > -static int jr_dequeue(int sec_idx)
> > +static int jr_dequeue(int sec_idx, struct caam_regs *caam)
> >  {
> > -       struct jr_regs *regs = (struct jr_regs *)SEC_JR0_ADDR(sec_idx);
> > -       struct jobring *jr = &jr0[sec_idx];
> > +       struct jr_regs *regs = caam->regs;
> > +       struct jobring *jr = &caam->jr[sec_idx];
> >         int head = jr->head;
> >         int tail = jr->tail;
> >         int idx, i, found;
> > @@ -349,14 +312,18 @@ static void desc_done(uint32_t status, void
> > *arg)  {
> >         struct result *x = arg;
> >         x->status = status;
> > -#ifndef CONFIG_SPL_BUILD
> >         caam_jr_strstatus(status);
> > -#endif
> >         x->done = 1;
> >  }
> >
> >  static inline int run_descriptor_jr_idx(uint32_t *desc, uint8_t
> > sec_idx)  {
> > +       struct caam_regs *caam;
> > +#if CONFIG_IS_ENABLED(DM)
> > +       caam = dev_get_priv(caam_dev); #else
> > +       caam = &caam_st;
> > +#endif
> >         unsigned long long timeval = 0;
> >         unsigned long long timeout = CONFIG_USEC_DEQ_TIMEOUT;
> >         struct result op;
> > @@ -364,7 +331,7 @@ static inline int run_descriptor_jr_idx(uint32_t
> > *desc, uint8_t sec_idx)
> >
> >         memset(&op, 0, sizeof(op));
> >
> > -       ret = jr_enqueue(desc, desc_done, &op, sec_idx);
> > +       ret = jr_enqueue(desc, desc_done, &op, sec_idx, caam);
> >         if (ret) {
> >                 debug("Error in SEC enq\n");
> >                 ret = JQ_ENQ_ERR;
> > @@ -375,7 +342,7 @@ static inline int run_descriptor_jr_idx(uint32_t
> > *desc, uint8_t sec_idx)
> >                 udelay(1);
> >                 timeval += 1;
> >
> > -               ret = jr_dequeue(sec_idx);
> > +               ret = jr_dequeue(sec_idx, caam);
> >                 if (ret) {
> >                         debug("Error in SEC deq\n");
> >                         ret = JQ_DEQ_ERR; @@ -402,13 +369,63 @@ int
> > run_descriptor_jr(uint32_t *desc)
> >         return run_descriptor_jr_idx(desc, 0);  }
> >
> > +#ifndef CONFIG_ARCH_IMX8
> > +static int jr_sw_cleanup(uint8_t sec_idx, struct caam_regs *caam) {
> > +       struct jobring *jr = &caam->jr[sec_idx];
> > +
> > +       jr->head = 0;
> > +       jr->tail = 0;
> > +       jr->read_idx = 0;
> > +       jr->write_idx = 0;
> > +       memset(jr->info, 0, sizeof(jr->info));
> > +       memset(jr->input_ring, 0, jr->size * sizeof(caam_dma_addr_t));
> > +       memset(jr->output_ring, 0, jr->size * sizeof(struct op_ring));
> > +
> > +       return 0;
> > +}
> > +
> > +static int jr_hw_reset(struct jr_regs *regs) {
> > +       uint32_t timeout = 100000;
> > +       uint32_t jrint, jrcr;
> > +
> > +       sec_out32(&regs->jrcr, JRCR_RESET);
> > +       do {
> > +               jrint = sec_in32(&regs->jrint);
> > +       } while (((jrint & JRINT_ERR_HALT_MASK) ==
> > +                 JRINT_ERR_HALT_INPROGRESS) && --timeout);
> > +
> > +       jrint = sec_in32(&regs->jrint);
> > +       if (((jrint & JRINT_ERR_HALT_MASK) !=
> > +            JRINT_ERR_HALT_INPROGRESS) && timeout == 0)
> > +               return -1;
> > +
> > +       timeout = 100000;
> > +       sec_out32(&regs->jrcr, JRCR_RESET);
> > +       do {
> > +               jrcr = sec_in32(&regs->jrcr);
> > +       } while ((jrcr & JRCR_RESET) && --timeout);
> > +
> > +       if (timeout == 0)
> > +               return -1;
> > +
> > +       return 0;
> > +}
> > +
> >  static inline int jr_reset_sec(uint8_t sec_idx)  {
> > -       if (jr_hw_reset(sec_idx) < 0)
> > +       struct caam_regs *caam;
> > +#if CONFIG_IS_ENABLED(DM)
> > +       caam = dev_get_priv(caam_dev); #else
> > +       caam = &caam_st;
> > +#endif
> > +       if (jr_hw_reset(caam->regs) < 0)
> >                 return -1;
> >
> >         /* Clean up the jobring structure maintained by software */
> > -       jr_sw_cleanup(sec_idx);
> > +       jr_sw_cleanup(sec_idx, caam);
> >
> >         return 0;
> >  }
> > @@ -418,9 +435,15 @@ int jr_reset(void)
> >         return jr_reset_sec(0);
> >  }
> >
> > -static inline int sec_reset_idx(uint8_t sec_idx)
> > +int sec_reset(void)
> >  {
> > -       ccsr_sec_t *sec = (void *)SEC_ADDR(sec_idx);
> > +       struct caam_regs *caam;
> > +#if CONFIG_IS_ENABLED(DM)
> > +       caam = dev_get_priv(caam_dev); #else
> > +       caam = &caam_st;
> > +#endif
> > +       ccsr_sec_t *sec = caam->sec;
> >         uint32_t mcfgr = sec_in32(&sec->mcfgr);
> >         uint32_t timeout = 100000;
> >
> > @@ -446,11 +469,7 @@ static inline int sec_reset_idx(uint8_t sec_idx)
> >
> >         return 0;
> >  }
> > -int sec_reset(void)
> > -{
> > -       return sec_reset_idx(0);
> > -}
> > -#ifndef CONFIG_SPL_BUILD
> > +
> >  static int deinstantiate_rng(u8 sec_idx, int state_handle_mask)  {
> >         u32 *desc;
> > @@ -496,12 +515,11 @@ static int deinstantiate_rng(u8 sec_idx, int
> > state_handle_mask)
> >         return ret;
> >  }
> >
> > -static int instantiate_rng(u8 sec_idx, int gen_sk)
> > +static int instantiate_rng(uint8_t sec_idx, ccsr_sec_t *sec, int
> > +gen_sk)
> >  {
> >         u32 *desc;
> >         u32 rdsta_val;
> >         int ret = 0, sh_idx, size;
> > -       ccsr_sec_t __iomem *sec = (ccsr_sec_t __iomem *)SEC_ADDR(sec_idx);
> >         struct rng4tst __iomem *rng =
> >                         (struct rng4tst __iomem *)&sec->rng;
> >
> > @@ -554,9 +572,8 @@ static int instantiate_rng(u8 sec_idx, int gen_sk)
> >         return ret;
> >  }
> >
> > -static u8 get_rng_vid(uint8_t sec_idx)
> > +static u8 get_rng_vid(ccsr_sec_t *sec)
> >  {
> > -       ccsr_sec_t *sec = (void *)SEC_ADDR(sec_idx);
> >         u8 vid;
> >
> >         if (caam_get_era() < 10) {
> > @@ -574,9 +591,8 @@ static u8 get_rng_vid(uint8_t sec_idx)
> >   * By default, the TRNG runs for 200 clocks per sample;
> >   * 1200 clocks per sample generates better entropy.
> >   */
> > -static void kick_trng(int ent_delay, uint8_t sec_idx)
> > +static void kick_trng(int ent_delay, ccsr_sec_t *sec)
> >  {
> > -       ccsr_sec_t __iomem *sec = (ccsr_sec_t __iomem *)SEC_ADDR(sec_idx);
> >         struct rng4tst __iomem *rng =
> >                         (struct rng4tst __iomem *)&sec->rng;
> >         u32 val;
> > @@ -603,10 +619,9 @@ static void kick_trng(int ent_delay, uint8_t sec_idx)
> >         sec_clrbits32(&rng->rtmctl, RTMCTL_PRGM);  }
> >
> > -static int rng_init(uint8_t sec_idx)
> > +static int rng_init(uint8_t sec_idx, ccsr_sec_t *sec)
> >  {
> >         int ret, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
> > -       ccsr_sec_t __iomem *sec = (ccsr_sec_t __iomem *)SEC_ADDR(sec_idx);
> >         struct rng4tst __iomem *rng =
> >                         (struct rng4tst __iomem *)&sec->rng;
> >         u32 inst_handles;
> > @@ -624,7 +639,7 @@ static int rng_init(uint8_t sec_idx)
> >                  * the TRNG parameters.
> >                  */
> >                 if (!inst_handles) {
> > -                       kick_trng(ent_delay, sec_idx);
> > +                       kick_trng(ent_delay, sec);
> >                         ent_delay += 400;
> >                 }
> >                 /*
> > @@ -634,7 +649,7 @@ static int rng_init(uint8_t sec_idx)
> >                  * interval, leading to a sucessful initialization of
> >                  * the RNG.
> >                  */
> > -               ret = instantiate_rng(sec_idx, gen_sk);
> > +               ret = instantiate_rng(sec_idx, sec, gen_sk);
> >         } while ((ret == -1) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
> >         if (ret) {
> >                 printf("SEC%u:  Failed to instantiate RNG\n",
> > sec_idx); @@ -647,12 +662,29 @@ static int rng_init(uint8_t sec_idx)
> >         return ret;
> >  }
> >  #endif
> > +
> >  int sec_init_idx(uint8_t sec_idx)
> >  {
> > -       ccsr_sec_t *sec = (void *)SEC_ADDR(sec_idx);
> > -       uint32_t mcr = sec_in32(&sec->mcfgr);
> >         int ret = 0;
> > -
> > +       struct caam_regs *caam;
> > +#if CONFIG_IS_ENABLED(DM)
> > +       if (caam_dev == NULL) {
> > +               printf("caam_jr: caam not found\n");
> > +               return -1;
> > +       }
> > +       caam = dev_get_priv(caam_dev); #else
> > +       caam_st.sec = (void *)SEC_ADDR(sec_idx);
> > +       caam_st.regs = (struct jr_regs *)SEC_JR0_ADDR(sec_idx);
> > +       caam_st.jrid = 0;
> > +       caam = &caam_st;
> > +#endif
> > +#ifndef CONFIG_ARCH_IMX8
> > +       ccsr_sec_t *sec = caam->sec;
> > +       uint32_t mcr = sec_in32(&sec->mcfgr); #if
> > +defined(CONFIG_SPL_BUILD) && defined(CONFIG_IMX8M)
> > +       uint32_t jrdid_ms = 0;
> > +#endif
> >  #ifdef CONFIG_FSL_CORENET
> >         uint32_t liodnr;
> >         uint32_t liodn_ns;
> > @@ -682,6 +714,11 @@ int sec_init_idx(uint8_t sec_idx)
> >         mcr |= (1 << MCFGR_PS_SHIFT);
> >  #endif
> >         sec_out32(&sec->mcfgr, mcr);
> > +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_IMX8M)
> 
> This would effectively reserve the JR0 on _all_ i.MX8M derivatives is S World.
This code is to set any JR DID in SPL so that the job ring can be configured. 

> 
> Current implementation only has JR0 reserved in S World on imx8mm derivative,
> but this new addition extends this to imx8mn, imx8mp and imx8mq.
Current implementation do not initialize CAAM for i.MX8M derivatives. It is not based on driver model approach and only using JR0.
With New implementation CAAM is enabled for i.MX8M derivative. Any JR whose DID is written in ATF, can be used in Uboot.
JR0 is reserved for HAB so JR1 will be used for all i.MX8M derivatives.

> 
> I'm wondering about several points here:
> 1. Why does current implementation on have this reservation done on imx8mm
> and
>    where does this happen? None of the code pieces suggests that it is done in
>    U-Boot, is it performed in BootROM?

I cannot see if current implementation(SPL/Uboot) has reservation done for imx8mm.
In ATF, we are reserving the JR0.

> 2. What is the intention of having JR0 reserved for all derivatives? Is this
>    the part of a bigger change that stretches across different SW components
>    (e.g. ATF, OP-TEE, etc.)? If that is the case - then a more detailed
>    description would be appreciated here.
> 
> ATF code already accounts for this reservation in commit:
> a83a7c65e ("TEE-639 plat: imx8m: Do not release JR0 to NS if HAB is using it")
> [1], but there is no description on why is this required though.
> 
> If this is required for HAB feature, then the question is: should it be kept in S
> World when U-Boot starts, or SPL can release it after the binary is verified and
> crypto facilities are not in use anymore?

Commit: a83a7c65e reserves JR0 for HAB and not released to NS but JR1, JR2 are released to NS.
HAB uses JR0 for secure boot on all i.MX8M derivatives. Uboot calls HAB API for authenticating kernel.

> 
> > +       jrdid_ms = JRDID_MS_TZ_OWN | JRDID_MS_PRIM_TZ |
> > + JRDID_MS_PRIM_DID;
> 
> What is the intention of setting JRDID_MS_PRIM_TZ? Isn't setting
> JRDID_MS_TZ_OWN would be sufficient here?

PRIM_TZ bit is set to 1 to indicate that only SecureWorld can
access registers in that Job Ring's register page

> 
> > +       sec_out32(&sec->jrliodnr[caam->jrid].ms, jrdid_ms); #endif
> > +       jr_reset();
> >
> >  #ifdef CONFIG_FSL_CORENET
> >  #ifdef CONFIG_SPL_BUILD
> > @@ -693,25 +730,26 @@ int sec_init_idx(uint8_t sec_idx)
> >         liodn_ns = CONFIG_SPL_JR0_LIODN_NS & JRNSLIODN_MASK;
> >         liodn_s = CONFIG_SPL_JR0_LIODN_S & JRSLIODN_MASK;
> >
> > -       liodnr = sec_in32(&sec->jrliodnr[0].ls) &
> > +       liodnr = sec_in32(&sec->jrliodnr[caam->jrid].ls) &
> >                  ~(JRNSLIODN_MASK | JRSLIODN_MASK);
> >         liodnr = liodnr |
> >                  (liodn_ns << JRNSLIODN_SHIFT) |
> >                  (liodn_s << JRSLIODN_SHIFT);
> > -       sec_out32(&sec->jrliodnr[0].ls, liodnr);
> > +       sec_out32(&sec->jrliodnr[caam->jrid].ls, liodnr);
> >  #else
> > -       liodnr = sec_in32(&sec->jrliodnr[0].ls);
> > +       liodnr = sec_in32(&sec->jrliodnr[caam->jrid].ls);
> >         liodn_ns = (liodnr & JRNSLIODN_MASK) >> JRNSLIODN_SHIFT;
> >         liodn_s = (liodnr & JRSLIODN_MASK) >> JRSLIODN_SHIFT;  #endif
> > #endif
> > -
> > -       ret = jr_init(sec_idx);
> > +#endif
> > +       ret = jr_init(sec_idx, caam);
> >         if (ret < 0) {
> >                 printf("SEC%u:  initialization failed\n", sec_idx);
> >                 return -1;
> >         }
> >
> > +#ifndef CONFIG_ARCH_IMX8
> >  #ifdef CONFIG_FSL_CORENET
> >         ret = sec_config_pamu_table(liodn_ns, liodn_s);
> >         if (ret < 0)
> > @@ -719,9 +757,9 @@ int sec_init_idx(uint8_t sec_idx)
> >
> >         pamu_enable();
> >  #endif
> > -#ifndef CONFIG_SPL_BUILD
> > -       if (get_rng_vid(sec_idx) >= 4) {
> > -               if (rng_init(sec_idx) < 0) {
> > +
> > +       if (get_rng_vid(caam->sec) >= 4) {
> > +               if (rng_init(sec_idx, caam->sec) < 0) {
> >                         printf("SEC%u:  RNG instantiation failed\n", sec_idx);
> >                         return -1;
> >                 }
> > @@ -743,3 +781,63 @@ int sec_init(void)  {
> >         return sec_init_idx(0);
> >  }
> > +
> > +#if CONFIG_IS_ENABLED(DM)
> > +static int caam_jr_probe(struct udevice *dev) {
> > +       struct caam_regs *caam = dev_get_priv(dev);
> > +       fdt_addr_t addr;
> > +       ofnode node;
> > +       unsigned int jr_node = 0;
> > +
> > +       caam_dev = dev;
> > +
> > +       addr = dev_read_addr(dev);
> > +       if (addr == FDT_ADDR_T_NONE) {
> > +               printf("caam_jr: crypto not found\n");
> > +               return -EINVAL;
> > +       }
> > +       caam->sec = (ccsr_sec_t *)(uintptr_t)addr;
> > +       caam->regs = (struct jr_regs *)caam->sec;
> > +
> > +       /* Check for enabled job ring node */
> > +       ofnode_for_each_subnode(node, dev_ofnode(dev)) {
> > +               if (!ofnode_is_available(node)) {
> > +                       continue;
> > +               }
> > +               jr_node = ofnode_read_u32_default(node, "reg", -1);
> > +               if (jr_node > 0) {
> > +                       caam->regs = (struct jr_regs
> > + *)((ulong)caam->sec +
> > jr_node);
> > +                       while (!(jr_node & 0x0F)) {
> > +                               jr_node = jr_node >> 4;
> > +                       }
> > +                       caam->jrid = jr_node - 1;
> > +                       break;
> > +               }
> > +       }
> > +
> > +       if (sec_init())
> > +               printf("\nsec_init failed!\n");
> > +
> > +       return 0;
> > +}
> > +
> > +static int caam_jr_bind(struct udevice *dev) {
> > +       return 0;
> > +}
> > +
> > +static const struct udevice_id caam_jr_match[] = {
> > +       { .compatible = "fsl,sec-v4.0" },
> > +       { }
> > +};
> > +
> > +U_BOOT_DRIVER(caam_jr) = {
> > +       .name           = "caam_jr",
> > +       .id             = UCLASS_MISC,
> > +       .of_match       = caam_jr_match,
> > +       .bind           = caam_jr_bind,
> > +       .probe          = caam_jr_probe,
> > +       .priv_auto      = sizeof(struct caam_regs),
> > +};
> > +#endif
> > diff --git a/drivers/crypto/fsl/jr.h b/drivers/crypto/fsl/jr.h index
> > 1047aa772c..43cb5e0753 100644
> > --- a/drivers/crypto/fsl/jr.h
> > +++ b/drivers/crypto/fsl/jr.h
> > @@ -1,6 +1,7 @@
> >  /* SPDX-License-Identifier: GPL-2.0+ */
> >  /*
> >   * Copyright 2008-2014 Freescale Semiconductor, Inc.
> > + * Copyright 2021 NXP
> >   *
> >   */
> >
> > @@ -8,7 +9,9 @@
> >  #define __JR_H
> >
> >  #include <linux/compiler.h>
> > +#include "fsl_sec.h"
> >  #include "type.h"
> > +#include <misc.h>
> >
> >  #define JR_SIZE 4
> >  /* Timeout currently defined as 10 sec */ @@ -35,6 +38,10 @@
> >  #define JRSLIODN_SHIFT         0
> >  #define JRSLIODN_MASK          0x00000fff
> >
> > +#define JRDID_MS_PRIM_DID      1
> > +#define JRDID_MS_PRIM_TZ       (1 << 4)
> > +#define JRDID_MS_TZ_OWN                (1 << 15)
> 
> Maybe use BIT() macro here?
Will do the change in next version of this patch series.

Regards
Gaurav Jain
> 
> > +
> >  #define JQ_DEQ_ERR             -1
> >  #define JQ_DEQ_TO_ERR          -2
> >  #define JQ_ENQ_ERR             -3
> > @@ -102,6 +109,13 @@ struct result {
> >         uint32_t status;
> >  };
> >
> > +struct caam_regs {
> > +       ccsr_sec_t *sec;
> > +       struct jr_regs *regs;
> > +       u8 jrid;
> > +       struct jobring jr[CONFIG_SYS_FSL_MAX_NUM_OF_SEC];
> > +};
> > +
> >  void caam_jr_strstatus(u32 status);
> >  int run_descriptor_jr(uint32_t *desc);
> >
> > --
> > 2.17.1
> 
> -- andrey
> 
> Link: [1]:
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.c
> odeaurora.org%2Fexternal%2Fimx%2Fimx-
> atf%2Fcommit%2F%3Fid%3Da83a7c65ea4e7b41d5c8fb129bac9caa89053d5e&a
> mp;data=04%7C01%7Cgaurav.jain%40nxp.com%7C1b6edcabe31e4b9cae3d08d
> 9a9195296%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637726748
> 521538374%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV
> 2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=ANasYQwEH
> %2BEFyBbbWn8dBk2HcvwYdFr3QHXUAu74SIg%3D&reserved=0



More information about the U-Boot mailing list