1f6a5dee1ff15a25a85e5885766de64367d78125
[oweals/u-boot.git] / board / xilinx / zynqmp / cmds.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * (C) Copyright 2018 Xilinx, Inc.
4  * Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
5  */
6
7 #include <common.h>
8 #include <malloc.h>
9 #include <asm/arch/sys_proto.h>
10 #include <asm/io.h>
11
12 static int do_zynqmp_verify_secure(cmd_tbl_t *cmdtp, int flag, int argc,
13                                    char * const argv[])
14 {
15         u64 src_addr, addr;
16         u32 len, src_lo, src_hi;
17         u8 *key_ptr = NULL;
18         int ret;
19         u32 key_lo = 0;
20         u32 key_hi = 0;
21         u32 ret_payload[PAYLOAD_ARG_CNT];
22
23         if (argc < 4)
24                 return CMD_RET_USAGE;
25
26         src_addr = simple_strtoull(argv[2], NULL, 16);
27         len = simple_strtoul(argv[3], NULL, 16);
28
29         if (argc == 5)
30                 key_ptr = (uint8_t *)(uintptr_t)simple_strtoull(argv[4],
31                                                                 NULL, 16);
32
33         if ((ulong)src_addr != ALIGN((ulong)src_addr,
34                                      CONFIG_SYS_CACHELINE_SIZE)) {
35                 printf("Failed: source address not aligned:%lx\n",
36                        (ulong)src_addr);
37                 return -EINVAL;
38         }
39
40         src_lo = lower_32_bits((ulong)src_addr);
41         src_hi = upper_32_bits((ulong)src_addr);
42         flush_dcache_range((ulong)src_addr, (ulong)(src_addr + len));
43
44         if (key_ptr) {
45                 key_lo = lower_32_bits((ulong)key_ptr);
46                 key_hi = upper_32_bits((ulong)key_ptr);
47                 flush_dcache_range((ulong)key_ptr,
48                                    (ulong)(key_ptr + KEY_PTR_LEN));
49         }
50
51         ret = invoke_smc(ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD, src_lo, src_hi,
52                          key_lo, key_hi, ret_payload);
53         if (ret) {
54                 printf("Failed: secure op status:0x%x\n", ret);
55         } else {
56                 addr = (u64)ret_payload[1] << 32 | ret_payload[2];
57                 printf("Verified image at 0x%llx\n", addr);
58                 env_set_hex("zynqmp_verified_img_addr", addr);
59         }
60
61         return ret;
62 }
63
64 static cmd_tbl_t cmd_zynqmp_sub[] = {
65         U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""),
66 };
67
68 /**
69  * do_zynqmp - Handle the "zynqmp" command-line command
70  * @cmdtp:      Command data struct pointer
71  * @flag:       Command flag
72  * @argc:       Command-line argument count
73  * @argv:       Array of command-line arguments
74  *
75  * Processes the zynqmp specific commands
76  *
77  * Return: return 0 on success and CMD_RET_USAGE incase of misuse and error
78  */
79 static int do_zynqmp(cmd_tbl_t *cmdtp, int flag, int argc,
80                      char *const argv[])
81 {
82         cmd_tbl_t *c;
83
84         if (argc < 2)
85                 return CMD_RET_USAGE;
86
87         c = find_cmd_tbl(argv[1], &cmd_zynqmp_sub[0],
88                          ARRAY_SIZE(cmd_zynqmp_sub));
89
90         if (c)
91                 return c->cmd(c, flag, argc, argv);
92         else
93                 return CMD_RET_USAGE;
94 }
95
96 /***************************************************/
97 #ifdef CONFIG_SYS_LONGHELP
98 static char zynqmp_help_text[] =
99         "secure src len [key_addr] - verifies secure images of $len bytes\n"
100         "                            long at address $src. Optional key_addr\n"
101         "                            can be specified if user key needs to\n"
102         "                            be used for decryption\n";
103 #endif
104
105 U_BOOT_CMD(
106         zynqmp, 5, 1, do_zynqmp,
107         "ZynqMP sub-system",
108         zynqmp_help_text
109 )