[U-Boot] [PATCH v2 3/3] fpga: zynqmp: Add secure bitstream loading for ZynqMP

Siva Durga Prasad Paladugu siva.durga.paladugu at xilinx.com
Thu May 31 09:40:23 UTC 2018


This patch adds support for loading secure bitstreams on ZynqMP
platforms. The secure bitstream images has to be generated using
Xilinx bootgen tool.

Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu at xilinx.com>
---
Changes for v2:
- None
---
 arch/arm/include/asm/arch-zynqmp/sys_proto.h  |  6 ++++
 configs/xilinx_zynqmp_zcu102_rev1_0_defconfig |  1 +
 drivers/fpga/xilinx.c                         | 18 ++++++++++
 drivers/fpga/zynqmppl.c                       | 48 +++++++++++++++++++++++++++
 include/xilinx.h                              |  4 +++
 include/zynqmppl.h                            |  3 ++
 6 files changed, 80 insertions(+)

diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
index 6056bc6..773b930 100644
--- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
@@ -13,8 +13,14 @@
 #define ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD      0xC200002D
 #define KEY_PTR_LEN    32

+#define ZYNQMP_FPGA_BIT_AUTH_DDR       1
+#define ZYNQMP_FPGA_BIT_AUTH_OCM       2
+#define ZYNQMP_FPGA_BIT_ENC_USR_KEY    3
+#define ZYNQMP_FPGA_BIT_ENC_DEV_KEY    4
 #define ZYNQMP_FPGA_BIT_NS             5

