|
|
1.1 root 1: /*
2: * CRIS helper routines.
3: *
4: * Copyright (c) 2007 AXIS Communications AB
5: * Written by Edgar E. Iglesias.
6: *
7: * This library is free software; you can redistribute it and/or
8: * modify it under the terms of the GNU Lesser General Public
9: * License as published by the Free Software Foundation; either
10: * version 2 of the License, or (at your option) any later version.
11: *
12: * This library is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * Lesser General Public License for more details.
16: *
17: * You should have received a copy of the GNU Lesser General Public
18: * License along with this library; if not, write to the Free Software
1.1.1.2 ! root 19: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
1.1 root 20: */
21:
22: #include <stdio.h>
23: #include <string.h>
24:
25: #include "config.h"
26: #include "cpu.h"
27: #include "mmu.h"
28: #include "exec-all.h"
29: #include "host-utils.h"
30:
1.1.1.2 ! root 31:
! 32: //#define CRIS_HELPER_DEBUG
! 33:
! 34:
! 35: #ifdef CRIS_HELPER_DEBUG
! 36: #define D(x) x
! 37: #define D_LOG(...) qemu_log(__VA__ARGS__)
! 38: #else
! 39: #define D(x)
! 40: #define D_LOG(...) do { } while (0)
! 41: #endif
! 42:
1.1 root 43: #if defined(CONFIG_USER_ONLY)
44:
45: void do_interrupt (CPUState *env)
46: {
1.1.1.2 ! root 47: env->exception_index = -1;
! 48: env->pregs[PR_ERP] = env->pc;
1.1 root 49: }
50:
51: int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
52: int mmu_idx, int is_softmmu)
53: {
1.1.1.2 ! root 54: env->exception_index = 0xaa;
! 55: env->pregs[PR_EDA] = address;
! 56: cpu_dump_state(env, stderr, fprintf, 0);
! 57: return 1;
1.1 root 58: }
59:
60: target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
61: {
1.1.1.2 ! root 62: return addr;
1.1 root 63: }
64:
65: #else /* !CONFIG_USER_ONLY */
66:
1.1.1.2 ! root 67:
! 68: static void cris_shift_ccs(CPUState *env)
! 69: {
! 70: uint32_t ccs;
! 71: /* Apply the ccs shift. */
! 72: ccs = env->pregs[PR_CCS];
! 73: ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff;
! 74: env->pregs[PR_CCS] = ccs;
! 75: }
! 76:
1.1 root 77: int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
78: int mmu_idx, int is_softmmu)
79: {
80: struct cris_mmu_result_t res;
81: int prot, miss;
1.1.1.2 ! root 82: int r = -1;
1.1 root 83: target_ulong phy;
84:
1.1.1.2 ! root 85: D(printf ("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
1.1 root 86: address &= TARGET_PAGE_MASK;
87: miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
88: if (miss)
89: {
1.1.1.2 ! root 90: if (env->exception_index == EXCP_BUSFAULT)
! 91: cpu_abort(env,
! 92: "CRIS: Illegal recursive bus fault."
! 93: "addr=%x rw=%d\n",
! 94: address, rw);
! 95:
! 96: env->exception_index = EXCP_BUSFAULT;
! 97: env->fault_vector = res.bf_vec;
! 98: r = 1;
1.1 root 99: }
100: else
101: {
1.1.1.2 ! root 102: /*
! 103: * Mask off the cache selection bit. The ETRAX busses do not
! 104: * see the top bit.
! 105: */
! 106: phy = res.phy & ~0x80000000;
! 107: prot = res.prot;
! 108: r = tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
1.1 root 109: }
1.1.1.2 ! root 110: if (r > 0)
! 111: D_LOG("%s returns %d irqreq=%x addr=%x"
! 112: " phy=%x ismmu=%d vec=%x pc=%x\n",
! 113: __func__, r, env->interrupt_request,
! 114: address, res.phy, is_softmmu, res.bf_vec, env->pc);
! 115: return r;
1.1 root 116: }
117:
118: void do_interrupt(CPUState *env)
119: {
1.1.1.2 ! root 120: int ex_vec = -1;
1.1 root 121:
1.1.1.2 ! root 122: D_LOG( "exception index=%d interrupt_req=%d\n",
! 123: env->exception_index,
! 124: env->interrupt_request);
1.1 root 125:
126: switch (env->exception_index)
127: {
128: case EXCP_BREAK:
1.1.1.2 ! root 129: /* These exceptions are genereated by the core itself.
! 130: ERP should point to the insn following the brk. */
! 131: ex_vec = env->trap_vector;
! 132: env->pregs[PR_ERP] = env->pc;
! 133: break;
1.1 root 134:
1.1.1.2 ! root 135: case EXCP_NMI:
! 136: /* NMI is hardwired to vector zero. */
! 137: ex_vec = 0;
! 138: env->pregs[PR_CCS] &= ~M_FLAG;
! 139: env->pregs[PR_NRP] = env->pc;
1.1 root 140: break;
1.1.1.2 ! root 141:
! 142: case EXCP_BUSFAULT:
! 143: ex_vec = env->fault_vector;
! 144: env->pregs[PR_ERP] = env->pc;
1.1 root 145: break;
146:
147: default:
1.1.1.2 ! root 148: /* The interrupt controller gives us the vector. */
! 149: ex_vec = env->interrupt_vector;
! 150: /* Normal interrupts are taken between
! 151: TB's. env->pc is valid here. */
! 152: env->pregs[PR_ERP] = env->pc;
! 153: break;
! 154: }
1.1 root 155:
1.1.1.2 ! root 156: /* Fill in the IDX field. */
! 157: env->pregs[PR_EXS] = (ex_vec & 0xff) << 8;
! 158:
! 159: if (env->dslot) {
! 160: D_LOG("excp isr=%x PC=%x ds=%d SP=%x"
! 161: " ERP=%x pid=%x ccs=%x cc=%d %x\n",
! 162: ex_vec, env->pc, env->dslot,
! 163: env->regs[R_SP],
! 164: env->pregs[PR_ERP], env->pregs[PR_PID],
! 165: env->pregs[PR_CCS],
! 166: env->cc_op, env->cc_mask);
! 167: /* We loose the btarget, btaken state here so rexec the
! 168: branch. */
! 169: env->pregs[PR_ERP] -= env->dslot;
! 170: /* Exception starts with dslot cleared. */
! 171: env->dslot = 0;
! 172: }
! 173:
! 174: env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
! 175:
! 176: if (env->pregs[PR_CCS] & U_FLAG) {
! 177: /* Swap stack pointers. */
! 178: env->pregs[PR_USP] = env->regs[R_SP];
! 179: env->regs[R_SP] = env->ksp;
1.1 root 180: }
1.1.1.2 ! root 181:
! 182: /* Apply the CRIS CCS shift. Clears U if set. */
! 183: cris_shift_ccs(env);
! 184: D_LOG("%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
! 185: __func__, env->pc, ex_vec,
! 186: env->pregs[PR_CCS],
! 187: env->pregs[PR_PID],
! 188: env->pregs[PR_ERP]);
1.1 root 189: }
190:
191: target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
192: {
193: uint32_t phy = addr;
194: struct cris_mmu_result_t res;
195: int miss;
196: miss = cris_mmu_translate(&res, env, addr, 0, 0);
197: if (!miss)
198: phy = res.phy;
1.1.1.2 ! root 199: D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
1.1 root 200: return phy;
201: }
202: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.