2
* CRIS helper routines.
4
* Copyright (c) 2007 AXIS Communications AB
5
* Written by Edgar E. Iglesias.
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.
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.
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
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29
#include "host-utils.h"
33
#if defined(CONFIG_USER_ONLY)
35
void do_interrupt (CPUState *env)
37
env->exception_index = -1;
38
env->pregs[PR_ERP] = env->pc;
41
int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
42
int mmu_idx, int is_softmmu)
44
env->exception_index = 0xaa;
45
env->pregs[PR_EDA] = address;
46
cpu_dump_state(env, stderr, fprintf, 0);
50
target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
55
#else /* !CONFIG_USER_ONLY */
58
static void cris_shift_ccs(CPUState *env)
61
/* Apply the ccs shift. */
62
ccs = env->pregs[PR_CCS];
63
ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff;
64
env->pregs[PR_CCS] = ccs;
67
int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
68
int mmu_idx, int is_softmmu)
70
struct cris_mmu_result_t res;
75
D(printf ("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
76
address &= TARGET_PAGE_MASK;
77
miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
80
if (env->exception_index == EXCP_BUSFAULT)
82
"CRIS: Illegal recursive bus fault."
86
env->exception_index = EXCP_BUSFAULT;
87
env->fault_vector = res.bf_vec;
93
* Mask off the cache selection bit. The ETRAX busses do not
96
phy = res.phy & ~0x80000000;
98
r = tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
101
D(fprintf(logfile, "%s returns %d irqreq=%x addr=%x"
102
" phy=%x ismmu=%d vec=%x pc=%x\n",
103
__func__, r, env->interrupt_request,
104
address, res.phy, is_softmmu, res.bf_vec, env->pc));
108
void do_interrupt(CPUState *env)
112
D(fprintf (logfile, "exception index=%d interrupt_req=%d\n",
113
env->exception_index,
114
env->interrupt_request));
116
switch (env->exception_index)
119
/* These exceptions are genereated by the core itself.
120
ERP should point to the insn following the brk. */
121
ex_vec = env->trap_vector;
122
env->pregs[PR_ERP] = env->pc;
126
/* NMI is hardwired to vector zero. */
128
env->pregs[PR_CCS] &= ~M_FLAG;
129
env->pregs[PR_NRP] = env->pc;
133
ex_vec = env->fault_vector;
134
env->pregs[PR_ERP] = env->pc;
138
/* The interrupt controller gives us the vector. */
139
ex_vec = env->interrupt_vector;
140
/* Normal interrupts are taken between
141
TB's. env->pc is valid here. */
142
env->pregs[PR_ERP] = env->pc;
146
/* Fill in the IDX field. */
147
env->pregs[PR_EXS] = (ex_vec & 0xff) << 8;
150
D(fprintf(logfile, "excp isr=%x PC=%x ds=%d SP=%x"
151
" ERP=%x pid=%x ccs=%x cc=%d %x\n",
152
ex_vec, env->pc, env->dslot,
154
env->pregs[PR_ERP], env->pregs[PR_PID],
156
env->cc_op, env->cc_mask));
157
/* We loose the btarget, btaken state here so rexec the
159
env->pregs[PR_ERP] -= env->dslot;
160
/* Exception starts with dslot cleared. */
164
env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
166
if (env->pregs[PR_CCS] & U_FLAG) {
167
/* Swap stack pointers. */
168
env->pregs[PR_USP] = env->regs[R_SP];
169
env->regs[R_SP] = env->ksp;
172
/* Apply the CRIS CCS shift. Clears U if set. */
174
D(fprintf (logfile, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
175
__func__, env->pc, ex_vec,
178
env->pregs[PR_ERP]));
181
target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
184
struct cris_mmu_result_t res;
186
miss = cris_mmu_translate(&res, env, addr, 0, 0);
189
D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));