mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/stsquad/tags/pull-testing-next-280519-2' into staging
Various testing updates - semihosting re-factor (used in system tests) - aarch64 and alpha system tests - editorconfig tweak for .S - some docker image updates - iotests clean-up (without make check inclusion) # gpg: Signature made Tue 28 May 2019 17:26:34 BST # 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-next-280519-2: (27 commits) tests/qemu-iotests: re-format output to for make check-block tests/qemu-iotests/group: Re-use the "auto" group for tests that can always run Makefile.target: support per-target coverage reports Makefile: include per-target build directories in coverage report Makefile: fix coverage-report reference to BUILD_DIR .travis.yml: enable aarch64-softmmu and alpha-softmmu tcg tests tests/tcg/alpha: add system boot.S tests/tcg/multiarch: expand system memory test to cover more tests/tcg/minilib: support %c format char tests/tcg/multiarch: move the system memory test tests/tcg/aarch64: add system boot.S editorconfig: add settings for .s/.S files tests/tcg/multiarch: add hello world system test tests/tcg/multiarch: add support for multiarch system tests tests/docker: Test more components on the Fedora default image tests/docker: add ubuntu 18.04 MAINTAINERS: update for semihostings new home target/mips: convert UHI_plog to use common semihosting code target/mips: only build mips-semi for softmmu target/arm: correct return values for WRITE/READ in arm-semi ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -26,6 +26,11 @@ file_type_emacs = makefile
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{s,S}]
|
||||
indent_style = tab
|
||||
indent_size = 8
|
||||
file_type_emacs = asm
|
||||
|
||||
[*.{vert,frag}]
|
||||
file_type_emacs = glsl
|
||||
|
||||
|
||||
+1
-1
@@ -284,5 +284,5 @@ matrix:
|
||||
|
||||
# Run check-tcg against softmmu targets
|
||||
- env:
|
||||
- CONFIG="--target-list=xtensa-softmmu,arm-softmmu"
|
||||
- CONFIG="--target-list=xtensa-softmmu,arm-softmmu,aarch64-softmmu,alpha-softmmu"
|
||||
- TEST_CMD="make -j3 check-tcg V=1"
|
||||
|
||||
@@ -470,6 +470,7 @@ M: Richard Henderson <rth@twiddle.net>
|
||||
S: Maintained
|
||||
F: hw/alpha/
|
||||
F: hw/isa/smc37c669-superio.c
|
||||
F: tests/tcg/alpha/system/
|
||||
|
||||
ARM Machines
|
||||
------------
|
||||
@@ -2563,6 +2564,13 @@ F: docs/pvrdma.txt
|
||||
F: contrib/rdmacm-mux/*
|
||||
F: qapi/rdma.json
|
||||
|
||||
Semihosting
|
||||
M: Alex Bennée <alex.bennee@linaro.org>
|
||||
L: qemu-devel@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/semihosting/
|
||||
F: include/hw/semihosting/
|
||||
|
||||
Build and test automation
|
||||
-------------------------
|
||||
Build and test automation
|
||||
|
||||
@@ -1009,7 +1009,9 @@ $(filter %.1 %.7 %.8,$(DOCS)): scripts/texi2pod.pl
|
||||
%/coverage-report.html:
|
||||
@mkdir -p $*
|
||||
$(call quiet-command,\
|
||||
gcovr -r $(SRC_PATH) --object-directory $(BUILD_PATH) \
|
||||
gcovr -r $(SRC_PATH) \
|
||||
$(foreach t, $(TARGET_DIRS), --object-directory $(BUILD_DIR)/$(t)) \
|
||||
--object-directory $(BUILD_DIR) \
|
||||
-p --html --html-details -o $@, \
|
||||
"GEN", "coverage-report.html")
|
||||
|
||||
|
||||
@@ -238,3 +238,19 @@ endif
|
||||
|
||||
generated-files-y += config-target.h
|
||||
Makefile: $(generated-files-y)
|
||||
|
||||
# Reports/Analysis
|
||||
#
|
||||
# The target specific coverage report only cares about target specific
|
||||
# blobs and not the shared code.
|
||||
#
|
||||
|
||||
%/coverage-report.html:
|
||||
@mkdir -p $*
|
||||
$(call quiet-command,\
|
||||
gcovr -r $(SRC_PATH) --object-directory $(CURDIR) \
|
||||
-p --html --html-details -o $@, \
|
||||
"GEN", "coverage-report.html")
|
||||
|
||||
.PHONY: coverage-report
|
||||
coverage-report: $(CURDIR)/reports/coverage/coverage-report.html
|
||||
|
||||
@@ -39,3 +39,4 @@ CONFIG_MICROBIT=y
|
||||
CONFIG_FSL_IMX25=y
|
||||
CONFIG_FSL_IMX7=y
|
||||
CONFIG_FSL_IMX6UL=y
|
||||
CONFIG_SEMIHOSTING=y
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#
|
||||
#CONFIG_MILKYMIST_TMU2=n # disabling it actually causes compile-time failures
|
||||
|
||||
CONFIG_SEMIHOSTING=y
|
||||
|
||||
# Boards:
|
||||
#
|
||||
CONFIG_LM32=y
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Default configuration for m68k-softmmu
|
||||
|
||||
CONFIG_SEMIHOSTING=y
|
||||
|
||||
# Boards:
|
||||
#
|
||||
CONFIG_AN5206=y
|
||||
|
||||
@@ -35,6 +35,7 @@ CONFIG_MIPS_CPS=y
|
||||
CONFIG_MIPS_ITU=y
|
||||
CONFIG_R4K=y
|
||||
CONFIG_MALTA=y
|
||||
CONFIG_SEMIHOSTING=y
|
||||
CONFIG_PCNET_PCI=y
|
||||
CONFIG_MIPSSIM=y
|
||||
CONFIG_ACPI_SMBUS=y
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Default configuration for nios2-softmmu
|
||||
|
||||
CONFIG_SEMIHOSTING=y
|
||||
|
||||
# Boards:
|
||||
#
|
||||
CONFIG_NIOS2_10M50=y
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Default configuration for Xtensa
|
||||
|
||||
CONFIG_SEMIHOSTING=y
|
||||
|
||||
# Boards:
|
||||
#
|
||||
CONFIG_XTENSA_SIM=y
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "qemu/sockets.h"
|
||||
#include "sysemu/hw_accel.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "exec/semihost.h"
|
||||
#include "hw/semihosting/semihost.h"
|
||||
#include "exec/exec-all.h"
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
|
||||
@@ -29,6 +29,7 @@ source pci/Kconfig
|
||||
source rdma/Kconfig
|
||||
source scsi/Kconfig
|
||||
source sd/Kconfig
|
||||
source semihosting/Kconfig
|
||||
source smbios/Kconfig
|
||||
source ssi/Kconfig
|
||||
source timer/Kconfig
|
||||
|
||||
@@ -36,6 +36,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
|
||||
devices-dirs-$(CONFIG_SOFTMMU) += xen/
|
||||
devices-dirs-$(CONFIG_MEM_DEVICE) += mem/
|
||||
devices-dirs-$(CONFIG_SOFTMMU) += smbios/
|
||||
devices-dirs-y += semihosting/
|
||||
devices-dirs-y += core/
|
||||
common-obj-y += $(devices-dirs-y)
|
||||
obj-y += $(devices-dirs-y)
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/empty_slot.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "exec/semihost.h"
|
||||
#include "hw/semihosting/semihost.h"
|
||||
#include "hw/mips/cps.h"
|
||||
|
||||
#define ENVP_ADDR 0x80002000l
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
config SEMIHOSTING
|
||||
bool
|
||||
@@ -0,0 +1,2 @@
|
||||
obj-$(CONFIG_SEMIHOSTING) += config.o
|
||||
obj-$(CONFIG_SEMIHOSTING) += console.o
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Semihosting configuration
|
||||
*
|
||||
* Copyright (c) 2015 Imagination Technologies
|
||||
* Copyright (c) 2019 Linaro Ltd
|
||||
*
|
||||
* This controls the configuration of semihosting for all guest
|
||||
* targets that support it. Architecture specific handling is handled
|
||||
* in target/HW/HW-semi.c
|
||||
*
|
||||
* Semihosting is sightly strange in that it is also supported by some
|
||||
* linux-user targets. However in that use case no configuration of
|
||||
* the outputs and command lines is supported.
|
||||
*
|
||||
* The config module is common to all softmmu targets however as vl.c
|
||||
* needs to link against the helpers.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/semihosting/semihost.h"
|
||||
#include "chardev/char.h"
|
||||
|
||||
QemuOptsList qemu_semihosting_config_opts = {
|
||||
.name = "semihosting-config",
|
||||
.implied_opt_name = "enable",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_semihosting_config_opts.head),
|
||||
.desc = {
|
||||
{
|
||||
.name = "enable",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
}, {
|
||||
.name = "target",
|
||||
.type = QEMU_OPT_STRING,
|
||||
}, {
|
||||
.name = "chardev",
|
||||
.type = QEMU_OPT_STRING,
|
||||
}, {
|
||||
.name = "arg",
|
||||
.type = QEMU_OPT_STRING,
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
|
||||
typedef struct SemihostingConfig {
|
||||
bool enabled;
|
||||
SemihostingTarget target;
|
||||
Chardev *chardev;
|
||||
const char **argv;
|
||||
int argc;
|
||||
const char *cmdline; /* concatenated argv */
|
||||
} SemihostingConfig;
|
||||
|
||||
static SemihostingConfig semihosting;
|
||||
static const char *semihost_chardev;
|
||||
|
||||
bool semihosting_enabled(void)
|
||||
{
|
||||
return semihosting.enabled;
|
||||
}
|
||||
|
||||
SemihostingTarget semihosting_get_target(void)
|
||||
{
|
||||
return semihosting.target;
|
||||
}
|
||||
|
||||
const char *semihosting_get_arg(int i)
|
||||
{
|
||||
if (i >= semihosting.argc) {
|
||||
return NULL;
|
||||
}
|
||||
return semihosting.argv[i];
|
||||
}
|
||||
|
||||
int semihosting_get_argc(void)
|
||||
{
|
||||
return semihosting.argc;
|
||||
}
|
||||
|
||||
const char *semihosting_get_cmdline(void)
|
||||
{
|
||||
if (semihosting.cmdline == NULL && semihosting.argc > 0) {
|
||||
semihosting.cmdline = g_strjoinv(" ", (gchar **)semihosting.argv);
|
||||
}
|
||||
return semihosting.cmdline;
|
||||
}
|
||||
|
||||
static int add_semihosting_arg(void *opaque,
|
||||
const char *name, const char *val,
|
||||
Error **errp)
|
||||
{
|
||||
SemihostingConfig *s = opaque;
|
||||
if (strcmp(name, "arg") == 0) {
|
||||
s->argc++;
|
||||
/* one extra element as g_strjoinv() expects NULL-terminated array */
|
||||
s->argv = g_realloc(s->argv, (s->argc + 1) * sizeof(void *));
|
||||
s->argv[s->argc - 1] = val;
|
||||
s->argv[s->argc] = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use strings passed via -kernel/-append to initialize semihosting.argv[] */
|
||||
void semihosting_arg_fallback(const char *file, const char *cmd)
|
||||
{
|
||||
char *cmd_token;
|
||||
|
||||
/* argv[0] */
|
||||
add_semihosting_arg(&semihosting, "arg", file, NULL);
|
||||
|
||||
/* split -append and initialize argv[1..n] */
|
||||
cmd_token = strtok(g_strdup(cmd), " ");
|
||||
while (cmd_token) {
|
||||
add_semihosting_arg(&semihosting, "arg", cmd_token, NULL);
|
||||
cmd_token = strtok(NULL, " ");
|
||||
}
|
||||
}
|
||||
|
||||
Chardev *semihosting_get_chardev(void)
|
||||
{
|
||||
return semihosting.chardev;
|
||||
}
|
||||
|
||||
void qemu_semihosting_enable(void)
|
||||
{
|
||||
semihosting.enabled = true;
|
||||
semihosting.target = SEMIHOSTING_TARGET_AUTO;
|
||||
}
|
||||
|
||||
int qemu_semihosting_config_options(const char *optarg)
|
||||
{
|
||||
QemuOptsList *opt_list = qemu_find_opts("semihosting-config");
|
||||
QemuOpts *opts = qemu_opts_parse_noisily(opt_list, optarg, false);
|
||||
|
||||
semihosting.enabled = true;
|
||||
|
||||
if (opts != NULL) {
|
||||
semihosting.enabled = qemu_opt_get_bool(opts, "enable",
|
||||
true);
|
||||
const char *target = qemu_opt_get(opts, "target");
|
||||
/* setup of chardev is deferred until they are initialised */
|
||||
semihost_chardev = qemu_opt_get(opts, "chardev");
|
||||
if (target != NULL) {
|
||||
if (strcmp("native", target) == 0) {
|
||||
semihosting.target = SEMIHOSTING_TARGET_NATIVE;
|
||||
} else if (strcmp("gdb", target) == 0) {
|
||||
semihosting.target = SEMIHOSTING_TARGET_GDB;
|
||||
} else if (strcmp("auto", target) == 0) {
|
||||
semihosting.target = SEMIHOSTING_TARGET_AUTO;
|
||||
} else {
|
||||
error_report("unsupported semihosting-config %s",
|
||||
optarg);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
semihosting.target = SEMIHOSTING_TARGET_AUTO;
|
||||
}
|
||||
/* Set semihosting argument count and vector */
|
||||
qemu_opt_foreach(opts, add_semihosting_arg,
|
||||
&semihosting, NULL);
|
||||
} else {
|
||||
error_report("unsupported semihosting-config %s", optarg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qemu_semihosting_connect_chardevs(void)
|
||||
{
|
||||
/* We had to defer this until chardevs were created */
|
||||
if (semihost_chardev) {
|
||||
Chardev *chr = qemu_chr_find(semihost_chardev);
|
||||
if (chr == NULL) {
|
||||
error_report("semihosting chardev '%s' not found",
|
||||
semihost_chardev);
|
||||
exit(1);
|
||||
}
|
||||
semihosting.chardev = chr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Semihosting Console Support
|
||||
*
|
||||
* Copyright (c) 2015 Imagination Technologies
|
||||
* Copyright (c) 2019 Linaro Ltd
|
||||
*
|
||||
* This provides support for outputting to a semihosting console.
|
||||
*
|
||||
* While most semihosting implementations support reading and writing
|
||||
* to arbitrary file descriptors we treat the console as something
|
||||
* specifically for debugging interaction. This means messages can be
|
||||
* re-directed to gdb (if currently being used to debug) or even
|
||||
* re-directed elsewhere.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "hw/semihosting/semihost.h"
|
||||
#include "hw/semihosting/console.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/log.h"
|
||||
#include "chardev/char.h"
|
||||
|
||||
int qemu_semihosting_log_out(const char *s, int len)
|
||||
{
|
||||
Chardev *chardev = semihosting_get_chardev();
|
||||
if (chardev) {
|
||||
return qemu_chr_write_all(chardev, (uint8_t *) s, len);
|
||||
} else {
|
||||
return write(STDERR_FILENO, s, len);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A re-implementation of lock_user_string that we can use locally
|
||||
* instead of relying on softmmu-semi. Hopefully we can deprecate that
|
||||
* in time. We either copy len bytes if specified or until we find a NULL.
|
||||
*/
|
||||
static GString *copy_user_string(CPUArchState *env, target_ulong addr, int len)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
GString *s = g_string_sized_new(len ? len : 128);
|
||||
uint8_t c;
|
||||
bool done;
|
||||
|
||||
do {
|
||||
if (cpu_memory_rw_debug(cpu, addr++, &c, 1, 0) == 0) {
|
||||
s = g_string_append_c(s, c);
|
||||
done = len ? s->len == len : c == 0;
|
||||
} else {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: passed inaccessible address " TARGET_FMT_lx,
|
||||
__func__, addr);
|
||||
done = true;
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static void semihosting_cb(CPUState *cs, target_ulong ret, target_ulong err)
|
||||
{
|
||||
if (ret == (target_ulong) -1) {
|
||||
qemu_log("%s: gdb console output failed ("TARGET_FMT_ld")",
|
||||
__func__, err);
|
||||
}
|
||||
}
|
||||
|
||||
int qemu_semihosting_console_out(CPUArchState *env, target_ulong addr, int len)
|
||||
{
|
||||
GString *s = copy_user_string(env, addr, len);
|
||||
int out = s->len;
|
||||
|
||||
if (use_gdb_syscalls()) {
|
||||
gdb_do_syscall(semihosting_cb, "write,2,%x,%x", addr, s->len);
|
||||
} else {
|
||||
out = qemu_semihosting_log_out(s->str, s->len);
|
||||
}
|
||||
|
||||
g_string_free(s, true);
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Semihosting Console
|
||||
*
|
||||
* Copyright (c) 2019 Linaro Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef _SEMIHOST_CONSOLE_H_
|
||||
#define _SEMIHOST_CONSOLE_H_
|
||||
|
||||
/**
|
||||
* qemu_semihosting_console_out:
|
||||
* @env: CPUArchState
|
||||
* @s: host address of guest string
|
||||
* @len: length of string or 0 (string is null terminated)
|
||||
*
|
||||
* Send a guest string to the debug console. This may be the remote
|
||||
* gdb session if a softmmu guest is currently being debugged.
|
||||
*
|
||||
* Returns: number of bytes written.
|
||||
*/
|
||||
int qemu_semihosting_console_out(CPUArchState *env, target_ulong s, int len);
|
||||
|
||||
/**
|
||||
* qemu_semihosting_log_out:
|
||||
* @s: pointer to string
|
||||
* @len: length of string
|
||||
*
|
||||
* Send a string to the debug output. Unlike console_out these strings
|
||||
* can't be sent to a remote gdb instance as they don't exist in guest
|
||||
* memory.
|
||||
*
|
||||
* Returns: number of bytes written
|
||||
*/
|
||||
int qemu_semihosting_log_out(const char *s, int len);
|
||||
|
||||
#endif /* _SEMIHOST_CONSOLE_H_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user