From 1b88e0e8c81866718839dd4f290820404ae97102 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 15 Feb 2018 10:53:48 -0500 Subject: [PATCH] target-arm: Wire up HLT 0xf000 as the A64 semihosting instruction For the A64 instruction set, the semihosting call instruction is 'HLT 0xf000'. Wire this up to call do_arm_semihosting() if semihosting is enabled. Backports commit 8012c84ff92a36d05dfe61af9b24dd01a7ea25e4 from qemu --- qemu/aarch64.h | 1 - qemu/aarch64eb.h | 1 - qemu/arm.h | 1 - qemu/armeb.h | 1 - qemu/header_gen.py | 5 ----- qemu/m68k.h | 1 - qemu/mips.h | 1 - qemu/mips64.h | 1 - qemu/mips64el.h | 1 - qemu/mipsel.h | 1 - qemu/powerpc.h | 1 - qemu/sparc.h | 1 - qemu/sparc64.h | 1 - qemu/target-arm/cpu.h | 1 + qemu/target-arm/helper-a64.c | 7 +++++++ qemu/target-arm/internals.h | 2 ++ qemu/target-arm/translate-a64.c | 23 +++++++++++++++++++++-- qemu/x86_64.h | 1 - 18 files changed, 31 insertions(+), 20 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 98f895c1..e2627126 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_aarch64 #define scr_write scr_write_aarch64 #define sctlr_write sctlr_write_aarch64 -#define semihosting_enabled semihosting_enabled_aarch64 #define semihosting_get_target semihosting_get_target_aarch64 #define semihosting_get_arg semihosting_get_arg_aarch64 #define semihosting_get_argc semihosting_get_argc_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index fcac2407..c9f0e672 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_aarch64eb #define scr_write scr_write_aarch64eb #define sctlr_write sctlr_write_aarch64eb -#define semihosting_enabled semihosting_enabled_aarch64eb #define semihosting_get_target semihosting_get_target_aarch64eb #define semihosting_get_arg semihosting_get_arg_aarch64eb #define semihosting_get_argc semihosting_get_argc_aarch64eb diff --git a/qemu/arm.h b/qemu/arm.h index f5dd7e72..5f3a85c5 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_arm #define scr_write scr_write_arm #define sctlr_write sctlr_write_arm -#define semihosting_enabled semihosting_enabled_arm #define semihosting_get_target semihosting_get_target_arm #define semihosting_get_arg semihosting_get_arg_arm #define semihosting_get_argc semihosting_get_argc_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 5a5e5948..2678a069 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_armeb #define scr_write scr_write_armeb #define sctlr_write sctlr_write_armeb -#define semihosting_enabled semihosting_enabled_armeb #define semihosting_get_target semihosting_get_target_armeb #define semihosting_get_arg semihosting_get_arg_armeb #define semihosting_get_argc semihosting_get_argc_armeb diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 2a529e4c..2e63f65c 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2588,11 +2588,6 @@ symbols = ( 'save_globals', 'scr_write', 'sctlr_write', - 'semihosting_enabled', - 'semihosting_get_target', - 'semihosting_get_arg', - 'semihosting_get_argc', - 'semihosting_get_cmdline', 'set_bit', 'set_bits', 'set_default_nan_mode', diff --git a/qemu/m68k.h b/qemu/m68k.h index 571aa4c3..a10ac6b3 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_m68k #define scr_write scr_write_m68k #define sctlr_write sctlr_write_m68k -#define semihosting_enabled semihosting_enabled_m68k #define semihosting_get_target semihosting_get_target_m68k #define semihosting_get_arg semihosting_get_arg_m68k #define semihosting_get_argc semihosting_get_argc_m68k diff --git a/qemu/mips.h b/qemu/mips.h index aa41cca2..d862264e 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_mips #define scr_write scr_write_mips #define sctlr_write sctlr_write_mips -#define semihosting_enabled semihosting_enabled_mips #define semihosting_get_target semihosting_get_target_mips #define semihosting_get_arg semihosting_get_arg_mips #define semihosting_get_argc semihosting_get_argc_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index c222d46b..0b8e3afa 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_mips64 #define scr_write scr_write_mips64 #define sctlr_write sctlr_write_mips64 -#define semihosting_enabled semihosting_enabled_mips64 #define semihosting_get_target semihosting_get_target_mips64 #define semihosting_get_arg semihosting_get_arg_mips64 #define semihosting_get_argc semihosting_get_argc_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 14db43ce..028f1e6d 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_mips64el #define scr_write scr_write_mips64el #define sctlr_write sctlr_write_mips64el -#define semihosting_enabled semihosting_enabled_mips64el #define semihosting_get_target semihosting_get_target_mips64el #define semihosting_get_arg semihosting_get_arg_mips64el #define semihosting_get_argc semihosting_get_argc_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 54508f1d..e7bfcaca 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_mipsel #define scr_write scr_write_mipsel #define sctlr_write sctlr_write_mipsel -#define semihosting_enabled semihosting_enabled_mipsel #define semihosting_get_target semihosting_get_target_mipsel #define semihosting_get_arg semihosting_get_arg_mipsel #define semihosting_get_argc semihosting_get_argc_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index daec1168..3bdbe1c5 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_powerpc #define scr_write scr_write_powerpc #define sctlr_write sctlr_write_powerpc -#define semihosting_enabled semihosting_enabled_powerpc #define semihosting_get_target semihosting_get_target_powerpc #define semihosting_get_arg semihosting_get_arg_powerpc #define semihosting_get_argc semihosting_get_argc_powerpc diff --git a/qemu/sparc.h b/qemu/sparc.h index 1b3dcbdb..5fc27a8e 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_sparc #define scr_write scr_write_sparc #define sctlr_write sctlr_write_sparc -#define semihosting_enabled semihosting_enabled_sparc #define semihosting_get_target semihosting_get_target_sparc #define semihosting_get_arg semihosting_get_arg_sparc #define semihosting_get_argc semihosting_get_argc_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index f334cec4..fba04f6c 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_sparc64 #define scr_write scr_write_sparc64 #define sctlr_write sctlr_write_sparc64 -#define semihosting_enabled semihosting_enabled_sparc64 #define semihosting_get_target semihosting_get_target_sparc64 #define semihosting_get_arg semihosting_get_arg_sparc64 #define semihosting_get_argc semihosting_get_argc_sparc64 diff --git a/qemu/target-arm/cpu.h b/qemu/target-arm/cpu.h index 5d6c23c7..32bfc414 100644 --- a/qemu/target-arm/cpu.h +++ b/qemu/target-arm/cpu.h @@ -58,6 +58,7 @@ #define EXCP_SMC 13 /* Secure Monitor Call */ #define EXCP_VIRQ 14 #define EXCP_VFIQ 15 +#define EXCP_SEMIHOST 16 /* semihosting call (A64 only) */ #define ARMV7M_EXCP_RESET 1 #define ARMV7M_EXCP_NMI 2 diff --git a/qemu/target-arm/helper-a64.c b/qemu/target-arm/helper-a64.c index eecedf90..fc25d215 100644 --- a/qemu/target-arm/helper-a64.c +++ b/qemu/target-arm/helper-a64.c @@ -570,6 +570,13 @@ void aarch64_cpu_do_interrupt(CPUState *cs) case EXCP_VFIQ: addr += 0x100; break; + case EXCP_SEMIHOST: + /* UNICORN: Commented out + 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); } diff --git a/qemu/target-arm/internals.h b/qemu/target-arm/internals.h index 61f77b78..67a4e096 100644 --- a/qemu/target-arm/internals.h +++ b/qemu/target-arm/internals.h @@ -36,6 +36,7 @@ static inline bool excp_is_internal(int excp) || excp == EXCP_HALTED || excp == EXCP_EXCEPTION_EXIT || excp == EXCP_KERNEL_TRAP + || excp == EXCP_SEMIHOST || excp == EXCP_STREX; } @@ -59,6 +60,7 @@ static const char * const excnames[] = { "Secure Monitor Call", "Virtual IRQ", "Virtual FIQ", + "Semihosting call", }; static inline void arm_log_exception(int idx) diff --git a/qemu/target-arm/translate-a64.c b/qemu/target-arm/translate-a64.c index 6b551a28..8b10103a 100644 --- a/qemu/target-arm/translate-a64.c +++ b/qemu/target-arm/translate-a64.c @@ -1584,8 +1584,27 @@ static void disas_exc(DisasContext *s, uint32_t insn) unallocated_encoding(s); break; } - /* HLT */ - unsupported_encoding(s, insn); + /* HLT. This has two purposes. + * Architecturally, it is an external halting debug instruction. + * Since QEMU doesn't implement external debug, we treat this as + * it is required for halting debug disabled: it will UNDEF. + * Secondly, "HLT 0xf000" is the A64 semihosting syscall instruction. + */ + if (semihosting_enabled() && imm16 == 0xf000) { +#ifndef CONFIG_USER_ONLY + /* In system mode, don't allow userspace access to semihosting, + * to provide some semblance of security (and for consistency + * with our 32-bit semihosting). + */ + if (s->current_el == 0) { + unsupported_encoding(s, insn); + break; + } +#endif + gen_exception_internal_insn(s, 0, EXCP_SEMIHOST); + } else { + unsupported_encoding(s, insn); + } break; case 5: if (op2_ll < 1 || op2_ll > 3) { diff --git a/qemu/x86_64.h b/qemu/x86_64.h index cb209727..aaf228f2 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2582,7 +2582,6 @@ #define save_globals save_globals_x86_64 #define scr_write scr_write_x86_64 #define sctlr_write sctlr_write_x86_64 -#define semihosting_enabled semihosting_enabled_x86_64 #define semihosting_get_target semihosting_get_target_x86_64 #define semihosting_get_arg semihosting_get_arg_x86_64 #define semihosting_get_argc semihosting_get_argc_x86_64