qemu
109 строк · 3.3 Кб
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
14void cpu_loop(CPULoongArchState *env)15{
16CPUState *cs = env_cpu(env);17int trapnr, si_code;18abi_long ret;19
20for (;;) {21cpu_exec_start(cs);22trapnr = cpu_exec(cs);23cpu_exec_end(cs);24process_queued_cpu_work(cs);25
26switch (trapnr) {27case EXCP_INTERRUPT:28/* just indicate that signals should be handled asap */29break;30case EXCCODE_SYS:31env->pc += 4;32ret = do_syscall(env, env->gpr[11],33env->gpr[4], env->gpr[5],34env->gpr[6], env->gpr[7],35env->gpr[8], env->gpr[9],36-1, -1);37if (ret == -QEMU_ERESTARTSYS) {38env->pc -= 4;39break;40}41if (ret == -QEMU_ESIGRETURN) {42/*43* Returning from a successful sigreturn syscall.
44* Avoid clobbering register state.
45*/
46break;47}48env->gpr[4] = ret;49break;50case EXCCODE_INE:51force_sig_fault(TARGET_SIGILL, 0, env->pc);52break;53case EXCCODE_FPE:54si_code = TARGET_FPE_FLTUNK;55if (GET_FP_CAUSE(env->fcsr0) & FP_INVALID) {56si_code = TARGET_FPE_FLTINV;57} else if (GET_FP_CAUSE(env->fcsr0) & FP_DIV0) {58si_code = TARGET_FPE_FLTDIV;59} else if (GET_FP_CAUSE(env->fcsr0) & FP_OVERFLOW) {60si_code = TARGET_FPE_FLTOVF;61} else if (GET_FP_CAUSE(env->fcsr0) & FP_UNDERFLOW) {62si_code = TARGET_FPE_FLTUND;63} else if (GET_FP_CAUSE(env->fcsr0) & FP_INEXACT) {64si_code = TARGET_FPE_FLTRES;65}66force_sig_fault(TARGET_SIGFPE, si_code, env->pc);67break;68case EXCP_DEBUG:69case EXCCODE_BRK:70force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);71break;72case EXCCODE_BCE:73force_sig_fault(TARGET_SIGSYS, TARGET_SI_KERNEL, env->pc);74break;75
76/*77* Begin with LSX and LASX disabled, then enable on the first trap.
78* In this way we can tell if the unit is in use. This is used to
79* choose the layout of any signal frame.
80*/
81case EXCCODE_SXD:82env->CSR_EUEN |= R_CSR_EUEN_SXE_MASK;83break;84case EXCCODE_ASXD:85env->CSR_EUEN |= R_CSR_EUEN_ASXE_MASK;86break;87
88case EXCP_ATOMIC:89cpu_exec_step_atomic(cs);90break;91default:92EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n",93trapnr);94exit(EXIT_FAILURE);95}96process_pending_signals(env);97}98}
99
100void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)101{
102int i;103
104for (i = 0; i < 32; i++) {105env->gpr[i] = regs->regs[i];106}107env->pc = regs->csr.era;108
109}
110