All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH  v3 0/6] semihosting read console support
@ 2020-01-08 15:02 Alex Bennée
  2020-01-08 15:02 ` [PATCH v3 1/6] target/arm: remove unused EXCP_SEMIHOST leg Alex Bennée
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Alex Bennée @ 2020-01-08 15:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: keithp, qemu-arm, Alex Bennée

Hi,

No major changes from the previous version except some tweaking of the
tests to exercise both thumb and arm modes. There is a minor
refactoring so the __semi_call helper can be re-used. I'm planning on
sending the PR in with my gdbstub fixes later this week.

The following patches need review
  05 - tests tcg extract __semi_call into a header and e
  06 - tests tcg add user version of dumb as bricks semi

Alex Bennée (5):
  target/arm: remove unused EXCP_SEMIHOST leg
  target/arm: only update pc after semihosting completes
  tests/tcg: add a dumb-as-bricks semihosting console test
  tests/tcg: extract __semi_call into a header and expand
  tests/tcg: add user version of dumb-as-bricks semiconsole test

Keith Packard (1):
  semihosting: add qemu_semihosting_console_inc for SYS_READC

 include/hw/semihosting/console.h          | 16 +++++
 include/hw/semihosting/semihost.h         |  4 ++
 tests/tcg/arm/semicall.h                  | 35 ++++++++++
 hw/semihosting/console.c                  | 79 +++++++++++++++++++++++
 linux-user/aarch64/cpu_loop.c             |  1 +
 linux-user/arm/cpu_loop.c                 |  1 +
 linux-user/arm/semihost.c                 | 27 ++++++++
 stubs/semihost.c                          |  4 ++
 target/arm/arm-semi.c                     |  3 +-
 target/arm/helper.c                       |  8 +--
 target/arm/m_helper.c                     |  1 +
 target/arm/translate-a64.c                |  2 +-
 target/arm/translate.c                    |  6 +-
 tests/tcg/aarch64/system/semiconsole.c    | 38 +++++++++++
 tests/tcg/arm/semiconsole.c               | 27 ++++++++
 tests/tcg/arm/semihosting.c               | 21 +-----
 vl.c                                      |  3 +
 tests/tcg/aarch64/Makefile.softmmu-target |  9 ++-
 tests/tcg/aarch64/Makefile.target         |  7 ++
 tests/tcg/arm/Makefile.target             | 28 ++++++++
 20 files changed, 287 insertions(+), 33 deletions(-)
 create mode 100644 tests/tcg/arm/semicall.h
 create mode 100644 tests/tcg/aarch64/system/semiconsole.c
 create mode 100644 tests/tcg/arm/semiconsole.c

-- 
2.20.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH  v3 1/6] target/arm: remove unused EXCP_SEMIHOST leg
  2020-01-08 15:02 [PATCH v3 0/6] semihosting read console support Alex Bennée
@ 2020-01-08 15:02 ` Alex Bennée
  2020-01-08 15:02 ` [PATCH v3 2/6] target/arm: only update pc after semihosting completes Alex Bennée
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Alex Bennée @ 2020-01-08 15:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: Richard Henderson, keithp, qemu-arm, Alex Bennée, Peter Maydell

All semihosting exceptions are dealt with earlier in the common code
so we should never get here.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Keith Packard <keithp@keithp.com>
Tested-by: Keith Packard <keithp@keithp.com>
---
 target/arm/helper.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index b6bec42f48e..da22c198006 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8566,12 +8566,6 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
     case EXCP_VFIQ:
         addr += 0x100;
         break;
-    case EXCP_SEMIHOST:
-        qemu_log_mask(CPU_LOG_INT,
-                      "...handling as semihosting call 0x%" PRIx64 "\n",
-                      env->xregs[0]);
-        env->xregs[0] = do_arm_semihosting(env);
-        return;
     default:
         cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
     }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 2/6] target/arm: only update pc after semihosting completes
  2020-01-08 15:02 [PATCH v3 0/6] semihosting read console support Alex Bennée
  2020-01-08 15:02 ` [PATCH v3 1/6] target/arm: remove unused EXCP_SEMIHOST leg Alex Bennée
@ 2020-01-08 15:02 ` Alex Bennée
  2020-01-08 15:02 ` [PATCH v3 3/6] semihosting: add qemu_semihosting_console_inc for SYS_READC Alex Bennée
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Alex Bennée @ 2020-01-08 15:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, keithp, Riku Voipio, Richard Henderson,
	Laurent Vivier, qemu-arm, Alex Bennée

