blob: 2ff284f4cde6d00eb11b32f071be9a337286198e [file] [log] [blame]
Simon Glassa0874dc2023-06-01 10:23:02 -06001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * 'cedit' command
4 *
5 * Copyright 2023 Google LLC
6 * Written by Simon Glass <sjg@chromium.org>
7 */
8
9#include <common.h>
Simon Glass2dee81f2023-08-14 16:40:33 -060010#include <abuf.h>
Simon Glass040b0462023-08-14 16:40:25 -060011#include <cedit.h>
Simon Glassa0874dc2023-06-01 10:23:02 -060012#include <command.h>
Simon Glasseb6c71b2023-08-14 16:40:37 -060013#include <dm.h>
Simon Glassa0874dc2023-06-01 10:23:02 -060014#include <expo.h>
15#include <fs.h>
Simon Glass2dee81f2023-08-14 16:40:33 -060016#include <malloc.h>
17#include <mapmem.h>
Simon Glassa0874dc2023-06-01 10:23:02 -060018#include <dm/ofnode.h>
19#include <linux/sizes.h>
20
21struct expo *cur_exp;
22
Simon Glass2dee81f2023-08-14 16:40:33 -060023static int check_cur_expo(void)
24{
25 if (!cur_exp) {
26 printf("No expo loaded\n");
27 return -ENOENT;
28 }
29
30 return 0;
31}
32
Simon Glassa0874dc2023-06-01 10:23:02 -060033static int do_cedit_load(struct cmd_tbl *cmdtp, int flag, int argc,
34 char *const argv[])
35{
36 const char *fname;
37 struct expo *exp;
38 oftree tree;
39 ulong size;
40 void *buf;
41 int ret;
42
43 if (argc < 4)
44 return CMD_RET_USAGE;
45 fname = argv[3];
46
47 ret = fs_load_alloc(argv[1], argv[2], argv[3], SZ_1M, 0, &buf, &size);
48 if (ret) {
49 printf("File not found\n");
50 return CMD_RET_FAILURE;
51 }
52
53 tree = oftree_from_fdt(buf);
54 if (!oftree_valid(tree)) {
55 printf("Cannot create oftree\n");
56 return CMD_RET_FAILURE;
57 }
58
59 ret = expo_build(oftree_root(tree), &exp);
60 oftree_dispose(tree);
61 if (ret) {
62 printf("Failed to build expo: %dE\n", ret);
63 return CMD_RET_FAILURE;
64 }
65
66 cur_exp = exp;
67
68 return 0;
69}
70
Simon Glass2dee81f2023-08-14 16:40:33 -060071static int do_cedit_write_fdt(struct cmd_tbl *cmdtp, int flag, int argc,
72 char *const argv[])
73{
74 const char *fname;
75 struct abuf buf;
76 loff_t bytes;
77 int ret;
78
79 if (argc < 4)
80 return CMD_RET_USAGE;
81 fname = argv[3];
82
83 if (check_cur_expo())
84 return CMD_RET_FAILURE;
85
86 ret = cedit_write_settings(cur_exp, &buf);
87 if (ret) {
88 printf("Failed to write settings: %dE\n", ret);
89 return CMD_RET_FAILURE;
90 }
91
92 if (fs_set_blk_dev(argv[1], argv[2], FS_TYPE_ANY))
93 return CMD_RET_FAILURE;
94
95 ret = fs_write(fname, map_to_sysmem(abuf_data(&buf)), 0,
96 abuf_size(&buf), &bytes);
97 if (ret)
98 return CMD_RET_FAILURE;
99
100 return 0;
101}
102
Simon Glass472317c2023-08-14 16:40:34 -0600103static int do_cedit_read_fdt(struct cmd_tbl *cmdtp, int flag, int argc,
104 char *const argv[])
105{
106 const char *fname;
107 void *buf;
108 oftree tree;
109 ulong size;
110 int ret;
111
112 if (argc < 4)
113 return CMD_RET_USAGE;
114 fname = argv[3];
115
116 ret = fs_load_alloc(argv[1], argv[2], argv[3], SZ_1M, 0, &buf, &size);
117 if (ret) {
118 printf("File not found\n");
119 return CMD_RET_FAILURE;
120 }
121
122 tree = oftree_from_fdt(buf);
123 if (!oftree_valid(tree)) {
124 free(buf);
125 printf("Cannot create oftree\n");
126 return CMD_RET_FAILURE;
127 }
128
129 ret = cedit_read_settings(cur_exp, tree);
130 oftree_dispose(tree);
131 free(buf);
132 if (ret) {
133 printf("Failed to read settings: %dE\n", ret);
134 return CMD_RET_FAILURE;
135 }
136
137 return 0;
138}
139
Simon Glassfc9c0e02023-08-14 16:40:35 -0600140static int do_cedit_write_env(struct cmd_tbl *cmdtp, int flag, int argc,
141 char *const argv[])
142{
143 bool verbose;
144 int ret;
145
146 if (check_cur_expo())
147 return CMD_RET_FAILURE;
148
149 verbose = argc > 1 && !strcmp(argv[1], "-v");
150
151 ret = cedit_write_settings_env(cur_exp, verbose);
152 if (ret) {
153 printf("Failed to write settings to environment: %dE\n", ret);
154 return CMD_RET_FAILURE;
155 }
156
157 return 0;
158}
159
Simon Glassbcf2b722023-08-14 16:40:36 -0600160static int do_cedit_read_env(struct cmd_tbl *cmdtp, int flag, int argc,
161 char *const argv[])
162{
163 bool verbose;
164 int ret;
165
166 if (check_cur_expo())
167 return CMD_RET_FAILURE;
168
169 verbose = argc > 1 && !strcmp(argv[1], "-v");
170
171 ret = cedit_read_settings_env(cur_exp, verbose);
172 if (ret) {
173 printf("Failed to read settings from environment: %dE\n", ret);
174 return CMD_RET_FAILURE;
175 }
176
177 return 0;
178}
179
Simon Glasseb6c71b2023-08-14 16:40:37 -0600180static int do_cedit_write_cmos(struct cmd_tbl *cmdtp, int flag, int argc,
181 char *const argv[])
182{
183 struct udevice *dev;
184 bool verbose = false;
185 int ret;
186
187 if (check_cur_expo())
188 return CMD_RET_FAILURE;
189
190 if (argc > 1 && !strcmp(argv[1], "-v")) {
191 verbose = true;
192 argc--;
193 argv++;
194 }
195
196 if (argc > 1)
197 ret = uclass_get_device_by_name(UCLASS_RTC, argv[1], &dev);
198 else
199 ret = uclass_first_device_err(UCLASS_RTC, &dev);
200 if (ret) {
201 printf("Failed to get RTC device: %dE\n", ret);
202 return CMD_RET_FAILURE;
203 }
204
205 if (cedit_write_settings_cmos(cur_exp, dev, verbose)) {
206 printf("Failed to write settings to CMOS\n");
207 return CMD_RET_FAILURE;
208 }
209
210 return 0;
211}
212
Simon Glasscfc402d2023-08-14 16:40:38 -0600213static int do_cedit_read_cmos(struct cmd_tbl *cmdtp, int flag, int argc,
214 char *const argv[])
215{
216 struct udevice *dev;
217 bool verbose = false;
218 int ret;
219
220 if (check_cur_expo())
221 return CMD_RET_FAILURE;
222
223 if (argc > 1 && !strcmp(argv[1], "-v")) {
224 verbose = true;
225 argc--;
226 argv++;
227 }
228
229 if (argc > 1)
230 ret = uclass_get_device_by_name(UCLASS_RTC, argv[1], &dev);
231 else
232 ret = uclass_first_device_err(UCLASS_RTC, &dev);
233 if (ret) {
234 printf("Failed to get RTC device: %dE\n", ret);
235 return CMD_RET_FAILURE;
236 }
237
238 ret = cedit_read_settings_cmos(cur_exp, dev, verbose);
239 if (ret) {
240 printf("Failed to read settings from CMOS: %dE\n", ret);
241 return CMD_RET_FAILURE;
242 }
243
244 return 0;
245}
246
Simon Glassa0874dc2023-06-01 10:23:02 -0600247static int do_cedit_run(struct cmd_tbl *cmdtp, int flag, int argc,
248 char *const argv[])
249{
250 ofnode node;
251 int ret;
252
Simon Glass2dee81f2023-08-14 16:40:33 -0600253 if (check_cur_expo())
Simon Glassa0874dc2023-06-01 10:23:02 -0600254 return CMD_RET_FAILURE;
Simon Glassa0874dc2023-06-01 10:23:02 -0600255
Simon Glass2045ca52023-08-14 16:40:30 -0600256 node = ofnode_path("/bootstd/cedit-theme");
Simon Glassa0874dc2023-06-01 10:23:02 -0600257 if (ofnode_valid(node)) {
258 ret = expo_apply_theme(cur_exp, node);
259 if (ret)
260 return CMD_RET_FAILURE;
261 } else {
262 log_warning("No theme found\n");
263 }
264 ret = cedit_run(cur_exp);
265 if (ret) {
266 log_err("Failed (err=%dE)\n", ret);
267 return CMD_RET_FAILURE;
268 }
269
270 return 0;
271}
272
273#ifdef CONFIG_SYS_LONGHELP
274static char cedit_help_text[] =
275 "load <interface> <dev[:part]> <filename> - load config editor\n"
Simon Glass472317c2023-08-14 16:40:34 -0600276 "cedit read_fdt <i/f> <dev[:part]> <filename> - read settings\n"
Simon Glass2dee81f2023-08-14 16:40:33 -0600277 "cedit write_fdt <i/f> <dev[:part]> <filename> - write settings\n"
Simon Glassbcf2b722023-08-14 16:40:36 -0600278 "cedit read_env [-v] - read settings from env vars\n"
Simon Glassfc9c0e02023-08-14 16:40:35 -0600279 "cedit write_env [-v] - write settings to env vars\n"
Simon Glasscfc402d2023-08-14 16:40:38 -0600280 "cedit read_cmos [-v] [dev] - read settings from CMOS RAM\n"
Simon Glasseb6c71b2023-08-14 16:40:37 -0600281 "cedit write_cmos [-v] [dev] - write settings to CMOS RAM\n"
Simon Glassa0874dc2023-06-01 10:23:02 -0600282 "cedit run - run config editor";
283#endif /* CONFIG_SYS_LONGHELP */
284
285U_BOOT_CMD_WITH_SUBCMDS(cedit, "Configuration editor", cedit_help_text,
286 U_BOOT_SUBCMD_MKENT(load, 5, 1, do_cedit_load),
Simon Glass472317c2023-08-14 16:40:34 -0600287 U_BOOT_SUBCMD_MKENT(read_fdt, 5, 1, do_cedit_read_fdt),
Simon Glass2dee81f2023-08-14 16:40:33 -0600288 U_BOOT_SUBCMD_MKENT(write_fdt, 5, 1, do_cedit_write_fdt),
Simon Glassbcf2b722023-08-14 16:40:36 -0600289 U_BOOT_SUBCMD_MKENT(read_env, 2, 1, do_cedit_read_env),
Simon Glassfc9c0e02023-08-14 16:40:35 -0600290 U_BOOT_SUBCMD_MKENT(write_env, 2, 1, do_cedit_write_env),
Simon Glasscfc402d2023-08-14 16:40:38 -0600291 U_BOOT_SUBCMD_MKENT(read_cmos, 2, 1, do_cedit_read_cmos),
Simon Glasseb6c71b2023-08-14 16:40:37 -0600292 U_BOOT_SUBCMD_MKENT(write_cmos, 2, 1, do_cedit_write_cmos),
Simon Glassa0874dc2023-06-01 10:23:02 -0600293 U_BOOT_SUBCMD_MKENT(run, 1, 1, do_cedit_run),
294);