#include <fpga.h>
#include <fs.h>
#include <malloc.h>
+#include <asm/arch/sys_proto.h>
/* Local functions */
static int fpga_get_op(char *opstr);
#endif
#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
case 8:
- fpga_sec_info.sec_img_type = simple_strtoul(argv[7], NULL, 16);
+ fpga_sec_info.userkey_addr = (u8 *)(uintptr_t)
+ simple_strtoull(argv[7], NULL, 16);
case 7:
- fpga_sec_info.ivaddr_size = argv[6];
- fpga_sec_info.keyaddr_size = argv[5];
+ fpga_sec_info.encflag = (u8)simple_strtoul(argv[6], NULL, 16);
+ if (((fpga_sec_info.encflag == ZYNQMP_FPGA_ENC_USR_KEY) &&
+ !fpga_sec_info.userkey_addr) ||
+ (fpga_sec_info.encflag > ZYNQMP_FPGA_NO_ENC)) {
+ op = FPGA_NONE;
+ break;
+ }
+ case 6:
+ fpga_sec_info.authflag = (u8)simple_strtoul(argv[5], NULL, 16);
+ if (fpga_sec_info.authflag > ZYNQMP_FPGA_NO_AUTH) {
+ op = FPGA_NONE;
+ break;
+ }
#endif
case 5: /* fpga <op> <dev> <data> <datasize> */
data_size = simple_strtoul(argv[4], NULL, 16);
#endif
#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
case FPGA_LOADS:
- if (!fpga_sec_info.keyaddr_size || !fpga_sec_info.keyaddr_size)
+ if (fpga_sec_info.authflag == ZYNQMP_FPGA_NO_AUTH &&
+ fpga_sec_info.encflag == ZYNQMP_FPGA_NO_ENC) {
wrong_parms = 1;
+ break;
+ }
#endif
case FPGA_LOAD:
case FPGA_LOADP:
#endif
#if defined(CONFIG_CMD_FPGA_LOAD_SECURE)
"Load encrypted bitstream (Xilinx only)\n"
- " loads [dev] [address] [size] [key/sigaddr:size]\n"
- " [IV/PPKaddr:size] [secureimgtype]\n"
- "Loads the secure bistreams(authenticated/encrypted)image of\n"
- "[size] from [address] using key/signature(key for encrypted\n"
- "bitstreams and signature for authenticated bitstreams) from\n"
- "address whose :size and IV/PPK at address with size. The secure\n"
- "image type specifies whether it is authenticated/encrypted\n"
- "(0-enc, 1-auth) type of bitstream\n"
+ " loads [dev] [address] [size] [auth-OCM-0/DDR-1/noauth-2]\n"
+ " [enc-devkey(0)/userkey(1)/nenc(2) [Userkey address]\n"
+ "Loads the secure bistreams(authenticated/encrypted/both\n"
+ "encrypted and encrypted) of [size] from [address].\n"
+ "The auth-OCM/DDR flag specifies to perform authentication\n"
+ "in OCM or in DDR. 0 for OCM, 1 for DDR, 2 for no authentication.\n"
+ "The enc flag specifies which key to be used for decryption\n"
+ "0-device key, 1-user key, 2-no encryption.\n"
+ "The optional Userkey address specifies from which address key\n"
+ "has to be used for decryption if user key is selected.\n"
+ "NOTE: the sceure bitstream has to be created using xilinx\n"
+ "bootgen tool only.\n"
#endif
);
static int zynqmp_loads(xilinx_desc *desc, const void *buf, size_t bsize,
fpga_secure_info *fpga_sec_info)
{
- u32 keyaddr, keysize, ivaddr, ivsize;
- char *key_str, *size_str, *dup_str;
- u32 *tmpbuf = (u32 *)buf;
- ulong bitsize = bsize;
- ulong key_iv_size;
int ret;
u32 buf_lo, buf_hi;
u32 ret_payload[PAYLOAD_ARG_CNT];
- u8 flag;
-
- size_str = strchr(fpga_sec_info->keyaddr_size, ':');
- if (size_str) {
- dup_str = strdup(fpga_sec_info->keyaddr_size);
- dup_str[size_str - fpga_sec_info->keyaddr_size] = 0;
- key_str = dup_str;
- size_str++;
- } else {
- debug("No Key Size mentioned\n");
- return FPGA_FAIL;
- }
-
- keyaddr = simple_strtoul(key_str, NULL, 16);
- keysize = simple_strtoul(size_str, NULL, 16);
-
- size_str = strchr(fpga_sec_info->ivaddr_size, ':');
- if (size_str) {
- dup_str = strdup(fpga_sec_info->ivaddr_size);
- dup_str[size_str - fpga_sec_info->ivaddr_size] = 0;
- key_str = dup_str;
- size_str++;
- } else {
- debug("No IV Size mentioned\n");
- return FPGA_FAIL;
- }
-
- ivaddr = simple_strtoul(key_str, NULL, 16);
- ivsize = simple_strtoul(size_str, NULL, 16);
+ u8 flag = 0;
- debug("Keyaddr:0x%x, keysize:P0x%x\n", keyaddr, keysize);
- debug("ivaddr:0x%x, ivsize:P0x%x\n", ivaddr, ivsize);
-
- key_iv_size = keysize + ivsize;
-
- if (bsize % 4)
- bsize = bsize / 4 + 1;
- else
- bsize = bsize / 4;
+ flush_dcache_range((ulong)buf, (ulong)buf + bsize);
- tmpbuf += bsize;
+ if (!fpga_sec_info->encflag)
+ flag |= BIT(ZYNQMP_FPGA_BIT_ENC_DEV_KEY);
- memcpy(tmpbuf, (const void *)(uintptr_t)keyaddr, keysize);
-
- if (keysize % 4)
- keysize = keysize / 4 + 1;
- else
- keysize = keysize / 4;
-
- tmpbuf += keysize;
+ if (fpga_sec_info->userkey_addr &&
+ fpga_sec_info->encflag == ZYNQMP_FPGA_ENC_USR_KEY) {
+ flush_dcache_range((ulong)fpga_sec_info->userkey_addr,
+ (ulong)fpga_sec_info->userkey_addr +
+ KEY_PTR_LEN);
+ flag |= BIT(ZYNQMP_FPGA_BIT_ENC_USR_KEY);
+ }
- memcpy(tmpbuf, (const void *)(uintptr_t)ivaddr, ivsize);
+ if (!fpga_sec_info->authflag)
+ flag |= BIT(ZYNQMP_FPGA_BIT_AUTH_OCM);
- debug("%s called!\n", __func__);
- flush_dcache_range((ulong)buf, (ulong)buf + bitsize + key_iv_size);
+ if (fpga_sec_info->authflag == ZYNQMP_FPGA_AUTH_DDR)
+ flag |= BIT(ZYNQMP_FPGA_BIT_AUTH_DDR);
buf_lo = (u32)(ulong)buf;
buf_hi = upper_32_bits((ulong)buf);
- switch (fpga_sec_info->sec_img_type) {
- case 0:
- flag = ZYNQMP_FPGA_FLAG_ENCRYPTED;
- break;
- case 1:
- flag = ZYNQMP_FPGA_FLAG_AUTHENTICATED;
- break;
- default:
- return FPGA_FAIL;
- }
-
- ret = invoke_smc(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, buf_lo, buf_hi, bsize,
+ 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)
- debug("PL FPGA LOAD fail\n");
+ printf("PL FPGA LOAD fail\n");
+ else
+ printf("Bitstream successfully loaded\n");
return ret;
}