Before we introduce blocking semihosting calls we need to ensure we
can restart the system on semi hosting exception. To be able to do
this the EXCP_SEMIHOST operation should be idempotent until it finally
completes. Practically this means ensureing we only update the pc
after the semihosting call has completed.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Keith Packard <keithp@keithp.com>
Tested-by: Keith Packard <keithp@keithp.com>
---
 linux-user/aarch64/cpu_loop.c | 1 +
 linux-user/arm/cpu_loop.c     | 1 +
 target/arm/helper.c           | 2 ++
 target/arm/m_helper.c         | 1 +
 target/arm/translate-a64.c    | 2 +-
 target/arm/translate.c        | 6 +++---
 6 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 31c845a70d4..bbe9fefca81 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -130,6 +130,7 @@ void cpu_loop(CPUARMState *env)
             break;
         case EXCP_SEMIHOST:
             env->xregs[0] = do_arm_semihosting(env);
+            env->pc += 4;
             break;
         case EXCP_YIELD:
             /* nothing to do here for user-mode, just resume guest code */
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index 7be40717518..1fae90c6dfc 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -377,6 +377,7 @@ void cpu_loop(CPUARMState *env)
             break;
         case EXCP_SEMIHOST:
             env->regs[0] = do_arm_semihosting(env);
+            env->regs[15] += env->thumb ? 2 : 4;
             break;
         case EXCP_INTERRUPT:
             /* just indicate that signals should be handled asap */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index da22c198006..19a57a17da5 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8614,11 +8614,13 @@ static void handle_semihosting(CPUState *cs)
                       "...handling as semihosting call 0x%" PRIx64 "\n",
                       env->xregs[0]);
         env->xregs[0] = do_arm_semihosting(env);
+        env->pc += 4;
     } else {
         qemu_log_mask(CPU_LOG_INT,
                       "...handling as semihosting call 0x%x\n",
                       env->regs[0]);
         env->regs[0] = do_arm_semihosting(env);
+        env->regs[15] += env->thumb ? 2 : 4;
     }
 }
 #endif
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
index 76de317e6af..33d414a684b 100644
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -2185,6 +2185,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
                       "...handling as semihosting call 0x%x\n",
                       env->regs[0]);
         env->regs[0] = do_arm_semihosting(env);
+        env->regs[15] += env->thumb ? 2 : 4;
         return;
     case EXCP_BKPT:
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG, false);
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index d4bebbe6295..972c28c3c95 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1937,7 +1937,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
                 break;
             }
 #endif
-            gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
+            gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
         } else {
             unsupported_encoding(s, insn);
         }
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 2b6c1f91bf9..5185e08641b 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -1124,7 +1124,7 @@ static inline void gen_hlt(DisasContext *s, int imm)
         s->current_el != 0 &&
 #endif
         (imm == (s->thumb ? 0x3c : 0xf000))) {
-        gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
+        gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
         return;
     }
 
@@ -8457,7 +8457,7 @@ static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
         !IS_USER(s) &&
 #endif
         (a->imm == 0xab)) {
-        gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
+        gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
     } else {
         gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
     }
@@ -10266,7 +10266,7 @@ static bool trans_SVC(DisasContext *s, arg_SVC *a)
         !IS_USER(s) &&
 #endif
         (a->imm == semihost_imm)) {
-        gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
+        gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
     } else {
         gen_set_pc_im(s, s->base.pc_next);
         s->svc_imm = a->imm;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 3/6] semihosting: add qemu_semihosting_console_inc for SYS_READC
  2020-01-08 15:02 [PATCH v3 0/6] semihosting read console support Alex Bennée
  2020-01-08 15:02 ` [PATCH v3 1/6] target/arm: remove unused EXCP_SEMIHOST leg Alex Bennée
  2020-01-08 15:02 ` [PATCH v3 2/6] target/arm: only update pc after semihosting completes Alex Bennée
@ 2020-01-08 15:02 ` Alex Bennée
  2020-01-08 15:02 ` [PATCH v3 4/6] tests/tcg: add a dumb-as-bricks semihosting console test Alex Bennée
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Alex Bennée @ 2020-01-08 15:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, keithp, Riku Voipio, Richard Henderson,
	Laurent Vivier, qemu-arm, Paolo Bonzini, Alex Bennée

From: Keith Packard <keithp@keithp.com>

Provides a blocking call to read a character from the console using
semihosting.chardev, if specified. This takes some careful command
line options to use stdio successfully as the serial ports, monitor
and semihost all want to use stdio. Here's a sample set of command
line options which share stdio between semihost, monitor and serial
ports:

	qemu \
	-chardev stdio,mux=on,id=stdio0 \
	-serial chardev:stdio0 \
	-semihosting-config enable=on,chardev=stdio0 \
	-mon chardev=stdio0,mode=readline

This creates a chardev hooked to stdio and then connects all of the
subsystems to it. A shorter mechanism would be good to hear about.

Signed-off-by: Keith Packard <keithp@keithp.com>
Message-Id: <20191104204230.12249-1-keithp@keithp.com>
[AJB: fixed up deadlock, minor commit title reword]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
Tested-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

---
v8
  - allow linux-user to block using unbuffered IO
  - spelling and wording fixes
