blob: 1b108118658e39c3cd039a53afb718a74df7ed81 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Miao Yan4fcd7f22016-05-22 19:37:14 -07002/*
3 * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
Miao Yan4fcd7f22016-05-22 19:37:14 -07004 */
5
Miao Yan4fcd7f22016-05-22 19:37:14 -07006#include <command.h>
Simon Glass5e6201b2019-08-01 09:46:51 -06007#include <env.h>
Miao Yan4fcd7f22016-05-22 19:37:14 -07008#include <errno.h>
Miao Yan92106272016-05-22 19:37:17 -07009#include <qfw.h>
Asherah Connor4ffa95d2021-03-19 18:21:40 +110010#include <dm.h>
11
12static struct udevice *qfw_dev;
Miao Yan4fcd7f22016-05-22 19:37:14 -070013
Asherah Connor4ffa95d2021-03-19 18:21:40 +110014static int qemu_fwcfg_cmd_list_firmware(void)
Miao Yan4fcd7f22016-05-22 19:37:14 -070015{
16 int ret;
17 struct fw_cfg_file_iter iter;
18 struct fw_file *file;
19
20 /* make sure fw_list is loaded */
Asherah Connor4ffa95d2021-03-19 18:21:40 +110021 ret = qfw_read_firmware_list(qfw_dev);
Miao Yan4fcd7f22016-05-22 19:37:14 -070022 if (ret)
23 return ret;
24
Asherah Connor4ffa95d2021-03-19 18:21:40 +110025 for (file = qfw_file_iter_init(qfw_dev, &iter);
26 !qfw_file_iter_end(&iter);
27 file = qfw_file_iter_next(&iter)) {
Simon Glass30e0bb82023-07-15 21:38:48 -060028 printf("%08lx %-56s\n", file->addr, file->cfg.name);
Miao Yan4fcd7f22016-05-22 19:37:14 -070029 }
30
31 return 0;
32}
33
Simon Glassed38aef2020-05-10 11:40:03 -060034static int qemu_fwcfg_do_list(struct cmd_tbl *cmdtp, int flag,
35 int argc, char *const argv[])
Miao Yan4fcd7f22016-05-22 19:37:14 -070036{
Asherah Connor4ffa95d2021-03-19 18:21:40 +110037 if (qemu_fwcfg_cmd_list_firmware() < 0)
Miao Yan4fcd7f22016-05-22 19:37:14 -070038 return CMD_RET_FAILURE;
39
40 return 0;
41}
42
Simon Glassed38aef2020-05-10 11:40:03 -060043static int qemu_fwcfg_do_cpus(struct cmd_tbl *cmdtp, int flag,
44 int argc, char *const argv[])
Miao Yan4fcd7f22016-05-22 19:37:14 -070045{
Asherah Connor4ffa95d2021-03-19 18:21:40 +110046 printf("%d cpu(s) online\n", qfw_online_cpus(qfw_dev));
Miao Yan4fcd7f22016-05-22 19:37:14 -070047 return 0;
48}
49
Simon Glassed38aef2020-05-10 11:40:03 -060050static int qemu_fwcfg_do_load(struct cmd_tbl *cmdtp, int flag,
51 int argc, char *const argv[])
Miao Yan4fcd7f22016-05-22 19:37:14 -070052{
53 char *env;
Simon Glassc1620b32023-01-28 15:00:22 -070054 ulong load_addr;
55 ulong initrd_addr;
Miao Yan4fcd7f22016-05-22 19:37:14 -070056
Simon Glass64b723f2017-08-03 12:22:12 -060057 env = env_get("loadaddr");
Miao Yan4fcd7f22016-05-22 19:37:14 -070058 load_addr = env ?
Simon Glassc1620b32023-01-28 15:00:22 -070059 hextoul(env, NULL) :
60 CONFIG_SYS_LOAD_ADDR;
Miao Yan4fcd7f22016-05-22 19:37:14 -070061
Simon Glass64b723f2017-08-03 12:22:12 -060062 env = env_get("ramdiskaddr");
Miao Yan4fcd7f22016-05-22 19:37:14 -070063 initrd_addr = env ?
Simon Glassc1620b32023-01-28 15:00:22 -070064 hextoul(env, NULL) :
Tom Rini0d5392d2022-12-04 10:13:39 -050065#ifdef CFG_RAMDISK_ADDR
Simon Glassc1620b32023-01-28 15:00:22 -070066 CFG_RAMDISK_ADDR;
Miao Yan43626762016-05-22 19:37:18 -070067#else
Simon Glassc1620b32023-01-28 15:00:22 -070068 0;
Miao Yan43626762016-05-22 19:37:18 -070069#endif
Miao Yan4fcd7f22016-05-22 19:37:14 -070070
71 if (argc == 2) {
Simon Glassc1620b32023-01-28 15:00:22 -070072 load_addr = hextoul(argv[0], NULL);
73 initrd_addr = hextoul(argv[1], NULL);
Miao Yan4fcd7f22016-05-22 19:37:14 -070074 } else if (argc == 1) {
Simon Glassc1620b32023-01-28 15:00:22 -070075 load_addr = hextoul(argv[0], NULL);
Miao Yan4fcd7f22016-05-22 19:37:14 -070076 }
77
Miao Yan43626762016-05-22 19:37:18 -070078 if (!load_addr || !initrd_addr) {
79 printf("missing load or initrd address\n");
80 return CMD_RET_FAILURE;
81 }
82
Simon Glass61f3e2e2023-01-28 15:00:23 -070083 return qemu_fwcfg_setup_kernel(qfw_dev, load_addr, initrd_addr);
Miao Yan4fcd7f22016-05-22 19:37:14 -070084}
85
Simon Glassed38aef2020-05-10 11:40:03 -060086static struct cmd_tbl fwcfg_commands[] = {
Miao Yan4fcd7f22016-05-22 19:37:14 -070087 U_BOOT_CMD_MKENT(list, 0, 1, qemu_fwcfg_do_list, "", ""),
88 U_BOOT_CMD_MKENT(cpus, 0, 1, qemu_fwcfg_do_cpus, "", ""),
89 U_BOOT_CMD_MKENT(load, 2, 1, qemu_fwcfg_do_load, "", ""),
90};
91
Simon Glassed38aef2020-05-10 11:40:03 -060092static int do_qemu_fw(struct cmd_tbl *cmdtp, int flag, int argc,
93 char *const argv[])
Miao Yan4fcd7f22016-05-22 19:37:14 -070094{
95 int ret;
Simon Glassed38aef2020-05-10 11:40:03 -060096 struct cmd_tbl *fwcfg_cmd;
Miao Yan4fcd7f22016-05-22 19:37:14 -070097
Asherah Connor4ffa95d2021-03-19 18:21:40 +110098 ret = qfw_get_dev(&qfw_dev);
99 if (ret) {
Miao Yan4fcd7f22016-05-22 19:37:14 -0700100 printf("QEMU fw_cfg interface not found\n");
101 return CMD_RET_USAGE;
102 }
103
104 fwcfg_cmd = find_cmd_tbl(argv[1], fwcfg_commands,
105 ARRAY_SIZE(fwcfg_commands));
106 argc -= 2;
107 argv += 2;
108 if (!fwcfg_cmd || argc > fwcfg_cmd->maxargs)
109 return CMD_RET_USAGE;
110
111 ret = fwcfg_cmd->cmd(fwcfg_cmd, flag, argc, argv);
112
113 return cmd_process_error(fwcfg_cmd, ret);
114}
115
116U_BOOT_CMD(
117 qfw, 4, 1, do_qemu_fw,
118 "QEMU firmware interface",
119 "<command>\n"
120 " - list : print firmware(s) currently loaded\n"
121 " - cpus : print online cpu number\n"
122 " - load <kernel addr> <initrd addr> : load kernel and initrd (if any), and setup for zboot\n"
Simon Glass761d6022023-11-18 14:04:52 -0700123);