fpga: zynqmp: Add secure bitstream loading for ZynqMP
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@xilinx.com> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
This commit is contained in:
		
							parent
							
								
									cedd48e2cd
								
							
						
					
					
						commit
						a18d09ea38
					
				|  | @ -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, | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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__)) { | ||||
|  |  | |||
|  | @ -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, | ||||
| }; | ||||
|  |  | |||
|  | @ -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
 | ||||
|  *********************************************************************/ | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue