From 0e80359e6285e094eaf1e403835c12081faef535 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 11 Mar 2017 11:24:44 -0800 Subject: [PATCH 1/2] target/xtensa: xtfpga: load DTB only when FDT support is enabled xtensa linux can use DTB but does not require it, so FDT support is not a requirement for target/xtensa. Don't try to load DTB when FDT support is not configured. Signed-off-by: Max Filippov --- hw/xtensa/xtfpga.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c index dc6fdcc266..11176e26bd 100644 --- a/hw/xtensa/xtfpga.c +++ b/hw/xtensa/xtfpga.c @@ -317,6 +317,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine) cur_tagptr = put_tag(cur_tagptr, BP_TAG_COMMAND_LINE, strlen(kernel_cmdline) + 1, kernel_cmdline); } +#ifdef CONFIG_FDT if (dtb_filename) { int fdt_size; void *fdt = load_device_tree(dtb_filename, &fdt_size); @@ -332,6 +333,14 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine) sizeof(dtb_addr), &dtb_addr); cur_lowmem = QEMU_ALIGN_UP(cur_lowmem + fdt_size, 4096); } +#else + if (dtb_filename) { + error_report("could not load DTB '%s': " + "FDT support is not configured in QEMU", + dtb_filename); + exit(EXIT_FAILURE); + } +#endif if (initrd_filename) { BpMemInfo initrd_location = { 0 }; int initrd_size = load_ramdisk(initrd_filename, cur_lowmem, From f289bb091e6876df2e0e3481cb414c277695a405 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sat, 11 Mar 2017 11:24:45 -0800 Subject: [PATCH 2/2] target/xtensa: fix semihosting argc/argv implementation So far xtensa provides fixed dummy argc/argv for the corresponding semihosting calls. Now that there are semihosting_get_argc and semihosting_get_arg, use them to pass actual command line arguments to guest. Signed-off-by: Max Filippov --- target/xtensa/xtensa-semi.c | 47 +++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/target/xtensa/xtensa-semi.c b/target/xtensa/xtensa-semi.c index 370e365c65..a888a9dc7b 100644 --- a/target/xtensa/xtensa-semi.c +++ b/target/xtensa/xtensa-semi.c @@ -28,6 +28,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" +#include "exec/semihost.h" #include "qemu/log.h" enum { @@ -261,28 +262,50 @@ void HELPER(simcall)(CPUXtensaState *env) break; case TARGET_SYS_argc: - regs[2] = 1; + regs[2] = semihosting_get_argc(); regs[3] = 0; break; case TARGET_SYS_argv_sz: - regs[2] = 128; - regs[3] = 0; + { + int argc = semihosting_get_argc(); + int sz = (argc + 1) * sizeof(uint32_t); + int i; + + for (i = 0; i < argc; ++i) { + sz += 1 + strlen(semihosting_get_arg(i)); + } + regs[2] = sz; + regs[3] = 0; + } break; case TARGET_SYS_argv: { - struct Argv { - uint32_t argptr[2]; - char text[120]; - } argv = { - {0, 0}, - "test" - }; + int argc = semihosting_get_argc(); + int str_offset = (argc + 1) * sizeof(uint32_t); + int i; + uint32_t argptr; - argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text)); + for (i = 0; i < argc; ++i) { + const char *str = semihosting_get_arg(i); + int str_size = strlen(str) + 1; + + argptr = tswap32(regs[3] + str_offset); + + cpu_memory_rw_debug(cs, + regs[3] + i * sizeof(uint32_t), + (uint8_t *)&argptr, sizeof(argptr), 1); + cpu_memory_rw_debug(cs, + regs[3] + str_offset, + (uint8_t *)str, str_size, 1); + str_offset += str_size; + } + argptr = 0; cpu_memory_rw_debug(cs, - regs[3], (uint8_t *)&argv, sizeof(argv), 1); + regs[3] + i * sizeof(uint32_t), + (uint8_t *)&argptr, sizeof(argptr), 1); + regs[3] = 0; } break;