command: Remove the cmd_tbl_t typedef
[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 <command.h>
9 #include <cpu_func.h>
10 #include <env.h>
11 #include <malloc.h>
12 #include <zynqmp_firmware.h>
13 #include <asm/arch/hardware.h>
14 #include <asm/arch/sys_proto.h>
15 #include <asm/io.h>
16
17 static int do_zynqmp_verify_secure(struct cmd_tbl *cmdtp, int flag, int argc,
18                                    char *const argv[])
19 {
20         u64 src_addr, addr;
21         u32 len, src_lo, src_hi;
22         u8 *key_ptr = NULL;
23         int ret;
24         u32 key_lo = 0;
25         u32 key_hi = 0;
26         u32 ret_payload[PAYLOAD_ARG_CNT];
27
28         if (argc < 4)
29                 return CMD_RET_USAGE;
30
31         src_addr = simple_strtoull(argv[2], NULL, 16);
32         len = simple_strtoul(argv[3], NULL, 16);
33
34         if (argc == 5)
35                 key_ptr = (uint8_t *)(uintptr_t)simple_strtoull(argv[4],
36                                                                 NULL, 16);
37
38         if ((ulong)src_addr != ALIGN((ulong)src_addr,
39                                      CONFIG_SYS_CACHELINE_SIZE)) {
40                 printf("Failed: source address not aligned:%lx\n",
41                        (ulong)src_addr);
42                 return -EINVAL;
43         }
44
45         src_lo = lower_32_bits((ulong)src_addr);
46         src_hi = upper_32_bits((ulong)src_addr);
47         flush_dcache_range((ulong)src_addr, (ulong)(src_addr + len));
48
49         if (key_ptr) {
50                 key_lo = lower_32_bits((ulong)key_ptr);
51                 key_hi = upper_32_bits((ulong)key_ptr);
52                 flush_dcache_range((ulong)key_ptr,
53                                    (ulong)(key_ptr + KEY_PTR_LEN));
54         }
55
56         ret = xilinx_pm_request(PM_SECURE_IMAGE, src_lo, src_hi,
57                                 key_lo, key_hi, ret_payload);
58         if (ret) {
59                 printf("Failed: secure op status:0x%x\n", ret);
60         } else {
61                 addr = (u64)ret_payload[1] << 32 | ret_payload[2];
62                 printf("Verified image at 0x%llx\n", addr);
63                 env_set_hex("zynqmp_verified_img_addr", addr);
64         }
65
66         return ret;
67 }
68
69 static int do_zynqmp_mmio_read(struct cmd_tbl *cmdtp, int flag, int argc,
70                                char *const argv[])
71 {
72         u32 read_val, addr;
73         int ret;
74
75         if (argc != cmdtp->maxargs)
76                 return CMD_RET_USAGE;
77
78         addr = simple_strtoul(argv[2], NULL, 16);
79
80         ret = zynqmp_mmio_read(addr, &read_val);
81         if (!ret)
82                 printf("mmio read value at 0x%x = 0x%x\n",
83                        addr, read_val);
84         else
85                 printf("Failed: mmio read\n");
86
87         return ret;
88 }
89
90 static int do_zynqmp_mmio_write(struct cmd_tbl *cmdtp, int flag, int argc,
91                                 char *const argv[])
92 {
93         u32 addr, mask, val;
94         int ret;
95
96         if (argc != cmdtp->maxargs)
97                 return CMD_RET_USAGE;
98
99         addr = simple_strtoul(argv[2], NULL, 16);
100         mask = simple_strtoul(argv[3], NULL, 16);
101         val = simple_strtoul(argv[4], NULL, 16);
102
103         ret = zynqmp_mmio_write(addr, mask, val);
104         if (ret != 0)
105                 printf("Failed: mmio write\n");
106
107         return ret;
108 }
109
110 #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
111 static int do_zynqmp_tcm_init(struct cmd_tbl *cmdtp, int flag, int argc,
112                               char *const argv[])
113 {
114         u8 mode;
115
116         if (argc != cmdtp->maxargs)
117                 return CMD_RET_USAGE;
118
119         mode = simple_strtoul(argv[2], NULL, 16);
120         if (mode != TCM_LOCK && mode != TCM_SPLIT) {
121                 printf("Mode should be either 0(lock)/1(split)\n");
122                 return CMD_RET_FAILURE;
123         }
124
125         dcache_disable();
126         tcm_init(mode);
127         dcache_enable();
128
129         return CMD_RET_SUCCESS;
130 }
131 #endif
132
133 static struct cmd_tbl cmd_zynqmp_sub[] = {
134         U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""),
135         U_BOOT_CMD_MKENT(mmio_read, 3, 0, do_zynqmp_mmio_read, "", ""),
136         U_BOOT_CMD_MKENT(mmio_write, 5, 0, do_zynqmp_mmio_write, "", ""),
137 #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
138         U_BOOT_CMD_MKENT(tcminit, 3, 0, do_zynqmp_tcm_init, "", ""),
139 #endif
140 };
141
142 /**
143  * do_zynqmp - Handle the "zynqmp" command-line command
144  * @cmdtp:      Command data struct pointer
145  * @flag:       Command flag
146  * @argc:       Command-line argument count
147  * @argv:       Array of command-line arguments
148  *
149  * Processes the zynqmp specific commands
150  *
151  * Return: return 0 on success and CMD_RET_USAGE incase of misuse and error
152  */
153 static int do_zynqmp(struct cmd_tbl *cmdtp, int flag, int argc,
154                      char *const argv[])
155 {
156         struct cmd_tbl *c;
157
158         if (argc < 2)
159                 return CMD_RET_USAGE;
160
161         c = find_cmd_tbl(argv[1], &cmd_zynqmp_sub[0],
162                          ARRAY_SIZE(cmd_zynqmp_sub));
163
164         if (c)
165                 return c->cmd(c, flag, argc, argv);
166         else
167                 return CMD_RET_USAGE;
168 }
169
170 /***************************************************/
171 #ifdef CONFIG_SYS_LONGHELP
172 static char zynqmp_help_text[] =
173         "secure src len [key_addr] - verifies secure images of $len bytes\n"
174         "                            long at address $src. Optional key_addr\n"
175         "                            can be specified if user key needs to\n"
176         "                            be used for decryption\n"
177         "zynqmp mmio_read address - read from address\n"
178         "zynqmp mmio_write address mask value - write value after masking to\n"
179         "                                       address\n"
180 #ifdef CONFIG_DEFINE_TCM_OCM_MMAP
181         "zynqmp tcminit mode - Initialize the TCM with zeros. TCM needs to be\n"
182         "                      initialized before accessing to avoid ECC\n"
183         "                      errors. mode specifies in which mode TCM has\n"
184         "                      to be initialized. Supported modes will be\n"
185         "                      lock(0)/split(1)\n"
186 #endif
187         ;
188 #endif
189
190 U_BOOT_CMD(
191         zynqmp, 5, 1, do_zynqmp,
192         "ZynqMP sub-system",
193         zynqmp_help_text
194 )