cpu.h 9.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 *  TriCore emulation for qemu: main CPU struct.
 *
 *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
19 20 21

#ifndef TRICORE_CPU_H
#define TRICORE_CPU_H
22 23 24

#include "tricore-defs.h"
#include "qemu-common.h"
25
#include "cpu-qom.h"
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#include "exec/cpu-defs.h"

#define CPUArchState struct CPUTriCoreState

struct CPUTriCoreState;

struct tricore_boot_info;

#define NB_MMU_MODES 3

typedef struct tricore_def_t tricore_def_t;

typedef struct CPUTriCoreState CPUTriCoreState;
struct CPUTriCoreState {
    /* GPR Register */
    uint32_t gpr_a[16];
    uint32_t gpr_d[16];
    /* CSFR Register */
    uint32_t PCXI;
/* Frequently accessed PSW_USB bits are stored separately for efficiency.
       This contains all the other bits.  Use psw_{read,write} to access
       the whole PSW.  */
    uint32_t PSW;

    /* PSW flag cache for faster execution
    */
    uint32_t PSW_USB_C;
    uint32_t PSW_USB_V;   /* Only if bit 31 set, then flag is set  */
    uint32_t PSW_USB_SV;  /* Only if bit 31 set, then flag is set  */
    uint32_t PSW_USB_AV;  /* Only if bit 31 set, then flag is set. */
    uint32_t PSW_USB_SAV; /* Only if bit 31 set, then flag is set. */

    uint32_t PC;
    uint32_t SYSCON;
    uint32_t CPU_ID;
D
David Brenken 已提交
61
    uint32_t CORE_ID;
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
    uint32_t BIV;
    uint32_t BTV;
    uint32_t ISP;
    uint32_t ICR;
    uint32_t FCX;
    uint32_t LCX;
    uint32_t COMPAT;

    /* Mem Protection Register */
    uint32_t DPR0_0L;
    uint32_t DPR0_0U;
    uint32_t DPR0_1L;
    uint32_t DPR0_1U;
    uint32_t DPR0_2L;
    uint32_t DPR0_2U;
    uint32_t DPR0_3L;
    uint32_t DPR0_3U;

    uint32_t DPR1_0L;
    uint32_t DPR1_0U;
    uint32_t DPR1_1L;
    uint32_t DPR1_1U;
    uint32_t DPR1_2L;
    uint32_t DPR1_2U;
    uint32_t DPR1_3L;
    uint32_t DPR1_3U;

    uint32_t DPR2_0L;
    uint32_t DPR2_0U;
    uint32_t DPR2_1L;
    uint32_t DPR2_1U;
    uint32_t DPR2_2L;
    uint32_t DPR2_2U;
    uint32_t DPR2_3L;
    uint32_t DPR2_3U;

    uint32_t DPR3_0L;
    uint32_t DPR3_0U;
    uint32_t DPR3_1L;
    uint32_t DPR3_1U;
    uint32_t DPR3_2L;
    uint32_t DPR3_2U;
    uint32_t DPR3_3L;
    uint32_t DPR3_3U;

    uint32_t CPR0_0L;
    uint32_t CPR0_0U;
    uint32_t CPR0_1L;
    uint32_t CPR0_1U;
    uint32_t CPR0_2L;
    uint32_t CPR0_2U;
    uint32_t CPR0_3L;
    uint32_t CPR0_3U;

    uint32_t CPR1_0L;
    uint32_t CPR1_0U;
    uint32_t CPR1_1L;
    uint32_t CPR1_1U;
    uint32_t CPR1_2L;
    uint32_t CPR1_2U;
    uint32_t CPR1_3L;
    uint32_t CPR1_3U;

    uint32_t CPR2_0L;
    uint32_t CPR2_0U;
    uint32_t CPR2_1L;
    uint32_t CPR2_1U;
    uint32_t CPR2_2L;
    uint32_t CPR2_2U;
    uint32_t CPR2_3L;
    uint32_t CPR2_3U;

    uint32_t CPR3_0L;
    uint32_t CPR3_0U;
    uint32_t CPR3_1L;
    uint32_t CPR3_1U;
    uint32_t CPR3_2L;
    uint32_t CPR3_2U;
    uint32_t CPR3_3L;
    uint32_t CPR3_3U;

    uint32_t DPM0;
    uint32_t DPM1;
    uint32_t DPM2;
    uint32_t DPM3;

    uint32_t CPM0;
    uint32_t CPM1;
    uint32_t CPM2;
    uint32_t CPM3;

