]>
Commit | Line | Data |
---|---|---|
264f4b0b SG |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Commands for UPL handoff generation | |
4 | * | |
5 | * Copyright 2024 Google LLC | |
6 | * Written by Simon Glass <[email protected]> | |
7 | */ | |
8 | ||
9 | #define LOG_CATEGORY UCLASS_BOOTSTD | |
10 | ||
11 | #include <abuf.h> | |
12 | #include <alist.h> | |
13 | #include <command.h> | |
14 | #include <display_options.h> | |
15 | #include <mapmem.h> | |
16 | #include <string.h> | |
17 | #include <upl.h> | |
18 | #include <dm/ofnode.h> | |
19 | #include <test/ut.h> | |
20 | ||
21 | DECLARE_GLOBAL_DATA_PTR; | |
22 | ||
23 | static int do_upl_info(struct cmd_tbl *cmdtp, int flag, int argc, | |
24 | char *const argv[]) | |
25 | { | |
26 | const struct upl *upl = gd_upl(); | |
27 | ||
28 | printf("UPL state: %sactive\n", upl ? "" : "in"); | |
29 | if (!upl) | |
30 | return 0; | |
31 | if (argc > 1 && !strcmp("-v", argv[1])) { | |
32 | int i; | |
33 | ||
34 | printf("fit %lx\n", upl->fit); | |
35 | printf("conf_offset %x\n", upl->conf_offset); | |
36 | for (i = 0; i < upl->image.count; i++) { | |
37 | const struct upl_image *img = | |
38 | alist_get(&upl->image, i, struct upl_image); | |
39 | ||
40 | printf("image %d: load %lx size %lx offset %x: %s\n", i, | |
41 | img->load, img->size, img->offset, | |
42 | img->description); | |
43 | } | |
44 | } | |
45 | ||
46 | return 0; | |
47 | } | |
48 | ||
49 | static int do_upl_write(struct cmd_tbl *cmdtp, int flag, int argc, | |
50 | char *const argv[]) | |
51 | { | |
52 | struct upl s_upl, *upl = &s_upl; | |
53 | struct unit_test_state uts; | |
54 | struct abuf buf; | |
55 | oftree tree; | |
56 | ulong addr; | |
57 | int ret; | |
58 | ||
59 | upl_get_test_data(&uts, upl); | |
60 | ||
61 | log_debug("Writing UPL\n"); | |
62 | ret = upl_create_handoff_tree(upl, &tree); | |
63 | if (ret) { | |
64 | log_err("Failed to write (err=%dE)\n", ret); | |
65 | return CMD_RET_FAILURE; | |
66 | } | |
67 | ||
68 | log_debug("Flattening\n"); | |
69 | ret = oftree_to_fdt(tree, &buf); | |
70 | if (ret) { | |
71 | log_err("Failed to write (err=%dE)\n", ret); | |
72 | return CMD_RET_FAILURE; | |
73 | } | |
74 | addr = map_to_sysmem(abuf_data(&buf)); | |
75 | printf("UPL handoff written to %lx size %lx\n", addr, abuf_size(&buf)); | |
76 | if (env_set_hex("upladdr", addr) || | |
77 | env_set_hex("uplsize", abuf_size(&buf))) { | |
78 | printf("Cannot set env var\n"); | |
79 | return CMD_RET_FAILURE; | |
80 | } | |
81 | ||
82 | log_debug("done\n"); | |
83 | ||
84 | return 0; | |
85 | } | |
86 | ||
87 | static int do_upl_read(struct cmd_tbl *cmdtp, int flag, int argc, | |
88 | char *const argv[]) | |
89 | { | |
90 | struct upl s_upl, *upl = &s_upl; | |
91 | oftree tree; | |
92 | ulong addr; | |
93 | int ret; | |
94 | ||
95 | if (argc < 1) | |
96 | return CMD_RET_USAGE; | |
97 | addr = hextoul(argv[1], NULL); | |
98 | ||
99 | printf("Reading UPL at %lx\n", addr); | |
100 | tree = oftree_from_fdt(map_sysmem(addr, 0)); | |
101 | ret = upl_read_handoff(upl, tree); | |
102 | if (ret) { | |
103 | log_err("Failed to read (err=%dE)\n", ret); | |
104 | return CMD_RET_FAILURE; | |
105 | } | |
106 | ||
107 | return 0; | |
108 | } | |
109 | ||
110 | U_BOOT_LONGHELP(upl, | |
111 | "info [-v] - Check UPL status\n" | |
112 | "upl read <addr> - Read handoff information\n" | |
113 | "upl write - Write handoff information"); | |
114 | ||
115 | U_BOOT_CMD_WITH_SUBCMDS(upl, "Universal Payload support", upl_help_text, | |
116 | U_BOOT_SUBCMD_MKENT(info, 2, 1, do_upl_info), | |
117 | U_BOOT_SUBCMD_MKENT(read, 2, 1, do_upl_read), | |
118 | U_BOOT_SUBCMD_MKENT(write, 1, 1, do_upl_write)); |