Hi Stefan,

> -----Original Message-----
> From: [email protected] [mailto:[email protected]]
> Sent: Friday, June 08, 2018 5:29 PM
> To: Siva Durga Prasad Paladugu <[email protected]>
> Cc: Stefan Herbrechtsmeier <[email protected]>;
> [email protected]; Michal Simek <[email protected]>;
> [email protected]
> Subject: [RFC PATCH] fpga: zynq: Add encrypted bitstream support with
> auto detect
> 

Patch description here please.

> From: Stefan Herbrechtsmeier
> <[email protected]>
> 
> Signed-off-by: Stefan Herbrechtsmeier
> <[email protected]>
> 
> ---
> 
>  drivers/fpga/zynqpl.c | 73
> ++++++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 57 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index
> fd37d18..6622750 100644
> --- a/drivers/fpga/zynqpl.c
> +++ b/drivers/fpga/zynqpl.c
> @@ -17,6 +17,7 @@
> 
>  #define DEVCFG_CTRL_PCFG_PROG_B              0x40000000
>  #define DEVCFG_CTRL_PCFG_AES_EFUSE_MASK      0x00001000
> +#define DEVCFG_CTRL_PCAP_RATE_EN_MASK        0x02000000
>  #define DEVCFG_ISR_FATAL_ERROR_MASK  0x00740040
>  #define DEVCFG_ISR_ERROR_FLAGS_MASK  0x00340840
>  #define DEVCFG_ISR_RX_FIFO_OV                0x00040000
> @@ -38,18 +39,16 @@
>  #define CONFIG_SYS_FPGA_PROG_TIME    (CONFIG_SYS_HZ * 4) /* 4 s
> */
>  #endif
> 
> +#define NOP_WORD     0x20000000
> +#define CTRL0_WORD   0x3000a001
> +#define MASK_WORD    0x3000c001
>  #define DUMMY_WORD   0xffffffff
> 
> +#define CTRL0_DEC_MASK       BIT(6)
> +
>  /* Xilinx binary format header */
> +#define MAX_DUMMY_WORD_COUNT 8
>  static const u32 bin_format[] = {
> -     DUMMY_WORD, /* Dummy words */
> -     DUMMY_WORD,
> -     DUMMY_WORD,
> -     DUMMY_WORD,
> -     DUMMY_WORD,
> -     DUMMY_WORD,
> -     DUMMY_WORD,
> -     DUMMY_WORD,
>       0x000000bb, /* Sync word */
>       0x11220044, /* Sync word */
>       DUMMY_WORD,
> @@ -85,7 +84,23 @@ static u32 load_word(const void *buf, u32 swap)
>       return word;
>  }
> 
> -static u32 check_header(const void *buf)
> +static void *skip_dummy_words(const void *buf) {
> +     u32 *test = (u32 *)buf;
> +     u32 i;
> +
> +     for (i = 0; i < MAX_DUMMY_WORD_COUNT; i++) {
> +             if (load_word(&test[i], SWAP_NO) != DUMMY_WORD) {
> +                     debug("%s: Found no dummy word at position
> %d/%x\n",
> +                           __func__, i, (u32)&test[i]);
> +                     return &test[i];
> +             }
> +     }
> +
> +     return &test[i];
> +}
> +
> +static u32 check_header(const void *buf, bool *encrypted)
>  {
>       u32 i, pattern;
>       int swap = SWAP_NO;
> @@ -93,6 +108,8 @@ static u32 check_header(const void *buf)
> 
>       debug("%s: Let's check bitstream header\n", __func__);
> 
> +     test = (u32 *)skip_dummy_words(buf);
> +
>       /* Checking that passing bin is not a bitstream */
>       for (i = 0; i < ARRAY_SIZE(bin_format); i++) {
>               pattern = load_word(&test[i], swap);
> @@ -112,18 +129,34 @@ static u32 check_header(const void *buf)
> 
>               debug("%s: %d/%x: pattern %x/%x bin_format\n",
> __func__, i,
>                     (u32)&test[i], pattern, bin_format[i]);
> +
>               if (pattern != bin_format[i]) {
>                       debug("%s: Bitstream is not recognized\n",
> __func__);
>                       return 0;
>               }
>       }
> -     debug("%s: Found bitstream header at %x %s swapinng\n",
> __func__,
> -           (u32)buf, swap == SWAP_NO ? "without" : "with");
> +
> +     test = &test[i];
> +
> +     /* Checking if passing bin is an encrypted bitstream */
> +     if ((load_word(&test[0], swap) == NOP_WORD) &&
> +         (load_word(&test[1], swap) == MASK_WORD) &&
> +         (load_word(&test[2], swap) & CTRL0_DEC_MASK) &&
> +         (load_word(&test[3], swap) == CTRL0_WORD) &&
> +         (load_word(&test[4], swap) & CTRL0_DEC_MASK) &&
> +         (load_word(&test[5], swap) == NOP_WORD))
> +             *encrypted = true;
> +     else
> +             *encrypted = false;
> +
> +     debug("%s: Found %sencrypted bitstream header at %x %s
> swapping\n",
> +           __func__, *encrypted ? "" : "un", (u32)buf,
> +           swap == SWAP_NO ? "without" : "with");
> 
>       return swap;
>  }
> 
> -static void *check_data(u8 *buf, size_t bsize, u32 *swap)
> +static void *check_data(u8 *buf, size_t bsize, u32 *swap, bool
> +*encrypted)
>  {
>       u32 word, p = 0; /* possition */
> 
> @@ -136,7 +169,7 @@ static void *check_data(u8 *buf, size_t bsize, u32
> *swap)
>               if (word == DUMMY_WORD) {
>                       debug("%s: Found dummy word at position
> %x/%x\n",
>                             __func__, p, (u32)&buf[p]);
> -                     *swap = check_header(&buf[p]);
> +                     *swap = check_header(&buf[p], encrypted);
>                       if (*swap) {
>                               /* FIXME add full bitstream checking here */
>                               return &buf[p];
> @@ -191,7 +224,7 @@ static int zynq_dma_transfer(u32 srcbuf, u32
> srclen, u32 dstbuf, u32 dstlen)
>       return FPGA_SUCCESS;
>  }
> 
> -static int zynq_dma_xfer_init(bitstream_type bstype)
> +static int zynq_dma_xfer_init(bitstream_type bstype, bool encrypted)
>  {
>       u32 status, control, isr_status;
>       unsigned long ts;
> @@ -291,6 +324,13 @@ static int zynq_dma_xfer_init(bitstream_type
> bstype)
>               writel(DEVCFG_STATUS_DMA_DONE_CNT_MASK,
> &devcfg_base->status);
>       }
> 
> +     control = readl(&devcfg_base->ctrl);
> +     if (encrypted)
> +             control |= DEVCFG_CTRL_PCAP_RATE_EN_MASK;
> +     else
> +             control &= ~DEVCFG_CTRL_PCAP_RATE_EN_MASK;

Clearing here is fine. Can we do the same at the end of bitstream programming 
because we should clear it
once we are done, just to be in proper state for next component.

> +     writel(control, &devcfg_base->ctrl);
> +
>       return FPGA_SUCCESS;
>  }
> 
> @@ -336,10 +376,11 @@ static int zynq_validate_bitstream(xilinx_desc
> *desc, const void *buf,
>                                  size_t bsize, u32 blocksize, u32 *swap,
>                                  bitstream_type *bstype)
>  {
> +     bool encrypted = false;
>       u32 *buf_start;
>       u32 diff;
> 
> -     buf_start = check_data((u8 *)buf, blocksize, swap);
> +     buf_start = check_data((u8 *)buf, blocksize, swap, &encrypted);
> 
>       if (!buf_start)
>               return FPGA_FAIL;
> @@ -358,7 +399,7 @@ static int zynq_validate_bitstream(xilinx_desc
> *desc, const void *buf,
>               return FPGA_FAIL;
>       }
> 
I think here we should add condition to check if AES engine is enabled in case 
of encrypted bitstream and return error if not enabled.

AES engine enablement can be checked using PCFG_AES_EN  bits 9-11 of control 
register. 

Thanks,
Siva

> -     if (zynq_dma_xfer_init(*bstype))
> +     if (zynq_dma_xfer_init(*bstype, encrypted))
>               return FPGA_FAIL;
> 
>       return 0;
> --
> 2.7.4

_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to