/*
 *  arm cpu init and loop
 *
 *  Copyright (c) 2013 Stacey D. Son
 *
 *  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 "any"

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

    cpsr_write(env, regs->uregs[16], CPSR_USER | CPSR_EXEC,
               CPSRWriteByInstr);
    for (i = 0; i < 16; i++) {
        env->regs[i] = regs->uregs[i];
    }
}

static inline void target_cpu_loop(CPUARMState *env)
{
    int trapnr, si_signo, si_code;
    unsigned int n;
    CPUState *cs = env_cpu(env);

    for (;;) {
        cpu_exec_start(cs);
        trapnr = cpu_exec(cs);
        cpu_exec_end(cs);
        process_queued_cpu_work(cs);
        switch (trapnr) {
        case EXCP_UDEF:
        case EXCP_NOCP:
        case EXCP_INVSTATE:
            /*
             * See arm/arm/undefined.c undefinedinstruction();
             *
             * A number of details aren't emulated (they likely don't matter):
             * o Misaligned PC generates ILL_ILLADR (these can't come from qemu)
             * o Thumb-2 instructions generate ILLADR
             * o Both modes implement coprocessor instructions, which we don't
             *   do here. FreeBSD just implements them for the VFP coprocessor
             *   and special kernel breakpoints, trace points, dtrace, etc.
             */
            force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC, env->regs[15]);
            break;
        case EXCP_SWI:
            {
                n = env->regs[7];
                if (bsd_type == target_freebsd) {
                    int ret;
                    abi_ulong params = get_sp_from_cpustate(env);
                    int32_t syscall_nr = n;
                    int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;

                    /* See arm/arm/syscall.c cpu_fetch_syscall_args() */
                    if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
                        syscall_nr = env->regs[0];
                        arg1 = env->regs[1];
                        arg2 = env->regs[2];
                        arg3 = env->regs[3];
                        get_user_s32(arg4, params);
                        params += sizeof(int32_t);
                        get_user_s32(arg5, params);
                        params += sizeof(int32_t);
                        get_user_s32(arg6, params);
                        params += sizeof(int32_t);
                        get_user_s32(arg7, params);
                        arg8 = 0;
                    } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
                        syscall_nr = env->regs[0];
                        arg1 = env->regs[2];
                        arg2 = env->regs[3];
                        get_user_s32(arg3, params);
                        params += sizeof(int32_t);
                        get_user_s32(arg4, params);
                        params += sizeof(int32_t);
                        get_user_s32(arg5, params);
                        params += sizeof(int32_t);
                        get_user_s32(arg6, params);
                        arg7 = 0;
                        arg8 = 0;
                    } else {
                        arg1 = env->regs[0];
                        arg2 = env->regs[1];
                        arg3 = env->regs[2];
                        arg4 = env->regs[3];
                        get_user_s32(arg5, params);
                        params += sizeof(int32_t);
                        get_user_s32(arg6, params);
                        params += sizeof(int32_t);
                        get_user_s32(arg7, params);
                        params += sizeof(int32_t);
                        get_user_s32(arg8, params);
                    }
                    ret = do_freebsd_syscall(env, syscall_nr, arg1, arg2, arg3,
                            arg4, arg5, arg6, arg7, arg8);
                    /*
                     * Compare to arm/arm/vm_machdep.c
                     * cpu_set_syscall_retval()
                     */
                    if (-TARGET_EJUSTRETURN == ret) {
                        /*
                         * Returning from a successful sigreturn syscall.
                         * Avoid clobbering register state.
                         */
                        break;
                    }
                    if (-TARGET_ERESTART == ret) {
                        env->regs[15] -= env->thumb ? 2 : 4;
                        break;
                    }
                    if ((unsigned int)ret >= (unsigned int)(-515)) {
                        ret = -ret;
                        cpsr_write(env, CPSR_C, CPSR_C, CPSRWriteByInstr);
                        env->regs[0] = ret;
                    } else {
                        cpsr_write(env, 0, CPSR_C, CPSRWriteByInstr);
                        env->regs[0] = ret; /* XXX need to handle lseek()? */
                        /* env->regs[1] = 0; */
                    }
                } else {
                    fprintf(stderr, "qemu: bsd_type (= %d) syscall "
                            "not supported\n", bsd_type);
                }
            }
            break;
        case EXCP_INTERRUPT:
            /* just indicate that signals should be handled asap */
            break;
        case EXCP_PREFETCH_ABORT:
        case EXCP_DATA_ABORT:
            /*
             * See arm/arm/trap-v6.c prefetch_abort_handler() and
             * data_abort_handler()
             *
             * However, FreeBSD maps these to a generic value and then uses that
             * to maybe fault in pages in vm/vm_fault.c:vm_fault_trap(). I
             * believe that the indirection maps the same as Linux, but haven't
             * chased down every single possible indirection.
             */

            /* For user-only we don't set TTBCR_EAE, so look at the FSR. */
            switch (env->exception.fsr & 0x1f) {
            case 0x1: /* Alignment */
                si_signo = TARGET_SIGBUS;
                si_code = TARGET_BUS_ADRALN;
                break;
            case 0x3: /* Access flag fault, level 1 */
            case 0x6: /* Access flag fault, level 2 */
            case 0x9: /* Domain fault, level 1 */
            case 0xb: /* Domain fault, level 2 */
            case 0xd: /* Permission fault, level 1 */
            case 0xf: /* Permission fault, level 2 */
                si_signo = TARGET_SIGSEGV;
                si_code = TARGET_SEGV_ACCERR;
                break;
            case 0x5: /* Translation fault, level 1 */
            case 0x7: /* Translation fault, level 2 */
                si_signo = TARGET_SIGSEGV;
                si_code = TARGET_SEGV_MAPERR;
                break;
            default:
                g_assert_not_reached();
            }
            force_sig_fault(si_signo, si_code, env->exception.vaddress);
            break;
        case EXCP_DEBUG:
        case EXCP_BKPT:
            force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->regs[15]);
            break;
        case EXCP_YIELD:
            /* nothing to do here for user-mode, just resume guest code */
            break;
        case EXCP_ATOMIC:
            cpu_exec_step_atomic(cs);
            break;
        default:
            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                    trapnr);
            cpu_dump_state(cs, stderr, 0);
            abort();
        } /* switch() */
        process_pending_signals(env);
    } /* for (;;) */
}

static inline void target_cpu_clone_regs(CPUARMState *env, target_ulong newsp)
{
    if (newsp) {
        env->regs[13] = newsp;
    }
    env->regs[0] = 0;
}

static inline void target_cpu_reset(CPUArchState *env)
{
}

#endif /* !_TARGET_ARCH_CPU_H */
