Re: [PATCH v14 22/26] linux-user: Add LoongArch cpu_loop support

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
---
  configure   |  3 +
  linux-user/loongarch64/cpu_loop.c   | 94 +
  linux-user/loongarch64/target_cpu.h | 34 +++
  3 files changed, 131 insertions(+)
  create mode 100644 linux-user/loongarch64/cpu_loop.c
  create mode 100644 linux-user/loongarch64/target_cpu.h

diff --git a/configure b/configure
index 030728d11e..93c4e5bd92 100755
--- a/configure
+++ b/configure
@@ -659,6 +659,9 @@ case "$cpu" in
mips*)
  cpu="mips" ;;
  
+  loongarch)

+cpu="loongarch64" ;;
+
Do you really need this? Looking at the part above setting initial value 
for $cpu, you can only get here if $cpu is given on command-line, or 
returned by uname on a presumably LoongArch system not defining 
__loongarch64. Either would be unlikely though, and we really don't want 
to turn on 64-bit code for 32-bit hosts (that don't exist at the 
moment), so this case seems useless.

ppc)
  CPU_CFLAGS="-m32" ;;
ppc64)
diff --git a/linux-user/loongarch64/cpu_loop.c 
b/linux-user/loongarch64/cpu_loop.c
new file mode 100644
index 00..6628d215ca
--- /dev/null
+++ b/linux-user/loongarch64/cpu_loop.c
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch user cpu_loop.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "qemu-common.h"
+#include "user-internals.h"
+#include "cpu_loop-common.h"
+#include "signal-common.h"
+
+void cpu_loop(CPULoongArchState *env)
+{
+CPUState *cs = env_cpu(env);
+int trapnr, si_code;
+abi_long ret;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_SYSCALL:
+env->pc += 4;
+ret = do_syscall(env, env->gpr[11],
+ env->gpr[4], env->gpr[5],
+ env->gpr[6], env->gpr[7],
+ env->gpr[8], env->gpr[9],
+ -1, -1);
+if (ret == -QEMU_ERESTARTSYS) {
+env->pc -= 4;
+break;
+}
+if (ret == -QEMU_ESIGRETURN) {
+/*
+ * Returning from a successful sigreturn syscall.
+ * Avoid clobbering register state.
+ */
+break;
+}
+env->gpr[4] = ret;
+break;
+case EXCP_INE:
+force_sig_fault(TARGET_SIGILL, 0, env->pc);
+break;
+case EXCP_FPE:
+si_code = TARGET_FPE_FLTUNK;
+if (GET_FP_CAUSE(env->fcsr0) & FP_INVALID) {
+si_code = TARGET_FPE_FLTINV;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_DIV0) {
+si_code = TARGET_FPE_FLTDIV;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_OVERFLOW) {
+si_code = TARGET_FPE_FLTOVF;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_UNDERFLOW) {
+si_code = TARGET_FPE_FLTUND;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_INEXACT) {
+si_code = TARGET_FPE_FLTRES;
+}
+force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
+break;
+case EXCP_DEBUG:
+case EXCP_BREAK:
+force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
+break;
+case EXCP_ATOMIC:
+cpu_exec_step_atomic(cs);
+break;
+default:
+EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n",
+  trapnr);
+exit(EXIT_FAILURE);
+}
+process_pending_signals(env);
+}
+}
+
+void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
+{
+int i;
+
+for (i = 0; i < 32; i++) {
+env->gpr[i] = regs->regs[i];
+}
+env->pc = regs->csr.era;
+
+}
diff --git a/linux-user/loongarch64/target_cpu.h 
b/linux-user/loongarch64/target_cpu.h
new file mode 100644
index 00..a29af66156
--- /dev/null
+++ b/linux-user/loongarch64/target_cpu.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_CPU_H
+#define LOONGARCH_TARGET_CPU_H
+
+static inline void cpu_clone_regs_child(CPULoongArchState *env,
+target_ulong newsp, unsigned flags)
+{
+if (newsp) {
+env->gpr[3] = newsp;
+}
+env->gpr[4] = 0;
+}
+
+static inline void cpu_clone_regs_parent(CPULoongArchState *env,
+   

[PATCH v14 22/26] linux-user: Add LoongArch cpu_loop support

2022-01-06 Thread Song Gao
Signed-off-by: Song Gao 
Signed-off-by: Xiaojuan Yang 
Reviewed-by: Richard Henderson 
---
 configure   |  3 +
 linux-user/loongarch64/cpu_loop.c   | 94 +
 linux-user/loongarch64/target_cpu.h | 34 +++
 3 files changed, 131 insertions(+)
 create mode 100644 linux-user/loongarch64/cpu_loop.c
 create mode 100644 linux-user/loongarch64/target_cpu.h

diff --git a/configure b/configure
index 030728d11e..93c4e5bd92 100755
--- a/configure
+++ b/configure
@@ -659,6 +659,9 @@ case "$cpu" in
   mips*)
 cpu="mips" ;;
 
