1 | /* |
2 | * CRIS virtual CPU header |
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 | * 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, see <http://www.gnu.org/licenses/>. |
19 | */ |
20 | |
21 | #ifndef CRIS_CPU_H |
22 | #define CRIS_CPU_H |
23 | |
24 | #include "cpu-qom.h" |
25 | #include "exec/cpu-defs.h" |
26 | |
27 | #define EXCP_NMI 1 |
28 | #define EXCP_GURU 2 |
29 | #define EXCP_BUSFAULT 3 |
30 | #define EXCP_IRQ 4 |
31 | #define EXCP_BREAK 5 |
32 | |
33 | /* CRIS-specific interrupt pending bits. */ |
34 | #define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_3 |
35 | |
36 | /* CRUS CPU device objects interrupt lines. */ |
37 | #define CRIS_CPU_IRQ 0 |
38 | #define CRIS_CPU_NMI 1 |
39 | |
40 | /* Register aliases. R0 - R15 */ |
41 | #define R_FP 8 |
42 | #define R_SP 14 |
43 | #define R_ACR 15 |
44 | |
45 | /* Support regs, P0 - P15 */ |
46 | #define PR_BZ 0 |
47 | #define PR_VR 1 |
48 | #define PR_PID 2 |
49 | #define PR_SRS 3 |
50 | #define PR_WZ 4 |
51 | #define PR_EXS 5 |
52 | #define PR_EDA 6 |
53 | #define PR_PREFIX 6 /* On CRISv10 P6 is reserved, we use it as prefix. */ |
54 | #define PR_MOF 7 |
55 | #define PR_DZ 8 |
56 | #define PR_EBP 9 |
57 | #define PR_ERP 10 |
58 | #define PR_SRP 11 |
59 | #define PR_NRP 12 |
60 | #define PR_CCS 13 |
61 | #define PR_USP 14 |
62 | #define PRV10_BRP 14 |
63 | #define PR_SPC 15 |
64 | |
65 | /* CPU flags. */ |
66 | #define Q_FLAG 0x80000000 |
67 | #define M_FLAG_V32 0x40000000 |
68 | #define PFIX_FLAG 0x800 /* CRISv10 Only. */ |
69 | #define F_FLAG_V10 0x400 |
70 | #define P_FLAG_V10 0x200 |
71 | #define S_FLAG 0x200 |
72 | #define R_FLAG 0x100 |
73 | #define P_FLAG 0x80 |
74 | #define M_FLAG_V10 0x80 |
75 | #define U_FLAG 0x40 |
76 | #define I_FLAG 0x20 |
77 | #define X_FLAG 0x10 |
78 | #define N_FLAG 0x08 |
79 | #define Z_FLAG 0x04 |
80 | #define V_FLAG 0x02 |
81 | #define C_FLAG 0x01 |
82 | #define ALU_FLAGS 0x1F |
83 | |
84 | /* Condition codes. */ |
85 | #define CC_CC 0 |
86 | #define CC_CS 1 |
87 | #define CC_NE 2 |
88 | #define CC_EQ 3 |
89 | #define CC_VC 4 |
90 | #define CC_VS 5 |
91 | #define CC_PL 6 |
92 | #define CC_MI 7 |
93 | #define CC_LS 8 |
94 | #define CC_HI 9 |
95 | #define CC_GE 10 |
96 | #define CC_LT 11 |
97 | #define CC_GT 12 |
98 | #define CC_LE 13 |
99 | #define CC_A 14 |
100 | #define CC_P 15 |
101 | |
102 | typedef struct { |
103 | uint32_t hi; |
104 | uint32_t lo; |
105 | } TLBSet; |
106 | |
107 | typedef struct CPUCRISState { |
108 | uint32_t regs[16]; |
109 | /* P0 - P15 are referred to as special registers in the docs. */ |
110 | uint32_t pregs[16]; |
111 | |
112 | /* Pseudo register for the PC. Not directly accessible on CRIS. */ |
113 | uint32_t pc; |
114 | |
115 | /* Pseudo register for the kernel stack. */ |
116 | uint32_t ksp; |
117 | |
118 | /* Branch. */ |
119 | int dslot; |
120 | int btaken; |
121 | uint32_t btarget; |
122 | |
123 | /* Condition flag tracking. */ |
124 | uint32_t cc_op; |
125 | uint32_t cc_mask; |
126 | uint32_t cc_dest; |
127 | uint32_t cc_src; |
128 | uint32_t cc_result; |
129 | /* size of the operation, 1 = byte, 2 = word, 4 = dword. */ |
130 | int cc_size; |
131 | /* X flag at the time of cc snapshot. */ |
132 | int cc_x; |
133 | |
134 | /* CRIS has certain insns that lockout interrupts. */ |
135 | int locked_irq; |
136 | int interrupt_vector; |
137 | int fault_vector; |
138 | int trap_vector; |
139 | |
140 | /* FIXME: add a check in the translator to avoid writing to support |
141 | register sets beyond the 4th. The ISA allows up to 256! but in |
142 | practice there is no core that implements more than 4. |
143 | |
144 | Support function registers are used to control units close to the |
145 | core. Accesses do not pass down the normal hierarchy. |
146 | */ |
147 | uint32_t sregs[4][16]; |
148 | |
149 | /* Linear feedback shift reg in the mmu. Used to provide pseudo |
150 | randomness for the 'hint' the mmu gives to sw for choosing valid |
151 | sets on TLB refills. */ |
152 | uint32_t mmu_rand_lfsr; |
153 | |
154 | /* |
155 | * We just store the stores to the tlbset here for later evaluation |
156 | * when the hw needs access to them. |
157 | * |
158 | * One for I and another for D. |
159 | */ |
160 | TLBSet tlbsets[2][4][16]; |
161 | |
162 | /* Fields up to this point are cleared by a CPU reset */ |
163 | struct {} end_reset_fields; |
164 | |
165 | /* Members from load_info on are preserved across resets. */ |
166 | void *load_info; |
167 | } CPUCRISState; |
168 | |
169 | /** |
170 | * CRISCPU: |
171 | * @env: #CPUCRISState |
172 | * |
173 | * A CRIS CPU. |
174 | */ |
175 | struct CRISCPU { |
176 | /*< private >*/ |
177 | CPUState parent_obj; |
178 | /*< public >*/ |
179 | |
180 | CPUNegativeOffsetState neg; |
181 | CPUCRISState env; |
182 | }; |
183 | |
184 | |
185 | #ifndef CONFIG_USER_ONLY |
186 | extern const VMStateDescription vmstate_cris_cpu; |
187 | #endif |
188 | |
189 | void cris_cpu_do_interrupt(CPUState *cpu); |
190 | void crisv10_cpu_do_interrupt(CPUState *cpu); |
191 | bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req); |
192 | |
193 | void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags); |
194 | |
195 | hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); |
196 | |
197 | int crisv10_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); |
198 | int cris_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); |
199 | int cris_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); |
200 | |
201 | /* you can call this signal handler from your SIGBUS and SIGSEGV |
202 | signal handlers to inform the virtual CPU of exceptions. non zero |
203 | is returned if the signal was handled by the virtual CPU. */ |
204 | int cpu_cris_signal_handler(int host_signum, void *pinfo, |
205 | void *puc); |
206 | |
207 | void cris_initialize_tcg(void); |
208 | void cris_initialize_crisv10_tcg(void); |
209 | |
210 | /* Instead of computing the condition codes after each CRIS instruction, |
211 | * QEMU just stores one operand (called CC_SRC), the result |
212 | * (called CC_DEST) and the type of operation (called CC_OP). When the |
213 | * condition codes are needed, the condition codes can be calculated |
214 | * using this information. Condition codes are not generated if they |
215 | * are only needed for conditional branches. |
216 | */ |
217 | enum { |
218 | CC_OP_DYNAMIC, /* Use env->cc_op */ |
219 | CC_OP_FLAGS, |
220 | CC_OP_CMP, |
221 | CC_OP_MOVE, |
222 | CC_OP_ADD, |
223 | CC_OP_ADDC, |
224 | CC_OP_MCP, |
225 | CC_OP_ADDU, |
226 | CC_OP_SUB, |
227 | CC_OP_SUBU, |
228 | CC_OP_NEG, |
229 | CC_OP_BTST, |
230 | CC_OP_MULS, |
231 | CC_OP_MULU, |
232 | CC_OP_DSTEP, |
233 | CC_OP_MSTEP, |
234 | CC_OP_BOUND, |
235 | |
236 | CC_OP_OR, |
237 | CC_OP_AND, |
238 | CC_OP_XOR, |
239 | CC_OP_LSL, |
240 | CC_OP_LSR, |
241 | CC_OP_ASR, |
242 | CC_OP_LZ |
243 | }; |
244 | |
245 | /* CRIS uses 8k pages. */ |
246 | #define MMAP_SHIFT TARGET_PAGE_BITS |
247 | |
248 | #define CRIS_CPU_TYPE_SUFFIX "-" TYPE_CRIS_CPU |
249 | #define CRIS_CPU_TYPE_NAME(name) (name CRIS_CPU_TYPE_SUFFIX) |
250 | #define CPU_RESOLVING_TYPE TYPE_CRIS_CPU |
251 | |
252 | #define cpu_signal_handler cpu_cris_signal_handler |
253 | |
254 | /* MMU modes definitions */ |
255 | #define MMU_MODE0_SUFFIX _kernel |
256 | #define MMU_MODE1_SUFFIX _user |
257 | #define MMU_USER_IDX 1 |
258 | static inline int cpu_mmu_index (CPUCRISState *env, bool ifetch) |
259 | { |
260 | return !!(env->pregs[PR_CCS] & U_FLAG); |
261 | } |
262 | |
263 | bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size, |
264 | MMUAccessType access_type, int mmu_idx, |
265 | bool probe, uintptr_t retaddr); |
266 | |
267 | /* Support function regs. */ |
268 | #define SFR_RW_GC_CFG 0][0 |
269 | #define SFR_RW_MM_CFG env->pregs[PR_SRS]][0 |
270 | #define SFR_RW_MM_KBASE_LO env->pregs[PR_SRS]][1 |
271 | #define SFR_RW_MM_KBASE_HI env->pregs[PR_SRS]][2 |
272 | #define SFR_R_MM_CAUSE env->pregs[PR_SRS]][3 |
273 | #define SFR_RW_MM_TLB_SEL env->pregs[PR_SRS]][4 |
274 | #define SFR_RW_MM_TLB_LO env->pregs[PR_SRS]][5 |
275 | #define SFR_RW_MM_TLB_HI env->pregs[PR_SRS]][6 |
276 | |
277 | typedef CPUCRISState CPUArchState; |
278 | typedef CRISCPU ArchCPU; |
279 | |
280 | #include "exec/cpu-all.h" |
281 | |
282 | static inline void cpu_get_tb_cpu_state(CPUCRISState *env, target_ulong *pc, |
283 | target_ulong *cs_base, uint32_t *flags) |
284 | { |
285 | *pc = env->pc; |
286 | *cs_base = 0; |
287 | *flags = env->dslot | |
288 | (env->pregs[PR_CCS] & (S_FLAG | P_FLAG | U_FLAG |
289 | | X_FLAG | PFIX_FLAG)); |
290 | } |
291 | |
292 | #define cpu_list cris_cpu_list |
293 | void cris_cpu_list(void); |
294 | |
295 | #endif |
296 | |