mirror of https://github.com/xemu-project/xemu.git
semihosting: create SemihostingConfig structure and semihost.h
Remove semihosting_enabled and semihosting_target and replace them with SemihostingConfig structure containing equivalent fields. The structure is defined in vl.c where it is actually set. Also introduce separate header file include/exec/semihost.h allowing to access semihosting config related stuff from target specific semihosting code. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1434643256-16858-2-git-send-email-leon.alrae@imgtec.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
b58850e79d
commit
cfe67cef48
|
@ -40,6 +40,7 @@
|
|||
#include "cpu.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "exec/semihost.h"
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
#define GDB_ATTACHED "0"
|
||||
|
@ -323,8 +324,6 @@ static GDBState *gdbserver_state;
|
|||
|
||||
bool gdb_has_xml;
|
||||
|
||||
int semihosting_target = SEMIHOSTING_TARGET_AUTO;
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
/* XXX: This is not thread safe. Do we care? */
|
||||
static int gdbserver_fd = -1;
|
||||
|
@ -362,10 +361,11 @@ static enum {
|
|||
/* Decide if either remote gdb syscalls or native file IO should be used. */
|
||||
int use_gdb_syscalls(void)
|
||||
{
|
||||
if (semihosting_target == SEMIHOSTING_TARGET_NATIVE) {
|
||||
SemihostingTarget target = semihosting_get_target();
|
||||
if (target == SEMIHOSTING_TARGET_NATIVE) {
|
||||
/* -semihosting-config target=native */
|
||||
return false;
|
||||
} else if (semihosting_target == SEMIHOSTING_TARGET_GDB) {
|
||||
} else if (target == SEMIHOSTING_TARGET_GDB) {
|
||||
/* -semihosting-config target=gdb */
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -95,10 +95,4 @@ extern bool gdb_has_xml;
|
|||
/* in gdbstub-xml.c, generated by scripts/feature_to_c.sh */
|
||||
extern const char *const xml_builtin[][2];
|
||||
|
||||
/* Command line option defining whether semihosting should go via gdb or not */
|
||||
extern int semihosting_target;
|
||||
#define SEMIHOSTING_TARGET_AUTO 0
|
||||
#define SEMIHOSTING_TARGET_NATIVE 1
|
||||
#define SEMIHOSTING_TARGET_GDB 2
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
typedef enum SemihostingTarget {
|
||||
SEMIHOSTING_TARGET_AUTO = 0,
|
||||
SEMIHOSTING_TARGET_NATIVE,
|
||||
SEMIHOSTING_TARGET_GDB
|
||||
} SemihostingTarget;
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
static inline bool semihosting_enabled(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline SemihostingTarget semihosting_get_target(void)
|
||||
{
|
||||
return SEMIHOSTING_TARGET_AUTO;
|
||||
}
|
||||
#else
|
||||
bool semihosting_enabled(void);
|
||||
SemihostingTarget semihosting_get_target(void);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -126,7 +126,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 bool get_phys_addr(CPUARMState *env, target_ulong address,
|
||||
|
@ -4554,7 +4555,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) {
|
||||
|
@ -4866,7 +4867,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)
|
||||
|
@ -4893,7 +4894,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);
|
||||
}
|
||||
|
|
38
vl.c
38
vl.c
|
@ -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 MAX_VIRTIO_CONSOLES 1
|
||||
#define MAX_SCLP_CONSOLES 1
|
||||
|
@ -169,7 +170,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;
|
||||
|
@ -1245,6 +1245,26 @@ static void configure_msg(QemuOpts *opts)
|
|||
enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true);
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
/* Semihosting */
|
||||
|
||||
typedef struct SemihostingConfig {
|
||||
bool enabled;
|
||||
SemihostingTarget target;
|
||||
} SemihostingConfig;
|
||||
|
||||
static SemihostingConfig semihosting;
|
||||
|
||||
bool semihosting_enabled(void)
|
||||
{
|
||||
return semihosting.enabled;
|
||||
}
|
||||
|
||||
SemihostingTarget semihosting_get_target(void)
|
||||
{
|
||||
return semihosting.target;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
/* USB devices */
|
||||
|
||||
|
@ -3622,24 +3642,24 @@ int main(int argc, char **argv, char **envp)
|
|||
nb_option_roms++;
|
||||
break;
|
||||
case QEMU_OPTION_semihosting:
|
||||
semihosting_enabled = 1;
|
||||
semihosting_target = SEMIHOSTING_TARGET_AUTO;
|
||||
semihosting.enabled = true;
|
||||
semihosting.target = SEMIHOSTING_TARGET_AUTO;
|
||||
break;
|
||||
case QEMU_OPTION_semihosting_config:
|
||||
semihosting_enabled = 1;
|
||||
semihosting.enabled = true;
|
||||
opts = qemu_opts_parse(qemu_find_opts("semihosting-config"),
|
||||
optarg, 0);
|
||||
if (opts != NULL) {
|
||||
semihosting_enabled = qemu_opt_get_bool(opts, "enable",
|
||||
semihosting.enabled = qemu_opt_get_bool(opts, "enable",
|
||||
true);
|
||||
const char *target = qemu_opt_get(opts, "target");
|
||||
if (target != NULL) {
|
||||
if (strcmp("native", target) == 0) {
|
||||
semihosting_target = SEMIHOSTING_TARGET_NATIVE;
|
||||
semihosting.target = SEMIHOSTING_TARGET_NATIVE;
|
||||
} else if (strcmp("gdb", target) == 0) {
|
||||
semihosting_target = SEMIHOSTING_TARGET_GDB;
|
||||
semihosting.target = SEMIHOSTING_TARGET_GDB;
|
||||
} else if (strcmp("auto", target) == 0) {
|
||||
semihosting_target = SEMIHOSTING_TARGET_AUTO;
|
||||
semihosting.target = SEMIHOSTING_TARGET_AUTO;
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported semihosting-config"
|
||||
" %s\n",
|
||||
|
@ -3647,7 +3667,7 @@ int main(int argc, char **argv, char **envp)
|
|||
exit(1);
|
||||
}
|
||||
} else {
|
||||
semihosting_target = SEMIHOSTING_TARGET_AUTO;
|
||||
semihosting.target = SEMIHOSTING_TARGET_AUTO;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported semihosting-config %s\n",
|
||||
|
|
Loading…
Reference in New Issue