From: Stefan Herbrechtsmeier <stefan.herbrechtsme...@weidmueller.com>

Signed-off-by: Stefan Herbrechtsmeier <stefan.herbrechtsme...@weidmueller.com>

---

 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;
+       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;
        }
 
-       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
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to