+#define ZYNQMP_FPGA_AUTH_DDR   1
+
 enum {
        IDCODE,
        VERSION,
diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
index 4cb3959..1379f14 100644
--- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
@@ -31,6 +31,7 @@ CONFIG_CMD_DFU=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_FPGA_LOADBP=y
 CONFIG_CMD_FPGA_LOADP=y
+CONFIG_CMD_FPGA_LOAD_SECURE=y
 CONFIG_CMD_GPIO=y
 CONFIG_CMD_GPT=y
 CONFIG_CMD_I2C=y
diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c
index 724304a..f513550 100644
--- a/drivers/fpga/xilinx.c
+++ b/drivers/fpga/xilinx.c
@@ -171,6 +171,24 @@ int xilinx_loadfs(xilinx_desc *desc, const void *buf, size_t bsize,
 }
 #endif

+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
+int xilinx_loads(xilinx_desc *desc, const void *buf, size_t bsize,
+                struct fpga_secure_info *fpga_sec_info)
+{
+       if (!xilinx_validate(desc, (char *)__func__)) {
+               printf("%s: Invalid device descriptor\n", __func__);
+               return FPGA_FAIL;
+       }
+
+       if (!desc->operations || !desc->operations->loads) {
+               printf("%s: Missing loads operation\n", __func__);
+               return FPGA_FAIL;
+       }
+
+       return desc->operations->loads(desc, buf, bsize, fpga_sec_info);
+}
+#endif
+
 int xilinx_dump(xilinx_desc *desc, const void *buf, size_t bsize)
 {
        if (!xilinx_validate (desc, (char *)__FUNCTION__)) {
diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c
index b57623b..03ffa8c 100644
--- a/drivers/fpga/zynqmppl.c
+++ b/drivers/fpga/zynqmppl.c
@@ -223,6 +223,51 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize,
        return ret;
 }

+#if defined(CONFIG_CMD_FPGA_LOAD_SECURE) && !defined(CONFIG_SPL_BUILD)
+static int zynqmp_loads(xilinx_desc *desc, const void *buf, size_t bsize,
+                       struct fpga_secure_info *fpga_sec_info)
+{
+       int ret;
+       u32 buf_lo, buf_hi;
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       u8 flag = 0;
+
+       flush_dcache_range((ulong)buf, (ulong)buf +
+                          ALIGN(bsize, CONFIG_SYS_CACHELINE_SIZE));
+
+       if (!fpga_sec_info->encflag)
+               flag |= BIT(ZYNQMP_FPGA_BIT_ENC_DEV_KEY);
+
+       if (fpga_sec_info->userkey_addr &&
+           fpga_sec_info->encflag == FPGA_ENC_USR_KEY) {
+               flush_dcache_range((ulong)fpga_sec_info->userkey_addr,
+                                  (ulong)fpga_sec_info->userkey_addr +
+                                  ALIGN(KEY_PTR_LEN,
+                                        CONFIG_SYS_CACHELINE_SIZE));
+               flag |= BIT(ZYNQMP_FPGA_BIT_ENC_USR_KEY);
+       }
+
+       if (!fpga_sec_info->authflag)
+               flag |= BIT(ZYNQMP_FPGA_BIT_AUTH_OCM);
+
+       if (fpga_sec_info->authflag == ZYNQMP_FPGA_AUTH_DDR)
+               flag |= BIT(ZYNQMP_FPGA_BIT_AUTH_DDR);
+
+       buf_lo = lower_32_bits((ulong)buf);
+       buf_hi = upper_32_bits((ulong)buf);
+
+       ret = invoke_smc(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, buf_lo, buf_hi,
+                        (u32)(uintptr_t)fpga_sec_info->userkey_addr,
+                        flag, ret_payload);
+       if (ret)
+               puts("PL FPGA LOAD fail\n");
+       else
+               puts("Bitstream successfully loaded\n");
+
+       return ret;
+}
+#endif
+
 static int zynqmp_pcap_info(xilinx_desc *desc)
 {
        int ret;
@@ -238,5 +283,8 @@ static int zynqmp_pcap_info(xilinx_desc *desc)

 struct xilinx_fpga_op zynqmp_op = {
        .load = zynqmp_load,
+#if defined CONFIG_CMD_FPGA_LOAD_SECURE
+       .loads = zynqmp_loads,
+#endif
        .info = zynqmp_pcap_info,
 };
diff --git a/include/xilinx.h b/include/xilinx.h
index 9429f51..af40bef 100644
--- a/include/xilinx.h
+++ b/include/xilinx.h
@@ -48,6 +48,8 @@ typedef struct {              /* typedef xilinx_desc */
 struct xilinx_fpga_op {
        int (*load)(xilinx_desc *, const void *, size_t, bitstream_type);
        int (*loadfs)(xilinx_desc *, const void *, size_t, fpga_fs_info *);
+       int (*loads)(xilinx_desc *desc, const void *buf, size_t bsize,
+                    struct fpga_secure_info *fpga_sec_info);
        int (*dump)(xilinx_desc *, const void *, size_t);
        int (*info)(xilinx_desc *);
 };
@@ -60,6 +62,8 @@ int xilinx_dump(xilinx_desc *desc, const void *buf, size_t bsize);
 int xilinx_info(xilinx_desc *desc);
 int xilinx_loadfs(xilinx_desc *desc, const void *buf, size_t bsize,
                  fpga_fs_info *fpga_fsinfo);
+int xilinx_loads(xilinx_desc *desc, const void *buf, size_t bsize,
+                struct fpga_secure_info *fpga_sec_info);

 /* Board specific implementation specific function types
  *********************************************************************/
diff --git a/include/zynqmppl.h b/include/zynqmppl.h
index a0f4e68..5214db9 100644
--- a/include/zynqmppl.h
+++ b/include/zynqmppl.h
@@ -16,6 +16,9 @@
 #define ZYNQMP_FPGA_OP_LOAD                    (1 << 1)
 #define ZYNQMP_FPGA_OP_DONE                    (1 << 2)

+#define ZYNQMP_FPGA_FLAG_AUTHENTICATED         BIT(2)
+#define ZYNQMP_FPGA_FLAG_ENCRYPTED             BIT(3)
+
 #define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT    15
 #define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK     (0xf << \
                                        ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
--
2.7.4

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


More information about the U-Boot mailing list