v7
  - reword commit title
  - remove mutexs, halt CPU until data available
  - document cpu_loop_exit behavior in function API

squash! semihosting: add qemu_semihosting_console_inc for SYS_READC
---
 include/hw/semihosting/console.h  | 16 +++++++
 include/hw/semihosting/semihost.h |  4 ++
 hw/semihosting/console.c          | 79 +++++++++++++++++++++++++++++++
 linux-user/arm/semihost.c         | 27 +++++++++++
 stubs/semihost.c                  |  4 ++
 target/arm/arm-semi.c             |  3 +-
 vl.c                              |  3 ++
 7 files changed, 134 insertions(+), 2 deletions(-)

diff --git a/include/hw/semihosting/console.h b/include/hw/semihosting/console.h
index 9be9754bcdf..0238f540f4b 100644
--- a/include/hw/semihosting/console.h
+++ b/include/hw/semihosting/console.h
@@ -37,6 +37,22 @@ int qemu_semihosting_console_outs(CPUArchState *env, target_ulong s);
  */
 void qemu_semihosting_console_outc(CPUArchState *env, target_ulong c);
 
+/**
+ * qemu_semihosting_console_inc:
+ * @env: CPUArchState
+ *
+ * Receive single character from debug console. This may be the remote
+ * gdb session if a softmmu guest is currently being debugged. As this
+ * call may block if no data is available we suspend the CPU and will
+ * re-execute the instruction when data is there. Therefore two
+ * conditions must be met:
+ *   - CPUState is synchronized before calling this function
+ *   - pc is only updated once the character is successfully returned
+ *
+ * Returns: character read OR cpu_loop_exit!
+ */
+target_ulong qemu_semihosting_console_inc(CPUArchState *env);
+
 /**
  * qemu_semihosting_log_out:
  * @s: pointer to string
diff --git a/include/hw/semihosting/semihost.h b/include/hw/semihosting/semihost.h
index 60fc42d851e..b8ce5117ae0 100644
--- a/include/hw/semihosting/semihost.h
+++ b/include/hw/semihosting/semihost.h
@@ -56,6 +56,9 @@ static inline Chardev *semihosting_get_chardev(void)
 {
     return NULL;
 }
+static inline void qemu_semihosting_console_init(void)
+{
+}
 #else /* !CONFIG_USER_ONLY */
 bool semihosting_enabled(void);
 SemihostingTarget semihosting_get_target(void);
@@ -68,6 +71,7 @@ Chardev *semihosting_get_chardev(void);
 void qemu_semihosting_enable(void);
 int qemu_semihosting_config_options(const char *opt);
 void qemu_semihosting_connect_chardevs(void);
+void qemu_semihosting_console_init(void);
 #endif /* CONFIG_USER_ONLY */
 
 #endif /* SEMIHOST_H */
diff --git a/hw/semihosting/console.c b/hw/semihosting/console.c
index b4b17c8afbc..6346bd7f506 100644
--- a/hw/semihosting/console.c
+++ b/hw/semihosting/console.c
@@ -20,8 +20,15 @@
 #include "hw/semihosting/semihost.h"
 #include "hw/semihosting/console.h"
 #include "exec/gdbstub.h"
+#include "exec/exec-all.h"
 #include "qemu/log.h"
 #include "chardev/char.h"
+#include <pthread.h>
+#include "chardev/char-fe.h"
+#include "sysemu/sysemu.h"
+#include "qemu/main-loop.h"
+#include "qapi/error.h"
+#include "qemu/fifo8.h"
 
 int qemu_semihosting_log_out(const char *s, int len)
 {
@@ -98,3 +105,75 @@ void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr)
                       __func__, addr);
     }
 }
