diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 166e3b7..068ea1e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1360,6 +1360,7 @@ source "board/toradex/colibri_pxa270/Kconfig" source "board/vscom/baltos/Kconfig" source "board/woodburn/Kconfig" source "board/work-microwave/work_92105/Kconfig" +source "board/xilinx/zynqmp/Kconfig" source "board/zipitz2/Kconfig" source "arch/arm/Kconfig.debug" diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h index 084d55a..ad3dc9a 100644 --- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h +++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h @@ -11,6 +11,8 @@ #define PAYLOAD_ARG_CNT 5 #define ZYNQMP_CSU_SILICON_VER_MASK 0xF +#define ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD 0xC200002D +#define KEY_PTR_LEN 32 enum { IDCODE, diff --git a/board/xilinx/zynqmp/Kconfig b/board/xilinx/zynqmp/Kconfig new file mode 100644 index 0000000..7d1f739 --- /dev/null +++ b/board/xilinx/zynqmp/Kconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2018, Xilinx, Inc. +# +# SPDX-License-Identifier: GPL-2.0 + +if ARCH_ZYNQMP + +config CMD_ZYNQMP + bool "Enable ZynqMP specific commands" + default y + help + Enable ZynqMP specific commands like "zynqmp secure" + which is used for zynqmp secure image verification. + The secure image is a xilinx specific BOOT.BIN with + either authentication or encryption or both encryption + and authentication feature enabled while generating + BOOT.BIN using Xilinx bootgen tool. + +endif diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile index 75aab92..3b7a10e 100644 --- a/board/xilinx/zynqmp/Makefile +++ b/board/xilinx/zynqmp/Makefile @@ -26,6 +26,10 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),) obj-y += $(init-objs) endif +ifndef CONFIG_SPL_BUILD +obj-$(CONFIG_CMD_ZYNQMP) += cmds.o +endif + # Suppress "warning: function declaration isn't a prototype" CFLAGS_REMOVE_psu_init_gpl.o := -Wstrict-prototypes diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c new file mode 100644 index 0000000..6712d7b --- /dev/null +++ b/board/xilinx/zynqmp/cmds.c @@ -0,0 +1,105 @@ +/* + * (C) Copyright 2018 Xilinx, Inc. + * Siva Durga Prasad Paladugu + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include + +static int zynqmp_verify_secure(u8 *key_ptr, u8 *src_ptr, u32 len) +{ + int ret; + u32 src_lo, src_hi; + u32 key_lo = 0; + u32 key_hi = 0; + u32 ret_payload[PAYLOAD_ARG_CNT]; + u64 addr; + + if ((ulong)src_ptr != ALIGN((ulong)src_ptr, + CONFIG_SYS_CACHELINE_SIZE)) { + printf("Failed: source address not aligned:%p\n", src_ptr); + return -EINVAL; + } + + src_lo = lower_32_bits((ulong)src_ptr); + src_hi = upper_32_bits((ulong)src_ptr); + flush_dcache_range((ulong)src_ptr, (ulong)(src_ptr + len)); + + if (key_ptr) { + key_lo = lower_32_bits((ulong)key_ptr); + key_hi = upper_32_bits((ulong)key_ptr); + flush_dcache_range((ulong)key_ptr, + (ulong)(key_ptr + KEY_PTR_LEN)); + } + + ret = invoke_smc(ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD, src_lo, src_hi, + key_lo, key_hi, ret_payload); + if (ret) { + printf("Failed: secure op status:0x%x\n", ret); + } else { + addr = (u64)ret_payload[1] << 32 | ret_payload[2]; + printf("Verified image at 0x%llx\n", addr); + env_set_hex("zynqmp_verified_img_addr", addr); + } + + return ret; +} + +/** + * do_zynqmp - Handle the "zynqmp" command-line command + * @cmdtp: Command data struct pointer + * @flag: Command flag + * @argc: Command-line argument count + * @argv: Array of command-line arguments + * + * Processes the zynqmp specific commands + * + * Return: return 0 on success and CMD_RET_USAGE incase of misuse and error + */ +static int do_zynqmp(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + u64 src_addr; + u32 len; + u8 *key_ptr = NULL; + u8 *src_ptr; + int ret; + + if (argc > 5 || argc < 4 || strncmp(argv[1], "secure", 6)) + return CMD_RET_USAGE; + + src_addr = simple_strtoull(argv[2], NULL, 16); + + len = simple_strtoul(argv[3], NULL, 16); + + if (argc > 4) + key_ptr = (uint8_t *)(uintptr_t)simple_strtoull(argv[4], + NULL, 16); + + src_ptr = (uint8_t *)(uintptr_t)src_addr; + + ret = zynqmp_verify_secure(key_ptr, src_ptr, len); + if (ret) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +/***************************************************/ +#ifdef CONFIG_SYS_LONGHELP +static char zynqmp_help_text[] = + "secure src len [key_addr] - verifies secure images of $len bytes\n" + " long at address $src. Optional key_addr\n" + " can be specified if user key needs to\n" + " be used for decryption\n"; +#endif + +U_BOOT_CMD( + zynqmp, 5, 1, do_zynqmp, + "Verify and load secure images", + zynqmp_help_text +) diff --git a/configs/xilinx_zynqmp_mini_emmc_defconfig b/configs/xilinx_zynqmp_mini_emmc_defconfig index b15120e..8f2596a 100644 --- a/configs/xilinx_zynqmp_mini_emmc_defconfig +++ b/configs/xilinx_zynqmp_mini_emmc_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_emmc" CONFIG_ARCH_ZYNQMP=y CONFIG_SYS_TEXT_BASE=0x10000 +# CONFIG_CMD_ZYNQMP is not set CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-emmc" CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_FIT=y diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig index 55200bc..1fec9ba 100644 --- a/configs/xilinx_zynqmp_mini_nand_defconfig +++ b/configs/xilinx_zynqmp_mini_nand_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_nand" CONFIG_ARCH_ZYNQMP=y CONFIG_SYS_TEXT_BASE=0x10000 +# CONFIG_CMD_ZYNQMP is not set CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-nand" CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_FIT=y