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