+
+#define FIFO_SIZE   1024
+
+/* Access to this structure is protected by the BQL */
+typedef struct SemihostingConsole {
+    CharBackend         backend;
+    GSList              *sleeping_cpus;
+    bool                got;
+    Fifo8               fifo;
+} SemihostingConsole;
+
+static SemihostingConsole console;
+
+static int console_can_read(void *opaque)
+{
+    SemihostingConsole *c = opaque;
+    int ret;
+    g_assert(qemu_mutex_iothread_locked());
+    ret = (int) fifo8_num_free(&c->fifo);
+    return ret;
+}
+
+static void console_wake_up(gpointer data, gpointer user_data)
+{
+    CPUState *cs = (CPUState *) data;
+    /* cpu_handle_halt won't know we have work so just unbung here */
+    cs->halted = 0;
+    qemu_cpu_kick(cs);
+}
+
+static void console_read(void *opaque, const uint8_t *buf, int size)
+{
+    SemihostingConsole *c = opaque;
+    g_assert(qemu_mutex_iothread_locked());
+    while (size-- && !fifo8_is_full(&c->fifo)) {
+        fifo8_push(&c->fifo, *buf++);
+    }
+    g_slist_foreach(c->sleeping_cpus, console_wake_up, NULL);
+    c->sleeping_cpus = NULL;
+}
+
+target_ulong qemu_semihosting_console_inc(CPUArchState *env)
+{
+    uint8_t ch;
+    SemihostingConsole *c = &console;
+    g_assert(qemu_mutex_iothread_locked());
+    g_assert(current_cpu);
+    if (fifo8_is_empty(&c->fifo)) {
+        c->sleeping_cpus = g_slist_prepend(c->sleeping_cpus, current_cpu);
+        current_cpu->halted = 1;
+        current_cpu->exception_index = EXCP_HALTED;
+        cpu_loop_exit(current_cpu);
+        /* never returns */
+    }
+    ch = fifo8_pop(&c->fifo);
+    return (target_ulong) ch;
+}
+
+void qemu_semihosting_console_init(void)
+{
+    Chardev *chr = semihosting_get_chardev();
+
+    if  (chr) {
+        fifo8_create(&console.fifo, FIFO_SIZE);
+        qemu_chr_fe_init(&console.backend, chr, &error_abort);
+        qemu_chr_fe_set_handlers(&console.backend,
+                                 console_can_read,
+                                 console_read,
+                                 NULL, NULL, &console,
+                                 NULL, true);
+    }
+}
diff --git a/linux-user/arm/semihost.c b/linux-user/arm/semihost.c
index a16b525eec0..a1f0f6050ea 100644
--- a/linux-user/arm/semihost.c
+++ b/linux-user/arm/semihost.c
@@ -14,6 +14,7 @@
 #include "cpu.h"
 #include "hw/semihosting/console.h"
 #include "qemu.h"
+#include <termios.h>
 
 int qemu_semihosting_console_outs(CPUArchState *env, target_ulong addr)
 {
@@ -47,3 +48,29 @@ void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr)
         }
     }
 }
+
+/*
+ * For linux-user we can safely block. However as we want to return as
+ * soon as a character is read we need to tweak the termio to disable
+ * line buffering. We restore the old mode afterwards in case the
+ * program is expecting more normal behaviour. This is slow but
+ * nothing using semihosting console reading is expecting to be fast.
+ */
+target_ulong qemu_semihosting_console_inc(CPUArchState *env)
+{
+    uint8_t c;
+    struct termios old_tio, new_tio;
+
+    /* Disable line-buffering and echo */
+    tcgetattr(STDIN_FILENO, &old_tio);
+    new_tio = old_tio;
+    new_tio.c_lflag &= (~ICANON & ~ECHO);
+    tcsetattr(STDIN_FILENO, TCSANOW, &new_tio);
+
+    c = getchar();
+
+    /* restore config */
+    tcsetattr(STDIN_FILENO, TCSANOW, &old_tio);
+
+    return (target_ulong) c;
+}
diff --git a/stubs/semihost.c b/stubs/semihost.c
index f90589259c0..1d8b37f7b2f 100644
--- a/stubs/semihost.c
+++ b/stubs/semihost.c
@@ -69,3 +69,7 @@ void semihosting_arg_fallback(const char *file, const char *cmd)
 void qemu_semihosting_connect_chardevs(void)
 {
 }
+
+void qemu_semihosting_console_init(void)
+{
+}
diff --git a/target/arm/arm-semi.c b/target/arm/arm-semi.c
index 6f7b6d801bf..47d61f6fe1f 100644
--- a/target/arm/arm-semi.c
+++ b/target/arm/arm-semi.c
@@ -802,8 +802,7 @@ target_ulong do_arm_semihosting(CPUARMState *env)
 
         return guestfd_fns[gf->type].readfn(cpu, gf, arg1, len);
     case TARGET_SYS_READC:
-        qemu_log_mask(LOG_UNIMP, "%s: SYS_READC not implemented", __func__);
-        return 0;
+        return qemu_semihosting_console_inc(env);
     case TARGET_SYS_ISTTY:
         GET_ARG(0);
 
diff --git a/vl.c b/vl.c
index 86474a55c9e..b2119212587 100644
--- a/vl.c
+++ b/vl.c
@@ -4238,6 +4238,9 @@ int main(int argc, char **argv, char **envp)
     qemu_opts_foreach(qemu_find_opts("mon"),
                       mon_init_func, NULL, &error_fatal);
 
+    /* connect semihosting console input if requested */
+    qemu_semihosting_console_init();
+
     if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
         exit(1);
     if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 4/6] tests/tcg: add a dumb-as-bricks semihosting console test
  2020-01-08 15:02 [PATCH v3 0/6] semihosting read console support Alex Bennée
                   ` (2 preceding siblings ...)
  2020-01-08 15:02 ` [PATCH v3 3/6] semihosting: add qemu_semihosting_console_inc for SYS_READC Alex Bennée
