qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

cpu_loop.c (2931B)


      1 /* SPDX-License-Identifier: GPL-2.0-or-later */
      2 /*
      3  * QEMU LoongArch user cpu_loop.
      4  *
      5  * Copyright (c) 2021 Loongson Technology Corporation Limited
      6  */
      7 
      8 #include "qemu/osdep.h"
      9 #include "qemu.h"
     10 #include "user-internals.h"
     11 #include "cpu_loop-common.h"
     12 #include "signal-common.h"
     13 
     14 void cpu_loop(CPULoongArchState *env)
     15 {
     16     CPUState *cs = env_cpu(env);
     17     int trapnr, si_code;
     18     abi_long ret;
     19 
     20     for (;;) {
     21         cpu_exec_start(cs);
     22         trapnr = cpu_exec(cs);
     23         cpu_exec_end(cs);
     24         process_queued_cpu_work(cs);
     25 
     26         switch (trapnr) {
     27         case EXCP_INTERRUPT:
     28             /* just indicate that signals should be handled asap */
     29             break;
     30         case EXCCODE_SYS:
     31             env->pc += 4;
     32             ret = do_syscall(env, env->gpr[11],
     33                              env->gpr[4], env->gpr[5],
     34                              env->gpr[6], env->gpr[7],
     35                              env->gpr[8], env->gpr[9],
     36                              -1, -1);
     37             if (ret == -QEMU_ERESTARTSYS) {
     38                 env->pc -= 4;
     39                 break;
     40             }
     41             if (ret == -QEMU_ESIGRETURN) {
     42                 /*
     43                  * Returning from a successful sigreturn syscall.
     44                  * Avoid clobbering register state.
     45                  */
     46                 break;
     47             }
     48             env->gpr[4] = ret;
     49             break;
     50         case EXCCODE_INE:
     51             force_sig_fault(TARGET_SIGILL, 0, env->pc);
     52             break;
     53         case EXCCODE_FPE:
     54             si_code = TARGET_FPE_FLTUNK;
     55             if (GET_FP_CAUSE(env->fcsr0) & FP_INVALID) {
     56                 si_code = TARGET_FPE_FLTINV;
     57             } else if (GET_FP_CAUSE(env->fcsr0) & FP_DIV0) {
     58                 si_code = TARGET_FPE_FLTDIV;
     59             } else if (GET_FP_CAUSE(env->fcsr0) & FP_OVERFLOW) {
     60                 si_code = TARGET_FPE_FLTOVF;
     61             } else if (GET_FP_CAUSE(env->fcsr0) & FP_UNDERFLOW) {
     62                 si_code = TARGET_FPE_FLTUND;
     63             } else if (GET_FP_CAUSE(env->fcsr0) & FP_INEXACT) {
     64                 si_code = TARGET_FPE_FLTRES;
     65             }
     66             force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
     67             break;
     68         case EXCP_DEBUG:
     69         case EXCCODE_BRK:
     70             force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
     71             break;
     72         case EXCCODE_BCE:
     73             force_sig_fault(TARGET_SIGSYS, TARGET_SI_KERNEL, env->pc);
     74             break;
     75         case EXCP_ATOMIC:
     76             cpu_exec_step_atomic(cs);
     77             break;
     78         default:
     79             EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n",
     80                       trapnr);
     81             exit(EXIT_FAILURE);
     82         }
     83         process_pending_signals(env);
     84     }
     85 }
     86 
     87 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
     88 {
     89     int i;
     90 
     91     for (i = 0; i < 32; i++) {
     92         env->gpr[i] = regs->regs[i];
     93     }
     94     env->pc = regs->csr.era;
     95 
     96 }