qemu/target/moxie/helper.c
<<
>>
Prefs
   1/*
   2 *  Moxie helper routines.
   3 *
   4 *  Copyright (c) 2008, 2009, 2010, 2013 Anthony Green
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public License
  17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21
  22#include "cpu.h"
  23#include "mmu.h"
  24#include "exec/exec-all.h"
  25#include "exec/cpu_ldst.h"
  26#include "qemu/host-utils.h"
  27#include "exec/helper-proto.h"
  28
  29void helper_raise_exception(CPUMoxieState *env, int ex)
  30{
  31    CPUState *cs = env_cpu(env);
  32
  33    cs->exception_index = ex;
  34    /* Stash the exception type.  */
  35    env->sregs[2] = ex;
  36    /* Stash the address where the exception occurred.  */
  37    cpu_restore_state(cs, GETPC(), true);
  38    env->sregs[5] = env->pc;
  39    /* Jump to the exception handline routine.  */
  40    env->pc = env->sregs[1];
  41    cpu_loop_exit(cs);
  42}
  43
  44uint32_t helper_div(CPUMoxieState *env, uint32_t a, uint32_t b)
  45{
  46    if (unlikely(b == 0)) {
  47        helper_raise_exception(env, MOXIE_EX_DIV0);
  48        return 0;
  49    }
  50    if (unlikely(a == INT_MIN && b == -1)) {
  51        return INT_MIN;
  52    }
  53
  54    return (int32_t)a / (int32_t)b;
  55}
  56
  57uint32_t helper_udiv(CPUMoxieState *env, uint32_t a, uint32_t b)
  58{
  59    if (unlikely(b == 0)) {
  60        helper_raise_exception(env, MOXIE_EX_DIV0);
  61        return 0;
  62    }
  63    return a / b;
  64}
  65
  66void helper_debug(CPUMoxieState *env)
  67{
  68    CPUState *cs = env_cpu(env);
  69
  70    cs->exception_index = EXCP_DEBUG;
  71    cpu_loop_exit(cs);
  72}
  73
  74bool moxie_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  75                        MMUAccessType access_type, int mmu_idx,
  76                        bool probe, uintptr_t retaddr)
  77{
  78    MoxieCPU *cpu = MOXIE_CPU(cs);
  79    CPUMoxieState *env = &cpu->env;
  80    MoxieMMUResult res;
  81    int prot, miss;
  82
  83    address &= TARGET_PAGE_MASK;
  84    prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
  85    miss = moxie_mmu_translate(&res, env, address, access_type, mmu_idx);
  86    if (likely(!miss)) {
  87        tlb_set_page(cs, address, res.phy, prot, mmu_idx, TARGET_PAGE_SIZE);
  88        return true;
  89    }
  90    if (probe) {
  91        return false;
  92    }
  93
  94    cs->exception_index = MOXIE_EX_MMU_MISS;
  95    cpu_loop_exit_restore(cs, retaddr);
  96}
  97
  98void moxie_cpu_do_interrupt(CPUState *cs)
  99{
 100    switch (cs->exception_index) {
 101    case MOXIE_EX_BREAK:
 102        break;
 103    default:
 104        break;
 105    }
 106}
 107
 108hwaddr moxie_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 109{
 110    MoxieCPU *cpu = MOXIE_CPU(cs);
 111    uint32_t phy = addr;
 112    MoxieMMUResult res;
 113    int miss;
 114
 115    miss = moxie_mmu_translate(&res, &cpu->env, addr, 0, 0);
 116    if (!miss) {
 117        phy = res.phy;
 118    }
 119    return phy;
 120}
 121