148e06fe0SBastian Koppelmann /* 248e06fe0SBastian Koppelmann * TriCore emulation for qemu: main CPU struct. 348e06fe0SBastian Koppelmann * 448e06fe0SBastian Koppelmann * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn 548e06fe0SBastian Koppelmann * 648e06fe0SBastian Koppelmann * This library is free software; you can redistribute it and/or 748e06fe0SBastian Koppelmann * modify it under the terms of the GNU Lesser General Public 848e06fe0SBastian Koppelmann * License as published by the Free Software Foundation; either 902754acdSThomas Huth * version 2.1 of the License, or (at your option) any later version. 1048e06fe0SBastian Koppelmann * 1148e06fe0SBastian Koppelmann * This library is distributed in the hope that it will be useful, 1248e06fe0SBastian Koppelmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 1348e06fe0SBastian Koppelmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1448e06fe0SBastian Koppelmann * Lesser General Public License for more details. 1548e06fe0SBastian Koppelmann * 1648e06fe0SBastian Koppelmann * You should have received a copy of the GNU Lesser General Public 1748e06fe0SBastian Koppelmann * License along with this library; if not, see <http://www.gnu.org/licenses/>. 1848e06fe0SBastian Koppelmann */ 1907f5a258SMarkus Armbruster 2007f5a258SMarkus Armbruster #ifndef TRICORE_CPU_H 2107f5a258SMarkus Armbruster #define TRICORE_CPU_H 2248e06fe0SBastian Koppelmann 23fc111b10SPaolo Bonzini #include "cpu-qom.h" 24343cdf2cSBastian Koppelmann #include "hw/registerfields.h" 2548e06fe0SBastian Koppelmann #include "exec/cpu-defs.h" 2669242e7eSMarc-André Lureau #include "qemu/cpu-float.h" 2774433bf0SRichard Henderson #include "tricore-defs.h" 2848e06fe0SBastian Koppelmann 291ea4a06aSPhilippe Mathieu-Daudé typedef struct CPUArchState { 3048e06fe0SBastian Koppelmann /* GPR Register */ 3148e06fe0SBastian Koppelmann uint32_t gpr_a[16]; 3248e06fe0SBastian Koppelmann uint32_t gpr_d[16]; 3348e06fe0SBastian Koppelmann /* Frequently accessed PSW_USB bits are stored separately for efficiency. 3448e06fe0SBastian Koppelmann This contains all the other bits. Use psw_{read,write} to access 3548e06fe0SBastian Koppelmann the whole PSW. */ 3648e06fe0SBastian Koppelmann uint32_t PSW; 37824b2cb3SBastian Koppelmann /* PSW flag cache for faster execution */ 3848e06fe0SBastian Koppelmann uint32_t PSW_USB_C; 3948e06fe0SBastian Koppelmann uint32_t PSW_USB_V; /* Only if bit 31 set, then flag is set */ 4048e06fe0SBastian Koppelmann uint32_t PSW_USB_SV; /* Only if bit 31 set, then flag is set */ 4148e06fe0SBastian Koppelmann uint32_t PSW_USB_AV; /* Only if bit 31 set, then flag is set. */ 4248e06fe0SBastian Koppelmann uint32_t PSW_USB_SAV; /* Only if bit 31 set, then flag is set. */ 4348e06fe0SBastian Koppelmann 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 5148e06fe0SBastian Koppelmann 5248e06fe0SBastian Koppelmann /* Floating Point Registers */ 53996a729fSBastian Koppelmann float_status fp_status; 5448e06fe0SBastian Koppelmann 5548e06fe0SBastian Koppelmann /* Internal CPU feature flags. */ 5648e06fe0SBastian Koppelmann uint64_t features; 571ea4a06aSPhilippe Mathieu-Daudé } CPUTriCoreState; 5848e06fe0SBastian Koppelmann 59fc111b10SPaolo Bonzini /** 60fc111b10SPaolo Bonzini * TriCoreCPU: 61fc111b10SPaolo Bonzini * @env: #CPUTriCoreState 62fc111b10SPaolo Bonzini * 63fc111b10SPaolo Bonzini * A TriCore CPU. 64fc111b10SPaolo Bonzini */ 65b36e239eSPhilippe Mathieu-Daudé struct ArchCPU { 66fc111b10SPaolo Bonzini CPUState parent_obj; 67fc111b10SPaolo Bonzini 68fc111b10SPaolo Bonzini CPUTriCoreState env; 69fc111b10SPaolo Bonzini }; 70fc111b10SPaolo Bonzini 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é }; 77fc111b10SPaolo Bonzini 78fc111b10SPaolo Bonzini hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); 7990c84c56SMarkus Armbruster void tricore_cpu_dump_state(CPUState *cpu, FILE *f, int flags); 80fc111b10SPaolo Bonzini 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); 97fc111b10SPaolo Bonzini 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); 10848e06fe0SBastian Koppelmann 10948e06fe0SBastian Koppelmann #define MASK_PSW_USB 0xff000000 11048e06fe0SBastian Koppelmann #define MASK_USB_C 0x80000000 11148e06fe0SBastian Koppelmann #define MASK_USB_V 0x40000000 11248e06fe0SBastian Koppelmann #define MASK_USB_SV 0x20000000 11348e06fe0SBastian Koppelmann #define MASK_USB_AV 0x10000000 11448e06fe0SBastian Koppelmann #define MASK_USB_SAV 0x08000000 11548e06fe0SBastian Koppelmann #define MASK_PSW_PRS 0x00003000 11648e06fe0SBastian Koppelmann #define MASK_PSW_IO 0x00000c00 11748e06fe0SBastian Koppelmann #define MASK_PSW_IS 0x00000200 11848e06fe0SBastian Koppelmann #define MASK_PSW_GW 0x00000100 11948e06fe0SBastian Koppelmann #define MASK_PSW_CDE 0x00000080 12048e06fe0SBastian Koppelmann #define MASK_PSW_CDC 0x0000007f 121996a729fSBastian Koppelmann #define MASK_PSW_FPU_RM 0x3000000 12248e06fe0SBastian Koppelmann 12348e06fe0SBastian Koppelmann #define MASK_SYSCON_PRO_TEN 0x2 12448e06fe0SBastian Koppelmann #define MASK_SYSCON_FCD_SF 0x1 12548e06fe0SBastian Koppelmann 12648e06fe0SBastian Koppelmann #define MASK_CPUID_MOD 0xffff0000 12748e06fe0SBastian Koppelmann #define MASK_CPUID_MOD_32B 0x0000ff00 12848e06fe0SBastian Koppelmann #define MASK_CPUID_REV 0x000000ff 12948e06fe0SBastian Koppelmann 13048e06fe0SBastian Koppelmann 13148e06fe0SBastian Koppelmann #define MASK_FCX_FCXS 0x000f0000 13248e06fe0SBastian Koppelmann #define MASK_FCX_FCXO 0x0000ffff 13348e06fe0SBastian Koppelmann 13448e06fe0SBastian Koppelmann #define MASK_LCX_LCXS 0x000f0000 13548e06fe0SBastian Koppelmann #define MASK_LCX_LCX0 0x0000ffff 13648e06fe0SBastian Koppelmann 137b724b012SBastian Koppelmann #define MASK_DBGSR_DE 0x1 138b724b012SBastian Koppelmann #define MASK_DBGSR_HALT 0x6 139b724b012SBastian Koppelmann #define MASK_DBGSR_SUSP 0x10 140b724b012SBastian Koppelmann #define MASK_DBGSR_PREVSUSP 0x20 141b724b012SBastian Koppelmann #define MASK_DBGSR_PEVT 0x40 142b724b012SBastian Koppelmann #define MASK_DBGSR_EVTSRC 0x1f00 143b724b012SBastian Koppelmann 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 }; 14948e06fe0SBastian Koppelmann 15048e06fe0SBastian Koppelmann enum tricore_features { 15148e06fe0SBastian Koppelmann TRICORE_FEATURE_13, 15248e06fe0SBastian Koppelmann TRICORE_FEATURE_131, 15348e06fe0SBastian Koppelmann TRICORE_FEATURE_16, 1546d2afc8aSBastian Koppelmann TRICORE_FEATURE_161, 1554d2b2e76SBastian Koppelmann TRICORE_FEATURE_162, 15648e06fe0SBastian Koppelmann }; 15748e06fe0SBastian Koppelmann 158f8cfdd20SBastian Koppelmann static inline int tricore_has_feature(CPUTriCoreState *env, int feature) 15948e06fe0SBastian Koppelmann { 16048e06fe0SBastian Koppelmann return (env->features & (1ULL << feature)) != 0; 16148e06fe0SBastian Koppelmann } 16248e06fe0SBastian Koppelmann 16348e06fe0SBastian Koppelmann /* TriCore Traps Classes*/ 16448e06fe0SBastian Koppelmann enum { 16548e06fe0SBastian Koppelmann TRAPC_NONE = -1, 16648e06fe0SBastian Koppelmann TRAPC_MMU = 0, 16748e06fe0SBastian Koppelmann TRAPC_PROT = 1, 16848e06fe0SBastian Koppelmann TRAPC_INSN_ERR = 2, 16948e06fe0SBastian Koppelmann TRAPC_CTX_MNG = 3, 17048e06fe0SBastian Koppelmann TRAPC_SYSBUS = 4, 17148e06fe0SBastian Koppelmann TRAPC_ASSERT = 5, 17248e06fe0SBastian Koppelmann TRAPC_SYSCALL = 6, 17348e06fe0SBastian Koppelmann TRAPC_NMI = 7, 174518d7fd2SBastian Koppelmann TRAPC_IRQ = 8 17548e06fe0SBastian Koppelmann }; 17648e06fe0SBastian Koppelmann 17748e06fe0SBastian Koppelmann /* Class 0 TIN */ 17848e06fe0SBastian Koppelmann enum { 17948e06fe0SBastian Koppelmann TIN0_VAF = 0, 18048e06fe0SBastian Koppelmann TIN0_VAP = 1, 18148e06fe0SBastian Koppelmann }; 18248e06fe0SBastian Koppelmann 18348e06fe0SBastian Koppelmann /* Class 1 TIN */ 18448e06fe0SBastian Koppelmann enum { 18548e06fe0SBastian Koppelmann TIN1_PRIV = 1, 18648e06fe0SBastian Koppelmann TIN1_MPR = 2, 18748e06fe0SBastian Koppelmann TIN1_MPW = 3, 18848e06fe0SBastian Koppelmann TIN1_MPX = 4, 18948e06fe0SBastian Koppelmann TIN1_MPP = 5, 19048e06fe0SBastian Koppelmann TIN1_MPN = 6, 19148e06fe0SBastian Koppelmann TIN1_GRWP = 7, 19248e06fe0SBastian Koppelmann }; 19348e06fe0SBastian Koppelmann 19448e06fe0SBastian Koppelmann /* Class 2 TIN */ 19548e06fe0SBastian Koppelmann enum { 19648e06fe0SBastian Koppelmann TIN2_IOPC = 1, 19748e06fe0SBastian Koppelmann TIN2_UOPC = 2, 19848e06fe0SBastian Koppelmann TIN2_OPD = 3, 19948e06fe0SBastian Koppelmann TIN2_ALN = 4, 20048e06fe0SBastian Koppelmann TIN2_MEM = 5, 20148e06fe0SBastian Koppelmann }; 20248e06fe0SBastian Koppelmann 20348e06fe0SBastian Koppelmann /* Class 3 TIN */ 20448e06fe0SBastian Koppelmann enum { 20548e06fe0SBastian Koppelmann TIN3_FCD = 1, 20648e06fe0SBastian Koppelmann TIN3_CDO = 2, 20748e06fe0SBastian Koppelmann TIN3_CDU = 3, 20848e06fe0SBastian Koppelmann TIN3_FCU = 4, 20948e06fe0SBastian Koppelmann TIN3_CSU = 5, 21048e06fe0SBastian Koppelmann TIN3_CTYP = 6, 21148e06fe0SBastian Koppelmann TIN3_NEST = 7, 21248e06fe0SBastian Koppelmann }; 21348e06fe0SBastian Koppelmann 21448e06fe0SBastian Koppelmann /* Class 4 TIN */ 21548e06fe0SBastian Koppelmann enum { 21648e06fe0SBastian Koppelmann TIN4_PSE = 1, 21748e06fe0SBastian Koppelmann TIN4_DSE = 2, 21848e06fe0SBastian Koppelmann TIN4_DAE = 3, 21948e06fe0SBastian Koppelmann TIN4_CAE = 4, 22048e06fe0SBastian Koppelmann TIN4_PIE = 5, 22148e06fe0SBastian Koppelmann TIN4_DIE = 6, 22248e06fe0SBastian Koppelmann }; 22348e06fe0SBastian Koppelmann 22448e06fe0SBastian Koppelmann /* Class 5 TIN */ 22548e06fe0SBastian Koppelmann enum { 22648e06fe0SBastian Koppelmann TIN5_OVF = 1, 22748e06fe0SBastian Koppelmann TIN5_SOVF = 1, 22848e06fe0SBastian Koppelmann }; 22948e06fe0SBastian Koppelmann 23048e06fe0SBastian Koppelmann /* Class 6 TIN 23148e06fe0SBastian Koppelmann * 23248e06fe0SBastian Koppelmann * Is always TIN6_SYS 23348e06fe0SBastian Koppelmann */ 23448e06fe0SBastian Koppelmann 23548e06fe0SBastian Koppelmann /* Class 7 TIN */ 23648e06fe0SBastian Koppelmann enum { 23748e06fe0SBastian Koppelmann TIN7_NMI = 0, 23848e06fe0SBastian Koppelmann }; 23948e06fe0SBastian Koppelmann 24048e06fe0SBastian Koppelmann uint32_t psw_read(CPUTriCoreState *env); 24148e06fe0SBastian Koppelmann 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); 24448e06fe0SBastian Koppelmann 245996a729fSBastian Koppelmann void fpu_set_state(CPUTriCoreState *env); 246996a729fSBastian Koppelmann 24748e06fe0SBastian Koppelmann #define MMU_USER_IDX 2 24848e06fe0SBastian Koppelmann 24948e06fe0SBastian Koppelmann #include "exec/cpu-all.h" 25048e06fe0SBastian Koppelmann 251878d1b6aSBastian Koppelmann FIELD(TB_FLAGS, PRIV, 0, 2) 252878d1b6aSBastian Koppelmann 25348e06fe0SBastian Koppelmann void cpu_state_reset(CPUTriCoreState *s); 25448e06fe0SBastian Koppelmann void tricore_tcg_init(void); 255*e4a8e093SRichard Henderson void tricore_translate_code(CPUState *cs, TranslationBlock *tb, 256*e4a8e093SRichard Henderson int *max_insns, vaddr pc, void *host_pc); 25748e06fe0SBastian Koppelmann 258bb5de525SAnton Johansson static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, vaddr *pc, 259bb5de525SAnton Johansson uint64_t *cs_base, uint32_t *flags) 26048e06fe0SBastian Koppelmann { 261878d1b6aSBastian Koppelmann uint32_t new_flags = 0; 26248e06fe0SBastian Koppelmann *pc = env->PC; 26348e06fe0SBastian Koppelmann *cs_base = 0; 264878d1b6aSBastian Koppelmann 265878d1b6aSBastian Koppelmann new_flags |= FIELD_DP32(new_flags, TB_FLAGS, PRIV, 266878d1b6aSBastian Koppelmann extract32(env->PSW, 10, 2)); 267878d1b6aSBastian Koppelmann *flags = new_flags; 26848e06fe0SBastian Koppelmann } 26948e06fe0SBastian Koppelmann 2700dacec87SIgor Mammedov #define CPU_RESOLVING_TYPE TYPE_TRICORE_CPU 27148e06fe0SBastian Koppelmann 27248e06fe0SBastian Koppelmann /* helpers.c */ 27368d6eee7SRichard Henderson bool tricore_cpu_tlb_fill(CPUState *cs, vaddr address, int size, 27468d6eee7SRichard Henderson MMUAccessType access_type, int mmu_idx, 27568d6eee7SRichard Henderson bool probe, uintptr_t retaddr); 27648e06fe0SBastian Koppelmann 27707f5a258SMarkus Armbruster #endif /* TRICORE_CPU_H */ 278