@ 2020-01-08 15:02 ` Alex Bennée
  2020-01-08 15:02 ` [PATCH v3 5/6] tests/tcg: extract __semi_call into a header and expand Alex Bennée
  2020-01-08 15:02 ` [PATCH v3 6/6] tests/tcg: add user version of dumb-as-bricks semiconsole test Alex Bennée
  5 siblings, 0 replies; 10+ messages in thread
From: Alex Bennée @ 2020-01-08 15:02 UTC (permalink / raw)
  To: qemu-devel
  Cc: Richard Henderson, keithp, qemu-arm, Alex Bennée, Peter Maydell

We don't run this during check-tcg as we would need to check stuff is
echoed back. However we can still build the binary so people can test
it manually.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

---
v8
  - actually return the result!
---
 tests/tcg/aarch64/system/semiconsole.c    | 38 +++++++++++++++++++++++
 tests/tcg/aarch64/Makefile.softmmu-target |  9 +++++-
 2 files changed, 46 insertions(+), 1 deletion(-)
 create mode 100644 tests/tcg/aarch64/system/semiconsole.c

diff --git a/tests/tcg/aarch64/system/semiconsole.c b/tests/tcg/aarch64/system/semiconsole.c
new file mode 100644
index 00000000000..bfe7c9e26b4
--- /dev/null
+++ b/tests/tcg/aarch64/system/semiconsole.c
@@ -0,0 +1,38 @@
+/*
+ * Semihosting Console Test
+ *
+ * Copyright (c) 2019 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <inttypes.h>
+#include <minilib.h>
+
+#define SYS_READC 0x7
+
+uintptr_t __semi_call(uintptr_t type, uintptr_t arg0)
+{
+    register uintptr_t t asm("x0") = type;
+    register uintptr_t a0 asm("x1") = arg0;
+    asm("hlt 0xf000"
+        : "=r" (t)
+        : "r" (t), "r" (a0));
+
+    return t;
+}
+
+int main(void)
+{
+    char c;
+
+    ml_printf("Semihosting Console Test\n");
+    ml_printf("hit X to exit:");
+
+    do {
+        c = __semi_call(SYS_READC, 0);
+        __sys_outc(c);
+    } while (c != 'X');
+
+    return 0;
+}
diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
index 950dbb4bac2..9bdcfd9e7e4 100644
--- a/tests/tcg/aarch64/Makefile.softmmu-target
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
@@ -31,7 +31,14 @@ LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
 memory: CFLAGS+=-DCHECK_UNALIGNED=1
 
 # Running
-QEMU_OPTS+=-M virt -cpu max -display none -semihosting-config enable=on,target=native,chardev=output -kernel
+QEMU_BASE_MACHINE=-M virt -cpu max -display none
+QEMU_OPTS+=$(QEMU_BASE_MACHINE) -semihosting-config enable=on,target=native,chardev=output -kernel
+
+# console test is manual only
+QEMU_SEMIHOST=-chardev stdio,mux=on,id=stdio0 -semihosting-config enable=on,chardev=stdio0 -mon chardev=stdio0,mode=readline
+run-semiconsole: QEMU_OPTS=$(QEMU_BASE_MACHINE) $(QEMU_SEMIHOST)  -kernel
+run-semiconsole: semiconsole
+	$(call skip-test, $<, "MANUAL ONLY")
 
 # Simple Record/Replay Test
 .PHONY: memory-record
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 5/6] tests/tcg: extract __semi_call into a header and expand
  2020-01-08 15:02 [PATCH v3 0/6] semihosting read console support Alex Bennée
                   ` (3 preceding siblings ...)
  2020-01-08 15:02 ` [PATCH v3 4/6] tests/tcg: add a dumb-as-bricks semihosting console test Alex Bennée
@ 2020-01-08 15:02 ` Alex Bennée
  2020-01-08 20:48   ` Richard Henderson
  2020-01-08 15:02 ` [PATCH v3 6/6] tests/tcg: add user version of dumb-as-bricks semiconsole test Alex Bennée
  5 siblings, 1 reply; 10+ messages in thread
From: Alex Bennée @ 2020-01-08 15:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, keithp, qemu-arm, Alex Bennée

There are two types of ARM semicall - lets test them both. Putting the
logic in a header will make re-using the functions easier later.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 tests/tcg/arm/semicall.h      | 35 +++++++++++++++++++++++++++++++++++
 tests/tcg/arm/semihosting.c   | 21 +--------------------
 tests/tcg/arm/Makefile.target |  9 +++++++++
 3 files changed, 45 insertions(+), 20 deletions(-)
 create mode 100644 tests/tcg/arm/semicall.h

