• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisiónf38a71b01f839c7b65ea73ddd507903cb9489ed6 (tree)
Tiempo2020-01-10 22:19:34
AutorPeter Maydell <peter.maydell@lina...>
CommiterPeter Maydell

Log Message

Testing fixes and semiconsole support:

- build fix (missing x86-iommu stubs)
- python fixes for freebsd and OSX
- nicer reporting of acceptance failures
- fix build nesting of fp-test (breaks bsds)
- semihosting clean-ups
- support for blocking semihosting console
-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAl4XEbsACgkQ+9DbCVqe
KkRtOwgAkdw3Pwi6sSlKdouR0lcWsRRqY2T3nA+xM/JrS+W9+hJ3VsM7EcBCJZcJ
juJkQs3kU7Gs3LAeKbjmNq9xj9eTElD20l23RufiNB2CgULwHJ2+skGCTCq+1T1P
VBWWNky4RyGjgcKoQQ8cNUmFhntnemGjnxvz1G0dObPu6yl5jNXIk7qJFZkSsERy
YptCN8AF2bLXekYiB9Zn0xRd+O5Q4u/RtOg62REZoZOTA11M2Zuy+fkRK4XSzM/I
wVdRd0t0hKViktl3Z4iu3MsQqCxaHIirsfEMVkmbGWMmepq3db9Xs1k4Ss2I7Uo3
YRTxj1BCwynsGbDpWSI/XHOYgKp8rA==
=lSAv
-----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-and-semihosting-090120-2' into staging

Testing fixes and semiconsole support:

- build fix (missing x86-iommu stubs)
- python fixes for freebsd and OSX
- nicer reporting of acceptance failures
- fix build nesting of fp-test (breaks bsds)
- semihosting clean-ups
- support for blocking semihosting console

# gpg: Signature made Thu 09 Jan 2020 11:42:51 GMT
# gpg: using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [full]
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44

* remotes/stsquad/tags/pull-testing-and-semihosting-090120-2:

tests/tcg: add user version of dumb-as-bricks semiconsole test
tests/tcg: extract semi_call into a header and expand
tests/tcg: add a dumb-as-bricks semihosting console test
semihosting: add qemu_semihosting_console_inc for SYS_READC
target/arm: only update pc after semihosting completes
target/arm: remove unused EXCP_SEMIHOST leg
testing: don't nest build for fp-test
travis.yml: install homebrew python for OS X
travis.yml: duplicate before_script for MacOSX
travis.yml: Detach build and test steps
travis.yml: avocado: Print logs of non-pass tests only
freebsd: use python37
tests/vm: update openbsd to release 6.6
hw/i386/x86-iommu: Add missing stubs

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Cambiar Resumen

Diferencia incremental

