1fcf5ef2aSThomas Huth /*
2fcf5ef2aSThomas Huth * TriCore emulation for qemu: main CPU struct.
3fcf5ef2aSThomas Huth *
4fcf5ef2aSThomas Huth * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
5fcf5ef2aSThomas Huth *
6fcf5ef2aSThomas Huth * This library is free software; you can redistribute it and/or
7fcf5ef2aSThomas Huth * modify it under the terms of the GNU Lesser General Public
8fcf5ef2aSThomas Huth * License as published by the Free Software Foundation; either
902754acdSThomas Huth * version 2.1 of the License, or (at your option) any later version.
10fcf5ef2aSThomas Huth *
11fcf5ef2aSThomas Huth * This library is distributed in the hope that it will be useful,
12fcf5ef2aSThomas Huth * but WITHOUT ANY WARRANTY; without even the implied warranty of
13fcf5ef2aSThomas Huth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14fcf5ef2aSThomas Huth * Lesser General Public License for more details.
15fcf5ef2aSThomas Huth *
16fcf5ef2aSThomas Huth * You should have received a copy of the GNU Lesser General Public
17fcf5ef2aSThomas Huth * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18fcf5ef2aSThomas Huth */
19fcf5ef2aSThomas Huth
20fcf5ef2aSThomas Huth #ifndef TRICORE_CPU_H
21fcf5ef2aSThomas Huth #define TRICORE_CPU_H
22fcf5ef2aSThomas Huth
23fcf5ef2aSThomas Huth #include "cpu-qom.h"
24343cdf2cSBastian Koppelmann #include "hw/registerfields.h"
25fcf5ef2aSThomas Huth #include "exec/cpu-defs.h"
2669242e7eSMarc-André Lureau #include "qemu/cpu-float.h"
2774433bf0SRichard Henderson #include "tricore-defs.h"
28fcf5ef2aSThomas Huth
291ea4a06aSPhilippe Mathieu-Daudé typedef struct CPUArchState {
30fcf5ef2aSThomas Huth /* GPR Register */
31fcf5ef2aSThomas Huth uint32_t gpr_a[16];
32fcf5ef2aSThomas Huth uint32_t gpr_d[16];
33fcf5ef2aSThomas Huth /* Frequently accessed PSW_USB bits are stored separately for efficiency.
34fcf5ef2aSThomas Huth This contains all the other bits. Use psw_{read,write} to access
35fcf5ef2aSThomas Huth the whole PSW. */
36fcf5ef2aSThomas Huth uint32_t PSW;
37824b2cb3SBastian Koppelmann /* PSW flag cache for faster execution */
38fcf5ef2aSThomas Huth uint32_t PSW_USB_C;
39fcf5ef2aSThomas Huth uint32_t PSW_USB_V; /* Only if bit 31 set, then flag is set */
40fcf5ef2aSThomas Huth uint32_t PSW_USB_SV; /* Only if bit 31 set, then flag is set */
41fcf5ef2aSThomas Huth uint32_t PSW_USB_AV; /* Only if bit 31 set, then flag is set. */
42fcf5ef2aSThomas Huth uint32_t PSW_USB_SAV; /* Only if bit 31 set, then flag is set. */
43fcf5ef2aSThomas Huth
44824b2cb3SBastian Koppelmann #define R(ADDR, NAME, FEATURE) uint32_t NAME;
45824b2cb3SBastian Koppelmann #define A(ADDR, NAME, FEATURE) uint32_t NAME;
46824b2cb3SBastian Koppelmann #define E(ADDR, NAME, FEATURE) uint32_t NAME;
47824b2cb3SBastian Koppelmann #include "csfr.h.inc"
48824b2cb3SBastian Koppelmann #undef R
49824b2cb3SBastian Koppelmann #undef A
50824b2cb3SBastian Koppelmann #undef E
51fcf5ef2aSThomas Huth
52fcf5ef2aSThomas Huth /* Floating Point Registers */
53fcf5ef2aSThomas Huth float_status fp_status;
54fcf5ef2aSThomas Huth
55fcf5ef2aSThomas Huth /* Internal CPU feature flags. */
56fcf5ef2aSThomas Huth uint64_t features;
571ea4a06aSPhilippe Mathieu-Daudé } CPUTriCoreState;
58fcf5ef2aSThomas Huth
59fcf5ef2aSThomas Huth /**
60fcf5ef2aSThomas Huth * TriCoreCPU:
61fcf5ef2aSThomas Huth * @env: #CPUTriCoreState
62fcf5ef2aSThomas Huth *
63fcf5ef2aSThomas Huth * A TriCore CPU.
64fcf5ef2aSThomas Huth */
65b36e239eSPhilippe Mathieu-Daudé struct ArchCPU {
66fcf5ef2aSThomas Huth CPUState parent_obj;
67fcf5ef2aSThomas Huth
68fcf5ef2aSThomas Huth CPUTriCoreState env;
69fcf5ef2aSThomas Huth };
70fcf5ef2aSThomas Huth
719348028eSPhilippe Mathieu-Daudé struct TriCoreCPUClass {
729348028eSPhilippe Mathieu-Daudé CPUClass parent_class;
739348028eSPhilippe Mathieu-Daudé
749348028eSPhilippe Mathieu-Daudé DeviceRealize parent_realize;
759348028eSPhilippe Mathieu-Daudé ResettablePhases parent_phases;
769348028eSPhilippe Mathieu-Daudé };
77fcf5ef2aSThomas Huth
78fcf5ef2aSThomas Huth hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
7990c84c56SMarkus Armbruster void tricore_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
80fcf5ef2aSThomas Huth
81343cdf2cSBastian Koppelmann FIELD(PCXI, PCPN_13, 24, 8)
82343cdf2cSBastian Koppelmann FIELD(PCXI, PCPN_161, 22, 8)
83343cdf2cSBastian Koppelmann FIELD(PCXI, PIE_13, 23, 1)
84343cdf2cSBastian Koppelmann FIELD(PCXI, PIE_161, 21, 1)
85343cdf2cSBastian Koppelmann FIELD(PCXI, UL_13, 22, 1)
86343cdf2cSBastian Koppelmann FIELD(PCXI, UL_161, 20, 1)
87343cdf2cSBastian Koppelmann FIELD(PCXI, PCXS, 16, 4)
88343cdf2cSBastian Koppelmann FIELD(PCXI, PCXO, 0, 16)
89343cdf2cSBastian Koppelmann uint32_t pcxi_get_ul(CPUTriCoreState *env);
90343cdf2cSBastian Koppelmann uint32_t pcxi_get_pie(CPUTriCoreState *env);
91343cdf2cSBastian Koppelmann uint32_t pcxi_get_pcpn(CPUTriCoreState *env);
92343cdf2cSBastian Koppelmann uint32_t pcxi_get_pcxs(CPUTriCoreState *env);
93343cdf2cSBastian Koppelmann uint32_t pcxi_get_pcxo(CPUTriCoreState *env);
94343cdf2cSBastian Koppelmann void pcxi_set_ul(CPUTriCoreState *env, uint32_t val);
95343cdf2cSBastian Koppelmann void pcxi_set_pie(CPUTriCoreState *env, uint32_t val);
96343cdf2cSBastian Koppelmann void pcxi_set_pcpn(CPUTriCoreState *env, uint32_t val);
97fcf5ef2aSThomas Huth
98343cdf2cSBastian Koppelmann FIELD(ICR, IE_161, 15, 1)
99343cdf2cSBastian Koppelmann FIELD(ICR, IE_13, 8, 1)
100343cdf2cSBastian Koppelmann FIELD(ICR, PIPN, 16, 8)
101343cdf2cSBastian Koppelmann FIELD(ICR, CCPN, 0, 8)
102343cdf2cSBastian Koppelmann
103343cdf2cSBastian Koppelmann uint32_t icr_get_ie(CPUTriCoreState *env);
104343cdf2cSBastian Koppelmann uint32_t icr_get_ccpn(CPUTriCoreState *env);
105343cdf2cSBastian Koppelmann
106343cdf2cSBastian Koppelmann void icr_set_ccpn(CPUTriCoreState *env, uint32_t val);
107343cdf2cSBastian Koppelmann void icr_set_ie(CPUTriCoreState *env, uint32_t val);
108fcf5ef2aSThomas Huth
109fcf5ef2aSThomas Huth #define MASK_PSW_USB 0xff000000
110fcf5ef2aSThomas Huth #define MASK_USB_C 0x80000000
111fcf5ef2aSThomas Huth #define MASK_USB_V 0x40000000
112fcf5ef2aSThomas Huth #define MASK_USB_SV 0x20000000
113fcf5ef2aSThomas Huth #define MASK_USB_AV 0x10000000
114fcf5ef2aSThomas Huth #define MASK_USB_SAV 0x08000000
115fcf5ef2aSThomas Huth #define MASK_PSW_PRS 0x00003000
116fcf5ef2aSThomas Huth #define MASK_PSW_IO 0x00000c00
117fcf5ef2aSThomas Huth #define MASK_PSW_IS 0x00000200
118fcf5ef2aSThomas Huth #define MASK_PSW_GW 0x00000100
119fcf5ef2aSThomas Huth #define MASK_PSW_CDE 0x00000080
120fcf5ef2aSThomas Huth #define MASK_PSW_CDC 0x0000007f
121fcf5ef2aSThomas Huth #define MASK_PSW_FPU_RM 0x3000000
122fcf5ef2aSThomas Huth
123fcf5ef2aSThomas Huth #define MASK_SYSCON_PRO_TEN 0x2
124fcf5ef2aSThomas Huth #define MASK_SYSCON_FCD_SF 0x1
125fcf5ef2aSThomas Huth
126fcf5ef2aSThomas Huth #define MASK_CPUID_MOD 0xffff0000
127fcf5ef2aSThomas Huth #define MASK_CPUID_MOD_32B 0x0000ff00
128fcf5ef2aSThomas Huth #define MASK_CPUID_REV 0x000000ff
129fcf5ef2aSThomas Huth
130fcf5ef2aSThomas Huth
131fcf5ef2aSThomas Huth #define MASK_FCX_FCXS 0x000f0000
132fcf5ef2aSThomas Huth #define MASK_FCX_FCXO 0x0000ffff
133fcf5ef2aSThomas Huth
134fcf5ef2aSThomas Huth #define MASK_LCX_LCXS 0x000f0000
135fcf5ef2aSThomas Huth #define MASK_LCX_LCX0 0x0000ffff
136fcf5ef2aSThomas Huth
137fcf5ef2aSThomas Huth #define MASK_DBGSR_DE 0x1
138fcf5ef2aSThomas Huth #define MASK_DBGSR_HALT 0x6
139fcf5ef2aSThomas Huth #define MASK_DBGSR_SUSP 0x10
140fcf5ef2aSThomas Huth #define MASK_DBGSR_PREVSUSP 0x20
141fcf5ef2aSThomas Huth #define MASK_DBGSR_PEVT 0x40
142fcf5ef2aSThomas Huth #define MASK_DBGSR_EVTSRC 0x1f00
143fcf5ef2aSThomas Huth
144878d1b6aSBastian Koppelmann enum tricore_priv_levels {
145878d1b6aSBastian Koppelmann TRICORE_PRIV_UM0 = 0x0, /* user mode-0 flag */
146878d1b6aSBastian Koppelmann TRICORE_PRIV_UM1 = 0x1, /* user mode-1 flag */
147878d1b6aSBastian Koppelmann TRICORE_PRIV_SM = 0x2, /* kernel mode flag */
148878d1b6aSBastian Koppelmann };
149fcf5ef2aSThomas Huth
150fcf5ef2aSThomas Huth enum tricore_features {
151fcf5ef2aSThomas Huth TRICORE_FEATURE_13,
152fcf5ef2aSThomas Huth TRICORE_FEATURE_131,
153fcf5ef2aSThomas Huth TRICORE_FEATURE_16,
154fcf5ef2aSThomas Huth TRICORE_FEATURE_161,
1554d2b2e76SBastian Koppelmann TRICORE_FEATURE_162,
156fcf5ef2aSThomas Huth };
157fcf5ef2aSThomas Huth
tricore_has_feature(CPUTriCoreState * env,int feature)158f8cfdd20SBastian Koppelmann static inline int tricore_has_feature(CPUTriCoreState *env, int feature)
159fcf5ef2aSThomas Huth {
160fcf5ef2aSThomas Huth return (env->features & (1ULL << feature)) != 0;
161fcf5ef2aSThomas Huth }
162fcf5ef2aSThomas Huth
163fcf5ef2aSThomas Huth /* TriCore Traps Classes*/
164fcf5ef2aSThomas Huth enum {
165fcf5ef2aSThomas Huth TRAPC_NONE = -1,
166fcf5ef2aSThomas Huth TRAPC_MMU = 0,
167fcf5ef2aSThomas Huth TRAPC_PROT = 1,
168fcf5ef2aSThomas Huth TRAPC_INSN_ERR = 2,
169fcf5ef2aSThomas Huth TRAPC_CTX_MNG = 3,
170fcf5ef2aSThomas Huth TRAPC_SYSBUS = 4,
171fcf5ef2aSThomas Huth TRAPC_ASSERT = 5,
172fcf5ef2aSThomas Huth TRAPC_SYSCALL = 6,
173fcf5ef2aSThomas Huth TRAPC_NMI = 7,
174fcf5ef2aSThomas Huth TRAPC_IRQ = 8
175fcf5ef2aSThomas Huth };
176fcf5ef2aSThomas Huth
177fcf5ef2aSThomas Huth /* Class 0 TIN */
178fcf5ef2aSThomas Huth enum {
179fcf5ef2aSThomas Huth TIN0_VAF = 0,
180fcf5ef2aSThomas Huth TIN0_VAP = 1,
181fcf5ef2aSThomas Huth };
182fcf5ef2aSThomas Huth
183fcf5ef2aSThomas Huth /* Class 1 TIN */
184fcf5ef2aSThomas Huth enum {
185fcf5ef2aSThomas Huth TIN1_PRIV = 1,
186fcf5ef2aSThomas Huth TIN1_MPR = 2,
187fcf5ef2aSThomas Huth TIN1_MPW = 3,
188fcf5ef2aSThomas Huth TIN1_MPX = 4,
189fcf5ef2aSThomas Huth TIN1_MPP = 5,
190fcf5ef2aSThomas Huth TIN1_MPN = 6,
191fcf5ef2aSThomas Huth TIN1_GRWP = 7,
192fcf5ef2aSThomas Huth };
193fcf5ef2aSThomas Huth
194fcf5ef2aSThomas Huth /* Class 2 TIN */
195fcf5ef2aSThomas Huth enum {
196fcf5ef2aSThomas Huth TIN2_IOPC = 1,
197fcf5ef2aSThomas Huth TIN2_UOPC = 2,
198fcf5ef2aSThomas Huth TIN2_OPD = 3,
199fcf5ef2aSThomas Huth TIN2_ALN = 4,
200fcf5ef2aSThomas Huth TIN2_MEM = 5,
201fcf5ef2aSThomas Huth };
202fcf5ef2aSThomas Huth
203fcf5ef2aSThomas Huth /* Class 3 TIN */
204fcf5ef2aSThomas Huth enum {
205fcf5ef2aSThomas Huth TIN3_FCD = 1,
206fcf5ef2aSThomas Huth TIN3_CDO = 2,
207fcf5ef2aSThomas Huth TIN3_CDU = 3,
208fcf5ef2aSThomas Huth TIN3_FCU = 4,
209fcf5ef2aSThomas Huth TIN3_CSU = 5,
210fcf5ef2aSThomas Huth TIN3_CTYP = 6,
211fcf5ef2aSThomas Huth TIN3_NEST = 7,
212fcf5ef2aSThomas Huth };
213fcf5ef2aSThomas Huth
214fcf5ef2aSThomas Huth /* Class 4 TIN */
215fcf5ef2aSThomas Huth enum {
216fcf5ef2aSThomas Huth TIN4_PSE = 1,
217fcf5ef2aSThomas Huth TIN4_DSE = 2,
218fcf5ef2aSThomas Huth TIN4_DAE = 3,
219fcf5ef2aSThomas Huth TIN4_CAE = 4,
220fcf5ef2aSThomas Huth TIN4_PIE = 5,
221fcf5ef2aSThomas Huth TIN4_DIE = 6,
222fcf5ef2aSThomas Huth };
223fcf5ef2aSThomas Huth
224fcf5ef2aSThomas Huth /* Class 5 TIN */
225fcf5ef2aSThomas Huth enum {
226fcf5ef2aSThomas Huth TIN5_OVF = 1,
227fcf5ef2aSThomas Huth TIN5_SOVF = 1,
228fcf5ef2aSThomas Huth };
229fcf5ef2aSThomas Huth
230fcf5ef2aSThomas Huth /* Class 6 TIN
231fcf5ef2aSThomas Huth *
232fcf5ef2aSThomas Huth * Is always TIN6_SYS
233fcf5ef2aSThomas Huth */
234fcf5ef2aSThomas Huth
235fcf5ef2aSThomas Huth /* Class 7 TIN */
236fcf5ef2aSThomas Huth enum {
237fcf5ef2aSThomas Huth TIN7_NMI = 0,
238fcf5ef2aSThomas Huth };
239fcf5ef2aSThomas Huth
240fcf5ef2aSThomas Huth uint32_t psw_read(CPUTriCoreState *env);
241fcf5ef2aSThomas Huth void psw_write(CPUTriCoreState *env, uint32_t val);
242d127de3bSBastian Koppelmann int tricore_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n);
243d127de3bSBastian Koppelmann int tricore_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
244fcf5ef2aSThomas Huth
245fcf5ef2aSThomas Huth void fpu_set_state(CPUTriCoreState *env);
246fcf5ef2aSThomas Huth
247fcf5ef2aSThomas Huth #define MMU_USER_IDX 2
248fcf5ef2aSThomas Huth
249fcf5ef2aSThomas Huth #include "exec/cpu-all.h"
250fcf5ef2aSThomas Huth
251878d1b6aSBastian Koppelmann FIELD(TB_FLAGS, PRIV, 0, 2)
252878d1b6aSBastian Koppelmann
253fcf5ef2aSThomas Huth void cpu_state_reset(CPUTriCoreState *s);
254fcf5ef2aSThomas Huth void tricore_tcg_init(void);
255fcf5ef2aSThomas Huth
cpu_get_tb_cpu_state(CPUTriCoreState * env,vaddr * pc,uint64_t * cs_base,uint32_t * flags)256bb5de525SAnton Johansson static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, vaddr *pc,
257bb5de525SAnton Johansson uint64_t *cs_base, uint32_t *flags)
258fcf5ef2aSThomas Huth {
259878d1b6aSBastian Koppelmann uint32_t new_flags = 0;
260fcf5ef2aSThomas Huth *pc = env->PC;
261fcf5ef2aSThomas Huth *cs_base = 0;
262878d1b6aSBastian Koppelmann
263878d1b6aSBastian Koppelmann new_flags |= FIELD_DP32(new_flags, TB_FLAGS, PRIV,
264878d1b6aSBastian Koppelmann extract32(env->PSW, 10, 2));
265878d1b6aSBastian Koppelmann *flags = new_flags;
266fcf5ef2aSThomas Huth }
267fcf5ef2aSThomas Huth
2680dacec87SIgor Mammedov #define CPU_RESOLVING_TYPE TYPE_TRICORE_CPU
269fcf5ef2aSThomas Huth
270fcf5ef2aSThomas Huth /* helpers.c */
27168d6eee7SRichard Henderson bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
27268d6eee7SRichard Henderson MMUAccessType access_type, int mmu_idx,
27368d6eee7SRichard Henderson bool probe, uintptr_t retaddr);
274fcf5ef2aSThomas Huth
275fcf5ef2aSThomas Huth #endif /* TRICORE_CPU_H */
276