diff --git a/tests/tcg/arm/semicall.h b/tests/tcg/arm/semicall.h
new file mode 100644
index 00000000000..d4f6818192d
--- /dev/null
+++ b/tests/tcg/arm/semicall.h
@@ -0,0 +1,35 @@
+/*
+ * Semihosting Tests
+ *
+ * Copyright (c) 2019
+ * Written by Alex Bennée <alex.bennee@linaro.org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#define SYS_WRITE0      0x04
+#define SYS_READC       0x07
+#define SYS_REPORTEXC   0x18
+
+uintptr_t __semi_call(uintptr_t type, uintptr_t arg0)
+{
+#if defined(__arm__)
+    register uintptr_t t asm("r0") = type;
+    register uintptr_t a0 asm("r1") = arg0;
+#ifdef __thumb__
+#  define SVC  "svc 0xab"
+#else
+#  define SVC  "svc 0x123456"
+#endif
+    asm(SVC : "=r" (t)
+        : "r" (t), "r" (a0));
+#else
+    register uintptr_t t asm("x0") = type;
+    register uintptr_t a0 asm("x1") = arg0;
+    asm("hlt 0xf000"
+        : "=r" (t)
+        : "r" (t), "r" (a0));
+#endif
+
+    return t;
+}
diff --git a/tests/tcg/arm/semihosting.c b/tests/tcg/arm/semihosting.c
index 09c89cb481a..33faac9916e 100644
--- a/tests/tcg/arm/semihosting.c
+++ b/tests/tcg/arm/semihosting.c
@@ -8,26 +8,7 @@
  */
 
 #include <stdint.h>
