/*
 *  RISC-V CPU init and loop
 *
 *  Copyright (c) 2019 Mark Corbin
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#ifndef TARGET_ARCH_CPU_H
#define TARGET_ARCH_CPU_H

#include "target_arch.h"
#include "signal-common.h"

#define TARGET_DEFAULT_CPU_MODEL "max"

static inline void target_cpu_init(CPURISCVState *env,
        struct target_pt_regs *regs)
{
    int i;

    for (i = 1; i < 32; i++) {
        env->gpr[i] = regs->regs[i];
    }

    env->pc = regs->sepc;
}

static inline void target_cpu_loop(CPURISCVState *env)
{
    CPUState *cs = env_cpu(env);
    int trapnr;
    abi_long ret;
    unsigned int syscall_num;
    int32_t signo, code;

    for (;;) {
        cpu_exec_start(cs);
        trapnr = cpu_exec(cs);
        cpu_exec_end(cs);
        process_queued_cpu_work(cs);

        signo = 0;

        switch (trapnr) {
        case EXCP_INTERRUPT:
            /* just indicate that signals should be handled asap */
            break;
        case EXCP_ATOMIC:
            cpu_exec_step_atomic(cs);
            break;
        case RISCV_EXCP_U_ECALL:
            syscall_num = env->gpr[xT0];
            env->pc += TARGET_INSN_SIZE;
            /* Compare to cpu_fetch_syscall_args() in riscv/riscv/trap.c */
            if (TARGET_FREEBSD_NR___syscall == syscall_num ||
                TARGET_FREEBSD_NR_syscall == syscall_num) {
                ret = do_freebsd_syscall(env,
                                         env->gpr[xA0],
                                         env->gpr[xA1],
                                         env->gpr[xA2],
                                         env->gpr[xA3],
                                         env->gpr[xA4],
                                         env->gpr[xA5],
                                         env->gpr[xA6],
                                         env->gpr[xA7],
                                         0);
            } else {
                ret = do_freebsd_syscall(env,
                                         syscall_num,
                                         env->gpr[xA0],
                                         env->gpr[xA1],
                                         env->gpr[xA2],
                                         env->gpr[xA3],
                                         env->gpr[xA4],
                                         env->gpr[xA5],
                                         env->gpr[xA6],
                                         env->gpr[xA7]
                    );
            }

            /*
             * Compare to cpu_set_syscall_retval() in
             * riscv/riscv/vm_machdep.c
             */
            if (ret >= 0) {
                env->gpr[xA0] = ret;
                env->gpr[xT0] = 0;
            } else if (ret == -TARGET_ERESTART) {
                env->pc -= TARGET_INSN_SIZE;
            } else if (ret != -TARGET_EJUSTRETURN) {
                env->gpr[xA0] = -ret;
                env->gpr[xT0] = 1;
            }
            break;
        case RISCV_EXCP_ILLEGAL_INST:
            signo = TARGET_SIGILL;
            code = TARGET_ILL_ILLOPC;
            break;
        case RISCV_EXCP_BREAKPOINT:
            signo = TARGET_SIGTRAP;
            code = TARGET_TRAP_BRKPT;
            break;
        case EXCP_DEBUG:
            signo = TARGET_SIGTRAP;
            code = TARGET_TRAP_BRKPT;
            break;
        default:
            fprintf(stderr, "qemu: unhandled CPU exception "
                "0x%x - aborting\n", trapnr);
            cpu_dump_state(cs, stderr, 0);
            abort();
        }

        if (signo) {
            force_sig_fault(signo, code, env->pc);
        }

        process_pending_signals(env);
    }
}

static inline void target_cpu_clone_regs(CPURISCVState *env, target_ulong newsp)
{
    if (newsp) {
        env->gpr[xSP] = newsp;
    }

    env->gpr[xA0] = 0;
    env->gpr[xT0] = 0;
}

static inline void target_cpu_reset(CPUArchState *env)
{
}

#endif /* TARGET_ARCH_CPU_H */
