/*
 *  Moxie helper routines.
 *
 *  Copyright (c) 2008, 2009, 2010, 2013 Anthony Green
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser 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/>.
 */

#include <stdio.h>
#include <string.h>

#include "config.h"
#include "cpu.h"
#include "mmu.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
#include "qemu/host-utils.h"
#include "exec/helper-proto.h"

/* Try to fill the TLB and return an exception if error. If retaddr is
   NULL, it means that the function was called in C code (i.e. not
   from generated code or from helper.c) */
void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
              uintptr_t retaddr)
{
    int ret;

    ret = moxie_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
    if (unlikely(ret)) {
        if (retaddr) {
            cpu_restore_state(cs, retaddr);
        }
    }
    cpu_loop_exit(cs);
}

void helper_raise_exception(CPUMoxieState *env, int ex)
{
    CPUState *cs = CPU(moxie_env_get_cpu(env));

    cs->exception_index = ex;
    /* Stash the exception type.  */
    env->sregs[2] = ex;
    /* Stash the address where the exception occurred.  */
    cpu_restore_state(cs, GETPC());
    env->sregs[5] = env->pc;
    /* Jump to the exception handline routine.  */
    env->pc = env->sregs[1];
    cpu_loop_exit(cs);
}

uint32_t helper_div(CPUMoxieState *env, uint32_t a, uint32_t b)
{
    if (unlikely(b == 0)) {
        helper_raise_exception(env, MOXIE_EX_DIV0);
        return 0;
    }
    if (unlikely(a == INT_MIN && b == -1)) {
        return INT_MIN;
    }

    return (int32_t)a / (int32_t)b;
}

uint32_t helper_udiv(CPUMoxieState *env, uint32_t a, uint32_t b)
{
    if (unlikely(b == 0)) {
        helper_raise_exception(env, MOXIE_EX_DIV0);
        return 0;
    }
    return a / b;
}

void helper_debug(CPUMoxieState *env)
{
    CPUState *cs = CPU(moxie_env_get_cpu(env));

    cs->exception_index = EXCP_DEBUG;
    cpu_loop_exit(cs);
}

#if defined(CONFIG_USER_ONLY)

void moxie_cpu_do_interrupt(CPUState *cs)
{
    CPUState *cs = CPU(moxie_env_get_cpu(env));

    cs->exception_index = -1;
}

int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
                               int rw, int mmu_idx)
{
    MoxieCPU *cpu = MOXIE_CPU(cs);

    cs->exception_index = 0xaa;
    cpu->env.debug1 = address;
    cpu_dump_state(cs, stderr, fprintf, 0);
    return 1;
}

#else /* !CONFIG_USER_ONLY */

int moxie_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
                               int rw, int mmu_idx)
{
    MoxieCPU *cpu = MOXIE_CPU(cs);
    CPUMoxieState *env = &cpu->env;
    MoxieMMUResult res;
    int prot, miss;
    target_ulong phy;
    int r = 1;

    address &= TARGET_PAGE_MASK;
    prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
    miss = moxie_mmu_translate(&res, env, address, rw, mmu_idx);
    if (miss) {
        /* handle the miss.  */
        phy = 0;
        cs->exception_index = MOXIE_EX_MMU_MISS;
    } else {
        phy = res.phy;
        r = 0;
    }
    tlb_set_page(cs, address, phy, prot, mmu_idx, TARGET_PAGE_SIZE);
    return r;
}


void moxie_cpu_do_interrupt(CPUState *cs)
{
    switch (cs->exception_index) {
    case MOXIE_EX_BREAK:
        break;
    default:
        break;
    }
}

hwaddr moxie_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
    MoxieCPU *cpu = MOXIE_CPU(cs);
    uint32_t phy = addr;
    MoxieMMUResult res;
    int miss;

    miss = moxie_mmu_translate(&res, &cpu->env, addr, 0, 0);
    if (!miss) {
        phy = res.phy;
    }
    return phy;
}
#endif
