blob: 6344ecd357b3f92afeb1676727cea970e8f5bee4 [file] [log] [blame]
Patrice Chotard993c9122019-11-25 09:07:38 +01001// SPDX-License-Identifier: GPL-2.0+
2
3#include <common.h>
4#include <command.h>
5#include <env.h>
6#include <fs.h>
Simon Glass262cfb52021-10-14 12:48:00 -06007#include <pxe_utils.h>
Patrice Chotard993c9122019-11-25 09:07:38 +01008
9static char *fs_argv[5];
10
Simon Glassb1ead6b2021-10-14 12:47:57 -060011static int do_get_ext2(struct pxe_context *ctx, const char *file_path,
Simon Glass4d79e882021-10-14 12:48:08 -060012 char *file_addr, ulong *sizep)
Patrice Chotard993c9122019-11-25 09:07:38 +010013{
14#ifdef CONFIG_CMD_EXT2
Simon Glass4d79e882021-10-14 12:48:08 -060015 int ret;
16
Patrice Chotard993c9122019-11-25 09:07:38 +010017 fs_argv[0] = "ext2load";
18 fs_argv[3] = file_addr;
19 fs_argv[4] = (void *)file_path;
20
Simon Glassb1ead6b2021-10-14 12:47:57 -060021 if (!do_ext2load(ctx->cmdtp, 0, 5, fs_argv))
Patrice Chotard993c9122019-11-25 09:07:38 +010022 return 1;
Simon Glass4d79e882021-10-14 12:48:08 -060023 ret = pxe_get_file_size(sizep);
24 if (ret)
25 return log_msg_ret("tftp", ret);
Patrice Chotard993c9122019-11-25 09:07:38 +010026#endif
27 return -ENOENT;
28}
29
Simon Glassb1ead6b2021-10-14 12:47:57 -060030static int do_get_fat(struct pxe_context *ctx, const char *file_path,
Simon Glass4d79e882021-10-14 12:48:08 -060031 char *file_addr, ulong *sizep)
Patrice Chotard993c9122019-11-25 09:07:38 +010032{
33#ifdef CONFIG_CMD_FAT
Simon Glass4d79e882021-10-14 12:48:08 -060034 int ret;
35
Patrice Chotard993c9122019-11-25 09:07:38 +010036 fs_argv[0] = "fatload";
37 fs_argv[3] = file_addr;
38 fs_argv[4] = (void *)file_path;
39
Simon Glassb1ead6b2021-10-14 12:47:57 -060040 if (!do_fat_fsload(ctx->cmdtp, 0, 5, fs_argv))
Patrice Chotard993c9122019-11-25 09:07:38 +010041 return 1;
Simon Glass4d79e882021-10-14 12:48:08 -060042 ret = pxe_get_file_size(sizep);
43 if (ret)
44 return log_msg_ret("tftp", ret);
Patrice Chotard993c9122019-11-25 09:07:38 +010045#endif
46 return -ENOENT;
47}
48
Simon Glassb1ead6b2021-10-14 12:47:57 -060049static int do_get_any(struct pxe_context *ctx, const char *file_path,
Simon Glass4d79e882021-10-14 12:48:08 -060050 char *file_addr, ulong *sizep)
Patrice Chotard993c9122019-11-25 09:07:38 +010051{
52#ifdef CONFIG_CMD_FS_GENERIC
Simon Glass4d79e882021-10-14 12:48:08 -060053 int ret;
54
Patrice Chotard993c9122019-11-25 09:07:38 +010055 fs_argv[0] = "load";
56 fs_argv[3] = file_addr;
57 fs_argv[4] = (void *)file_path;
58
Simon Glassb1ead6b2021-10-14 12:47:57 -060059 if (!do_load(ctx->cmdtp, 0, 5, fs_argv, FS_TYPE_ANY))
Patrice Chotard993c9122019-11-25 09:07:38 +010060 return 1;
Simon Glass4d79e882021-10-14 12:48:08 -060061 ret = pxe_get_file_size(sizep);
62 if (ret)
63 return log_msg_ret("tftp", ret);
Patrice Chotard993c9122019-11-25 09:07:38 +010064#endif
65 return -ENOENT;
66}
67
68/*
69 * Boots a system using a local disk syslinux/extlinux file
70 *
71 * Returns 0 on success, 1 on error.
72 */
Simon Glass09140112020-05-10 11:40:03 -060073static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
74 char *const argv[])
Patrice Chotard993c9122019-11-25 09:07:38 +010075{
76 unsigned long pxefile_addr_r;
Simon Glass12df8422021-10-14 12:48:04 -060077 pxe_getfile_func getfile;
Simon Glassfd3fa5c2021-10-14 12:47:56 -060078 struct pxe_context ctx;
Patrice Chotard993c9122019-11-25 09:07:38 +010079 char *pxefile_addr_str;
80 char *filename;
81 int prompt = 0;
Simon Glass9e62e7c2021-10-14 12:48:03 -060082 int ret;
Patrice Chotard993c9122019-11-25 09:07:38 +010083
Patrice Chotard993c9122019-11-25 09:07:38 +010084 if (argc > 1 && strstr(argv[1], "-p")) {
85 prompt = 1;
86 argc--;
87 argv++;
88 }
89
90 if (argc < 4)
91 return cmd_usage(cmdtp);
92
93 if (argc < 5) {
94 pxefile_addr_str = from_env("pxefile_addr_r");
95 if (!pxefile_addr_str)
96 return 1;
97 } else {
98 pxefile_addr_str = argv[4];
99 }
100
Patrice Chotard51843ea2019-11-25 09:07:40 +0100101 if (argc < 6) {
Patrice Chotard993c9122019-11-25 09:07:38 +0100102 filename = env_get("bootfile");
Patrice Chotard51843ea2019-11-25 09:07:40 +0100103 } else {
Patrice Chotard993c9122019-11-25 09:07:38 +0100104 filename = argv[5];
105 env_set("bootfile", filename);
106 }
107
Patrice Chotard51843ea2019-11-25 09:07:40 +0100108 if (strstr(argv[3], "ext2")) {
Simon Glass12df8422021-10-14 12:48:04 -0600109 getfile = do_get_ext2;
Patrice Chotard51843ea2019-11-25 09:07:40 +0100110 } else if (strstr(argv[3], "fat")) {
Simon Glass12df8422021-10-14 12:48:04 -0600111 getfile = do_get_fat;
Patrice Chotard51843ea2019-11-25 09:07:40 +0100112 } else if (strstr(argv[3], "any")) {
Simon Glass12df8422021-10-14 12:48:04 -0600113 getfile = do_get_any;
Patrice Chotard51843ea2019-11-25 09:07:40 +0100114 } else {
Patrice Chotard993c9122019-11-25 09:07:38 +0100115 printf("Invalid filesystem: %s\n", argv[3]);
116 return 1;
117 }
118 fs_argv[1] = argv[1];
119 fs_argv[2] = argv[2];
120
121 if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) {
122 printf("Invalid pxefile address: %s\n", pxefile_addr_str);
123 return 1;
124 }
125
Simon Glass12df8422021-10-14 12:48:04 -0600126 if (pxe_setup_ctx(&ctx, cmdtp, getfile, NULL, true, filename)) {
127 printf("Out of memory\n");
128 return CMD_RET_FAILURE;
129 }
130
Simon Glassfd3fa5c2021-10-14 12:47:56 -0600131 if (get_pxe_file(&ctx, filename, pxefile_addr_r) < 0) {
Patrice Chotard993c9122019-11-25 09:07:38 +0100132 printf("Error reading config file\n");
Simon Glass12df8422021-10-14 12:48:04 -0600133 pxe_destroy_ctx(&ctx);
Patrice Chotard993c9122019-11-25 09:07:38 +0100134 return 1;
135 }
136
Simon Glass9e62e7c2021-10-14 12:48:03 -0600137 ret = pxe_process(&ctx, pxefile_addr_r, prompt);
Simon Glass12df8422021-10-14 12:48:04 -0600138 pxe_destroy_ctx(&ctx);
Simon Glass9e62e7c2021-10-14 12:48:03 -0600139 if (ret)
140 return CMD_RET_FAILURE;
Patrice Chotard993c9122019-11-25 09:07:38 +0100141
142 return 0;
143}
144
Patrice Chotard51843ea2019-11-25 09:07:40 +0100145U_BOOT_CMD(sysboot, 7, 1, do_sysboot,
146 "command to get and boot from syslinux files",
147 "[-p] <interface> <dev[:part]> <ext2|fat|any> [addr] [filename]\n"
148 " - load and parse syslinux menu file 'filename' from ext2, fat\n"
149 " or any filesystem on 'dev' on 'interface' to address 'addr'"
Patrice Chotard993c9122019-11-25 09:07:38 +0100150);