bugfix CAAM error on startup

Heinrich Schuchardt xypron.glpk at gmx.de
Fri May 2 19:33:34 CEST 2025


Hello Olaf,

The mail arrived without any subject line in the email header.
There was only a subject line in the message body.
The patch cannot be processed by the tooling of the U-Boot project 
without a proper subject line.

Please, resend your patch with a subject header line,
e.g. using `git email`.

Best regards

Heinrich

On 5/2/25 11:02, Baehring, Olaf wrote:
> Internal
> 
> Subject: [PATCH] bugfix CAAM error on startup
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
> 
> In rare cases U-Boot returns an error message when intantiating the RNG
> of the CAAM device:
> "SEC0:  RNG4 SH0 instantiation failed with error 0xffffffff"
> This  means, that even when the CAAM device reports a finished
> descriptor, none is found in the output ring.
> This might be caused by a missing cache invalidation before
> reading the memory of the output ring
> This patch moves the cache invalidation of the output ring from start of
> the job to immediately after the notification from hardware where the
> output ring will be read.
> 
> Signed-off-by: Baehring, Olaf <olaf.baehring at draeger.com>
> ---
> 
>   drivers/crypto/fsl/jr.c | 30 +++++++++++++++++-------------
>   drivers/crypto/fsl/jr.h |  4 ----
>   2 files changed, 17 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
> index 8f7a821ebf3..edf678d363e 100644
> --- a/drivers/crypto/fsl/jr.c
> +++ b/drivers/crypto/fsl/jr.c
> @@ -217,13 +217,6 @@ static int jr_enqueue(uint32_t *desc_addr,
> 
>          jr->head = (head + 1) & (jr->size - 1);
> 
> -       /* Invalidate output ring */
> -       start = (unsigned long)jr->output_ring &
> -                                       ~(ARCH_DMA_MINALIGN - 1);
> -       end = ALIGN((unsigned long)jr->output_ring + jr->op_size,
> -                   ARCH_DMA_MINALIGN);
> -       invalidate_dcache_range(start, end);
> -
>          sec_out32(&regs->irja, 1);
> 
>          return 0;
> @@ -243,6 +236,7 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam)
>   #else
>          uint32_t *addr;
>   #endif
> +       unsigned long start, end;
> 
>          while (sec_in32(&regs->orsf) && CIRC_CNT(jr->head, jr->tail,
>                                                   jr->size)) {
> @@ -250,6 +244,14 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam)
>                  found = 0;
> 
>                  caam_dma_addr_t op_desc;
> +
> +               /* Invalidate output ring */
> +               start = (unsigned long)jr->output_ring &
> +                                               ~(ARCH_DMA_MINALIGN - 1);
> +               end = ALIGN((unsigned long)jr->output_ring
> +                                       + jr->op_size, ARCH_DMA_MINALIGN);
> +               invalidate_dcache_range(start, end);
> +
>          #ifdef CONFIG_CAAM_64BIT
>                  /* Read the 64 bit Descriptor address from Output Ring.
>                   * The 32 bit hign and low part of the address will
> @@ -283,28 +285,31 @@ static int jr_dequeue(int sec_idx, struct caam_regs *caam)
>                  }
> 
>                  /* Error condition if match not found */
> -               if (!found)
> +               if (!found) {
> +                       int slots_full = sec_in32(&regs->orsf);
> +
> +                       jr->tail = (jr->tail + slots_full) & (jr->size - 1);
> +                       sec_out32(&regs->orjr, slots_full);
>                          return -1;
> +               }
> 
>                  jr->info[idx].op_done = 1;
>                  callback = (void *)jr->info[idx].callback;
>                  arg = jr->info[idx].arg;
> 
>                  /* When the job on tail idx gets done, increment
> -                * tail till the point where job completed out of oredr has
> +                * tail till the point where job completed out of order has
>                   * been taken into account
>                   */
>                  if (idx == tail)
>                          do {
> +                               jr->info[tail].op_done = 0;
>                                  tail = (tail + 1) & (jr->size - 1);
>                          } while (jr->info[tail].op_done);
> 
>                  jr->tail = tail;
> -               jr->read_idx = (jr->read_idx + 1) & (jr->size - 1);
> 
>                  sec_out32(&regs->orjr, 1);
> -               jr->info[idx].op_done = 0;
> -
>                  callback(status, arg);
>          }
> 
> @@ -378,7 +383,6 @@ static int jr_sw_cleanup(uint8_t sec_idx, struct caam_regs *caam)
> 
>          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));
> diff --git a/drivers/crypto/fsl/jr.h b/drivers/crypto/fsl/jr.h
> index b136cd8d05a..8d5ca03e501 100644
> --- a/drivers/crypto/fsl/jr.h
> +++ b/drivers/crypto/fsl/jr.h
> @@ -83,10 +83,6 @@ struct jobring {
>           * in-order job completion
>           */
>          int tail;
> -       /* Read index of the output ring. It may not match with tail in case
> -        * of out of order completetion
> -        */
> -       int read_idx;
>          /* Write index to input ring. Would be always equal to head */
>          int write_idx;
>          /* Size of the rings. */
> --
> 2.34.1
> 
> ---
> This communication contains confidential information. If you are not the intended recipient please return this email to the sender and delete it from your records.
> 
> Diese Nachricht enthaelt vertrauliche Informationen. Sollten Sie nicht der beabsichtigte Empfaenger dieser E-mail sein, senden Sie bitte diese an den Absender zurueck und loeschen Sie die E-mail aus Ihrem System.



More information about the U-Boot mailing list