qemu/target/xtensa/cpu.h
<<
>>
Prefs
   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#include "cpu-qom.h"
  32#include "exec/cpu-defs.h"
  33#include "xtensa-isa.h"
  34
  35/* Xtensa processors have a weak memory model */
  36#define TCG_GUEST_DEFAULT_MO      (0)
  37
  38enum {
  39    /* Additional instructions */
  40    XTENSA_OPTION_CODE_DENSITY,
  41    XTENSA_OPTION_LOOP,
  42    XTENSA_OPTION_EXTENDED_L32R,
  43    XTENSA_OPTION_16_BIT_IMUL,
  44    XTENSA_OPTION_32_BIT_IMUL,
  45    XTENSA_OPTION_32_BIT_IMUL_HIGH,
  46    XTENSA_OPTION_32_BIT_IDIV,
  47    XTENSA_OPTION_MAC16,
  48    XTENSA_OPTION_MISC_OP_NSA,
  49    XTENSA_OPTION_MISC_OP_MINMAX,
  50    XTENSA_OPTION_MISC_OP_SEXT,
  51    XTENSA_OPTION_MISC_OP_CLAMPS,
  52    XTENSA_OPTION_COPROCESSOR,
  53    XTENSA_OPTION_BOOLEAN,
  54    XTENSA_OPTION_FP_COPROCESSOR,
  55    XTENSA_OPTION_DFP_COPROCESSOR,
  56    XTENSA_OPTION_DFPU_SINGLE_ONLY,
  57    XTENSA_OPTION_MP_SYNCHRO,
  58    XTENSA_OPTION_CONDITIONAL_STORE,
  59    XTENSA_OPTION_ATOMCTL,
  60    XTENSA_OPTION_DEPBITS,
  61
  62    /* Interrupts and exceptions */
  63    XTENSA_OPTION_EXCEPTION,
  64    XTENSA_OPTION_RELOCATABLE_VECTOR,
  65    XTENSA_OPTION_UNALIGNED_EXCEPTION,
  66    XTENSA_OPTION_INTERRUPT,
  67    XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
  68    XTENSA_OPTION_TIMER_INTERRUPT,
  69
  70    /* Local memory */
  71    XTENSA_OPTION_ICACHE,
  72    XTENSA_OPTION_ICACHE_TEST,
  73    XTENSA_OPTION_ICACHE_INDEX_LOCK,
  74    XTENSA_OPTION_DCACHE,
  75    XTENSA_OPTION_DCACHE_TEST,
  76    XTENSA_OPTION_DCACHE_INDEX_LOCK,
  77    XTENSA_OPTION_IRAM,
  78    XTENSA_OPTION_IROM,
  79    XTENSA_OPTION_DRAM,
  80    XTENSA_OPTION_DROM,
  81    XTENSA_OPTION_XLMI,
  82    XTENSA_OPTION_HW_ALIGNMENT,
  83    XTENSA_OPTION_MEMORY_ECC_PARITY,
  84
  85    /* Memory protection and translation */
  86    XTENSA_OPTION_REGION_PROTECTION,
  87    XTENSA_OPTION_REGION_TRANSLATION,
  88    XTENSA_OPTION_MPU,
  89    XTENSA_OPTION_MMU,
  90    XTENSA_OPTION_CACHEATTR,
  91
  92    /* Other */
  93    XTENSA_OPTION_WINDOWED_REGISTER,
  94    XTENSA_OPTION_PROCESSOR_INTERFACE,
  95    XTENSA_OPTION_MISC_SR,
  96    XTENSA_OPTION_THREAD_POINTER,
  97    XTENSA_OPTION_PROCESSOR_ID,
  98    XTENSA_OPTION_DEBUG,
  99    XTENSA_OPTION_TRACE_PORT,
 100    XTENSA_OPTION_EXTERN_REGS,
 101};
 102
 103enum {
 104    EXPSTATE = 230,
 105    THREADPTR = 231,
 106    FCR = 232,
 107    FSR = 233,
 108};
 109
 110enum {
 111    LBEG = 0,
 112    LEND = 1,
 113    LCOUNT = 2,
 114    SAR = 3,
 115    BR = 4,
 116    LITBASE = 5,
 117    SCOMPARE1 = 12,
 118    ACCLO = 16,
 119    ACCHI = 17,
 120    MR = 32,
 121    PREFCTL = 40,
 122    WINDOW_BASE = 72,
 123    WINDOW_START = 73,
 124    PTEVADDR = 83,
 125    MMID = 89,
 126    RASID = 90,
 127    MPUENB = 90,
 128    ITLBCFG = 91,
 129    DTLBCFG = 92,
 130    MPUCFG = 92,
 131    ERACCESS = 95,
 132    IBREAKENABLE = 96,
 133    MEMCTL = 97,
 134    CACHEATTR = 98,
 135    CACHEADRDIS = 98,
 136    ATOMCTL = 99,
 137    DDR = 104,
 138    MEPC = 106,
 139    MEPS = 107,
 140    MESAVE = 108,
 141    MESR = 109,
 142    MECR = 110,
 143    MEVADDR = 111,
 144    IBREAKA = 128,
 145    DBREAKA = 144,
 146    DBREAKC = 160,
 147    CONFIGID0 = 176,
 148    EPC1 = 177,
 149    DEPC = 192,
 150    EPS2 = 194,
 151    CONFIGID1 = 208,
 152    EXCSAVE1 = 209,
 153    CPENABLE = 224,
 154    INTSET = 226,
 155    INTCLEAR = 227,
 156    INTENABLE = 228,
 157    PS = 230,
 158    VECBASE = 231,
 159    EXCCAUSE = 232,
 160    DEBUGCAUSE = 233,
 161    CCOUNT = 234,
 162    PRID = 235,
 163    ICOUNT = 236,
 164    ICOUNTLEVEL = 237,
 165    EXCVADDR = 238,
 166    CCOMPARE = 240,
 167    MISC = 244,
 168};
 169
 170#define PS_INTLEVEL 0xf
 171#define PS_INTLEVEL_SHIFT 0
 172
 173#define PS_EXCM 0x10
 174#define PS_UM 0x20
 175
 176#define PS_RING 0xc0
 177#define PS_RING_SHIFT 6
 178
 179#define PS_OWB 0xf00
 180#define PS_OWB_SHIFT 8
 181#define PS_OWB_LEN 4
 182
 183#define PS_CALLINC 0x30000
 184#define PS_CALLINC_SHIFT 16
 185#define PS_CALLINC_LEN 2
 186
 187#define PS_WOE 0x40000
 188
 189#define DEBUGCAUSE_IC 0x1
 190#define DEBUGCAUSE_IB 0x2
 191#define DEBUGCAUSE_DB 0x4
 192#define DEBUGCAUSE_BI 0x8
 193#define DEBUGCAUSE_BN 0x10
 194#define DEBUGCAUSE_DI 0x20
 195#define DEBUGCAUSE_DBNUM 0xf00
 196#define DEBUGCAUSE_DBNUM_SHIFT 8
 197
 198#define DBREAKC_SB 0x80000000
 199#define DBREAKC_LB 0x40000000
 200#define DBREAKC_SB_LB (DBREAKC_SB | DBREAKC_LB)
 201#define DBREAKC_MASK 0x3f
 202
 203#define MEMCTL_INIT 0x00800000
 204#define MEMCTL_IUSEWAYS_SHIFT 18
 205#define MEMCTL_IUSEWAYS_LEN 5
 206#define MEMCTL_IUSEWAYS_MASK 0x007c0000
 207#define MEMCTL_DALLOCWAYS_SHIFT 13
 208#define MEMCTL_DALLOCWAYS_LEN 5
 209#define MEMCTL_DALLOCWAYS_MASK 0x0003e000
 210#define MEMCTL_DUSEWAYS_SHIFT 8
 211#define MEMCTL_DUSEWAYS_LEN 5
 212#define MEMCTL_DUSEWAYS_MASK 0x00001f00
 213#define MEMCTL_ISNP 0x4
 214#define MEMCTL_DSNP 0x2
 215#define MEMCTL_IL0EN 0x1
 216
 217#define MAX_INSN_LENGTH 64
 218#define MAX_INSNBUF_LENGTH \
 219    ((MAX_INSN_LENGTH + sizeof(xtensa_insnbuf_word) - 1) / \
 220     sizeof(xtensa_insnbuf_word))
 221#define MAX_INSN_SLOTS 32
 222#define MAX_OPCODE_ARGS 16
 223#define MAX_NAREG 64
 224#define MAX_NINTERRUPT 32
 225#define MAX_NLEVEL 6
 226#define MAX_NNMI 1
 227#define MAX_NCCOMPARE 3
 228#define MAX_TLB_WAY_SIZE 8
 229#define MAX_NDBREAK 2
 230#define MAX_NMEMORY 4
 231#define MAX_MPU_FOREGROUND_SEGMENTS 32
 232
 233#define REGION_PAGE_MASK 0xe0000000
 234
 235#define PAGE_CACHE_MASK    0x700
 236#define PAGE_CACHE_SHIFT   8
 237#define PAGE_CACHE_INVALID 0x000
 238#define PAGE_CACHE_BYPASS  0x100
 239#define PAGE_CACHE_WT      0x200
 240#define PAGE_CACHE_WB      0x400
 241#define PAGE_CACHE_ISOLATE 0x600
 242
 243enum {
 244    /* Static vectors */
 245    EXC_RESET0,
 246    EXC_RESET1,
 247    EXC_MEMORY_ERROR,
 248
 249    /* Dynamic vectors */
 250    EXC_WINDOW_OVERFLOW4,
 251    EXC_WINDOW_UNDERFLOW4,
 252    EXC_WINDOW_OVERFLOW8,
 253    EXC_WINDOW_UNDERFLOW8,
 254    EXC_WINDOW_OVERFLOW12,
 255    EXC_WINDOW_UNDERFLOW12,
 256    EXC_IRQ,
 257    EXC_KERNEL,
 258    EXC_USER,
 259    EXC_DOUBLE,
 260    EXC_DEBUG,
 261    EXC_MAX
 262};
 263
 264enum {
 265    ILLEGAL_INSTRUCTION_CAUSE = 0,
 266    SYSCALL_CAUSE,
 267    INSTRUCTION_FETCH_ERROR_CAUSE,
 268    LOAD_STORE_ERROR_CAUSE,
 269    LEVEL1_INTERRUPT_CAUSE,
 270    ALLOCA_CAUSE,
 271    INTEGER_DIVIDE_BY_ZERO_CAUSE,
 272    PC_VALUE_ERROR_CAUSE,
 273    PRIVILEGED_CAUSE,
 274    LOAD_STORE_ALIGNMENT_CAUSE,
 275    EXTERNAL_REG_PRIVILEGE_CAUSE,
 276    EXCLUSIVE_ERROR_CAUSE,
 277    INSTR_PIF_DATA_ERROR_CAUSE,
 278    LOAD_STORE_PIF_DATA_ERROR_CAUSE,
 279    INSTR_PIF_ADDR_ERROR_CAUSE,
 280    LOAD_STORE_PIF_ADDR_ERROR_CAUSE,
 281    INST_TLB_MISS_CAUSE,
 282    INST_TLB_MULTI_HIT_CAUSE,
 283    INST_FETCH_PRIVILEGE_CAUSE,
 284    INST_FETCH_PROHIBITED_CAUSE = 20,
 285    LOAD_STORE_TLB_MISS_CAUSE = 24,
 286    LOAD_STORE_TLB_MULTI_HIT_CAUSE,
 287    LOAD_STORE_PRIVILEGE_CAUSE,
 288    LOAD_PROHIBITED_CAUSE = 28,
 289    STORE_PROHIBITED_CAUSE,
 290
 291    COPROCESSOR0_DISABLED = 32,
 292};
 293
 294typedef enum {
 295    INTTYPE_LEVEL,
 296    INTTYPE_EDGE,
 297    INTTYPE_NMI,
 298    INTTYPE_SOFTWARE,
 299    INTTYPE_TIMER,
 300    INTTYPE_DEBUG,
 301    INTTYPE_WRITE_ERR,
 302    INTTYPE_PROFILING,
 303    INTTYPE_IDMA_DONE,
 304    INTTYPE_IDMA_ERR,
 305    INTTYPE_GS_ERR,
 306    INTTYPE_MAX
 307} interrupt_type;
 308
 309struct CPUXtensaState;
 310
 311typedef struct xtensa_tlb_entry {
 312    uint32_t vaddr;
 313    uint32_t paddr;
 314    uint8_t asid;
 315    uint8_t attr;
 316    bool variable;
 317} xtensa_tlb_entry;
 318
 319typedef struct xtensa_tlb {
 320    unsigned nways;
 321    const unsigned way_size[10];
 322    bool varway56;
 323    unsigned nrefillentries;
 324} xtensa_tlb;
 325
 326typedef struct xtensa_mpu_entry {
 327    uint32_t vaddr;
 328    uint32_t attr;
 329} xtensa_mpu_entry;
 330
 331typedef struct XtensaGdbReg {
 332    int targno;
 333    unsigned flags;
 334    int type;
 335    int group;
 336    unsigned size;
 337} XtensaGdbReg;
 338
 339typedef struct XtensaGdbRegmap {
 340    int num_regs;
 341    int num_core_regs;
 342    /* PC + a + ar + sr + ur */
 343    XtensaGdbReg reg[1 + 16 + 64 + 256 + 256];
 344} XtensaGdbRegmap;
 345
 346typedef struct XtensaCcompareTimer {
 347    struct CPUXtensaState *env;
 348    QEMUTimer *timer;
 349} XtensaCcompareTimer;
 350
 351typedef struct XtensaMemory {
 352    unsigned num;
 353    struct XtensaMemoryRegion {
 354        uint32_t addr;
 355        uint32_t size;
 356    } location[MAX_NMEMORY];
 357} XtensaMemory;
 358
 359typedef struct opcode_arg {
 360    uint32_t imm;
 361    uint32_t raw_imm;
 362    void *in;
 363    void *out;
 364    uint32_t num_bits;
 365} OpcodeArg;
 366
 367typedef struct DisasContext DisasContext;
 368typedef void (*XtensaOpcodeOp)(DisasContext *dc, const OpcodeArg arg[],
 369                               const uint32_t par[]);
 370typedef uint32_t (*XtensaOpcodeUintTest)(DisasContext *dc,
 371                                         const OpcodeArg arg[],
 372                                         const uint32_t par[]);
 373
 374enum {
 375    XTENSA_OP_ILL = 0x1,
 376    XTENSA_OP_PRIVILEGED = 0x2,
 377    XTENSA_OP_SYSCALL = 0x4,
 378    XTENSA_OP_DEBUG_BREAK = 0x8,
 379
 380    XTENSA_OP_OVERFLOW = 0x10,
 381    XTENSA_OP_UNDERFLOW = 0x20,
 382    XTENSA_OP_ALLOCA = 0x40,
 383    XTENSA_OP_COPROCESSOR = 0x80,
 384
 385    XTENSA_OP_DIVIDE_BY_ZERO = 0x100,
 386
 387    /* Postprocessing flags */
 388    XTENSA_OP_CHECK_INTERRUPTS = 0x200,
 389    XTENSA_OP_EXIT_TB_M1 = 0x400,
 390    XTENSA_OP_EXIT_TB_0 = 0x800,
 391    XTENSA_OP_SYNC_REGISTER_WINDOW = 0x1000,
 392
 393    XTENSA_OP_POSTPROCESS =
 394        XTENSA_OP_CHECK_INTERRUPTS |
 395        XTENSA_OP_EXIT_TB_M1 |
 396        XTENSA_OP_EXIT_TB_0 |
 397        XTENSA_OP_SYNC_REGISTER_WINDOW,
 398
 399    XTENSA_OP_NAME_ARRAY = 0x8000,
 400
 401    XTENSA_OP_CONTROL_FLOW = 0x10000,
 402    XTENSA_OP_STORE = 0x20000,
 403    XTENSA_OP_LOAD = 0x40000,
 404    XTENSA_OP_LOAD_STORE =
 405        XTENSA_OP_LOAD | XTENSA_OP_STORE,
 406};
 407
 408typedef struct XtensaOpcodeOps {
 409    const void *name;
 410    XtensaOpcodeOp translate;
 411    XtensaOpcodeUintTest test_exceptions;
 412    XtensaOpcodeUintTest test_overflow;
 413    const uint32_t *par;
 414    uint32_t op_flags;
 415    uint32_t coprocessor;
 416} XtensaOpcodeOps;
 417
 418typedef struct XtensaOpcodeTranslators {
 419    unsigned num_opcodes;
 420    const XtensaOpcodeOps *opcode;
 421} XtensaOpcodeTranslators;
 422
 423extern const XtensaOpcodeTranslators xtensa_core_opcodes;
 424extern const XtensaOpcodeTranslators xtensa_fpu2000_opcodes;
 425extern const XtensaOpcodeTranslators xtensa_fpu_opcodes;
 426
 427struct XtensaConfig {
 428    const char *name;
 429    uint64_t options;
 430    XtensaGdbRegmap gdb_regmap;
 431    unsigned nareg;
 432    int excm_level;
 433    int ndepc;
 434    unsigned inst_fetch_width;
 435    unsigned max_insn_size;
 436    uint32_t vecbase;
 437    uint32_t exception_vector[EXC_MAX];
 438    unsigned ninterrupt;
 439    unsigned nlevel;
 440    unsigned nmi_level;
 441    uint32_t interrupt_vector[MAX_NLEVEL + MAX_NNMI + 1];
 442    uint32_t level_mask[MAX_NLEVEL + MAX_NNMI + 1];
 443    uint32_t inttype_mask[INTTYPE_MAX];
 444    struct {
 445        uint32_t level;
 446        interrupt_type inttype;
 447    } interrupt[MAX_NINTERRUPT];
 448    unsigned nccompare;
 449    uint32_t timerint[MAX_NCCOMPARE];
 450    unsigned nextint;
 451    unsigned extint[MAX_NINTERRUPT];
 452
 453    unsigned debug_level;
 454    unsigned nibreak;
 455    unsigned ndbreak;
 456
 457    unsigned icache_ways;
 458    unsigned dcache_ways;
 459    unsigned dcache_line_bytes;
 460    uint32_t memctl_mask;
 461
 462    XtensaMemory instrom;
 463    XtensaMemory instram;
 464    XtensaMemory datarom;
 465    XtensaMemory dataram;
 466    XtensaMemory sysrom;
 467    XtensaMemory sysram;
 468
 469    unsigned hw_version;
 470    uint32_t configid[2];
 471
 472    void *isa_internal;
 473    xtensa_isa isa;
 474    XtensaOpcodeOps **opcode_ops;
 475    const XtensaOpcodeTranslators **opcode_translators;
 476    xtensa_regfile a_regfile;
 477    void ***regfile;
 478
 479    uint32_t clock_freq_khz;
 480
 481    xtensa_tlb itlb;
 482    xtensa_tlb dtlb;
 483
 484    uint32_t mpu_align;
 485    unsigned n_mpu_fg_segments;
 486    unsigned n_mpu_bg_segments;
 487    const xtensa_mpu_entry *mpu_bg;
 488
 489    bool use_first_nan;
 490};
 491
 492typedef struct XtensaConfigList {
 493    const XtensaConfig *config;
 494    struct XtensaConfigList *next;
 495} XtensaConfigList;
 496
 497#ifdef HOST_WORDS_BIGENDIAN
 498enum {
 499    FP_F32_HIGH,
 500    FP_F32_LOW,
 501};
 502#else
 503enum {
 504    FP_F32_LOW,
 505    FP_F32_HIGH,
 506};
 507#endif
 508
 509typedef struct CPUXtensaState {
 510    const XtensaConfig *config;
 511    uint32_t regs[16];
 512    uint32_t pc;
 513    uint32_t sregs[256];
 514    uint32_t uregs[256];
 515    uint32_t phys_regs[MAX_NAREG];
 516    union {
 517        float32 f32[2];
 518        float64 f64;
 519    } fregs[16];
 520    float_status fp_status;
 521    uint32_t windowbase_next;
 522    uint32_t exclusive_addr;
 523    uint32_t exclusive_val;
 524
 525#ifndef CONFIG_USER_ONLY
 526    xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE];
 527    xtensa_tlb_entry dtlb[10][MAX_TLB_WAY_SIZE];
 528    xtensa_mpu_entry mpu_fg[MAX_MPU_FOREGROUND_SEGMENTS];
 529    unsigned autorefill_idx;
 530    bool runstall;
 531    AddressSpace *address_space_er;
 532    MemoryRegion *system_er;
 533    int pending_irq_level; /* level of last raised IRQ */
 534    qemu_irq *irq_inputs;
 535    qemu_irq ext_irq_inputs[MAX_NINTERRUPT];
 536    qemu_irq runstall_irq;
 537    XtensaCcompareTimer ccompare[MAX_NCCOMPARE];
 538    uint64_t time_base;
 539    uint64_t ccount_time;
 540    uint32_t ccount_base;
 541#endif
 542
 543    int yield_needed;
 544    unsigned static_vectors;
 545
 546    /* Watchpoints for DBREAK registers */
 547    struct CPUWatchpoint *cpu_watchpoint[MAX_NDBREAK];
 548} CPUXtensaState;
 549
 550/**
 551 * XtensaCPU:
 552 * @env: #CPUXtensaState
 553 *
 554 * An Xtensa CPU.
 555 */
 556struct XtensaCPU {
 557    /*< private >*/
 558    CPUState parent_obj;
 559    /*< public >*/
 560
 561    CPUNegativeOffsetState neg;
 562    CPUXtensaState env;
 563};
 564
 565
 566#ifndef CONFIG_USER_ONLY
 567bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 568                         MMUAccessType access_type, int mmu_idx,
 569                         bool probe, uintptr_t retaddr);
 570void xtensa_cpu_do_interrupt(CPUState *cpu);
 571bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
 572void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
 573                                      unsigned size, MMUAccessType access_type,
 574                                      int mmu_idx, MemTxAttrs attrs,
 575                                      MemTxResult response, uintptr_t retaddr);
 576#endif
 577void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
 578hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 579void xtensa_count_regs(const XtensaConfig *config,
 580                       unsigned *n_regs, unsigned *n_core_regs);
 581int xtensa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 582int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 583void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
 584                                    MMUAccessType access_type, int mmu_idx,
 585                                    uintptr_t retaddr) QEMU_NORETURN;
 586
 587#define cpu_list xtensa_cpu_list
 588
 589#define XTENSA_CPU_TYPE_SUFFIX "-" TYPE_XTENSA_CPU
 590#define XTENSA_CPU_TYPE_NAME(model) model XTENSA_CPU_TYPE_SUFFIX
 591#define CPU_RESOLVING_TYPE TYPE_XTENSA_CPU
 592
 593#ifdef TARGET_WORDS_BIGENDIAN
 594#define XTENSA_DEFAULT_CPU_MODEL "fsf"
 595#define XTENSA_DEFAULT_CPU_NOMMU_MODEL "fsf"
 596#else
 597#define XTENSA_DEFAULT_CPU_MODEL "dc232b"
 598#define XTENSA_DEFAULT_CPU_NOMMU_MODEL "de212"
 599#endif
 600#define XTENSA_DEFAULT_CPU_TYPE \
 601    XTENSA_CPU_TYPE_NAME(XTENSA_DEFAULT_CPU_MODEL)
 602#define XTENSA_DEFAULT_CPU_NOMMU_TYPE \
 603    XTENSA_CPU_TYPE_NAME(XTENSA_DEFAULT_CPU_NOMMU_MODEL)
 604
 605void xtensa_collect_sr_names(const XtensaConfig *config);
 606void xtensa_translate_init(void);
 607void **xtensa_get_regfile_by_name(const char *name, int entries, int bits);
 608void xtensa_breakpoint_handler(CPUState *cs);
 609void xtensa_register_core(XtensaConfigList *node);
 610void xtensa_sim_open_console(Chardev *chr);
 611void check_interrupts(CPUXtensaState *s);
 612void xtensa_irq_init(CPUXtensaState *env);
 613qemu_irq *xtensa_get_extints(CPUXtensaState *env);
 614qemu_irq xtensa_get_runstall(CPUXtensaState *env);
 615void xtensa_cpu_list(void);
 616void xtensa_sync_window_from_phys(CPUXtensaState *env);
 617void xtensa_sync_phys_from_window(CPUXtensaState *env);
 618void xtensa_rotate_window(CPUXtensaState *env, uint32_t delta);
 619void xtensa_restore_owb(CPUXtensaState *env);
 620void debug_exception_env(CPUXtensaState *new_env, uint32_t cause);
 621
 622static inline void xtensa_select_static_vectors(CPUXtensaState *env,
 623                                                unsigned n)
 624{
 625    assert(n < 2);
 626    env->static_vectors = n;
 627}
 628void xtensa_runstall(CPUXtensaState *env, bool runstall);
 629
 630#define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
 631#define XTENSA_OPTION_ALL (~(uint64_t)0)
 632
 633static inline bool xtensa_option_bits_enabled(const XtensaConfig *config,
 634        uint64_t opt)
 635{
 636    return (config->options & opt) != 0;
 637}
 638
 639static inline bool xtensa_option_enabled(const XtensaConfig *config, int opt)
 640{
 641    return xtensa_option_bits_enabled(config, XTENSA_OPTION_BIT(opt));
 642}
 643
 644static inline int xtensa_get_cintlevel(const CPUXtensaState *env)
 645{
 646    int level = (env->sregs[PS] & PS_INTLEVEL) >> PS_INTLEVEL_SHIFT;
 647    if ((env->sregs[PS] & PS_EXCM) && env->config->excm_level > level) {
 648        level = env->config->excm_level;
 649    }
 650    return level;
 651}
 652
 653static inline int xtensa_get_ring(const CPUXtensaState *env)
 654{
 655    if (xtensa_option_bits_enabled(env->config,
 656                                   XTENSA_OPTION_BIT(XTENSA_OPTION_MMU) |
 657                                   XTENSA_OPTION_BIT(XTENSA_OPTION_MPU))) {
 658        return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
 659    } else {
 660        return 0;
 661    }
 662}
 663
 664static inline int xtensa_get_cring(const CPUXtensaState *env)
 665{
 666    if (xtensa_option_bits_enabled(env->config,
 667                                   XTENSA_OPTION_BIT(XTENSA_OPTION_MMU) |
 668                                   XTENSA_OPTION_BIT(XTENSA_OPTION_MPU)) &&
 669        (env->sregs[PS] & PS_EXCM) == 0) {
 670        return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
 671    } else {
 672        return 0;
 673    }
 674}
 675
 676#ifndef CONFIG_USER_ONLY
 677int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
 678        uint32_t vaddr, int is_write, int mmu_idx,
 679        uint32_t *paddr, uint32_t *page_size, unsigned *access);
 680void reset_mmu(CPUXtensaState *env);
 681void dump_mmu(CPUXtensaState *env);
 682
 683static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env)
 684{
 685    return env->system_er;
 686}
 687#else
 688void xtensa_set_abi_call0(void);
 689bool xtensa_abi_call0(void);
 690#endif
 691
 692static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env)
 693{
 694    return env->sregs[WINDOW_START] |
 695        (env->sregs[WINDOW_START] << env->config->nareg / 4);
 696}
 697
 698/* MMU modes definitions */
 699#define MMU_USER_IDX 3
 700
 701static inline int cpu_mmu_index(CPUXtensaState *env, bool ifetch)
 702{
 703    return xtensa_get_cring(env);
 704}
 705
 706#define XTENSA_TBFLAG_RING_MASK 0x3
 707#define XTENSA_TBFLAG_EXCM 0x4
 708#define XTENSA_TBFLAG_LITBASE 0x8
 709#define XTENSA_TBFLAG_DEBUG 0x10
 710#define XTENSA_TBFLAG_ICOUNT 0x20
 711#define XTENSA_TBFLAG_CPENABLE_MASK 0x3fc0
 712#define XTENSA_TBFLAG_CPENABLE_SHIFT 6
 713#define XTENSA_TBFLAG_WINDOW_MASK 0x18000
 714#define XTENSA_TBFLAG_WINDOW_SHIFT 15
 715#define XTENSA_TBFLAG_YIELD 0x20000
 716#define XTENSA_TBFLAG_CWOE 0x40000
 717#define XTENSA_TBFLAG_CALLINC_MASK 0x180000
 718#define XTENSA_TBFLAG_CALLINC_SHIFT 19
 719
 720#define XTENSA_CSBASE_LEND_MASK 0x0000ffff
 721#define XTENSA_CSBASE_LEND_SHIFT 0
 722#define XTENSA_CSBASE_LBEG_OFF_MASK 0x00ff0000
 723#define XTENSA_CSBASE_LBEG_OFF_SHIFT 16
 724
 725typedef CPUXtensaState CPUArchState;
 726typedef XtensaCPU ArchCPU;
 727
 728#include "exec/cpu-all.h"
 729
 730static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
 731        target_ulong *cs_base, uint32_t *flags)
 732{
 733    *pc = env->pc;
 734    *cs_base = 0;
 735    *flags = 0;
 736    *flags |= xtensa_get_ring(env);
 737    if (env->sregs[PS] & PS_EXCM) {
 738        *flags |= XTENSA_TBFLAG_EXCM;
 739    } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_LOOP)) {
 740        target_ulong lend_dist =
 741            env->sregs[LEND] - (env->pc & -(1u << TARGET_PAGE_BITS));
 742
 743        /*
 744         * 0 in the csbase_lend field means that there may not be a loopback
 745         * for any instruction that starts inside this page. Any other value
 746         * means that an instruction that ends at this offset from the page
 747         * start may loop back and will need loopback code to be generated.
 748         *
 749         * lend_dist is 0 when LEND points to the start of the page, but
 750         * no instruction that starts inside this page may end at offset 0,
 751         * so it's still correct.
 752         *
 753         * When an instruction ends at a page boundary it may only start in
 754         * the previous page. lend_dist will be encoded as TARGET_PAGE_SIZE
 755         * for the TB that contains this instruction.
 756         */
 757        if (lend_dist < (1u << TARGET_PAGE_BITS) + env->config->max_insn_size) {
 758            target_ulong lbeg_off = env->sregs[LEND] - env->sregs[LBEG];
 759
 760            *cs_base = lend_dist;
 761            if (lbeg_off < 256) {
 762                *cs_base |= lbeg_off << XTENSA_CSBASE_LBEG_OFF_SHIFT;
 763            }
 764        }
 765    }
 766    if (xtensa_option_enabled(env->config, XTENSA_OPTION_EXTENDED_L32R) &&
 767            (env->sregs[LITBASE] & 1)) {
 768        *flags |= XTENSA_TBFLAG_LITBASE;
 769    }
 770    if (xtensa_option_enabled(env->config, XTENSA_OPTION_DEBUG)) {
 771        if (xtensa_get_cintlevel(env) < env->config->debug_level) {
 772            *flags |= XTENSA_TBFLAG_DEBUG;
 773        }
 774        if (xtensa_get_cintlevel(env) < env->sregs[ICOUNTLEVEL]) {
 775            *flags |= XTENSA_TBFLAG_ICOUNT;
 776        }
 777    }
 778    if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) {
 779        *flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT;
 780    }
 781    if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER) &&
 782        (env->sregs[PS] & (PS_WOE | PS_EXCM)) == PS_WOE) {
 783        uint32_t windowstart = xtensa_replicate_windowstart(env) >>
 784            (env->sregs[WINDOW_BASE] + 1);
 785        uint32_t w = ctz32(windowstart | 0x8);
 786
 787        *flags |= (w << XTENSA_TBFLAG_WINDOW_SHIFT) | XTENSA_TBFLAG_CWOE;
 788        *flags |= extract32(env->sregs[PS], PS_CALLINC_SHIFT,
 789                            PS_CALLINC_LEN) << XTENSA_TBFLAG_CALLINC_SHIFT;
 790    } else {
 791        *flags |= 3 << XTENSA_TBFLAG_WINDOW_SHIFT;
 792    }
 793    if (env->yield_needed) {
 794        *flags |= XTENSA_TBFLAG_YIELD;
 795    }
 796}
 797
 798#endif
 799