-
-#define SYS_WRITE0      0x04
-#define SYS_REPORTEXC   0x18
-
-void __semi_call(uintptr_t type, uintptr_t arg0)
-{
-#if defined(__arm__)
-    register uintptr_t t asm("r0") = type;
-    register uintptr_t a0 asm("r1") = arg0;
-    asm("svc 0xab"
-        : /* no return */
-        : "r" (t), "r" (a0));
-#else
-    register uintptr_t t asm("x0") = type;
-    register uintptr_t a0 asm("x1") = arg0;
-    asm("hlt 0xf000"
-        : /* no return */
-        : "r" (t), "r" (a0));
-#endif
-}
+#include "semicall.h"
 
 int main(int argc, char *argv[argc])
 {
diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target
index 0765f37ff04..41aa26f4e17 100644
--- a/tests/tcg/arm/Makefile.target
+++ b/tests/tcg/arm/Makefile.target
@@ -31,9 +31,18 @@ run-fcvt: fcvt
 
 # Semihosting smoke test for linux-user
 ARM_TESTS += semihosting
+semihosting: CFLAGS += -mthumb
 run-semihosting: semihosting
 	$(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
 
+ARM_TESTS += semihosting-arm
+semihosting-arm: CFLAGS += -marm
+semihosting-arm: semihosting.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+
+run-semihosting-arm: semihosting-arm
+	$(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
+
 run-plugin-semihosting-with-%:
 	$(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
 		-plugin $(PLUGIN_DIR)/$(call extract-plugin,$@) \
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 6/6] tests/tcg: add user version of dumb-as-bricks semiconsole test
  2020-01-08 15:02 [PATCH v3 0/6] semihosting read console support Alex Bennée
                   ` (4 preceding siblings ...)
  2020-01-08 15:02 ` [PATCH v3 5/6] tests/tcg: extract __semi_call into a header and expand Alex Bennée
@ 2020-01-08 15:02 ` Alex Bennée
  2020-01-08 19:55   ` Alex Bennée
  5 siblings, 1 reply; 10+ messages in thread
From: Alex Bennée @ 2020-01-08 15:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, keithp, qemu-arm, Alex Bennée

There are linux-user users of semihosting so we'd better check things
work for them as well.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

---
v3
  - include aarch64 version
v4
  - use common semicall.h, test thumb & arm
---
 tests/tcg/arm/semiconsole.c       | 27 +++++++++++++++++++++++++++
 tests/tcg/aarch64/Makefile.target |  7 +++++++
 tests/tcg/arm/Makefile.target     | 19 +++++++++++++++++++
 3 files changed, 53 insertions(+)
 create mode 100644 tests/tcg/arm/semiconsole.c

diff --git a/tests/tcg/arm/semiconsole.c b/tests/tcg/arm/semiconsole.c
new file mode 100644
index 00000000000..6ef0bd24500
--- /dev/null
+++ b/tests/tcg/arm/semiconsole.c
@@ -0,0 +1,27 @@
+/*
+ * linux-user semihosting console
+ *
+ * Copyright (c) 2019
+ * Written by Alex Bennée <alex.bennee@linaro.org>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include "semicall.h"
+
+int main(void)
+{
+    char c;
+
+    printf("Semihosting Console Test\n");
+    printf("hit X to exit:");
+
+    do {
+        c = __semi_call(SYS_READC, 0);
+        printf("got '%c'\n", c);
+    } while (c != 'X');
+
+    return 0;
+}
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
index 96d2321045a..4281c766419 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -32,4 +32,11 @@ run-plugin-semihosting-with-%:
 		 $(call strip-plugin,$<) 2> $<.err, \
 		"$< on $(TARGET_NAME) with $*")
 
+AARCH64_TESTS += semiconsole
+run-semiconsole: semiconsole
+	$(call skip-test, $<, "MANUAL ONLY")
+
+run-semiconsole-with-%:
+	$(call skip-test, $<, "MANUAL ONLY")
+
 TESTS += $(AARCH64_TESTS)
diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target
index 41aa26f4e17..a104ca30281 100644
--- a/tests/tcg/arm/Makefile.target
+++ b/tests/tcg/arm/Makefile.target
@@ -49,6 +49,25 @@ run-plugin-semihosting-with-%:
 		 $(call strip-plugin,$<) 2> $<.err, \
 		"$< on $(TARGET_NAME) with $*")
 
+ARM_TESTS += semiconsole semiconsole-arm
+
+semiconsole: CFLAGS += -mthumb
+run-semiconsole: semiconsole
+	$(call skip-test, $<, "MANUAL ONLY")
+
+run-semiconsole-with-%:
+	$(call skip-test, $<, "MANUAL ONLY")
+
+semiconsole-arm: CFLAGS += -marm
+semiconsole-arm: semiconsole.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+
+run-semiconsole-arm: semiconsole-arm
+	$(call skip-test, $<, "MANUAL ONLY")
+
+run-semiconsole-arm-with-%:
+	$(call skip-test, $<, "MANUAL ONLY")
+
 TESTS += $(ARM_TESTS)
 
 # On ARM Linux only supports 4k pages
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH  v3 6/6] tests/tcg: add user version of dumb-as-bricks semiconsole test
  2020-01-08 15:02 ` [PATCH v3 6/6] tests/tcg: add user version of dumb-as-bricks semiconsole test Alex Bennée
@ 2020-01-08 19:55   ` Alex Bennée
  2020-01-08 20:56     ` Richard Henderson
  0 siblings, 1 reply; 10+ messages in thread
From: Alex Bennée @ 2020-01-08 19:55 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, keithp, qemu-arm, Alex Bennée


Alex Bennée <alex.bennee@linaro.org> writes:

> There are linux-user users of semihosting so we'd better check things
> work for them as well.
>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>
> ---
> v3
>   - include aarch64 version
> v4
>   - use common semicall.h, test thumb & arm
> ---
>  tests/tcg/arm/semiconsole.c       | 27 +++++++++++++++++++++++++++
>  tests/tcg/aarch64/Makefile.target |  7 +++++++
>  tests/tcg/arm/Makefile.target     | 19 +++++++++++++++++++
>  3 files changed, 53 insertions(+)
>  create mode 100644 tests/tcg/arm/semiconsole.c
>
> diff --git a/tests/tcg/arm/semiconsole.c b/tests/tcg/arm/semiconsole.c
> new file mode 100644
> index 00000000000..6ef0bd24500
> --- /dev/null
> +++ b/tests/tcg/arm/semiconsole.c
> @@ -0,0 +1,27 @@
> +/*
> + * linux-user semihosting console
> + *
> + * Copyright (c) 2019
> + * Written by Alex Bennée <alex.bennee@linaro.org>
> + *
> + * SPDX-License-Identifier: GPL-3.0-or-later
> + */
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include "semicall.h"
> +
> +int main(void)
> +{
> +    char c;
> +
> +    printf("Semihosting Console Test\n");
> +    printf("hit X to exit:");
> +
> +    do {
> +        c = __semi_call(SYS_READC, 0);
> +        printf("got '%c'\n", c);
> +    } while (c != 'X');
> +
> +    return 0;
> +}
> diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
> index 96d2321045a..4281c766419 100644
> --- a/tests/tcg/aarch64/Makefile.target
> +++ b/tests/tcg/aarch64/Makefile.target
> @@ -32,4 +32,11 @@ run-plugin-semihosting-with-%:
>  		 $(call strip-plugin,$<) 2> $<.err, \
>  		"$< on $(TARGET_NAME) with $*")
>  
> +AARCH64_TESTS += semiconsole
> +run-semiconsole: semiconsole
> +	$(call skip-test, $<, "MANUAL ONLY")
> +
> +run-semiconsole-with-%:

this should be run-plugin-semiconsole-with-%

<snip>
> +run-semiconsole-with-%:
<snip>
> +run-semiconsole-arm-with-%:

ditto for these


-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 5/6] tests/tcg: extract __semi_call into a header and expand
  2020-01-08 15:02 ` [PATCH v3 5/6] tests/tcg: extract __semi_call into a header and expand Alex Bennée
@ 2020-01-08 20:48   ` Richard Henderson
  0 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2020-01-08 20:48 UTC (permalink / raw)
  To: Alex Bennée, qemu-devel; +Cc: Peter Maydell, keithp, qemu-arm

On 1/9/20 2:02 AM, Alex Bennée wrote:
> There are two types of ARM semicall - lets test them both. Putting the
> logic in a header will make re-using the functions easier later.
> 
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
> ---
>  tests/tcg/arm/semicall.h      | 35 +++++++++++++++++++++++++++++++++++
>  tests/tcg/arm/semihosting.c   | 21 +--------------------
>  tests/tcg/arm/Makefile.target |  9 +++++++++
>  3 files changed, 45 insertions(+), 20 deletions(-)
>  create mode 100644 tests/tcg/arm/semicall.h

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 6/6] tests/tcg: add user version of dumb-as-bricks semiconsole test
  2020-01-08 19:55   ` Alex Bennée
@ 2020-01-08 20:56     ` Richard Henderson
  0 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2020-01-08 20:56 UTC (permalink / raw)
  To: Alex Bennée, qemu-devel; +Cc: Peter Maydell, keithp, qemu-arm

