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