[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 07/27] target-arm/arm-semi.c: Support widening APIs t
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 07/27] target-arm/arm-semi.c: Support widening APIs to 64 bits |
Date: |
Fri, 4 Sep 2015 16:05:36 +0100 |
The 64-bit A64 semihosting API has some pervasive changes from
the 32-bit version:
* all parameter blocks are arrays of 64-bit values, not 32-bit
* the semihosting call number is passed in W0
* the return value is a 64-bit value in X0
Implement the necessary handling for this widening.
Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Christopher Covington <address@hidden>
Tested-by: Christopher Covington <address@hidden>
Message-id: address@hidden
---
target-arm/arm-semi.c | 69 ++++++++++++++++++++++++++++++++++++++++++---------
target-arm/cpu.h | 2 +-
2 files changed, 58 insertions(+), 13 deletions(-)
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index dbdc211..1d4cc59 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -134,7 +134,7 @@ static void arm_semi_cb(CPUState *cs, target_ulong ret,
target_ulong err)
#ifdef CONFIG_USER_ONLY
TaskState *ts = cs->opaque;
#endif
- target_ulong reg0 = env->regs[0];
+ target_ulong reg0 = is_a64(env) ? env->xregs[0] : env->regs[0];
if (ret == (target_ulong)-1) {
#ifdef CONFIG_USER_ONLY
@@ -158,7 +158,30 @@ static void arm_semi_cb(CPUState *cs, target_ulong ret,
target_ulong err)
break;
}
}
- env->regs[0] = reg0;
+ if (is_a64(env)) {
+ env->xregs[0] = reg0;
+ } else {
+ env->regs[0] = reg0;
+ }
+}
+
+static target_ulong arm_flen_buf(ARMCPU *cpu)
+{
+ /* Return an address in target memory of 64 bytes where the remote
+ * gdb should write its stat struct. (The format of this structure
+ * is defined by GDB's remote protocol and is not target-specific.)
+ * We put this on the guest's stack just below SP.
+ */
+ CPUARMState *env = &cpu->env;
+ target_ulong sp;
+
+ if (is_a64(env)) {
+ sp = env->xregs[31];
+ } else {
+ sp = env->regs[13];
+ }
+
+ return sp - 64;
}
static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
@@ -168,8 +191,13 @@ static void arm_semi_flen_cb(CPUState *cs, target_ulong
ret, target_ulong err)
/* The size is always stored in big-endian order, extract
the value. We assume the size always fit in 32 bits. */
uint32_t size;
- cpu_memory_rw_debug(cs, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
- env->regs[0] = be32_to_cpu(size);
+ cpu_memory_rw_debug(cs, arm_flen_buf(cpu) + 32, (uint8_t *)&size, 4, 0);
+ size = be32_to_cpu(size);
+ if (is_a64(env)) {
+ env->xregs[0] = size;
+ } else {
+ env->regs[0] = size;
+ }
#ifdef CONFIG_USER_ONLY
((TaskState *)cs->opaque)->swi_errno = err;
#else
@@ -193,20 +221,30 @@ static target_ulong arm_gdb_syscall(ARMCPU *cpu,
gdb_syscall_complete_cb cb,
* the callback function.
*/
- return env->regs[0];
+ return is_a64(env) ? env->xregs[0] : env->regs[0];
}
/* Read the input value from the argument block; fail the semihosting
* call if the memory read fails.
*/
#define GET_ARG(n) do { \
- if (get_user_ual(arg ## n, args + (n) * 4)) { \
- return (uint32_t)-1; \
+ if (is_a64(env)) { \
+ if (get_user_u64(arg ## n, args + (n) * 8)) { \
+ return -1; \
+ } \
+ } else { \
+ if (get_user_u32(arg ## n, args + (n) * 4)) { \
+ return -1; \
+ } \
} \
} while (0)
-#define SET_ARG(n, val) put_user_ual(val, args + (n) * 4)
-uint32_t do_arm_semihosting(CPUARMState *env)
+#define SET_ARG(n, val) \
+ (is_a64(env) ? \
+ put_user_u64(val, args + (n) * 8) : \
+ put_user_u32(val, args + (n) * 4))
+
+target_ulong do_arm_semihosting(CPUARMState *env)
{
ARMCPU *cpu = arm_env_get_cpu(env);
CPUState *cs = CPU(cpu);
@@ -222,8 +260,15 @@ uint32_t do_arm_semihosting(CPUARMState *env)
CPUARMState *ts = env;
#endif
- nr = env->regs[0];
- args = env->regs[1];
+ if (is_a64(env)) {
+ /* Note that the syscall number is in W0, not X0 */
+ nr = env->xregs[0] & 0xffffffffU;
+ args = env->xregs[1];
+ } else {
+ nr = env->regs[0];
+ args = env->regs[1];
+ }
+
switch (nr) {
case TARGET_SYS_OPEN:
GET_ARG(0);
@@ -355,7 +400,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
GET_ARG(0);
if (use_gdb_syscalls()) {
return arm_gdb_syscall(cpu, arm_semi_flen_cb, "fstat,%x,%x",
- arg0, env->regs[13]-64);
+ arg0, arm_flen_buf(cpu));
} else {
struct stat buf;
ret = set_swi_errno(ts, fstat(arg0, &buf));
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 31825d3..0a25335 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -504,7 +504,7 @@ typedef struct CPUARMState {
ARMCPU *cpu_arm_init(const char *cpu_model);
int cpu_arm_exec(CPUState *cpu);
-uint32_t do_arm_semihosting(CPUARMState *env);
+target_ulong do_arm_semihosting(CPUARMState *env);
void aarch64_sync_32_to_64(CPUARMState *env);
void aarch64_sync_64_to_32(CPUARMState *env);
--
1.9.1
- [Qemu-devel] [PULL 13/27] arm: cpu: assert() on no-EL2 virt IRQ error condition., (continued)
- [Qemu-devel] [PULL 13/27] arm: cpu: assert() on no-EL2 virt IRQ error condition., Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 09/27] target-arm/arm-semi.c: SYS_EXIT on A64 takes a parameter block, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 16/27] hw/arm/virt: Add high MMIO PCI region, 512G in size, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 21/27] i.MX: Add FEC Ethernet Emulator, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 18/27] i.MX: Add SOC support for i.MX31, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 20/27] i.MX: Add I2C controller emulator, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 02/27] target-arm/arm-semi.c: Fix broken SYS_WRITE0 via gdb, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 12/27] smbios: implement smbios support for mach-virt, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 03/27] target-arm: Improve semihosting debug prints, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 27/27] arm/virt: Add full-sized CPU affinity handling, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 07/27] target-arm/arm-semi.c: Support widening APIs to 64 bits,
Peter Maydell <=
- [Qemu-devel] [PULL 26/27] target-arm: Refactor CPU affinity handling, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 24/27] i.MX: Add qtest support for I2C device emulator., Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 04/27] gdbstub: Implement gdb_do_syscallv(), Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 06/27] include/exec/softmmu-semi.h: Add support for 64-bit values, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 01/27] arm: Use g_new() & friends where that makes obvious sense, Peter Maydell, 2015/09/04
- Re: [Qemu-devel] [PULL 00/27] target-arm queue, Peter Maydell, 2015/09/07
- [Qemu-devel] [PULL 00/27] target-arm queue, Peter Maydell, 2015/09/07