1 /*
2 * TriCore emulation for qemu: main CPU struct.
3 *
4 * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
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
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef TRICORE_CPU_H
21 #define TRICORE_CPU_H
22
23 #include "cpu-qom.h"
24 #include "hw/registerfields.h"
25 #include "exec/cpu-defs.h"
26 #include "qemu/cpu-float.h"
27 #include "tricore-defs.h"
28
29 #ifdef CONFIG_USER_ONLY
30 #error "TriCore does not support user mode emulation"
31 #endif
32
33 typedef struct CPUArchState {
34 /* GPR Register */
35 uint32_t gpr_a[16];
36 uint32_t gpr_d[16];
37 /* Frequently accessed PSW_USB bits are stored separately for efficiency.
38 This contains all the other bits. Use psw_{read,write} to access
39 the whole PSW. */
40 uint32_t PSW;
41 /* PSW flag cache for faster execution */
42 uint32_t PSW_USB_C;
43 uint32_t PSW_USB_V; /* Only if bit 31 set, then flag is set */
44 uint32_t PSW_USB_SV; /* Only if bit 31 set, then flag is set */
45 uint32_t PSW_USB_AV; /* Only if bit 31 set, then flag is set. */
46 uint32_t PSW_USB_SAV; /* Only if bit 31 set, then flag is set. */
47
48 #define R(ADDR, NAME, FEATURE) uint32_t NAME;
49 #define A(ADDR, NAME, FEATURE) uint32_t NAME;
50 #define E(ADDR, NAME, FEATURE) uint32_t NAME;
51 #include "csfr.h.inc"
52 #undef R
53 #undef A
54 #undef E
55
56 /* Floating Point Registers */
57 float_status fp_status;
58
59 /* Internal CPU feature flags. */
60 uint64_t features;
61 } CPUTriCoreState;
62
63 /**
64 * TriCoreCPU:
65 * @env: #CPUTriCoreState
66 *
67 * A TriCore CPU.
68 */
69 struct ArchCPU {
70 CPUState parent_obj;
71
72 CPUTriCoreState env;
73 };
74
75 struct TriCoreCPUClass {
76 CPUClass parent_class;
77
78 DeviceRealize parent_realize;
79 ResettablePhases parent_phases;
80 };
81
82 hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
83 void tricore_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
84
85 FIELD(PCXI, PCPN_13, 24, 8)
86 FIELD(PCXI, PCPN_161, 22, 8)
87 FIELD(PCXI, PIE_13, 23, 1)
88 FIELD(PCXI, PIE_161, 21, 1)
89 FIELD(PCXI, UL_13, 22, 1)
90 FIELD(PCXI, UL_161, 20, 1)
91 FIELD(PCXI, PCXS, 16, 4)
92 FIELD(PCXI, PCXO, 0, 16)
93 uint32_t pcxi_get_ul(CPUTriCoreState *env);
94 uint32_t pcxi_get_pie(CPUTriCoreState *env);
95 uint32_t pcxi_get_pcpn(CPUTriCoreState *env);
96 uint32_t pcxi_get_pcxs(CPUTriCoreState *env);
97 uint32_t pcxi_get_pcxo(CPUTriCoreState *env);
98 void pcxi_set_ul(CPUTriCoreState *env, uint32_t val);
99 void pcxi_set_pie(CPUTriCoreState *env, uint32_t val);
100 void pcxi_set_pcpn(CPUTriCoreState *env, uint32_t val);
101
102 FIELD(ICR, IE_161, 15, 1)
103 FIELD(ICR, IE_13, 8, 1)
104 FIELD(ICR, PIPN, 16, 8)
105 FIELD(ICR, CCPN, 0, 8)
106
107 uint32_t icr_get_ie(CPUTriCoreState *env);
108 uint32_t icr_get_ccpn(CPUTriCoreState *env);
109
110 void icr_set_ccpn(CPUTriCoreState *env, uint32_t val);
111 void icr_set_ie(CPUTriCoreState *env, uint32_t val);
112
113 #define MASK_PSW_USB 0xff000000
114 #define MASK_USB_C 0x80000000
115 #define MASK_USB_V 0x40000000
116 #define MASK_USB_SV 0x20000000
117 #define MASK_USB_AV 0x10000000
118 #define MASK_USB_SAV 0x08000000
119 #define MASK_PSW_PRS 0x00003000
120 #define MASK_PSW_IO 0x00000c00
121 #define MASK_PSW_IS 0x00000200
122 #define MASK_PSW_GW 0x00000100
123 #define MASK_PSW_CDE 0x00000080
124 #define MASK_PSW_CDC 0x0000007f
125 #define MASK_PSW_FPU_RM 0x3000000
126
127 #define MASK_SYSCON_PRO_TEN 0x2
128 #define MASK_SYSCON_FCD_SF 0x1
129
130 #define MASK_CPUID_MOD 0xffff0000
131 #define MASK_CPUID_MOD_32B 0x0000ff00
132 #define MASK_CPUID_REV 0x000000ff
133
134
135 #define MASK_FCX_FCXS 0x000f0000
136 #define MASK_FCX_FCXO 0x0000ffff
137
138 #define MASK_LCX_LCXS 0x000f0000
139 #define MASK_LCX_LCX0 0x0000ffff
140
141 #define MASK_DBGSR_DE 0x1
142 #define MASK_DBGSR_HALT 0x6
143 #define MASK_DBGSR_SUSP 0x10
144 #define MASK_DBGSR_PREVSUSP 0x20
145 #define MASK_DBGSR_PEVT 0x40
146 #define MASK_DBGSR_EVTSRC 0x1f00
147
148 enum tricore_priv_levels {
149 TRICORE_PRIV_UM0 = 0x0, /* user mode-0 flag */
150 TRICORE_PRIV_UM1 = 0x1, /* user mode-1 flag */
151 TRICORE_PRIV_SM = 0x2, /* kernel mode flag */
152 };
153
154 enum tricore_features {
155 TRICORE_FEATURE_13,
156 TRICORE_FEATURE_131,
157 TRICORE_FEATURE_16,
158 TRICORE_FEATURE_161,
159 TRICORE_FEATURE_162,
160 };
161
tricore_has_feature(CPUTriCoreState * env,int feature)162 static inline int tricore_has_feature(CPUTriCoreState *env, int feature)
163 {
164 return (env->features & (1ULL << feature)) != 0;
165 }
166
167 /* TriCore Traps Classes*/
168 enum {
169 TRAPC_NONE = -1,
170 TRAPC_MMU = 0,
171 TRAPC_PROT = 1,
172 TRAPC_INSN_ERR = 2,
173 TRAPC_CTX_MNG = 3,
174 TRAPC_SYSBUS = 4,
175 TRAPC_ASSERT = 5,
176 TRAPC_SYSCALL = 6,
177 TRAPC_NMI = 7,
178 TRAPC_IRQ = 8
179 };
180
181 /* Class 0 TIN */
182 enum {
183 TIN0_VAF = 0,
184 TIN0_VAP = 1,
185 };
186
187 /* Class 1 TIN */
188 enum {
189 TIN1_PRIV = 1,
190 TIN1_MPR = 2,
191 TIN1_MPW = 3,
192 TIN1_MPX = 4,
193 TIN1_MPP = 5,
194 TIN1_MPN = 6,
195 TIN1_GRWP = 7,
196 };
197
198 /* Class 2 TIN */
199 enum {
200 TIN2_IOPC = 1,
201 TIN2_UOPC = 2,
202 TIN2_OPD = 3,
203 TIN2_ALN = 4,
204 TIN2_MEM = 5,
205 };
206
207 /* Class 3 TIN */
208 enum {
209 TIN3_FCD = 1,
210 TIN3_CDO = 2,
211 TIN3_CDU = 3,
212 TIN3_FCU = 4,
213 TIN3_CSU = 5,
214 TIN3_CTYP = 6,
215 TIN3_NEST = 7,
216 };
217
218 /* Class 4 TIN */
219 enum {
220 TIN4_PSE = 1,
221 TIN4_DSE = 2,
222 TIN4_DAE = 3,
223 TIN4_CAE = 4,
224 TIN4_PIE = 5,
225 TIN4_DIE = 6,
226 };
227
228 /* Class 5 TIN */
229 enum {
230 TIN5_OVF = 1,
231 TIN5_SOVF = 1,
232 };
233
234 /* Class 6 TIN
235 *
236 * Is always TIN6_SYS
237 */
238
239 /* Class 7 TIN */
240 enum {
241 TIN7_NMI = 0,
242 };
243
244 uint32_t psw_read(CPUTriCoreState *env);
245 void psw_write(CPUTriCoreState *env, uint32_t val);
246 int tricore_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n);
247 int tricore_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
248
249 void fpu_set_state(CPUTriCoreState *env);
250
251 #define MMU_USER_IDX 2
252
253 #include "exec/cpu-all.h"
254
255 FIELD(TB_FLAGS, PRIV, 0, 2)
256
257 void cpu_state_reset(CPUTriCoreState *s);
258 void tricore_tcg_init(void);
259 void tricore_translate_code(CPUState *cs, TranslationBlock *tb,
260 int *max_insns, vaddr pc, void *host_pc);
261
cpu_get_tb_cpu_state(CPUTriCoreState * env,vaddr * pc,uint64_t * cs_base,uint32_t * flags)262 static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, vaddr *pc,
263 uint64_t *cs_base, uint32_t *flags)
264 {
265 uint32_t new_flags = 0;
266 *pc = env->PC;
267 *cs_base = 0;
268
269 new_flags |= FIELD_DP32(new_flags, TB_FLAGS, PRIV,
270 extract32(env->PSW, 10, 2));
271 *flags = new_flags;
272 }
273
274 #define CPU_RESOLVING_TYPE TYPE_TRICORE_CPU
275
276 /* helpers.c */
277 bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
278 MMUAccessType access_type, int mmu_idx,
279 bool probe, uintptr_t retaddr);
280
281 #endif /* TRICORE_CPU_H */
282