1 /* 2 * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * * Neither the name of the Open Source and Linux Lab nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef XTENSA_CPU_H 29 #define XTENSA_CPU_H 30 31 #define ALIGNED_ONLY 32 #define TARGET_LONG_BITS 32 33 34 #define CPUArchState struct CPUXtensaState 35 36 #include "qemu-common.h" 37 #include "cpu-qom.h" 38 #include "exec/cpu-defs.h" 39 #include "fpu/softfloat.h" 40 #include "xtensa-isa.h" 41 42 #define NB_MMU_MODES 4 43 44 #define TARGET_PHYS_ADDR_SPACE_BITS 32 45 #define TARGET_VIRT_ADDR_SPACE_BITS 32 46 #define TARGET_PAGE_BITS 12 47 48 enum { 49 /* Additional instructions */ 50 XTENSA_OPTION_CODE_DENSITY, 51 XTENSA_OPTION_LOOP, 52 XTENSA_OPTION_EXTENDED_L32R, 53 XTENSA_OPTION_16_BIT_IMUL, 54 XTENSA_OPTION_32_BIT_IMUL, 55 XTENSA_OPTION_32_BIT_IMUL_HIGH, 56 XTENSA_OPTION_32_BIT_IDIV, 57 XTENSA_OPTION_MAC16, 58 XTENSA_OPTION_MISC_OP_NSA, 59 XTENSA_OPTION_MISC_OP_MINMAX, 60 XTENSA_OPTION_MISC_OP_SEXT, 61 XTENSA_OPTION_MISC_OP_CLAMPS, 62 XTENSA_OPTION_COPROCESSOR, 63 XTENSA_OPTION_BOOLEAN, 64 XTENSA_OPTION_FP_COPROCESSOR, 65 XTENSA_OPTION_MP_SYNCHRO, 66 XTENSA_OPTION_CONDITIONAL_STORE, 67 XTENSA_OPTION_ATOMCTL, 68 XTENSA_OPTION_DEPBITS, 69 70 /* Interrupts and exceptions */ 71 XTENSA_OPTION_EXCEPTION, 72 XTENSA_OPTION_RELOCATABLE_VECTOR, 73 XTENSA_OPTION_UNALIGNED_EXCEPTION, 74 XTENSA_OPTION_INTERRUPT, 75 XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT, 76 XTENSA_OPTION_TIMER_INTERRUPT, 77 78 /* Local memory */ 79 XTENSA_OPTION_ICACHE, 80 XTENSA_OPTION_ICACHE_TEST, 81 XTENSA_OPTION_ICACHE_INDEX_LOCK, 82 XTENSA_OPTION_DCACHE, 83 XTENSA_OPTION_DCACHE_TEST, 84 XTENSA_OPTION_DCACHE_INDEX_LOCK, 85 XTENSA_OPTION_IRAM, 86 XTENSA_OPTION_IROM, 87 XTENSA_OPTION_DRAM, 88 XTENSA_OPTION_DROM, 89 XTENSA_OPTION_XLMI, 90 XTENSA_OPTION_HW_ALIGNMENT, 91 XTENSA_OPTION_MEMORY_ECC_PARITY, 92 93 /* Memory protection and translation */ 94 XTENSA_OPTION_REGION_PROTECTION, 95 XTENSA_OPTION_REGION_TRANSLATION, 96 XTENSA_OPTION_MMU, 97 XTENSA_OPTION_CACHEATTR, 98 99 /* Other */ 100 XTENSA_OPTION_WINDOWED_REGISTER, 101 XTENSA_OPTION_PROCESSOR_INTERFACE, 102 XTENSA_OPTION_MISC_SR, 103 XTENSA_OPTION_THREAD_POINTER, 104 XTENSA_OPTION_PROCESSOR_ID, 105 XTENSA_OPTION_DEBUG, 106 XTENSA_OPTION_TRACE_PORT, 107 XTENSA_OPTION_EXTERN_REGS, 108 }; 109 110 enum { 111 THREADPTR = 231, 112 FCR = 232, 113 FSR = 233, 114 }; 115 116 enum { 117 LBEG = 0, 118 LEND = 1, 119 LCOUNT = 2, 120 SAR = 3, 121 BR = 4, 122 LITBASE = 5, 123 SCOMPARE1 = 12, 124 ACCLO = 16, 125 ACCHI = 17, 126 MR = 32, 127 WINDOW_BASE = 72, 128 WINDOW_START = 73, 129 PTEVADDR = 83, 130 RASID = 90, 131 ITLBCFG = 91, 132 DTLBCFG = 92, 133 IBREAKENABLE = 96, 134 MEMCTL = 97, 135 CACHEATTR = 98, 136 ATOMCTL = 99, 137 IBREAKA = 128, 138 DBREAKA = 144, 139 DBREAKC = 160, 140 CONFIGID0 = 176, 141 EPC1 = 177, 142 DEPC = 192, 143 EPS2 = 194, 144 CONFIGID1 = 208, 145 EXCSAVE1 = 209, 146 CPENABLE = 224, 147 INTSET = 226, 148 INTCLEAR = 227, 149 INTENABLE = 228, 150 PS = 230, 151 VECBASE = 231, 152 EXCCAUSE = 232, 153 DEBUGCAUSE = 233, 154 CCOUNT = 234, 155 PRID = 235, 156 ICOUNT = 236, 157 ICOUNTLEVEL = 237, 158 EXCVADDR = 238, 159 CCOMPARE = 240, 160 MISC = 244, 161 }; 162 163 #define PS_INTLEVEL 0xf 164 #define PS_INTLEVEL_SHIFT 0 165 166 #define PS_EXCM 0x10 167 #define PS_UM 0x20 168 169 #define PS_RING 0xc0 170 #define PS_RING_SHIFT 6 171 172 #define PS_OWB 0xf00 173 #define PS_OWB_SHIFT 8 174 175 #define PS_CALLINC 0x30000 176 #define PS_CALLINC_SHIFT 16 177 #define PS_CALLINC_LEN 2 178 179 #define PS_WOE 0x40000 180 181 #define DEBUGCAUSE_IC 0x1 182 #define DEBUGCAUSE_IB 0x2 183 #define DEBUGCAUSE_DB 0x4 184 #define DEBUGCAUSE_BI 0x8 185 #define DEBUGCAUSE_BN 0x10 186 #define DEBUGCAUSE_DI 0x20 187 #define DEBUGCAUSE_DBNUM 0xf00 188 #define DEBUGCAUSE_DBNUM_SHIFT 8 189 190 #define DBREAKC_SB 0x80000000 191 #define DBREAKC_LB 0x40000000 192 #define DBREAKC_SB_LB (DBREAKC_SB | DBREAKC_LB) 193 #define DBREAKC_MASK 0x3f 194 195 #define MEMCTL_INIT 0x00800000 196 #define MEMCTL_IUSEWAYS_SHIFT 18 197 #define MEMCTL_IUSEWAYS_LEN 5 198 #define MEMCTL_IUSEWAYS_MASK 0x007c0000 199 #define MEMCTL_DALLOCWAYS_SHIFT 13 200 #define MEMCTL_DALLOCWAYS_LEN 5 201 #define MEMCTL_DALLOCWAYS_MASK 0x0003e000 202 #define MEMCTL_DUSEWAYS_SHIFT 8 203 #define MEMCTL_DUSEWAYS_LEN 5 204 #define MEMCTL_DUSEWAYS_MASK 0x00001f00 205 #define MEMCTL_ISNP 0x4 206 #define MEMCTL_DSNP 0x2 207 #define MEMCTL_IL0EN 0x1 208 209 #define MAX_INSN_LENGTH 64 210 #define MAX_OPCODE_ARGS 16 211 #define MAX_NAREG 64 212 #define MAX_NINTERRUPT 32 213 #define MAX_NLEVEL 6 214 #define MAX_NNMI 1 215 #define MAX_NCCOMPARE 3 216 #define MAX_TLB_WAY_SIZE 8 217 #define MAX_NDBREAK 2 218 #define MAX_NMEMORY 4 219 220 #define REGION_PAGE_MASK 0xe0000000 221 222 #define PAGE_CACHE_MASK 0x700 223 #define PAGE_CACHE_SHIFT 8 224 #define PAGE_CACHE_INVALID 0x000 225 #define PAGE_CACHE_BYPASS 0x100 226 #define PAGE_CACHE_WT 0x200 227 #define PAGE_CACHE_WB 0x400 228 #define PAGE_CACHE_ISOLATE 0x600 229 230 enum { 231 /* Static vectors */ 232 EXC_RESET0, 233 EXC_RESET1, 234 EXC_MEMORY_ERROR, 235 236 /* Dynamic vectors */ 237 EXC_WINDOW_OVERFLOW4, 238 EXC_WINDOW_UNDERFLOW4, 239 EXC_WINDOW_OVERFLOW8, 240 EXC_WINDOW_UNDERFLOW8, 241 EXC_WINDOW_OVERFLOW12, 242 EXC_WINDOW_UNDERFLOW12, 243 EXC_IRQ, 244 EXC_KERNEL, 245 EXC_USER, 246 EXC_DOUBLE, 247 EXC_DEBUG, 248 EXC_MAX 249 }; 250 251 enum { 252 ILLEGAL_INSTRUCTION_CAUSE = 0, 253 SYSCALL_CAUSE, 254 INSTRUCTION_FETCH_ERROR_CAUSE, 255 LOAD_STORE_ERROR_CAUSE, 256 LEVEL1_INTERRUPT_CAUSE, 257 ALLOCA_CAUSE, 258 INTEGER_DIVIDE_BY_ZERO_CAUSE, 259 PRIVILEGED_CAUSE = 8, 260 LOAD_STORE_ALIGNMENT_CAUSE, 261 262 INSTR_PIF_DATA_ERROR_CAUSE = 12, 263 LOAD_STORE_PIF_DATA_ERROR_CAUSE, 264 INSTR_PIF_ADDR_ERROR_CAUSE, 265 LOAD_STORE_PIF_ADDR_ERROR_CAUSE, 266 267 INST_TLB_MISS_CAUSE, 268 INST_TLB_MULTI_HIT_CAUSE, 269 INST_FETCH_PRIVILEGE_CAUSE, 270 INST_FETCH_PROHIBITED_CAUSE = 20, 271 LOAD_STORE_TLB_MISS_CAUSE = 24, 272 LOAD_STORE_TLB_MULTI_HIT_CAUSE, 273 LOAD_STORE_PRIVILEGE_CAUSE, 274 LOAD_PROHIBITED_CAUSE = 28, 275 STORE_PROHIBITED_CAUSE, 276 277 COPROCESSOR0_DISABLED = 32, 278 }; 279 280 typedef enum { 281 INTTYPE_LEVEL, 282 INTTYPE_EDGE, 283 INTTYPE_NMI, 284 INTTYPE_SOFTWARE, 285 INTTYPE_TIMER, 286 INTTYPE_DEBUG, 287 INTTYPE_WRITE_ERR, 288 INTTYPE_PROFILING, 289 INTTYPE_MAX 290 } interrupt_type; 291 292 struct CPUXtensaState; 293 294 typedef struct xtensa_tlb_entry { 295 uint32_t vaddr; 296 uint32_t paddr; 297 uint8_t asid; 298 uint8_t attr; 299 bool variable; 300 } xtensa_tlb_entry; 301 302 typedef struct xtensa_tlb { 303 unsigned nways; 304 const unsigned way_size[10]; 305 bool varway56; 306 unsigned nrefillentries; 307 } xtensa_tlb; 308 309 typedef struct XtensaGdbReg { 310 int targno; 311 int type; 312 int group; 313 unsigned size; 314 } XtensaGdbReg; 315 316 typedef struct XtensaGdbRegmap { 317 int num_regs; 318 int num_core_regs; 319 /* PC + a + ar + sr + ur */ 320 XtensaGdbReg reg[1 + 16 + 64 + 256 + 256]; 321 } XtensaGdbRegmap; 322 323 typedef struct XtensaCcompareTimer { 324 struct CPUXtensaState *env; 325 QEMUTimer *timer; 326 } XtensaCcompareTimer; 327 328 typedef struct XtensaMemory { 329 unsigned num; 330 struct XtensaMemoryRegion { 331 uint32_t addr; 332 uint32_t size; 333 } location[MAX_NMEMORY]; 334 } XtensaMemory; 335 336 typedef struct DisasContext DisasContext; 337 typedef void (*XtensaOpcodeOp)(DisasContext *dc, const uint32_t arg[], 338 const uint32_t par[]); 339 340 typedef struct XtensaOpcodeOps { 341 const char *name; 342 XtensaOpcodeOp translate; 343 const uint32_t *par; 344 } XtensaOpcodeOps; 345 346 typedef struct XtensaOpcodeTranslators { 347 unsigned num_opcodes; 348 const XtensaOpcodeOps *opcode; 349 } XtensaOpcodeTranslators; 350 351 extern const XtensaOpcodeTranslators xtensa_core_opcodes; 352 extern const XtensaOpcodeTranslators xtensa_fpu2000_opcodes; 353 354 struct XtensaConfig { 355 const char *name; 356 uint64_t options; 357 XtensaGdbRegmap gdb_regmap; 358 unsigned nareg; 359 int excm_level; 360 int ndepc; 361 uint32_t vecbase; 362 uint32_t exception_vector[EXC_MAX]; 363 unsigned ninterrupt; 364 unsigned nlevel; 365 uint32_t interrupt_vector[MAX_NLEVEL + MAX_NNMI + 1]; 366 uint32_t level_mask[MAX_NLEVEL + MAX_NNMI + 1]; 367 uint32_t inttype_mask[INTTYPE_MAX]; 368 struct { 369 uint32_t level; 370 interrupt_type inttype; 371 } interrupt[MAX_NINTERRUPT]; 372 unsigned nccompare; 373 uint32_t timerint[MAX_NCCOMPARE]; 374 unsigned nextint; 375 unsigned extint[MAX_NINTERRUPT]; 376 377 unsigned debug_level; 378 unsigned nibreak; 379 unsigned ndbreak; 380 381 unsigned icache_ways; 382 unsigned dcache_ways; 383 uint32_t memctl_mask; 384 385 XtensaMemory instrom; 386 XtensaMemory instram; 387 XtensaMemory datarom; 388 XtensaMemory dataram; 389 XtensaMemory sysrom; 390 XtensaMemory sysram; 391 392 uint32_t configid[2]; 393 394 void *isa_internal; 395 396 uint32_t clock_freq_khz; 397 398 xtensa_tlb itlb; 399 xtensa_tlb dtlb; 400 }; 401 402 typedef struct XtensaConfigList { 403 const XtensaConfig *config; 404 struct XtensaConfigList *next; 405 } XtensaConfigList; 406 407 #ifdef HOST_WORDS_BIGENDIAN 408 enum { 409 FP_F32_HIGH, 410 FP_F32_LOW, 411 }; 412 #else 413 enum { 414 FP_F32_LOW, 415 FP_F32_HIGH, 416 }; 417 #endif 418 419 typedef struct CPUXtensaState { 420 const XtensaConfig *config; 421 uint32_t regs[16]; 422 uint32_t pc; 423 uint32_t sregs[256]; 424 uint32_t uregs[256]; 425 uint32_t phys_regs[MAX_NAREG]; 426 union { 427 float32 f32[2]; 428 float64 f64; 429 } fregs[16]; 430 float_status fp_status; 431 432 xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE]; 433 xtensa_tlb_entry dtlb[10][MAX_TLB_WAY_SIZE]; 434 unsigned autorefill_idx; 435 bool runstall; 436 AddressSpace *address_space_er; 437 MemoryRegion *system_er; 438 int pending_irq_level; /* level of last raised IRQ */ 439 void **irq_inputs; 440 XtensaCcompareTimer ccompare[MAX_NCCOMPARE]; 441 uint64_t time_base; 442 uint64_t ccount_time; 443 uint32_t ccount_base; 444 445 int exception_taken; 446 int yield_needed; 447 unsigned static_vectors; 448 449 /* Watchpoints for DBREAK registers */ 450 struct CPUWatchpoint *cpu_watchpoint[MAX_NDBREAK]; 451 452 CPU_COMMON 453 } CPUXtensaState; 454 455 /** 456 * XtensaCPU: 457 * @env: #CPUXtensaState 458 * 459 * An Xtensa CPU. 460 */ 461 struct XtensaCPU { 462 /*< private >*/ 463 CPUState parent_obj; 464 /*< public >*/ 465 466 CPUXtensaState env; 467 }; 468 469 static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env) 470 { 471 return container_of(env, XtensaCPU, env); 472 } 473 474 #define ENV_GET_CPU(e) CPU(xtensa_env_get_cpu(e)) 475 476 #define ENV_OFFSET offsetof(XtensaCPU, env) 477 478 void xtensa_cpu_do_interrupt(CPUState *cpu); 479 bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request); 480 void xtensa_cpu_do_unassigned_access(CPUState *cpu, hwaddr addr, 481 bool is_write, bool is_exec, int opaque, 482 unsigned size); 483 void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, 484 fprintf_function cpu_fprintf, int flags); 485 hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); 486 int xtensa_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); 487 int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); 488 void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, 489 MMUAccessType access_type, 490 int mmu_idx, uintptr_t retaddr); 491 492 #define cpu_signal_handler cpu_xtensa_signal_handler 493 #define cpu_list xtensa_cpu_list 494 495 #define XTENSA_CPU_TYPE_SUFFIX "-" TYPE_XTENSA_CPU 496 #define XTENSA_CPU_TYPE_NAME(model) model XTENSA_CPU_TYPE_SUFFIX 497 498 #ifdef TARGET_WORDS_BIGENDIAN 499 #define XTENSA_DEFAULT_CPU_MODEL "fsf" 500 #else 501 #define XTENSA_DEFAULT_CPU_MODEL "dc232b" 502 #endif 503 #define XTENSA_DEFAULT_CPU_TYPE XTENSA_CPU_TYPE_NAME(XTENSA_DEFAULT_CPU_MODEL) 504 505 #define cpu_init(cpu_model) cpu_generic_init(TYPE_XTENSA_CPU, cpu_model) 506 507 void xtensa_translate_init(void); 508 void xtensa_breakpoint_handler(CPUState *cs); 509 void xtensa_finalize_config(XtensaConfig *config); 510 void xtensa_register_core(XtensaConfigList *node); 511 void xtensa_sim_open_console(Chardev *chr); 512 void check_interrupts(CPUXtensaState *s); 513 void xtensa_irq_init(CPUXtensaState *env); 514 void *xtensa_get_extint(CPUXtensaState *env, unsigned extint); 515 void xtensa_timer_irq(CPUXtensaState *env, uint32_t id, uint32_t active); 516 int cpu_xtensa_signal_handler(int host_signum, void *pinfo, void *puc); 517 void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf); 518 void xtensa_sync_window_from_phys(CPUXtensaState *env); 519 void xtensa_sync_phys_from_window(CPUXtensaState *env); 520 uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, bool dtlb, uint32_t way); 521 void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb, 522 uint32_t *vpn, uint32_t wi, uint32_t *ei); 523 int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb, 524 uint32_t *pwi, uint32_t *pei, uint8_t *pring); 525 void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env, 526 xtensa_tlb_entry *entry, bool dtlb, 527 unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); 528 void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, 529 unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); 530 int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb, 531 uint32_t vaddr, int is_write, int mmu_idx, 532 uint32_t *paddr, uint32_t *page_size, unsigned *access); 533 void reset_mmu(CPUXtensaState *env); 534 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env); 535 void debug_exception_env(CPUXtensaState *new_env, uint32_t cause); 536 static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env) 537 { 538 return env->system_er; 539 } 540 541 static inline void xtensa_select_static_vectors(CPUXtensaState *env, 542 unsigned n) 543 { 544 assert(n < 2); 545 env->static_vectors = n; 546 } 547 void xtensa_runstall(CPUXtensaState *env, bool runstall); 548 XtensaOpcodeOps *xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t, 549 const char *opcode); 550 551 #define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt)) 552 #define XTENSA_OPTION_ALL (~(uint64_t)0) 553 554 static inline bool xtensa_option_bits_enabled(const XtensaConfig *config, 555 uint64_t opt) 556 { 557 return (config->options & opt) != 0; 558 } 559 560 static inline bool xtensa_option_enabled(const XtensaConfig *config, int opt) 561 { 562 return xtensa_option_bits_enabled(config, XTENSA_OPTION_BIT(opt)); 563 } 564 565 static inline int xtensa_get_cintlevel(const CPUXtensaState *env) 566 { 567 int level = (env->sregs[PS] & PS_INTLEVEL) >> PS_INTLEVEL_SHIFT; 568 if ((env->sregs[PS] & PS_EXCM) && env->config->excm_level > level) { 569 level = env->config->excm_level; 570 } 571 return level; 572 } 573 574 static inline int xtensa_get_ring(const CPUXtensaState *env) 575 { 576 if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { 577 return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT; 578 } else { 579 return 0; 580 } 581 } 582 583 static inline int xtensa_get_cring(const CPUXtensaState *env) 584 { 585 if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) && 586 (env->sregs[PS] & PS_EXCM) == 0) { 587 return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT; 588 } else { 589 return 0; 590 } 591 } 592 593 static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env, 594 bool dtlb, unsigned wi, unsigned ei) 595 { 596 return dtlb ? 597 env->dtlb[wi] + ei : 598 env->itlb[wi] + ei; 599 } 600 601 static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env) 602 { 603 return env->sregs[WINDOW_START] | 604 (env->sregs[WINDOW_START] << env->config->nareg / 4); 605 } 606 607 /* MMU modes definitions */ 608 #define MMU_MODE0_SUFFIX _ring0 609 #define MMU_MODE1_SUFFIX _ring1 610 #define MMU_MODE2_SUFFIX _ring2 611 #define MMU_MODE3_SUFFIX _ring3 612 613 static inline int cpu_mmu_index(CPUXtensaState *env, bool ifetch) 614 { 615 return xtensa_get_cring(env); 616 } 617 618 #define XTENSA_TBFLAG_RING_MASK 0x3 619 #define XTENSA_TBFLAG_EXCM 0x4 620 #define XTENSA_TBFLAG_LITBASE 0x8 621 #define XTENSA_TBFLAG_DEBUG 0x10 622 #define XTENSA_TBFLAG_ICOUNT 0x20 623 #define XTENSA_TBFLAG_CPENABLE_MASK 0x3fc0 624 #define XTENSA_TBFLAG_CPENABLE_SHIFT 6 625 #define XTENSA_TBFLAG_EXCEPTION 0x4000 626 #define XTENSA_TBFLAG_WINDOW_MASK 0x18000 627 #define XTENSA_TBFLAG_WINDOW_SHIFT 15 628 #define XTENSA_TBFLAG_YIELD 0x20000 629 630 static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc, 631 target_ulong *cs_base, uint32_t *flags) 632 { 633 CPUState *cs = CPU(xtensa_env_get_cpu(env)); 634 635 *pc = env->pc; 636 *cs_base = 0; 637 *flags = 0; 638 *flags |= xtensa_get_ring(env); 639 if (env->sregs[PS] & PS_EXCM) { 640 *flags |= XTENSA_TBFLAG_EXCM; 641 } 642 if (xtensa_option_enabled(env->config, XTENSA_OPTION_EXTENDED_L32R) && 643 (env->sregs[LITBASE] & 1)) { 644 *flags |= XTENSA_TBFLAG_LITBASE; 645 } 646 if (xtensa_option_enabled(env->config, XTENSA_OPTION_DEBUG)) { 647 if (xtensa_get_cintlevel(env) < env->config->debug_level) { 648 *flags |= XTENSA_TBFLAG_DEBUG; 649 } 650 if (xtensa_get_cintlevel(env) < env->sregs[ICOUNTLEVEL]) { 651 *flags |= XTENSA_TBFLAG_ICOUNT; 652 } 653 } 654 if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) { 655 *flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT; 656 } 657 if (cs->singlestep_enabled && env->exception_taken) { 658 *flags |= XTENSA_TBFLAG_EXCEPTION; 659 } 660 if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER) && 661 (env->sregs[PS] & (PS_WOE | PS_EXCM)) == PS_WOE) { 662 uint32_t windowstart = xtensa_replicate_windowstart(env) >> 663 (env->sregs[WINDOW_BASE] + 1); 664 uint32_t w = ctz32(windowstart | 0x8); 665 666 *flags |= w << XTENSA_TBFLAG_WINDOW_SHIFT; 667 } else { 668 *flags |= 3 << XTENSA_TBFLAG_WINDOW_SHIFT; 669 } 670 if (env->yield_needed) { 671 *flags |= XTENSA_TBFLAG_YIELD; 672 } 673 } 674 675 #include "exec/cpu-all.h" 676 677 #endif 678