/*
 *  i386 cpu init and loop
 *
 *
 *  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 "qemu32"

static inline void target_cpu_init(CPUX86State *env,
        struct target_pt_regs *regs)
{
    uint64_t *gdt_table;

    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
    env->hflags |= HF_PE_MASK | HF_CPL_MASK;
    if (env->features[FEAT_1_EDX] & CPUID_SSE) {
        env->cr[4] |= CR4_OSFXSR_MASK;
        env->hflags |= HF_OSFXSR_MASK;
    }

    /* flags setup : we activate the IRQs by default as in user mode */
    env->eflags |= IF_MASK;

    /* register setup */
    env->regs[R_EAX] = regs->eax;
    env->regs[R_EBX] = regs->ebx;
    env->regs[R_ECX] = regs->ecx;
    env->regs[R_EDX] = regs->edx;
    env->regs[R_ESI] = regs->esi;
    env->regs[R_EDI] = regs->edi;
    env->regs[R_EBP] = regs->ebp;
    env->regs[R_ESP] = regs->esp;
    env->eip = regs->eip;

    /* interrupt setup */
    env->idt.limit = 255;

    env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
        PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    bsd_i386_set_idt_base(env->idt.base);
    bsd_i386_set_idt(0, 0);
    bsd_i386_set_idt(1, 0);
    bsd_i386_set_idt(2, 0);
    bsd_i386_set_idt(3, 3);
    bsd_i386_set_idt(4, 3);
    bsd_i386_set_idt(5, 0);
    bsd_i386_set_idt(6, 0);
    bsd_i386_set_idt(7, 0);
    bsd_i386_set_idt(8, 0);
    bsd_i386_set_idt(9, 0);
    bsd_i386_set_idt(10, 0);
    bsd_i386_set_idt(11, 0);
    bsd_i386_set_idt(12, 0);
    bsd_i386_set_idt(13, 0);
    bsd_i386_set_idt(14, 0);
    bsd_i386_set_idt(15, 0);
    bsd_i386_set_idt(16, 0);
    bsd_i386_set_idt(17, 0);
    bsd_i386_set_idt(18, 0);
    bsd_i386_set_idt(19, 0);
    bsd_i386_set_idt(0x80, 3);

    /* segment setup */
    env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
            PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
    gdt_table = g2h_untagged(env->gdt.base);

    bsd_i386_write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
            DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
            (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));

    bsd_i386_write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
            DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
            (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));

    cpu_x86_load_seg(env, R_CS, __USER_CS);
    cpu_x86_load_seg(env, R_SS, __USER_DS);
    cpu_x86_load_seg(env, R_DS, __USER_DS);
    cpu_x86_load_seg(env, R_ES, __USER_DS);
    cpu_x86_load_seg(env, R_FS, __USER_DS);
    cpu_x86_load_seg(env, R_GS, __USER_DS);
    /* This hack makes Wine work... */
    env->segs[R_FS].selector = 0;
}

static inline void target_cpu_loop(CPUX86State *env)
{
    CPUState *cs = env_cpu(env);
    int trapnr;
    abi_ulong pc;
    /* target_siginfo_t info; */

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

        switch (trapnr) {
        case 0x80: {
            /* syscall from int $0x80 */
            abi_ulong params = (abi_ulong) env->regs[R_ESP] +
                sizeof(int32_t);
            int32_t syscall_nr = env->regs[R_EAX];
            int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;

            if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
                get_user_s32(syscall_nr, params);
                params += sizeof(int32_t);
            } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
                get_user_s32(syscall_nr, params);
                params += sizeof(int64_t);
            }
            get_user_s32(arg1, params);
            params += sizeof(int32_t);
            get_user_s32(arg2, params);
            params += sizeof(int32_t);
            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);
            params += sizeof(int32_t);
            get_user_s32(arg7, params);
            params += sizeof(int32_t);
            get_user_s32(arg8, params);
            env->regs[R_EAX] = do_freebsd_syscall(env,
                                                  syscall_nr,
                                                  arg1,
                                                  arg2,
                                                  arg3,
                                                  arg4,
                                                  arg5,
                                                  arg6,
                                                  arg7,
                                                  arg8);
            }
            if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
                env->regs[R_EAX] = -env->regs[R_EAX];
                env->eflags |= CC_C;
            } else {
                env->eflags &= ~CC_C;
            }
            break;

        case EXCP_INTERRUPT:
            /* just indicate that signals should be handled asap */
            break;

        case EXCP_ATOMIC:
            cpu_exec_step_atomic(cs);
            break;

        default:
            pc = env->segs[R_CS].base + env->eip;
            fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - "
                    "aborting\n", (long)pc, trapnr);
            abort();
        }
        process_pending_signals(env);
    }
}

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

static inline void target_cpu_reset(CPUArchState *env)
{
    cpu_reset(env_cpu(env));
}

#endif /* TARGET_ARCH_CPU_H */