    /* Memory Management Registers */
    uint32_t MMU_CON;
    uint32_t MMU_ASI;
    uint32_t MMU_TVA;
    uint32_t MMU_TPA;
    uint32_t MMU_TPX;
    uint32_t MMU_TFA;
    /* {1.3.1 only */
    uint32_t BMACON;
    uint32_t SMACON;
    uint32_t DIEAR;
    uint32_t DIETR;
    uint32_t CCDIER;
    uint32_t MIECON;
    uint32_t PIEAR;
    uint32_t PIETR;
    uint32_t CCPIER;
    /*} */
    /* Debug Registers */
    uint32_t DBGSR;
    uint32_t EXEVT;
    uint32_t CREVT;
    uint32_t SWEVT;
    uint32_t TR0EVT;
    uint32_t TR1EVT;
    uint32_t DMS;
    uint32_t DCX;
    uint32_t DBGTCR;
    uint32_t CCTRL;
    uint32_t CCNT;
    uint32_t ICNT;
    uint32_t M1CNT;
    uint32_t M2CNT;
    uint32_t M3CNT;
    /* Floating Point Registers */
188
    float_status fp_status;
189 190 191 192 193 194 195 196 197 198 199 200 201 202
    /* QEMU */
    int error_code;
    uint32_t hflags;    /* CPU State */

    CPU_COMMON

    /* Internal CPU feature flags.  */
    uint64_t features;

    const tricore_def_t *cpu_model;
    void *irq[8];
    struct QEMUTimer *timer; /* Internal timer */
};

203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
/**
 * TriCoreCPU:
 * @env: #CPUTriCoreState
 *
 * A TriCore CPU.
 */
struct TriCoreCPU {
    /*< private >*/
    CPUState parent_obj;
    /*< public >*/

    CPUTriCoreState env;
};

static inline TriCoreCPU *tricore_env_get_cpu(CPUTriCoreState *env)
{
    return TRICORE_CPU(container_of(env, TriCoreCPU, env));
}

#define ENV_GET_CPU(e) CPU(tricore_env_get_cpu(e))

#define ENV_OFFSET offsetof(TriCoreCPU, env)

hwaddr tricore_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
void tricore_cpu_dump_state(CPUState *cpu, FILE *f,
                            fprintf_function cpu_fprintf, int flags);


231
#define MASK_PCXI_PCPN 0xff000000
D
David Brenken 已提交
232 233
#define MASK_PCXI_PIE_1_3  0x00800000
#define MASK_PCXI_PIE_1_6  0x00200000
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
#define MASK_PCXI_UL   0x00400000
#define MASK_PCXI_PCXS 0x000f0000
#define MASK_PCXI_PCXO 0x0000ffff

#define MASK_PSW_USB 0xff000000
#define MASK_USB_C   0x80000000
#define MASK_USB_V   0x40000000
#define MASK_USB_SV  0x20000000
#define MASK_USB_AV  0x10000000
#define MASK_USB_SAV 0x08000000
#define MASK_PSW_PRS 0x00003000
#define MASK_PSW_IO  0x00000c00
#define MASK_PSW_IS  0x00000200
#define MASK_PSW_GW  0x00000100
#define MASK_PSW_CDE 0x00000080
#define MASK_PSW_CDC 0x0000007f
250
#define MASK_PSW_FPU_RM 0x3000000
251 252 253 254 255 256 257 258 259

#define MASK_SYSCON_PRO_TEN 0x2
#define MASK_SYSCON_FCD_SF  0x1

#define MASK_CPUID_MOD     0xffff0000
#define MASK_CPUID_MOD_32B 0x0000ff00
#define MASK_CPUID_REV     0x000000ff

#define MASK_ICR_PIPN 0x00ff0000
D
David Brenken 已提交
260 261
#define MASK_ICR_IE_1_3   0x00000100
#define MASK_ICR_IE_1_6   0x00008000
262 263 264 265 266 267 268 269
#define MASK_ICR_CCPN 0x000000ff

#define MASK_FCX_FCXS 0x000f0000
#define MASK_FCX_FCXO 0x0000ffff

#define MASK_LCX_LCXS 0x000f0000
#define MASK_LCX_LCX0 0x0000ffff

270 271 272 273 274 275 276
#define MASK_DBGSR_DE 0x1
#define MASK_DBGSR_HALT 0x6
#define MASK_DBGSR_SUSP 0x10
#define MASK_DBGSR_PREVSUSP 0x20
#define MASK_DBGSR_PEVT 0x40
#define MASK_DBGSR_EVTSRC 0x1f00

277
#define TRICORE_HFLAG_KUU     0x3
278 279 280 281 282 283 284 285
#define TRICORE_HFLAG_UM0     0x00002 /* user mode-0 flag          */
#define TRICORE_HFLAG_UM1     0x00001 /* user mode-1 flag          */
#define TRICORE_HFLAG_SM      0x00000 /* kernel mode flag          */