--- a/.travis.yml
+++ b/.travis.yml
@@ -51,13 +51,6 @@ addons:
5151 - sparse
5252 - uuid-dev
5353 - gcovr
54- homebrew:
55- packages:
56- - ccache
57- - glib
58- - pixman
59- - gnu-sed
60- update: true
6154
6255
6356 # The channel name "irc.oftc.net#qemu" is encrypted against qemu/qemu
@@ -89,12 +82,12 @@ git:
8982
9083
9184 before_script:
92- - if [ "$TRAVIS_OS_NAME" == "osx" ] ; then export PATH="/usr/local/opt/ccache/libexec:$PATH" ; fi
9385 - if command -v ccache ; then ccache --zero-stats ; fi
9486 - mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR}
9587 - ${SRC_DIR}/configure ${BASE_CONFIG} ${CONFIG} || { cat config.log && exit 1; }
9688 script:
97- - make -j3 && travis_retry ${TEST_CMD}
89+ - BUILD_RC=0 && make -j3 || BUILD_RC=$?
90+ - if [ "$BUILD_RC" -eq 0 ] ; then travis_retry ${TEST_CMD} ; else $(exit $BUILD_RC); fi
9891 after_script:
9992 - if command -v ccache ; then ccache --show-stats ; fi
10093
@@ -239,6 +232,21 @@ matrix:
239232 os: osx
240233 osx_image: xcode10.3
241234 compiler: clang
235+ addons:
236+ homebrew:
237+ packages:
238+ - ccache
239+ - glib
240+ - pixman
241+ - gnu-sed
242+ - python
243+ update: true
244+ before_script:
245+ - brew link --overwrite python
246+ - export PATH="/usr/local/opt/ccache/libexec:$PATH"
247+ - if command -v ccache ; then ccache --zero-stats ; fi
248+ - mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR}
249+ - ${SRC_DIR}/configure ${BASE_CONFIG} ${CONFIG} || { cat config.log && exit 1; }
242250
243251
244252 # Python builds
@@ -262,8 +270,8 @@ matrix:
262270 - env:
263271 - CONFIG="--python=/usr/bin/python3 --target-list=x86_64-softmmu,mips-softmmu,mips64el-softmmu,aarch64-softmmu,arm-softmmu,s390x-softmmu,alpha-softmmu,ppc-softmmu,ppc64-softmmu,m68k-softmmu,sparc-softmmu"
264272 - TEST_CMD="make check-acceptance"
265- after_failure:
266- - cat tests/results/latest/job.log
273+ after_script:
274+ - python3 -c 'import json; r = json.load(open("tests/results/latest/results.json")); [print(t["logfile"]) for t in r["tests"] if t["status"] not in ("PASS", "SKIP")]' | xargs cat
267275 addons:
268276 apt:
269277 packages:
--- a/hw/i386/x86-iommu-stub.c
+++ b/hw/i386/x86-iommu-stub.c
@@ -32,3 +32,12 @@ X86IOMMUState *x86_iommu_get_default(void)
3232 return NULL;
3333 }
3434
35+bool x86_iommu_ir_supported(X86IOMMUState *s)
36+{
37+ return false;
38+}
39+
40+IommuType x86_iommu_get_type(void)
41+{
42+ abort();
43+}
--- a/hw/semihosting/console.c
+++ b/hw/semihosting/console.c
@@ -20,8 +20,15 @@
2020 #include "hw/semihosting/semihost.h"
2121 #include "hw/semihosting/console.h"
2222 #include "exec/gdbstub.h"
23+#include "exec/exec-all.h"
2324 #include "qemu/log.h"
2425 #include "chardev/char.h"
26+#include <pthread.h>
27+#include "chardev/char-fe.h"
28+#include "sysemu/sysemu.h"
29+#include "qemu/main-loop.h"
30+#include "qapi/error.h"
31+#include "qemu/fifo8.h"
2532
2633 int qemu_semihosting_log_out(const char *s, int len)
2734 {
@@ -98,3 +105,75 @@ void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr)
98105 __func__, addr);
99106 }
100107 }
108+
109+#define FIFO_SIZE 1024
110+
111+/* Access to this structure is protected by the BQL */
112+typedef struct SemihostingConsole {
113+ CharBackend backend;
114+ GSList *sleeping_cpus;
115+ bool got;
116+ Fifo8 fifo;
117+} SemihostingConsole;
118+
119+static SemihostingConsole console;
120+
121+static int console_can_read(void *opaque)
122+{
123+ SemihostingConsole *c = opaque;
124+ int ret;
125+ g_assert(qemu_mutex_iothread_locked());
126+ ret = (int) fifo8_num_free(&c->fifo);
127+ return ret;
128+}
129+
130+static void console_wake_up(gpointer data, gpointer user_data)
131+{
132+ CPUState *cs = (CPUState *) data;
133+ /* cpu_handle_halt won't know we have work so just unbung here */
134+ cs->halted = 0;
135+ qemu_cpu_kick(cs);
136+}
137+
138+static void console_read(void *opaque, const uint8_t *buf, int size)
139+{
140+ SemihostingConsole *c = opaque;
141+ g_assert(qemu_mutex_iothread_locked());
142+ while (size-- && !fifo8_is_full(&c->fifo)) {
143+ fifo8_push(&c->fifo, *buf++);
144+ }
145+ g_slist_foreach(c->sleeping_cpus, console_wake_up, NULL);
146+ c->sleeping_cpus = NULL;
147+}
148+
149+target_ulong qemu_semihosting_console_inc(CPUArchState *env)
150+{
151+ uint8_t ch;
152+ SemihostingConsole *c = &console;
153+ g_assert(qemu_mutex_iothread_locked());
154+ g_assert(current_cpu);
155+ if (fifo8_is_empty(&c->fifo)) {
156+ c->sleeping_cpus = g_slist_prepend(c->sleeping_cpus, current_cpu);
157+ current_cpu->halted = 1;
158+ current_cpu->exception_index = EXCP_HALTED;
159+ cpu_loop_exit(current_cpu);
160+ /* never returns */
161+ }
162+ ch = fifo8_pop(&c->fifo);
163+ return (target_ulong) ch;
164+}
165+
166+void qemu_semihosting_console_init(void)
167+{
168+ Chardev *chr = semihosting_get_chardev();
169+
170+ if (chr) {
171+ fifo8_create(&console.fifo, FIFO_SIZE);
172+ qemu_chr_fe_init(&console.backend, chr, &error_abort);
173+ qemu_chr_fe_set_handlers(&console.backend,
174+ console_can_read,
175+ console_read,
176+ NULL, NULL, &console,
177+ NULL, true);
178+ }
179+}
--- a/include/hw/semihosting/console.h
+++ b/include/hw/semihosting/console.h
@@ -38,6 +38,22 @@ int qemu_semihosting_console_outs(CPUArchState *env, target_ulong s);
3838 void qemu_semihosting_console_outc(CPUArchState *env, target_ulong c);
3939
4040 /**
41+ * qemu_semihosting_console_inc:
42+ * @env: CPUArchState
43+ *
44+ * Receive single character from debug console. This may be the remote
45+ * gdb session if a softmmu guest is currently being debugged. As this
46+ * call may block if no data is available we suspend the CPU and will
47+ * re-execute the instruction when data is there. Therefore two
48+ * conditions must be met:
49+ * - CPUState is synchronized before calling this function
50+ * - pc is only updated once the character is successfully returned
51+ *
52+ * Returns: character read OR cpu_loop_exit!
53+ */
54+target_ulong qemu_semihosting_console_inc(CPUArchState *env);
55+
56+/**
4157 * qemu_semihosting_log_out:
4258 * @s: pointer to string
4359 * @len: length of string
--- a/include/hw/semihosting/semihost.h
+++ b/include/hw/semihosting/semihost.h
@@ -56,6 +56,9 @@ static inline Chardev *semihosting_get_chardev(void)
5656 {
5757 return NULL;
5858 }
59+static inline void qemu_semihosting_console_init(void)
60+{
61+}
5962 #else /* !CONFIG_USER_ONLY */
6063 bool semihosting_enabled(void);
6164 SemihostingTarget semihosting_get_target(void);
@@ -68,6 +71,7 @@ Chardev *semihosting_get_chardev(void);
6871 void qemu_semihosting_enable(void);
6972 int qemu_semihosting_config_options(const char *opt);
7073 void qemu_semihosting_connect_chardevs(void);
74+void qemu_semihosting_console_init(void);
7175 #endif /* CONFIG_USER_ONLY */
7276
7377 #endif /* SEMIHOST_H */
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -130,6 +130,7 @@ void cpu_loop(CPUARMState *env)
130130 break;
131131 case EXCP_SEMIHOST:
132132 env->xregs[0] = do_arm_semihosting(env);
133+ env->pc += 4;
133134 break;
134135 case EXCP_YIELD:
135136 /* nothing to do here for user-mode, just resume guest code */
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -377,6 +377,7 @@ void cpu_loop(CPUARMState *env)
377377 break;
378378 case EXCP_SEMIHOST:
379379 env->regs[0] = do_arm_semihosting(env);
380+ env->regs[15] += env->thumb ? 2 : 4;
380381 break;
381382 case EXCP_INTERRUPT:
382383 /* just indicate that signals should be handled asap */
--- a/linux-user/arm/semihost.c
+++ b/linux-user/arm/semihost.c
@@ -14,6 +14,7 @@
1414 #include "cpu.h"
1515 #include "hw/semihosting/console.h"
1616 #include "qemu.h"
17+#include <termios.h>
1718
1819 int qemu_semihosting_console_outs(CPUArchState *env, target_ulong addr)
1920 {
@@ -47,3 +48,29 @@ void qemu_semihosting_console_outc(CPUArchState *env, target_ulong addr)
4748 }
4849 }
4950 }
51+
52+/*
53+ * For linux-user we can safely block. However as we want to return as
54+ * soon as a character is read we need to tweak the termio to disable
55+ * line buffering. We restore the old mode afterwards in case the
56+ * program is expecting more normal behaviour. This is slow but
57+ * nothing using semihosting console reading is expecting to be fast.
58+ */
59+target_ulong qemu_semihosting_console_inc(CPUArchState *env)
60+{
61+ uint8_t c;
62+ struct termios old_tio, new_tio;
63+
64+ /* Disable line-buffering and echo */
65+ tcgetattr(STDIN_FILENO, &old_tio);
66+ new_tio = old_tio;
67+ new_tio.c_lflag &= (~ICANON & ~ECHO);
68+ tcsetattr(STDIN_FILENO, TCSANOW, &new_tio);
69+
70+ c = getchar();
71+
72+ /* restore config */
73+ tcsetattr(STDIN_FILENO, TCSANOW, &old_tio);
74+
75+ return (target_ulong) c;
76+}
--- a/stubs/semihost.c
+++ b/stubs/semihost.c
@@ -69,3 +69,7 @@ void semihosting_arg_fallback(const char *file, const char *cmd)
6969 void qemu_semihosting_connect_chardevs(void)
7070 {
7171 }
72+
73+void qemu_semihosting_console_init(void)
74+{
75+}
--- a/target/arm/arm-semi.c
+++ b/target/arm/arm-semi.c
@@ -802,8 +802,7 @@ target_ulong do_arm_semihosting(CPUARMState *env)
802802
803803 return guestfd_fns[gf->type].readfn(cpu, gf, arg1, len);
804804 case TARGET_SYS_READC:
805- qemu_log_mask(LOG_UNIMP, "%s: SYS_READC not implemented", __func__);
806- return 0;
805+ return qemu_semihosting_console_inc(env);
807806 case TARGET_SYS_ISTTY:
808807 GET_ARG(0);
809808
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8566,12 +8566,6 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
85668566 case EXCP_VFIQ:
85678567 addr += 0x100;
85688568 break;
8569- case EXCP_SEMIHOST:
8570- qemu_log_mask(CPU_LOG_INT,
8571- "...handling as semihosting call 0x%" PRIx64 "\n",
8572- env->xregs[0]);
8573- env->xregs[0] = do_arm_semihosting(env);
8574- return;
85758569 default:
85768570 cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
85778571 }
@@ -8620,11 +8614,13 @@ static void handle_semihosting(CPUState *cs)
86208614 "...handling as semihosting call 0x%" PRIx64 "\n",
86218615 env->xregs[0]);
86228616 env->xregs[0] = do_arm_semihosting(env);
8617+ env->pc += 4;
86238618 } else {
86248619 qemu_log_mask(CPU_LOG_INT,
86258620 "...handling as semihosting call 0x%x\n",
86268621 env->regs[0]);
86278622 env->regs[0] = do_arm_semihosting(env);
8623+ env->regs[15] += env->thumb ? 2 : 4;
86288624 }
86298625 }
86308626 #endif
--- a/target/arm/m_helper.c
+++ b/target/arm/m_helper.c
@@ -2185,6 +2185,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
21852185 "...handling as semihosting call 0x%x\n",
21862186 env->regs[0]);
21872187 env->regs[0] = do_arm_semihosting(env);
2188+ env->regs[15] += env->thumb ? 2 : 4;
21882189 return;
21892190 case EXCP_BKPT:
21902191 armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG, false);
--- 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)
19371937 break;
19381938 }
19391939 #endif
1940- gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
1940+ gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
19411941 } else {
19421942 unsupported_encoding(s, insn);
19431943 }
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -1124,7 +1124,7 @@ static inline void gen_hlt(DisasContext *s, int imm)
11241124 s->current_el != 0 &&
11251125 #endif
11261126 (imm == (s->thumb ? 0x3c : 0xf000))) {
1127- gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
1127+ gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
11281128 return;
11291129 }
11301130
@@ -8457,7 +8457,7 @@ static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
84578457 !IS_USER(s) &&
84588458 #endif
84598459 (a->imm == 0xab)) {
8460- gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
8460+ gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
84618461 } else {
84628462 gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
84638463 }
@@ -10266,7 +10266,7 @@ static bool trans_SVC(DisasContext *s, arg_SVC *a)
1026610266 !IS_USER(s) &&
1026710267 #endif
1026810268 (a->imm == semihost_imm)) {
10269- gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
10269+ gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
1027010270 } else {
1027110271 gen_set_pc_im(s, s->base.pc_next);
1027210272 s->svc_imm = a->imm;
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -969,7 +969,7 @@ FP_TEST_BIN=$(BUILD_DIR)/tests/fp/fp-test
969969
970970 # the build dir is created by configure
971971 .PHONY: $(FP_TEST_BIN)
972-$(FP_TEST_BIN):
972+$(FP_TEST_BIN): config-host.h $(test-util-obj-y)
973973 $(call quiet-command, \
974974 $(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) V="$(V)" $(notdir $@), \
975975 "BUILD", "$(notdir $@)")
--- a/tests/fp/Makefile
+++ b/tests/fp/Makefile
@@ -554,15 +554,13 @@ TF_OBJS_LIB += $(TF_OBJS_TEST)
554554
555555 BINARIES := fp-test$(EXESUF) fp-bench$(EXESUF)
556556
557-# everything depends on config-host.h because platform.h includes it
558-all: $(BUILD_DIR)/config-host.h
559- $(MAKE) $(BINARIES)
557+# We require artefacts from the main build including config-host.h
558+# because platform.h includes it. Rather than re-invoking the main
559+# build we just error out if things aren't there.
560+$(LIBQEMUUTIL) $(BUILD_DIR)/config-host.h:
561+ $(error $@ missing, re-run parent build)
560562
561-$(LIBQEMUUTIL):
562- $(MAKE) -C $(BUILD_DIR) libqemuutil.a
563-
564-$(BUILD_DIR)/config-host.h:
565- $(MAKE) -C $(BUILD_DIR) config-host.h
563+all: $(BUILD_DIR)/config-host.h $(BINARIES)
566564
567565 # libtestfloat.a depends on libsoftfloat.a, so specify it first
568566 FP_TEST_LIBS := libtestfloat.a libsoftfloat.a $(LIBQEMUUTIL)
--- a/tests/tcg/aarch64/Makefile.softmmu-target
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
@@ -31,7 +31,16 @@ LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
3131 memory: CFLAGS+=-DCHECK_UNALIGNED=1
3232
3333 # Running
34-QEMU_OPTS+=-M virt -cpu max -display none -semihosting-config enable=on,target=native,chardev=output -kernel
34+QEMU_BASE_MACHINE=-M virt -cpu max -display none
35+QEMU_OPTS+=$(QEMU_BASE_MACHINE) -semihosting-config enable=on,target=native,chardev=output -kernel
36+
37+# console test is manual only
38+QEMU_SEMIHOST=-chardev stdio,mux=on,id=stdio0 -semihosting-config enable=on,chardev=stdio0 -mon chardev=stdio0,mode=readline
39+run-semiconsole: QEMU_OPTS=$(QEMU_BASE_MACHINE) $(QEMU_SEMIHOST) -kernel
40+run-semiconsole: semiconsole
41+ $(call skip-test, $<, "MANUAL ONLY")
42+run-plugin-semiconsole-with-%: semiconsole
43+ $(call skip-test, $<, "MANUAL ONLY")
3544
3645 # Simple Record/Replay Test
3746 .PHONY: memory-record
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -32,4 +32,11 @@ run-plugin-semihosting-with-%:
3232 $(call strip-plugin,$<) 2> $<.err, \
3333 "$< on $(TARGET_NAME) with $*")
3434
35+AARCH64_TESTS += semiconsole
36+run-semiconsole: semiconsole
37+ $(call skip-test, $<, "MANUAL ONLY")
38+
39+run-plugin-semiconsole-with-%:
40+ $(call skip-test, $<, "MANUAL ONLY")
41+
3542 TESTS += $(AARCH64_TESTS)
--- /dev/null
+++ b/tests/tcg/aarch64/system/semiconsole.c
@@ -0,0 +1,38 @@
1+/*
2+ * Semihosting Console Test
3+ *
4+ * Copyright (c) 2019 Linaro Ltd
5+ *
6+ * SPDX-License-Identifier: GPL-2.0-or-later
7+ */
8+
9+#include <inttypes.h>
10+#include <minilib.h>
11+
12+#define SYS_READC 0x7
13+
14+uintptr_t __semi_call(uintptr_t type, uintptr_t arg0)
15+{
16+ register uintptr_t t asm("x0") = type;
17+ register uintptr_t a0 asm("x1") = arg0;
18+ asm("hlt 0xf000"
19+ : "=r" (t)
20+ : "r" (t), "r" (a0));
21+
22+ return t;
23+}
24+
25+int main(void)
26+{
27+ char c;
28+
29+ ml_printf("Semihosting Console Test\n");
30+ ml_printf("hit X to exit:");
31+
32+ do {
33+ c = __semi_call(SYS_READC, 0);
34+ __sys_outc(c);
35+ } while (c != 'X');
36+
37+ return 0;
38+}
--- a/tests/tcg/arm/Makefile.target
+++ b/tests/tcg/arm/Makefile.target
@@ -31,15 +31,43 @@ run-fcvt: fcvt
3131
3232 # Semihosting smoke test for linux-user
3333 ARM_TESTS += semihosting
34+semihosting: CFLAGS += -mthumb
3435 run-semihosting: semihosting
3536 $(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
3637
38+ARM_TESTS += semihosting-arm
39+semihosting-arm: CFLAGS += -marm
40+semihosting-arm: semihosting.c
41+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
42+
43+run-semihosting-arm: semihosting-arm
44+ $(call run-test,$<,$(QEMU) $< 2> $<.err, "$< on $(TARGET_NAME)")
45+
3746 run-plugin-semihosting-with-%:
3847 $(call run-test, $@, $(QEMU) $(QEMU_OPTS) \
3948 -plugin $(PLUGIN_DIR)/$(call extract-plugin,$@) \
4049 $(call strip-plugin,$<) 2> $<.err, \
4150 "$< on $(TARGET_NAME) with $*")
4251
52+ARM_TESTS += semiconsole semiconsole-arm
53+
54+semiconsole: CFLAGS += -mthumb
55+run-semiconsole: semiconsole
56+ $(call skip-test, $<, "MANUAL ONLY")
57+
58+run-plugin-semiconsole-with-%:
59+ $(call skip-test, $<, "MANUAL ONLY")
60+
61+semiconsole-arm: CFLAGS += -marm
62+semiconsole-arm: semiconsole.c
63+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
64+
65+run-semiconsole-arm: semiconsole-arm
66+ $(call skip-test, $<, "MANUAL ONLY")
67+
68+run-plugin-semiconsole-arm-with-%:
69+ $(call skip-test, $<, "MANUAL ONLY")
70+
4371 TESTS += $(ARM_TESTS)
4472
4573 # On ARM Linux only supports 4k pages
--- /dev/null
+++ b/tests/tcg/arm/semicall.h
@@ -0,0 +1,35 @@
1+/*
2+ * Semihosting Tests
3+ *
4+ * Copyright (c) 2019
5+ * Written by Alex Bennée <alex.bennee@linaro.org>
6+ *
7+ * SPDX-License-Identifier: GPL-3.0-or-later
8+ */
9+
10+#define SYS_WRITE0 0x04
11+#define SYS_READC 0x07
12+#define SYS_REPORTEXC 0x18
13+
14+uintptr_t __semi_call(uintptr_t type, uintptr_t arg0)
15+{
16+#if defined(__arm__)
17+ register uintptr_t t asm("r0") = type;
18+ register uintptr_t a0 asm("r1") = arg0;
19+#ifdef __thumb__
20+# define SVC "svc 0xab"
21+#else
22+# define SVC "svc 0x123456"
23+#endif
24+ asm(SVC : "=r" (t)
25+ : "r" (t), "r" (a0));
26+#else
27+ register uintptr_t t asm("x0") = type;
28+ register uintptr_t a0 asm("x1") = arg0;
29+ asm("hlt 0xf000"
30+ : "=r" (t)
31+ : "r" (t), "r" (a0));
32+#endif
33+
34+ return t;
35+}
--- /dev/null
+++ b/tests/tcg/arm/semiconsole.c
@@ -0,0 +1,27 @@
1+/*
2+ * linux-user semihosting console
3+ *
4+ * Copyright (c) 2019
5+ * Written by Alex Bennée <alex.bennee@linaro.org>
6+ *
7+ * SPDX-License-Identifier: GPL-3.0-or-later
8+ */
9+
10+#include <stdio.h>
11+#include <stdint.h>
12+#include "semicall.h"
13+
14+int main(void)
15+{
16+ char c;
17+
18+ printf("Semihosting Console Test\n");
19+ printf("hit X to exit:");
20+
21+ do {
22+ c = __semi_call(SYS_READC, 0);
23+ printf("got '%c'\n", c);
24+ } while (c != 'X');
25+
26+ return 0;
27+}
--- a/tests/tcg/arm/semihosting.c
+++ b/tests/tcg/arm/semihosting.c
@@ -8,26 +8,7 @@
88 */
99
1010 #include <stdint.h>
11-
12-#define SYS_WRITE0 0x04
13-#define SYS_REPORTEXC 0x18
14-
15-void __semi_call(uintptr_t type, uintptr_t arg0)
16-{
17-#if defined(__arm__)
18- register uintptr_t t asm("r0") = type;
19- register uintptr_t a0 asm("r1") = arg0;
20- asm("svc 0xab"
21- : /* no return */
22- : "r" (t), "r" (a0));
23-#else
24- register uintptr_t t asm("x0") = type;
25- register uintptr_t a0 asm("x1") = arg0;
26- asm("hlt 0xf000"
27- : /* no return */
28- : "r" (t), "r" (a0));
29-#endif
30-}
11+#include "semicall.h"
3112
3213 int main(int argc, char *argv[argc])
3314 {
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -32,6 +32,7 @@ class FreeBSDVM(basevm.BaseVM):
3232 "git",
3333 "pkgconf",
3434 "bzip2",
35+ "python37",
3536
3637 # gnu tools
3738 "bash",
@@ -63,7 +64,7 @@ class FreeBSDVM(basevm.BaseVM):
6364 mkdir src build; cd src;
6465 tar -xf /dev/vtbd1;
6566 cd ../build
66- ../src/configure --python=python3.6 {configure_opts};
67+ ../src/configure --python=python3.7 {configure_opts};
6768 gmake --output-sync -j{jobs} {target} {verbose};
6869 """
6970
--- a/tests/vm/openbsd
+++ b/tests/vm/openbsd
@@ -22,8 +22,8 @@ class OpenBSDVM(basevm.BaseVM):
2222 name = "openbsd"
2323 arch = "x86_64"
2424
25- link = "https://cdn.openbsd.org/pub/OpenBSD/6.5/amd64/install65.iso"
26- csum = "38d1f8cadd502f1c27bf05c5abde6cc505dd28f3f34f8a941048ff9a54f9f608"
25+ link = "https://cdn.openbsd.org/pub/OpenBSD/6.6/amd64/install66.iso"
26+ csum = "b22e63df56e6266de6bbeed8e9be0fbe9ee2291551c5bc03f3cc2e4ab9436ee3"
2727 size = "20G"
2828 pkgs = [
2929 # tools
--- a/vl.c
+++ b/vl.c
@@ -4238,6 +4238,9 @@ int main(int argc, char **argv, char **envp)
42384238 qemu_opts_foreach(qemu_find_opts("mon"),
42394239 mon_init_func, NULL, &error_fatal);
42404240
4241+ /* connect semihosting console input if requested */
4242+ qemu_semihosting_console_init();
4243+
42414244 if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
42424245 exit(1);
42434246 if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)