new file mode 100644
@@ -0,0 +1,32 @@
+/*
+ * Semihosting support
+ *
+ * Copyright (c) 2015 Imagination Technologies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SEMIHOST_H
+#define SEMIHOST_H
+
+#ifdef CONFIG_USER_ONLY
+static inline bool semihosting_enabled(void)
+{
+ return true;
+}
+#else
+bool semihosting_enabled(void);
+#endif
+
+#endif
@@ -125,7 +125,6 @@ extern int cursor_hide;
extern int graphic_rotate;
extern int no_quit;
extern int no_shutdown;
-extern int semihosting_enabled;
extern int old_param;
extern int boot_menu;
extern bool boot_strict;
@@ -10,6 +10,7 @@
#include "exec/cpu_ldst.h"
#include "arm_ldst.h"
#include <zlib.h> /* For crc32 */
+#include "exec/semihost.h"
#ifndef CONFIG_USER_ONLY
static inline int get_phys_addr(CPUARMState *env, target_ulong address,
@@ -4401,7 +4402,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
return;
case EXCP_BKPT:
- if (semihosting_enabled) {
+ if (semihosting_enabled()) {
int nr;
nr = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff;
if (nr == 0xab) {
@@ -4713,7 +4714,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
offset = 4;
break;
case EXCP_SWI:
- if (semihosting_enabled) {
+ if (semihosting_enabled()) {
/* Check for semihosting interrupt. */
if (env->thumb) {
mask = arm_lduw_code(env, env->regs[15] - 2, env->bswap_code)
@@ -4740,7 +4741,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
break;
case EXCP_BKPT:
/* See if this is a semihosting syscall. */
- if (env->thumb && semihosting_enabled) {
+ if (env->thumb && semihosting_enabled()) {
mask = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff;
if (mask == 0xab
&& (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
@@ -20,6 +20,7 @@
#include "cpu.h"
#include "qemu/host-utils.h"
#include "sysemu/sysemu.h"
+#include "exec/semihost.h"
int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
int mmu_idx)
@@ -162,7 +163,7 @@ void lm32_cpu_do_interrupt(CPUState *cs)
switch (cs->exception_index) {
case EXCP_SYSTEMCALL:
- if (unlikely(semihosting_enabled)) {
+ if (unlikely(semihosting_enabled())) {
/* do_semicall() returns true if call was handled. Otherwise
* do the normal exception handling. */
if (lm32_cpu_do_semihosting(cs)) {
@@ -19,6 +19,7 @@
#include "cpu.h"
#include "exec/helper-proto.h"
#include "exec/cpu_ldst.h"
+#include "exec/semihost.h"
#if defined(CONFIG_USER_ONLY)
@@ -33,8 +34,6 @@ static inline void do_interrupt_m68k_hardirq(CPUM68KState *env)
#else
-extern int semihosting_enabled;
-
/* Try to fill the TLB and return an exception if error. If retaddr is
NULL, it means that the function was called in C code (i.e. not
from generated code or from helper.c) */
@@ -85,7 +84,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw)
do_rte(env);
return;
case EXCP_HALT_INSN:
- if (semihosting_enabled
+ if (semihosting_enabled()
&& (env->sr & SR_S) != 0
&& (env->pc & 3) == 0
&& cpu_lduw_code(env, env->pc - 4) == 0x4e71
@@ -37,6 +37,7 @@
#include "qemu/log.h"
#include "sysemu/sysemu.h"
#include "exec/cpu_ldst.h"
+#include "exec/semihost.h"
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
@@ -1216,7 +1217,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
break;
case 1: /*SIMCALL*/
- if (semihosting_enabled) {
+ if (semihosting_enabled()) {
if (gen_check_privilege(dc)) {
gen_helper_simcall(cpu_env);
}
@@ -119,6 +119,7 @@ int main(int argc, char **argv)
#include "qapi/opts-visitor.h"
#include "qom/object_interfaces.h"
#include "qapi-event.h"
+#include "exec/semihost.h"
#define DEFAULT_RAM_SIZE 128
@@ -171,7 +172,6 @@ int graphic_rotate = 0;
const char *watchdog;
QEMUOptionRom option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
-int semihosting_enabled = 0;
int old_param = 0;
const char *qemu_name;
int alt_grab = 0;
@@ -1225,6 +1225,16 @@ static void configure_msg(QemuOpts *opts)
}
/***********************************************************/
+/* Semihosting */
+
+static bool semihosting_allowed;
+
+bool semihosting_enabled(void)
+{
+ return semihosting_allowed;
+}
+
+/***********************************************************/
/* USB devices */
static int usb_device_add(const char *devname)
@@ -3545,15 +3555,15 @@ int main(int argc, char **argv, char **envp)
nb_option_roms++;
break;
case QEMU_OPTION_semihosting:
- semihosting_enabled = 1;
+ semihosting_allowed = true;
semihosting_target = SEMIHOSTING_TARGET_AUTO;
break;
case QEMU_OPTION_semihosting_config:
- semihosting_enabled = 1;
+ semihosting_allowed = true;
opts = qemu_opts_parse(qemu_find_opts("semihosting-config"),
optarg, 0);
if (opts != NULL) {
- semihosting_enabled = qemu_opt_get_bool(opts, "enable",
+ semihosting_allowed = qemu_opt_get_bool(opts, "enable",
true);
const char *target = qemu_opt_get(opts, "target");
if (target != NULL) {
Remove extern int semihosting_enabled declaration from sysemu.h and create equivalent semihosting_enabled() function. Also introduce semihost.h containing things related to semihosting config. Suggested-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> --- include/exec/semihost.h | 32 ++++++++++++++++++++++++++++++++ include/sysemu/sysemu.h | 1 - target-arm/helper.c | 7 ++++--- target-lm32/helper.c | 3 ++- target-m68k/op_helper.c | 5 ++--- target-xtensa/translate.c | 3 ++- vl.c | 18 ++++++++++++++---- 7 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 include/exec/semihost.h