cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

cpu.h (22691B)


      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
    566bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
    567                         MMUAccessType access_type, int mmu_idx,
    568                         bool probe, uintptr_t retaddr);
    569#ifndef CONFIG_USER_ONLY
    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