+  loongarch)
+cpu="loongarch64" ;;
+
   ppc)
 CPU_CFLAGS="-m32" ;;
   ppc64)
diff --git a/linux-user/loongarch64/cpu_loop.c 
b/linux-user/loongarch64/cpu_loop.c
new file mode 100644
index 00..6628d215ca
--- /dev/null
+++ b/linux-user/loongarch64/cpu_loop.c
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch user cpu_loop.
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "qemu-common.h"
+#include "user-internals.h"
+#include "cpu_loop-common.h"
+#include "signal-common.h"
+
+void cpu_loop(CPULoongArchState *env)
+{
+CPUState *cs = env_cpu(env);
+int trapnr, si_code;
+abi_long ret;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_SYSCALL:
+env->pc += 4;
+ret = do_syscall(env, env->gpr[11],
+ env->gpr[4], env->gpr[5],
+ env->gpr[6], env->gpr[7],
+ env->gpr[8], env->gpr[9],
+ -1, -1);
+if (ret == -QEMU_ERESTARTSYS) {
+env->pc -= 4;
+break;
+}
+if (ret == -QEMU_ESIGRETURN) {
+/*
+ * Returning from a successful sigreturn syscall.
+ * Avoid clobbering register state.
+ */
+break;
+}
+env->gpr[4] = ret;
+break;
+case EXCP_INE:
+force_sig_fault(TARGET_SIGILL, 0, env->pc);
+break;
+case EXCP_FPE:
+si_code = TARGET_FPE_FLTUNK;
+if (GET_FP_CAUSE(env->fcsr0) & FP_INVALID) {
+si_code = TARGET_FPE_FLTINV;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_DIV0) {
+si_code = TARGET_FPE_FLTDIV;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_OVERFLOW) {
+si_code = TARGET_FPE_FLTOVF;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_UNDERFLOW) {
+si_code = TARGET_FPE_FLTUND;
+} else if (GET_FP_CAUSE(env->fcsr0) & FP_INEXACT) {
+si_code = TARGET_FPE_FLTRES;
+}
+force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
+break;
+case EXCP_DEBUG:
+case EXCP_BREAK:
+force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
+break;
+case EXCP_ATOMIC:
+cpu_exec_step_atomic(cs);
+break;
+default:
+EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n",
+  trapnr);
+exit(EXIT_FAILURE);
+}
+process_pending_signals(env);
+}
+}
+
+void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
+{
+int i;
+
+for (i = 0; i < 32; i++) {
+env->gpr[i] = regs->regs[i];
+}
+env->pc = regs->csr.era;
+
+}
diff --git a/linux-user/loongarch64/target_cpu.h 
b/linux-user/loongarch64/target_cpu.h
new file mode 100644
index 00..a29af66156
--- /dev/null
+++ b/linux-user/loongarch64/target_cpu.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_CPU_H
+#define LOONGARCH_TARGET_CPU_H
+
+static inline void cpu_clone_regs_child(CPULoongArchState *env,
+target_ulong newsp, unsigned flags)
+{
+if (newsp) {
+env->gpr[3] = newsp;
+}
+env->gpr[4] = 0;
+}
+
+static inline void cpu_clone_regs_parent(CPULoongArchState *env,
+ unsigned flags)
+{
+}
+
+static inline void cpu_set_tls(CPULoongArchState *env, target_ulong newtls)
+{
+env->gpr[2] = newtls;
+}
+
+static inline abi_ulong get_sp_from_cpustate(CPULoongArchState *state)
+{
+return state->gpr[3];
+}
+#endif
-- 
2.27.0