From patchwork Wed Nov 19 22:05:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liviu Ionescu X-Patchwork-Id: 412529 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id BF0BE140139 for ; Thu, 20 Nov 2014 09:06:21 +1100 (AEDT) Received: from localhost ([::1]:60929 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XrDOE-0005cT-68 for incoming@patchwork.ozlabs.org; Wed, 19 Nov 2014 17:06:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37377) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XrDNl-00056p-R0 for qemu-devel@nongnu.org; Wed, 19 Nov 2014 17:05:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XrDNd-0005Mv-5u for qemu-devel@nongnu.org; Wed, 19 Nov 2014 17:05:49 -0500 Received: from [109.99.239.84] (port=48816 helo=ilg-mbp.local) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XrDNc-0005Mf-O0 for qemu-devel@nongnu.org; Wed, 19 Nov 2014 17:05:41 -0500 Received: by ilg-mbp.local (Postfix, from userid 501) id 10F002E44390; Thu, 20 Nov 2014 00:05:32 +0200 (EET) From: Liviu Ionescu To: qemu-devel@nongnu.org Date: Thu, 20 Nov 2014 00:05:23 +0200 Message-Id: <1416434723-59406-1-git-send-email-ilg@livius.net> X-Mailer: git-send-email 1.9.3 (Apple Git-50) X-detected-operating-system: by eggs.gnu.org: iOS iPhone or iPad X-Received-From: 109.99.239.84 Cc: peter.maydell@linaro.org, ilg@livius.net Subject: [Qemu-devel] [PATCH] Add -semihosting-config ....cmdline=string. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org A new sub-option was added to -semihosting-config to define the entire semihosting command line (cmdline=string). This string is passed down to armv7m.c; if not defined, for compatibility reasons, the -kernel -append values are used. The armv7m_init() and stellaris_init() interfaces were streamlined, to use the MachineState structure instead of separate strings. The semihosting_cmdline was added to the structures MachineState and arm_boot_info. Signed-off-by: Liviu Ionescu --- hw/arm/armv7m.c | 15 ++++++++++++++- hw/arm/stellaris.c | 12 ++++-------- include/hw/arm/arm.h | 3 ++- include/hw/boards.h | 1 + qemu-options.hx | 10 +++++++--- target-arm/arm-semi.c | 19 +++++++++++++++---- vl.c | 9 +++++++++ 7 files changed, 52 insertions(+), 17 deletions(-) mode change 100644 => 100755 qemu-options.hx diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index ef24ca4..696de12 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -13,6 +13,9 @@ #include "elf.h" #include "sysemu/qtest.h" #include "qemu/error-report.h" +#include "hw/boards.h" + +static struct arm_boot_info armv7m_binfo; /* Bitbanded IO. Each word corresponds to a single bit. */ @@ -168,7 +171,7 @@ static void armv7m_reset(void *opaque) qemu_irq *armv7m_init(MemoryRegion *system_memory, int flash_size, int sram_size, - const char *kernel_filename, const char *cpu_model) + MachineState *machine) { ARMCPU *cpu; CPUARMState *env; @@ -184,6 +187,9 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, MemoryRegion *flash = g_new(MemoryRegion, 1); MemoryRegion *hack = g_new(MemoryRegion, 1); + const char *kernel_filename = machine->kernel_filename; + const char *cpu_model = machine->cpu_model; + flash_size *= 1024; sram_size *= 1024; @@ -240,6 +246,13 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, exit(1); } + /* Fill-in a minimalistic boot info, required for semihosting */ + armv7m_binfo.kernel_filename = kernel_filename; + armv7m_binfo.kernel_cmdline = machine->kernel_cmdline; + armv7m_binfo.semihosting_cmdline = machine->semihosting_cmdline; + + env->boot_info = &armv7m_binfo; + if (kernel_filename) { image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr, NULL, big_endian, ELF_MACHINE, 1); diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index 64bd4b4..f93326a 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -1198,7 +1198,7 @@ static stellaris_board_info stellaris_boards[] = { } }; -static void stellaris_init(const char *kernel_filename, const char *cpu_model, +static void stellaris_init(MachineState *machine, stellaris_board_info *board) { static const int uart_irq[] = {5, 6, 33, 34}; @@ -1223,7 +1223,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, flash_size = ((board->dc0 & 0xffff) + 1) << 1; sram_size = (board->dc0 >> 18) + 1; pic = armv7m_init(get_system_memory(), - flash_size, sram_size, kernel_filename, cpu_model); + flash_size, sram_size, machine); if (board->dc1 & (1 << 16)) { dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000, @@ -1335,16 +1335,12 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, /* FIXME: Figure out how to generate these from stellaris_boards. */ static void lm3s811evb_init(MachineState *machine) { - const char *cpu_model = machine->cpu_model; - const char *kernel_filename = machine->kernel_filename; - stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]); + stellaris_init(machine, &stellaris_boards[0]); } static void lm3s6965evb_init(MachineState *machine) { - const char *cpu_model = machine->cpu_model; - const char *kernel_filename = machine->kernel_filename; - stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]); + stellaris_init(machine, &stellaris_boards[1]); } static QEMUMachine lm3s811evb_machine = { diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h index cefc9e6..bae853c 100644 --- a/include/hw/arm/arm.h +++ b/include/hw/arm/arm.h @@ -17,7 +17,7 @@ /* armv7m.c */ qemu_irq *armv7m_init(MemoryRegion *system_memory, int flash_size, int sram_size, - const char *kernel_filename, const char *cpu_model); + MachineState *machine); /* arm_boot.c */ struct arm_boot_info { @@ -26,6 +26,7 @@ struct arm_boot_info { const char *kernel_cmdline; const char *initrd_filename; const char *dtb_filename; + const char *semihosting_cmdline; hwaddr loader_start; /* multicore boards that use the default secondary core boot functions * need to put the address of the secondary boot code, the boot reg, diff --git a/include/hw/boards.h b/include/hw/boards.h index e0a6790..a739d74 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -142,6 +142,7 @@ struct MachineState { char *kernel_cmdline; char *initrd_filename; const char *cpu_model; + char *semihosting_cmdline; AccelState *accelerator; }; diff --git a/qemu-options.hx b/qemu-options.hx old mode 100644 new mode 100755 index 3e81222..c5db4d1 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3219,14 +3219,18 @@ STEXI Enable semihosting mode (ARM, M68K, Xtensa only). ETEXI DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config, - "-semihosting-config [enable=on|off,]target=native|gdb|auto semihosting configuration\n", + "-semihosting-config [enable=on|off,]target=native|gdb|auto[,cmdline=string] semihosting configuration\n", QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32) STEXI -@item -semihosting-config [enable=on|off,]target=native|gdb|auto +@item -semihosting-config [enable=on|off,]target=native|gdb|auto[,cmdline=string] @findex -semihosting-config Enable semihosting and define where the semihosting calls will be addressed, to QEMU (@code{native}) or to GDB (@code{gdb}). The default is @code{auto}, which means -@code{gdb} during debug sessions and @code{native} otherwise (ARM, M68K, Xtensa only). +@code{gdb} during debug sessions and @code{native} otherwise. The optional +@code{cmdline} defines the entire command line passed to the application via the +semihosting SYS_GET_CMDLINE call, including the program name that will be +passed as argv[0]. +(ARM, M68K, Xtensa only) ETEXI DEF("old-param", 0, QEMU_OPTION_old_param, "-old-param old param mode\n", QEMU_ARCH_ARM) diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c index ebb5235..b5b9c76 100644 --- a/target-arm/arm-semi.c +++ b/target-arm/arm-semi.c @@ -436,10 +436,14 @@ uint32_t do_arm_semihosting(CPUARMState *env) input_size = arg1; /* Compute the size of the output string. */ #if !defined(CONFIG_USER_ONLY) - output_size = strlen(ts->boot_info->kernel_filename) + if (ts->boot_info->semihosting_cmdline) { + output_size = strlen(ts->boot_info->semihosting_cmdline) + 1; + } else { + output_size = strlen(ts->boot_info->kernel_filename) + 1 /* Separating space. */ + strlen(ts->boot_info->kernel_cmdline) + 1; /* Terminating null byte. */ + } #else unsigned int i; @@ -470,9 +474,16 @@ uint32_t do_arm_semihosting(CPUARMState *env) /* Copy the command-line arguments. */ #if !defined(CONFIG_USER_ONLY) - pstrcpy(output_buffer, output_size, ts->boot_info->kernel_filename); - pstrcat(output_buffer, output_size, " "); - pstrcat(output_buffer, output_size, ts->boot_info->kernel_cmdline); + if (ts->boot_info->semihosting_cmdline) { + pstrcpy(output_buffer, output_size, + ts->boot_info->semihosting_cmdline); + } else { + pstrcpy(output_buffer, output_size, + ts->boot_info->kernel_filename); + pstrcat(output_buffer, output_size, " "); + pstrcat(output_buffer, output_size, + ts->boot_info->kernel_cmdline); + } #else if (output_size == 1) { /* Empty command-line. */ diff --git a/vl.c b/vl.c index 8844983..a88e5da 100644 --- a/vl.c +++ b/vl.c @@ -566,6 +566,9 @@ static QemuOptsList qemu_semihosting_config_opts = { }, { .name = "target", .type = QEMU_OPT_STRING, + }, { + .name = "cmdline", + .type = QEMU_OPT_STRING, }, { /* end of list */ } }, @@ -2758,6 +2761,7 @@ int main(int argc, char **argv, char **envp) int snapshot, linux_boot; const char *initrd_filename; const char *kernel_filename, *kernel_cmdline; + const char *semihosting_cmdline = NULL; const char *boot_order; DisplayState *ds; int cyls, heads, secs, translation; @@ -3662,6 +3666,9 @@ int main(int argc, char **argv, char **envp) } else { semihosting_target = SEMIHOSTING_TARGET_AUTO; } + + semihosting_cmdline = qemu_opt_get(opts, "cmdline"); + } else { fprintf(stderr, "Unsupported semihosting-config %s\n", optarg); @@ -4169,6 +4176,8 @@ int main(int argc, char **argv, char **envp) current_machine->kernel_cmdline = (char *)kernel_cmdline; } + current_machine->semihosting_cmdline = (char *)semihosting_cmdline; + linux_boot = (kernel_filename != NULL); if (!linux_boot && *kernel_cmdline != '\0') {