enum tricore_features {
    TRICORE_FEATURE_13,
    TRICORE_FEATURE_131,
    TRICORE_FEATURE_16,
286
    TRICORE_FEATURE_161,
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
};

static inline int tricore_feature(CPUTriCoreState *env, int feature)
{
    return (env->features & (1ULL << feature)) != 0;
}

/* TriCore Traps Classes*/
enum {
    TRAPC_NONE     = -1,
    TRAPC_MMU      = 0,
    TRAPC_PROT     = 1,
    TRAPC_INSN_ERR = 2,
    TRAPC_CTX_MNG  = 3,
    TRAPC_SYSBUS   = 4,
    TRAPC_ASSERT   = 5,
    TRAPC_SYSCALL  = 6,
    TRAPC_NMI      = 7,
305
    TRAPC_IRQ      = 8
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
};

/* Class 0 TIN */
enum {
    TIN0_VAF = 0,
    TIN0_VAP = 1,
};

/* Class 1 TIN */
enum {
    TIN1_PRIV = 1,
    TIN1_MPR  = 2,
    TIN1_MPW  = 3,
    TIN1_MPX  = 4,
    TIN1_MPP  = 5,
    TIN1_MPN  = 6,
    TIN1_GRWP = 7,
};

/* Class 2 TIN */
enum {
    TIN2_IOPC = 1,
    TIN2_UOPC = 2,
    TIN2_OPD  = 3,
    TIN2_ALN  = 4,
    TIN2_MEM  = 5,
};

/* Class 3 TIN */
enum {
    TIN3_FCD  = 1,
    TIN3_CDO  = 2,
    TIN3_CDU  = 3,
    TIN3_FCU  = 4,
    TIN3_CSU  = 5,
    TIN3_CTYP = 6,
    TIN3_NEST = 7,
};

/* Class 4 TIN */
enum {
    TIN4_PSE = 1,
    TIN4_DSE = 2,
    TIN4_DAE = 3,
    TIN4_CAE = 4,
    TIN4_PIE = 5,
    TIN4_DIE = 6,
};

/* Class 5 TIN */
enum {
    TIN5_OVF  = 1,
    TIN5_SOVF = 1,
};

/* Class 6 TIN
 *
 * Is always TIN6_SYS
 */

/* Class 7 TIN */
enum {
    TIN7_NMI = 0,
};

uint32_t psw_read(CPUTriCoreState *env);
void psw_write(CPUTriCoreState *env, uint32_t val);

374 375
void fpu_set_state(CPUTriCoreState *env);

376 377 378 379 380 381 382
#define MMU_USER_IDX 2

void tricore_cpu_list(FILE *f, fprintf_function cpu_fprintf);

#define cpu_signal_handler cpu_tricore_signal_handler
#define cpu_list tricore_cpu_list

383
static inline int cpu_mmu_index(CPUTriCoreState *env, bool ifetch)
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
{
    return 0;
}



#include "exec/cpu-all.h"

enum {
    /* 1 bit to define user level / supervisor access */
    ACCESS_USER  = 0x00,
    ACCESS_SUPER = 0x01,
    /* 1 bit to indicate direction */
    ACCESS_STORE = 0x02,
    /* Type of instruction that generated the access */
    ACCESS_CODE  = 0x10, /* Code fetch access                */
    ACCESS_INT   = 0x20, /* Integer load/store access        */
    ACCESS_FLOAT = 0x30, /* floating point load/store access */
};

void cpu_state_reset(CPUTriCoreState *s);
void tricore_tcg_init(void);
int cpu_tricore_signal_handler(int host_signum, void *pinfo, void *puc);

static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, target_ulong *pc,
409
                                        target_ulong *cs_base, uint32_t *flags)
410 411 412 413 414 415
{
    *pc = env->PC;
    *cs_base = 0;
    *flags = 0;
}

416
#define cpu_init(cpu_model) cpu_generic_init(TYPE_TRICORE_CPU, cpu_model)
417

418 419
#define TRICORE_CPU_TYPE_SUFFIX "-" TYPE_TRICORE_CPU
#define TRICORE_CPU_TYPE_NAME(model) model TRICORE_CPU_TYPE_SUFFIX
420
#define CPU_RESOLVING_TYPE TYPE_TRICORE_CPU
421 422 423 424 425 426

/* helpers.c */
int cpu_tricore_handle_mmu_fault(CPUState *cpu, target_ulong address,
                                 int rw, int mmu_idx);
#define cpu_handle_mmu_fault cpu_tricore_handle_mmu_fault

427
#endif /* TRICORE_CPU_H */