On 1/9/20 6:55 AM, Alex Bennée wrote:
> 
> Alex Bennée <alex.bennee@linaro.org> writes:
> 
>> There are linux-user users of semihosting so we'd better check things
>> work for them as well.
>>
>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>>
>> ---
>> v3
>>   - include aarch64 version
>> v4
>>   - use common semicall.h, test thumb & arm
>> ---
>>  tests/tcg/arm/semiconsole.c       | 27 +++++++++++++++++++++++++++
>>  tests/tcg/aarch64/Makefile.target |  7 +++++++
>>  tests/tcg/arm/Makefile.target     | 19 +++++++++++++++++++
>>  3 files changed, 53 insertions(+)
>>  create mode 100644 tests/tcg/arm/semiconsole.c
>>
>> diff --git a/tests/tcg/arm/semiconsole.c b/tests/tcg/arm/semiconsole.c
>> new file mode 100644
>> index 00000000000..6ef0bd24500
>> --- /dev/null
>> +++ b/tests/tcg/arm/semiconsole.c
>> @@ -0,0 +1,27 @@
>> +/*
>> + * linux-user semihosting console
>> + *
>> + * Copyright (c) 2019
>> + * Written by Alex Bennée <alex.bennee@linaro.org>
>> + *
>> + * SPDX-License-Identifier: GPL-3.0-or-later
>> + */
>> +
>> +#include <stdio.h>
>> +#include <stdint.h>
>> +#include "semicall.h"
>> +
>> +int main(void)
>> +{
>> +    char c;
>> +
>> +    printf("Semihosting Console Test\n");
>> +    printf("hit X to exit:");
>> +
>> +    do {
>> +        c = __semi_call(SYS_READC, 0);
>> +        printf("got '%c'\n", c);
>> +    } while (c != 'X');
>> +
>> +    return 0;
>> +}
>> diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
>> index 96d2321045a..4281c766419 100644
>> --- a/tests/tcg/aarch64/Makefile.target
>> +++ b/tests/tcg/aarch64/Makefile.target
>> @@ -32,4 +32,11 @@ run-plugin-semihosting-with-%:
>>  		 $(call strip-plugin,$<) 2> $<.err, \
>>  		"$< on $(TARGET_NAME) with $*")
>>  
>> +AARCH64_TESTS += semiconsole
>> +run-semiconsole: semiconsole
>> +	$(call skip-test, $<, "MANUAL ONLY")
>> +
>> +run-semiconsole-with-%:
> 
> this should be run-plugin-semiconsole-with-%
> 
> <snip>
>> +run-semiconsole-with-%:
> <snip>
>> +run-semiconsole-arm-with-%:
> 
> ditto for these

With these,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-01-08 20:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-08 15:02 [PATCH v3 0/6] semihosting read console support Alex Bennée
2020-01-08 15:02 ` [PATCH v3 1/6] target/arm: remove unused EXCP_SEMIHOST leg Alex Bennée
2020-01-08 15:02 ` [PATCH v3 2/6] target/arm: only update pc after semihosting completes Alex Bennée
2020-01-08 15:02 ` [PATCH v3 3/6] semihosting: add qemu_semihosting_console_inc for SYS_READC Alex Bennée
2020-01-08 15:02 ` [PATCH v3 4/6] tests/tcg: add a dumb-as-bricks semihosting console test Alex Bennée
2020-01-08 15:02 ` [PATCH v3 5/6] tests/tcg: extract __semi_call into a header and expand Alex Bennée
2020-01-08 20:48   ` Richard Henderson
2020-01-08 15:02 ` [PATCH v3 6/6] tests/tcg: add user version of dumb-as-bricks semiconsole test Alex Bennée
2020-01-08 19:55   ` Alex Bennée
2020-01-08 20:56     ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.