From patchwork Tue May 28 09:49:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 165277 Delivered-To: patch@linaro.org Received: by 2002:a92:9e1a:0:0:0:0:0 with SMTP id q26csp8252204ili; Tue, 28 May 2019 02:55:53 -0700 (PDT) X-Google-Smtp-Source: APXvYqwEUXk39RMmDQJnE+oSkusZDP8or1RlBLlhEfIfEJ1zpjNnrubHiXuODx+Wk5FaAHkdRoP0 X-Received: by 2002:ac8:228e:: with SMTP id f14mr65868286qta.79.1559037353419; Tue, 28 May 2019 02:55:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1559037353; cv=none; d=google.com; s=arc-20160816; b=qT+vHDpN0rL7OVEmHrmvqwivf1rgO+L9ZUQJtimeQBJon2N/0uKzZck0q55RFi5tNk 1iJyQPksj3VwIZlZfaZldSMqJ8lo8cNv/+KHoAqtAEV72Zyoh9kjsw04C87Pl0ff+2Ac 76FeJmLG228DRq5TaqfWLKg9OZvGfWuc0EkVw4Sk+p0qqfmoDUIq6QmCxBXr4orrN2rC TzWqKs41cK4thNbM64JiMzFtEATK6xPs+QLPKy19/QQ1orexxtRWsXNWmr/IyeOPUfwR yvD+MGzXg1y2bNIkmqalFYITBP8Gnlf9i2ZScOASaJWYyx5KedVuC0y6jPryCqH9gcw2 AnDQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=TyxM8f0bgznD46UNumFr9MU2H3Me2+hTtxb1e2LSXfA=; b=wksBj6q9f/bygq75y2s6MzWZg6GGiXyX+ImXYUVWEn8xqUfmLeBOcRhDh2z3lWwWQ6 t2gDqkbTsdQ9F7e3AXFFM6SxSZQrpCLvHnKgN7vjzq2cniEGwri1OWb2WnQbGLSH/IIG Jv10HMx43Yqj/3JVaoB3SdUsPPi3IefU0n0fItQEPrdvxjm41VWw8sa59LtXfwu8RwDj wPOJvsn6JD8aMfTtnNbIFt/R3kJMfKCvMFL2iLMXrKVJJlS72v0KKY1hhyzPFpp7T2aA fEzxkmJNAbZUQDg9z7ih0wNl3wabySzACwQ8XEBtwSjPu+8Q1oR7q2CKTGp6EV7Pp9HA HzHA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b="xBjDGp/9"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id h9si4595412qkk.248.2019.05.28.02.55.53 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 28 May 2019 02:55:53 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b="xBjDGp/9"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1]:60021 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hVYpk-0002qc-Uh for patch@linaro.org; Tue, 28 May 2019 05:55:53 -0400 Received: from eggs.gnu.org ([209.51.188.92]:40697) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hVYk2-0006Da-Vo for qemu-devel@nongnu.org; Tue, 28 May 2019 05:50:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hVYk0-0008Ql-Iz for qemu-devel@nongnu.org; Tue, 28 May 2019 05:49:58 -0400 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:36785) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hVYk0-0008PV-9T for qemu-devel@nongnu.org; Tue, 28 May 2019 05:49:56 -0400 Received: by mail-wr1-x443.google.com with SMTP id s17so19479419wru.3 for ; Tue, 28 May 2019 02:49:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=TyxM8f0bgznD46UNumFr9MU2H3Me2+hTtxb1e2LSXfA=; b=xBjDGp/9i/SI1KNVWmmEb1tt/jVZ+iVCRey810AZh4ud15EnbCOvcyBpihjkBT1/Yv +r1IFWfAmOCBfuCL8TwRLAXwuNdq9UFfFRYkCt5JLxbCTF5+nfmLx+TfQkBVwpq2YWkt 0I2QMCiM89OexyM5aE9Nn1ZMVHwlfceGCPgfRflOwfRBtxJ7gofAptj5a+1hbPQO6Rln KYTFPoyvE56W1jHCdNmRmA++/HlzrNBRkO8XeAhMbqDGsVjz+b8TlUSwVnnDTLc1ZFhb IrF8kYj2eOOurAU0b3x+xyNqqj8P9G+y1YkSpqbviZktJ4hMaPdUiHwgymedjwqtPtxS ID8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TyxM8f0bgznD46UNumFr9MU2H3Me2+hTtxb1e2LSXfA=; b=lLfcdnNCnXkgit+g0LSBx9blfANe1q5lWTo58MlEhXyaG4yT8cCG7xskXAOfTpU+Ss kaqELLxI0wV6oBwC+eC0Xd+368ANWqPMufAkIhtAvwLZG+x4DzGBkaGr8NHU8znCqE8Q apblyFRZ+issSz+fa0kniv5r95t/kUfXcmWKFKiozUJKdLNHTQIkIwA9xpbZ69oyIyFL DIqCXfklAidajclAPkcraj+eKZ4FaWD+nmtMAEU2sG199IDKvS5VwSVwNqD2SEjfkcND yzS0CkQ5R5iLK/wiGvFXHrKhctpWBKQuX3+Tp0w4zEmGsxrA+95H+8Y5UN1b23VscQij HbQg== X-Gm-Message-State: APjAAAV7MrZ18NuXOKpOLkvUg3FUrbTUCa7eXZerKqBHbBToUp9oEdgm vxbP77yBhrANH4Utiv8L/sC94A== X-Received: by 2002:adf:ee0c:: with SMTP id y12mr53945770wrn.34.1559036994858; Tue, 28 May 2019 02:49:54 -0700 (PDT) Received: from zen.linaroharston ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id j206sm2496799wma.47.2019.05.28.02.49.53 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 28 May 2019 02:49:54 -0700 (PDT) Received: from zen.linaroharston. (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 725651FF8C; Tue, 28 May 2019 10:49:53 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Tue, 28 May 2019 10:49:26 +0100 Message-Id: <20190528094953.14898-2-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190528094953.14898-1-alex.bennee@linaro.org> References: <20190528094953.14898-1-alex.bennee@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::443 Subject: [Qemu-devel] [PULL 01/28] semihosting: move semihosting configuration into its own directory X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marek Vasut , Aleksandar Rikalo , =?utf-8?q?Alex_Benn=C3=A9e?= , Chris Wulff , Richard Henderson , qemu-devel@nongnu.org, Laurent Vivier , Max Filippov , Michael Walle , "open list:ARM" , Aleksandar Markovic , Paolo Bonzini , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?b?w6k=?= , Aurelien Jarno Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" In preparation for having some more common semihosting code let's excise the current config magic from vl.c into its own file. We shall later add more conditionals to the build configurations so we can avoid building this if we don't need it. Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson -- 2.20.1 diff --git a/gdbstub.c b/gdbstub.c index b129df4e597..462f89edfee 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -37,7 +37,7 @@ #include "qemu/sockets.h" #include "sysemu/hw_accel.h" #include "sysemu/kvm.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "exec/exec-all.h" #ifdef CONFIG_USER_ONLY diff --git a/hw/Makefile.objs b/hw/Makefile.objs index 82aa7fab8e4..d770926ba96 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -36,6 +36,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += watchdog/ devices-dirs-$(CONFIG_SOFTMMU) += xen/ devices-dirs-$(CONFIG_MEM_DEVICE) += mem/ devices-dirs-$(CONFIG_SOFTMMU) += smbios/ +devices-dirs-y += semihosting/ devices-dirs-y += core/ common-obj-y += $(devices-dirs-y) obj-y += $(devices-dirs-y) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 439665ab45e..3b009fda25f 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -55,7 +55,7 @@ #include "qemu/error-report.h" #include "hw/empty_slot.h" #include "sysemu/kvm.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "hw/mips/cps.h" #define ENVP_ADDR 0x80002000l diff --git a/hw/semihosting/Makefile.objs b/hw/semihosting/Makefile.objs new file mode 100644 index 00000000000..546954f4ff4 --- /dev/null +++ b/hw/semihosting/Makefile.objs @@ -0,0 +1 @@ +common-obj-$(CONFIG_SOFTMMU) += config.o diff --git a/hw/semihosting/config.c b/hw/semihosting/config.c new file mode 100644 index 00000000000..f1d3fe1e4c6 --- /dev/null +++ b/hw/semihosting/config.c @@ -0,0 +1,160 @@ +/* + * Semihosting configuration + * + * Copyright (c) 2015 Imagination Technologies + * Copyright (c) 2019 Linaro Ltd + * + * This controls the configuration of semihosting for all guest + * targets that support it. Architecture specific handling is handled + * in target/HW/HW-semi.c + * + * Semihosting is sightly strange in that it is also supported by some + * linux-user targets. However in that use case no configuration of + * the outputs and command lines is supported. + * + * The config module is common to all softmmu targets however as vl.c + * needs to link against the helpers. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/option.h" +#include "qemu/config-file.h" +#include "qemu/error-report.h" +#include "hw/semihosting/semihost.h" + +QemuOptsList qemu_semihosting_config_opts = { + .name = "semihosting-config", + .implied_opt_name = "enable", + .head = QTAILQ_HEAD_INITIALIZER(qemu_semihosting_config_opts.head), + .desc = { + { + .name = "enable", + .type = QEMU_OPT_BOOL, + }, { + .name = "target", + .type = QEMU_OPT_STRING, + }, { + .name = "arg", + .type = QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + +typedef struct SemihostingConfig { + bool enabled; + SemihostingTarget target; + const char **argv; + int argc; + const char *cmdline; /* concatenated argv */ +} SemihostingConfig; + +static SemihostingConfig semihosting; + +bool semihosting_enabled(void) +{ + return semihosting.enabled; +} + +SemihostingTarget semihosting_get_target(void) +{ + return semihosting.target; +} + +const char *semihosting_get_arg(int i) +{ + if (i >= semihosting.argc) { + return NULL; + } + return semihosting.argv[i]; +} + +int semihosting_get_argc(void) +{ + return semihosting.argc; +} + +const char *semihosting_get_cmdline(void) +{ + if (semihosting.cmdline == NULL && semihosting.argc > 0) { + semihosting.cmdline = g_strjoinv(" ", (gchar **)semihosting.argv); + } + return semihosting.cmdline; +} + +static int add_semihosting_arg(void *opaque, + const char *name, const char *val, + Error **errp) +{ + SemihostingConfig *s = opaque; + if (strcmp(name, "arg") == 0) { + s->argc++; + /* one extra element as g_strjoinv() expects NULL-terminated array */ + s->argv = g_realloc(s->argv, (s->argc + 1) * sizeof(void *)); + s->argv[s->argc - 1] = val; + s->argv[s->argc] = NULL; + } + return 0; +} + +/* Use strings passed via -kernel/-append to initialize semihosting.argv[] */ +void semihosting_arg_fallback(const char *file, const char *cmd) +{ + char *cmd_token; + + /* argv[0] */ + add_semihosting_arg(&semihosting, "arg", file, NULL); + + /* split -append and initialize argv[1..n] */ + cmd_token = strtok(g_strdup(cmd), " "); + while (cmd_token) { + add_semihosting_arg(&semihosting, "arg", cmd_token, NULL); + cmd_token = strtok(NULL, " "); + } +} + +void qemu_semihosting_enable(void) +{ + semihosting.enabled = true; + semihosting.target = SEMIHOSTING_TARGET_AUTO; +} + +int qemu_semihosting_config_options(const char *optarg) +{ + QemuOptsList *opt_list = qemu_find_opts("semihosting-config"); + QemuOpts *opts = qemu_opts_parse_noisily(opt_list, optarg, false); + + semihosting.enabled = true; + + if (opts != NULL) { + semihosting.enabled = qemu_opt_get_bool(opts, "enable", + true); + const char *target = qemu_opt_get(opts, "target"); + if (target != NULL) { + if (strcmp("native", target) == 0) { + semihosting.target = SEMIHOSTING_TARGET_NATIVE; + } else if (strcmp("gdb", target) == 0) { + semihosting.target = SEMIHOSTING_TARGET_GDB; + } else if (strcmp("auto", target) == 0) { + semihosting.target = SEMIHOSTING_TARGET_AUTO; + } else { + error_report("unsupported semihosting-config %s", + optarg); + return 1; + } + } else { + semihosting.target = SEMIHOSTING_TARGET_AUTO; + } + /* Set semihosting argument count and vector */ + qemu_opt_foreach(opts, add_semihosting_arg, + &semihosting, NULL); + } else { + error_report("unsupported semihosting-config %s", optarg); + return 1; + } + + return 0; +} + diff --git a/include/exec/semihost.h b/include/hw/semihosting/semihost.h similarity index 85% rename from include/exec/semihost.h rename to include/hw/semihosting/semihost.h index 5980939c7b8..07ea40a322f 100644 --- a/include/exec/semihost.h +++ b/include/hw/semihosting/semihost.h @@ -51,12 +51,16 @@ static inline const char *semihosting_get_cmdline(void) { return NULL; } -#else +#else /* !CONFIG_USER_ONLY */ bool semihosting_enabled(void); SemihostingTarget semihosting_get_target(void); const char *semihosting_get_arg(int i); int semihosting_get_argc(void); const char *semihosting_get_cmdline(void); -#endif +void semihosting_arg_fallback(const char *file, const char *cmd); +/* for vl.c hooks */ +void qemu_semihosting_enable(void); +int qemu_semihosting_config_options(const char *opt); +#endif /* CONFIG_USER_ONLY */ -#endif +#endif /* SEMIHOST_H */ diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 5f133cae837..61579ae71ef 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -193,5 +193,6 @@ extern QemuOptsList qemu_nic_opts; extern QemuOptsList qemu_net_opts; extern QemuOptsList qemu_global_opts; extern QemuOptsList qemu_mon_opts; +extern QemuOptsList qemu_semihosting_config_opts; #endif diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c index ddb94e0aba0..a99049c7d58 100644 --- a/target/arm/arm-semi.c +++ b/target/arm/arm-semi.c @@ -21,7 +21,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #ifdef CONFIG_USER_ONLY #include "qemu.h" diff --git a/target/arm/helper.c b/target/arm/helper.c index acd23c53ca6..719fb92e600 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -16,7 +16,7 @@ #include "exec/cpu_ldst.h" #include "arm_ldst.h" #include /* For crc32 */ -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "sysemu/cpus.h" #include "sysemu/kvm.h" #include "fpu/softfloat.h" diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 42999c58011..092f0df3c4b 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -29,7 +29,7 @@ #include "qemu/host-utils.h" #include "qemu/qemu-print.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "exec/gen-icount.h" #include "exec/helper-proto.h" diff --git a/target/arm/translate.c b/target/arm/translate.c index 298c262825d..d240c1b7144 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -30,7 +30,7 @@ #include "qemu/bitops.h" #include "qemu/qemu-print.h" #include "arm_ldst.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "exec/helper-proto.h" #include "exec/helper-gen.h" diff --git a/target/lm32/helper.c b/target/lm32/helper.c index 20ea17ba23c..8cd48400521 100644 --- a/target/lm32/helper.c +++ b/target/lm32/helper.c @@ -22,7 +22,7 @@ #include "exec/exec-all.h" #include "qemu/host-utils.h" #include "sysemu/sysemu.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "exec/log.h" bool lm32_cpu_tlb_fill(CPUState *cs, vaddr address, int size, diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c index 1ecc772b5cb..bde2d551ff6 100644 --- a/target/m68k/op_helper.c +++ b/target/m68k/op_helper.c @@ -21,7 +21,7 @@ #include "exec/helper-proto.h" #include "exec/exec-all.h" #include "exec/cpu_ldst.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #if defined(CONFIG_USER_ONLY) diff --git a/target/mips/mips-semi.c b/target/mips/mips-semi.c index a7aefbaefc8..eac8374fb34 100644 --- a/target/mips/mips-semi.c +++ b/target/mips/mips-semi.c @@ -22,7 +22,7 @@ #include "qemu/log.h" #include "exec/helper-proto.h" #include "exec/softmmu-semi.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" typedef enum UHIOp { UHI_exit = 1, diff --git a/target/mips/translate.c b/target/mips/translate.c index f96c0d01ef1..3cd5b11b16b 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -32,7 +32,7 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "target/mips/trace.h" #include "trace-tcg.h" diff --git a/target/nios2/helper.c b/target/nios2/helper.c index ffb83fc1045..57c97bde3c6 100644 --- a/target/nios2/helper.c +++ b/target/nios2/helper.c @@ -26,7 +26,7 @@ #include "exec/cpu_ldst.h" #include "exec/log.h" #include "exec/helper-proto.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #if defined(CONFIG_USER_ONLY) diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index 53dce470c17..6f1da878752 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -38,7 +38,7 @@ #include "qemu/qemu-print.h" #include "sysemu/sysemu.h" #include "exec/cpu_ldst.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "exec/translator.h" #include "exec/helper-proto.h" diff --git a/target/xtensa/xtensa-semi.c b/target/xtensa/xtensa-semi.c index 5f5ce4f344c..38efa3485af 100644 --- a/target/xtensa/xtensa-semi.c +++ b/target/xtensa/xtensa-semi.c @@ -29,7 +29,7 @@ #include "cpu.h" #include "chardev/char-fe.h" #include "exec/helper-proto.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "qapi/error.h" #include "qemu/log.h" #include "sysemu/sysemu.h" diff --git a/vl.c b/vl.c index 5550bd7693c..be8963b2705 100644 --- a/vl.c +++ b/vl.c @@ -116,7 +116,7 @@ int main(int argc, char **argv) #include "qapi/opts-visitor.h" #include "qapi/clone-visitor.h" #include "qom/object_interfaces.h" -#include "exec/semihost.h" +#include "hw/semihosting/semihost.h" #include "crypto/init.h" #include "sysemu/replay.h" #include "qapi/qapi-events-run-state.h" @@ -501,25 +501,6 @@ static QemuOptsList qemu_icount_opts = { }, }; -static QemuOptsList qemu_semihosting_config_opts = { - .name = "semihosting-config", - .implied_opt_name = "enable", - .head = QTAILQ_HEAD_INITIALIZER(qemu_semihosting_config_opts.head), - .desc = { - { - .name = "enable", - .type = QEMU_OPT_BOOL, - }, { - .name = "target", - .type = QEMU_OPT_STRING, - }, { - .name = "arg", - .type = QEMU_OPT_STRING, - }, - { /* end of list */ } - }, -}; - static QemuOptsList qemu_fw_cfg_opts = { .name = "fw_cfg", .implied_opt_name = "name", @@ -1351,80 +1332,6 @@ static void configure_msg(QemuOpts *opts) enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true); } -/***********************************************************/ -/* Semihosting */ - -typedef struct SemihostingConfig { - bool enabled; - SemihostingTarget target; - const char **argv; - int argc; - const char *cmdline; /* concatenated argv */ -} SemihostingConfig; - -static SemihostingConfig semihosting; - -bool semihosting_enabled(void) -{ - return semihosting.enabled; -} - -SemihostingTarget semihosting_get_target(void) -{ - return semihosting.target; -} - -const char *semihosting_get_arg(int i) -{ - if (i >= semihosting.argc) { - return NULL; - } - return semihosting.argv[i]; -} - -int semihosting_get_argc(void) -{ - return semihosting.argc; -} - -const char *semihosting_get_cmdline(void) -{ - if (semihosting.cmdline == NULL && semihosting.argc > 0) { - semihosting.cmdline = g_strjoinv(" ", (gchar **)semihosting.argv); - } - return semihosting.cmdline; -} - -static int add_semihosting_arg(void *opaque, - const char *name, const char *val, - Error **errp) -{ - SemihostingConfig *s = opaque; - if (strcmp(name, "arg") == 0) { - s->argc++; - /* one extra element as g_strjoinv() expects NULL-terminated array */ - s->argv = g_realloc(s->argv, (s->argc + 1) * sizeof(void *)); - s->argv[s->argc - 1] = val; - s->argv[s->argc] = NULL; - } - return 0; -} - -/* Use strings passed via -kernel/-append to initialize semihosting.argv[] */ -static inline void semihosting_arg_fallback(const char *file, const char *cmd) -{ - char *cmd_token; - - /* argv[0] */ - add_semihosting_arg(&semihosting, "arg", file, NULL); - - /* split -append and initialize argv[1..n] */ - cmd_token = strtok(g_strdup(cmd), " "); - while (cmd_token) { - add_semihosting_arg(&semihosting, "arg", cmd_token, NULL); - cmd_token = strtok(NULL, " "); - } -} /* Now we still need this for compatibility with XEN. */ bool has_igd_gfx_passthru; @@ -3743,37 +3650,10 @@ int main(int argc, char **argv, char **envp) nb_option_roms++; break; case QEMU_OPTION_semihosting: - semihosting.enabled = true; - semihosting.target = SEMIHOSTING_TARGET_AUTO; + qemu_semihosting_enable(); break; case QEMU_OPTION_semihosting_config: - semihosting.enabled = true; - opts = qemu_opts_parse_noisily(qemu_find_opts("semihosting-config"), - optarg, false); - if (opts != NULL) { - semihosting.enabled = qemu_opt_get_bool(opts, "enable", - true); - const char *target = qemu_opt_get(opts, "target"); - if (target != NULL) { - if (strcmp("native", target) == 0) { - semihosting.target = SEMIHOSTING_TARGET_NATIVE; - } else if (strcmp("gdb", target) == 0) { - semihosting.target = SEMIHOSTING_TARGET_GDB; - } else if (strcmp("auto", target) == 0) { - semihosting.target = SEMIHOSTING_TARGET_AUTO; - } else { - error_report("unsupported semihosting-config %s", - optarg); - exit(1); - } - } else { - semihosting.target = SEMIHOSTING_TARGET_AUTO; - } - /* Set semihosting argument count and vector */ - qemu_opt_foreach(opts, add_semihosting_arg, - &semihosting, NULL); - } else { - error_report("unsupported semihosting-config %s", optarg); + if (qemu_semihosting_config_options(optarg) != 0) { exit(1); } break;