1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com> 4 */ 5 6#include <common.h> 7#include <command.h> 8#include <env.h> 9#include <errno.h> 10#include <qfw.h> 11#include <dm.h> 12 13static struct udevice *qfw_dev; 14 15static int qemu_fwcfg_cmd_list_firmware(void) 16{ 17 int ret; 18 struct fw_cfg_file_iter iter; 19 struct fw_file *file; 20 21 /* make sure fw_list is loaded */ 22 ret = qfw_read_firmware_list(qfw_dev); 23 if (ret) 24 return ret; 25 26 for (file = qfw_file_iter_init(qfw_dev, &iter); 27 !qfw_file_iter_end(&iter); 28 file = qfw_file_iter_next(&iter)) { 29 printf("%08lx %-56s\n", file->addr, file->cfg.name); 30 } 31 32 return 0; 33} 34 35static int qemu_fwcfg_do_list(struct cmd_tbl *cmdtp, int flag, 36 int argc, char *const argv[]) 37{ 38 if (qemu_fwcfg_cmd_list_firmware() < 0) 39 return CMD_RET_FAILURE; 40 41 return 0; 42} 43 44static int qemu_fwcfg_do_cpus(struct cmd_tbl *cmdtp, int flag, 45 int argc, char *const argv[]) 46{ 47 printf("%d cpu(s) online\n", qfw_online_cpus(qfw_dev)); 48 return 0; 49} 50 51static int qemu_fwcfg_do_load(struct cmd_tbl *cmdtp, int flag, 52 int argc, char *const argv[]) 53{ 54 char *env; 55 ulong load_addr; 56 ulong initrd_addr; 57 58 env = env_get("loadaddr"); 59 load_addr = env ? 60 hextoul(env, NULL) : 61 CONFIG_SYS_LOAD_ADDR; 62 63 env = env_get("ramdiskaddr"); 64 initrd_addr = env ? 65 hextoul(env, NULL) : 66#ifdef CFG_RAMDISK_ADDR 67 CFG_RAMDISK_ADDR; 68#else 69 0; 70#endif 71 72 if (argc == 2) { 73 load_addr = hextoul(argv[0], NULL); 74 initrd_addr = hextoul(argv[1], NULL); 75 } else if (argc == 1) { 76 load_addr = hextoul(argv[0], NULL); 77 } 78 79 if (!load_addr || !initrd_addr) { 80 printf("missing load or initrd address\n"); 81 return CMD_RET_FAILURE; 82 } 83 84 return qemu_fwcfg_setup_kernel(qfw_dev, load_addr, initrd_addr); 85} 86 87static struct cmd_tbl fwcfg_commands[] = { 88 U_BOOT_CMD_MKENT(list, 0, 1, qemu_fwcfg_do_list, "", ""), 89 U_BOOT_CMD_MKENT(cpus, 0, 1, qemu_fwcfg_do_cpus, "", ""), 90 U_BOOT_CMD_MKENT(load, 2, 1, qemu_fwcfg_do_load, "", ""), 91}; 92 93static int do_qemu_fw(struct cmd_tbl *cmdtp, int flag, int argc, 94 char *const argv[]) 95{ 96 int ret; 97 struct cmd_tbl *fwcfg_cmd; 98 99 ret = qfw_get_dev(&qfw_dev); 100 if (ret) { 101 printf("QEMU fw_cfg interface not found\n"); 102 return CMD_RET_USAGE; 103 } 104 105 fwcfg_cmd = find_cmd_tbl(argv[1], fwcfg_commands, 106 ARRAY_SIZE(fwcfg_commands)); 107 argc -= 2; 108 argv += 2; 109 if (!fwcfg_cmd || argc > fwcfg_cmd->maxargs) 110 return CMD_RET_USAGE; 111 112 ret = fwcfg_cmd->cmd(fwcfg_cmd, flag, argc, argv); 113 114 return cmd_process_error(fwcfg_cmd, ret); 115} 116 117U_BOOT_CMD( 118 qfw, 4, 1, do_qemu_fw, 119 "QEMU firmware interface", 120 "<command>\n" 121 " - list : print firmware(s) currently loaded\n" 122 " - cpus : print online cpu number\n" 123 " - load <kernel addr> <initrd addr> : load kernel and initrd (if any), and setup for zboot\n" 124); 125