summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-03-18 17:24:49 +0000
committerPeter Maydell <peter.maydell@linaro.org>2017-03-18 17:24:49 +0000
commit96dd9c89c193a5ce829eff5ef6301a58032dcf63 (patch)
tree0e9c732c0b2f6e50b71c5d1de4cf694b00c9a40c
parent6b3cca76dd3ae464e585f65dff03f431163b07fa (diff)
parentf289bb091e6876df2e0e3481cb414c277695a405 (diff)
downloadfocaccia-qemu-96dd9c89c193a5ce829eff5ef6301a58032dcf63.tar.gz
focaccia-qemu-96dd9c89c193a5ce829eff5ef6301a58032dcf63.zip
Merge remote-tracking branch 'remotes/xtensa/tags/20170317-xtensa' into staging
target/xtensa fixes for 2.9:

- fix build failure when FDT support is not enabled;
- correctly pass command line arguments to semihosting guests.

# gpg: Signature made Fri 17 Mar 2017 18:14:01 GMT
# gpg:                using RSA key 0x51F9CC91F83FA044
# gpg: Good signature from "Max Filippov <filippov@cadence.com>"
# gpg:                 aka "Max Filippov <max.filippov@cogentembedded.com>"
# gpg:                 aka "Max Filippov <jcmvbkbc@gmail.com>"
# Primary key fingerprint: 2B67 854B 98E5 327D CDEB  17D8 51F9 CC91 F83F A044

* remotes/xtensa/tags/20170317-xtensa:
  target/xtensa: fix semihosting argc/argv implementation
  target/xtensa: xtfpga: load DTB only when FDT support is enabled

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/xtensa/xtfpga.c9
-rw-r--r--target/xtensa/xtensa-semi.c49
2 files changed, 45 insertions, 13 deletions
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,
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"
-            };
-
-            argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text));
+            int argc = semihosting_get_argc();
+            int str_offset = (argc + 1) * sizeof(uint32_t);
+            int i;
+            uint32_t argptr;
+
+            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;