@@ -2,6 +2,7 @@
* Arm "Angel" semihosting syscalls
*
* Copyright (c) 2005, 2007 CodeSourcery.
+ * Copyright (c) 2019 Linaro
* Written by Paul Brook.
*
* This program is free software; you can redistribute it and/or modify
@@ -16,6 +17,10 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * ARM Semihosting is documented in:
+ * Semihosting for AArch32 and AArch64 Release 2.0
+ * https://static.docs.arm.com/100863/0200/semihosting.pdf
*/
#include "qemu/osdep.h"
@@ -239,6 +244,15 @@ static target_ulong arm_gdb_syscall(ARMCPU *cpu, gdb_syscall_complete_cb cb,
put_user_u64(val, args + (n) * 8) : \
put_user_u32(val, args + (n) * 4))
+/*
+ * Do a semihosting call.
+ *
+ * The specification always says that the "return register" either
+ * returns a specific value or is corrupted, so we don't need to
+ * report to our caller whether we are returning a value or trying to
+ * leave the register unchanged. We use 0xdeadbeef as the return value
+ * when there isn't a defined return value for the call.
+ */
target_ulong do_arm_semihosting(CPUARMState *env)
{
ARMCPU *cpu = arm_env_get_cpu(env);
@@ -509,14 +523,16 @@ target_ulong do_arm_semihosting(CPUARMState *env)
output_size = ts->info->arg_end - ts->info->arg_start;
if (!output_size) {
- /* We special-case the "empty command line" case (argc==0).
- Just provide the terminating 0. */
+ /*
+ * We special-case the "empty command line" case (argc==0).
+ * Just provide the terminating 0.
+ */
output_size = 1;
}
#endif
if (output_size > input_size) {
- /* Not enough space to store command-line arguments. */
+ /* Not enough space to store command-line arguments. */
return -1;
}
@@ -570,8 +586,10 @@ target_ulong do_arm_semihosting(CPUARMState *env)
GET_ARG(0);
#ifdef CONFIG_USER_ONLY
- /* Some C libraries assume the heap immediately follows .bss, so
- allocate it using sbrk. */
+ /*
+ * Some C libraries assume the heap immediately follows .bss, so
+ * allocate it using sbrk.
+ */
if (!ts->heap_limit) {
abi_ulong ret;
@@ -619,7 +637,8 @@ target_ulong do_arm_semihosting(CPUARMState *env)
}
case TARGET_SYS_EXIT:
if (is_a64(env)) {
- /* The A64 version of this call takes a parameter block,
+ /*
+ * The A64 version of this call takes a parameter block,
* so the application-exit type can return a subcode which
* is the exit status code from the application.
*/
@@ -632,14 +651,17 @@ target_ulong do_arm_semihosting(CPUARMState *env)
ret = 1;
}
} else {
- /* ARM specifies only Stopped_ApplicationExit as normal
- * exit, everything else is considered an error */
+ /*
+ * ARM specifies only Stopped_ApplicationExit as normal
+ * exit, everything else is considered an error
+ */
ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1;
}
gdb_exit(env, ret);
exit(ret);
case TARGET_SYS_SYNCCACHE:
- /* Clean the D-cache and invalidate the I-cache for the specified
+ /*
+ * Clean the D-cache and invalidate the I-cache for the specified
* virtual address range. This is a nop for us since we don't
* implement caches. This is only present on A64.
*/