1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2023 Addiva Elektronik
4 * Author: Tobias Waldekranz <tobias@waldekranz.com>
11 #include <dm/device.h>
13 static int blkmap_curr_dev
;
17 lbaint_t blknr
, blkcnt
;
20 typedef int (*map_parser_fn
)(struct map_ctx
*ctx
, int argc
, char *const argv
[]);
27 static int do_blkmap_map_linear(struct map_ctx
*ctx
, int argc
,
37 ldevnum
= dectoul(argv
[2], NULL
);
38 lblknr
= dectoul(argv
[3], NULL
);
40 lbd
= blk_get_devnum_by_uclass_idname(argv
[1], ldevnum
);
42 printf("Found no device matching \"%s %d\"\n",
44 return CMD_RET_FAILURE
;
47 err
= blkmap_map_linear(ctx
->dev
, ctx
->blknr
, ctx
->blkcnt
,
50 printf("Unable to map \"%s %d\" at block 0x" LBAF
": %d\n",
51 argv
[1], ldevnum
, ctx
->blknr
, err
);
53 return CMD_RET_FAILURE
;
56 printf("Block 0x" LBAF
"+0x" LBAF
" mapped to block 0x" LBAF
" of \"%s %d\"\n",
57 ctx
->blknr
, ctx
->blkcnt
, lblknr
, argv
[1], ldevnum
);
58 return CMD_RET_SUCCESS
;
61 static int do_blkmap_map_mem(struct map_ctx
*ctx
, int argc
, char *const argv
[])
69 addr
= hextoul(argv
[1], NULL
);
71 err
= blkmap_map_pmem(ctx
->dev
, ctx
->blknr
, ctx
->blkcnt
, addr
);
73 printf("Unable to map %#llx at block 0x" LBAF
": %d\n",
74 (unsigned long long)addr
, ctx
->blknr
, err
);
75 return CMD_RET_FAILURE
;
78 printf("Block 0x" LBAF
"+0x" LBAF
" mapped to %#llx\n",
79 ctx
->blknr
, ctx
->blkcnt
, (unsigned long long)addr
);
80 return CMD_RET_SUCCESS
;
83 static struct map_handler map_handlers
[] = {
84 { .name
= "linear", .fn
= do_blkmap_map_linear
},
85 { .name
= "mem", .fn
= do_blkmap_map_mem
},
90 static int do_blkmap_map(struct cmd_tbl
*cmdtp
, int flag
,
91 int argc
, char *const argv
[])
93 struct map_handler
*handler
;
99 ctx
.dev
= blkmap_from_label(argv
[1]);
101 printf("\"%s\" is not the name of any known blkmap\n", argv
[1]);
102 return CMD_RET_FAILURE
;
105 ctx
.blknr
= hextoul(argv
[2], NULL
);
106 ctx
.blkcnt
= hextoul(argv
[3], NULL
);
110 for (handler
= map_handlers
; handler
->name
; handler
++) {
111 if (!strcmp(handler
->name
, argv
[0]))
112 return handler
->fn(&ctx
, argc
, argv
);
115 printf("Unknown map type \"%s\"\n", argv
[0]);
116 return CMD_RET_USAGE
;
119 static int do_blkmap_create(struct cmd_tbl
*cmdtp
, int flag
,
120 int argc
, char *const argv
[])
126 return CMD_RET_USAGE
;
130 err
= blkmap_create(label
, NULL
);
132 printf("Unable to create \"%s\": %d\n", label
, err
);
133 return CMD_RET_FAILURE
;
136 printf("Created \"%s\"\n", label
);
137 return CMD_RET_SUCCESS
;
140 static int do_blkmap_destroy(struct cmd_tbl
*cmdtp
, int flag
,
141 int argc
, char *const argv
[])
148 return CMD_RET_USAGE
;
152 dev
= blkmap_from_label(label
);
154 printf("\"%s\" is not the name of any known blkmap\n", label
);
155 return CMD_RET_FAILURE
;
158 err
= blkmap_destroy(dev
);
160 printf("Unable to destroy \"%s\": %d\n", label
, err
);
161 return CMD_RET_FAILURE
;
164 printf("Destroyed \"%s\"\n", label
);
165 return CMD_RET_SUCCESS
;
168 static int do_blkmap_get(struct cmd_tbl
*cmdtp
, int flag
,
169 int argc
, char *const argv
[])
176 return CMD_RET_USAGE
;
180 dev
= blkmap_from_label(label
);
182 printf("\"%s\" is not the name of any known blkmap\n", label
);
183 return CMD_RET_FAILURE
;
186 if (!strcmp(argv
[2], "dev")) {
188 printf("%d\n", dev_seq(dev
));
190 err
= env_set_hex(argv
[3], dev_seq(dev
));
192 return CMD_RET_FAILURE
;
195 return CMD_RET_USAGE
;
198 return CMD_RET_SUCCESS
;
201 static int do_blkmap_common(struct cmd_tbl
*cmdtp
, int flag
,
202 int argc
, char *const argv
[])
204 /* The subcommand parsing pops the original argv[0] ("blkmap")
205 * which blk_common_cmd expects. Push it back again.
210 return blk_common_cmd(argc
, argv
, UCLASS_BLKMAP
, &blkmap_curr_dev
);
213 U_BOOT_CMD_WITH_SUBCMDS(
214 blkmap
, "Composeable virtual block devices",
215 "info - list configured devices\n"
216 "blkmap part - list available partitions on current blkmap device\n"
217 "blkmap dev [<dev>] - show or set current blkmap device\n"
218 "blkmap read <addr> <blk#> <cnt>\n"
219 "blkmap write <addr> <blk#> <cnt>\n"
220 "blkmap get <label> dev [<var>] - store device number in variable\n"
221 "blkmap create <label> - create device\n"
222 "blkmap destroy <label> - destroy device\n"
223 "blkmap map <label> <blk#> <cnt> linear <interface> <dev> <blk#> - device mapping\n"
224 "blkmap map <label> <blk#> <cnt> mem <addr> - memory mapping\n",
225 U_BOOT_SUBCMD_MKENT(info
, 2, 1, do_blkmap_common
),
226 U_BOOT_SUBCMD_MKENT(part
, 2, 1, do_blkmap_common
),
227 U_BOOT_SUBCMD_MKENT(dev
, 4, 1, do_blkmap_common
),
228 U_BOOT_SUBCMD_MKENT(read
, 5, 1, do_blkmap_common
),
229 U_BOOT_SUBCMD_MKENT(write
, 5, 1, do_blkmap_common
),
230 U_BOOT_SUBCMD_MKENT(get
, 5, 1, do_blkmap_get
),
231 U_BOOT_SUBCMD_MKENT(create
, 2, 1, do_blkmap_create
),
232 U_BOOT_SUBCMD_MKENT(destroy
, 2, 1, do_blkmap_destroy
),
233 U_BOOT_SUBCMD_MKENT(map
, 32, 1, do_blkmap_map
));