diff options
Diffstat (limited to 'drivers/fpga')
-rw-r--r-- | drivers/fpga/fpga.c | 29 | ||||
-rw-r--r-- | drivers/fpga/xilinx.c | 18 | ||||
-rw-r--r-- | drivers/fpga/zynqmppl.c | 48 |
3 files changed, 95 insertions, 0 deletions
diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c index 55bdf9e7cf2..7e8bd7eae88 100644 --- a/drivers/fpga/fpga.c +++ b/drivers/fpga/fpga.c @@ -217,6 +217,35 @@ int fpga_fsload(int devnum, const void *buf, size_t size, } #endif +#if defined(CONFIG_CMD_FPGA_LOAD_SECURE) +int fpga_loads(int devnum, const void *buf, size_t size, + struct fpga_secure_info *fpga_sec_info) +{ + int ret_val = FPGA_FAIL; + + const fpga_desc *desc = fpga_validate(devnum, buf, size, + (char *)__func__); + + if (desc) { + switch (desc->devtype) { + case fpga_xilinx: +#if defined(CONFIG_FPGA_XILINX) + ret_val = xilinx_loads(desc->devdesc, buf, size, + fpga_sec_info); +#else + fpga_no_sup((char *)__func__, "Xilinx devices"); +#endif + break; + default: + printf("%s: Invalid or unsupported device type %d\n", + __func__, desc->devtype); + } + } + + return ret_val; +} +#endif + /* * Generic multiplexing code */ diff --git a/drivers/fpga/xilinx.c b/drivers/fpga/xilinx.c index 724304a5451..f5135504eeb 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 b57623b6a75..03ffa8c11f2 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, }; |