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