xref: /openbmc/qemu/target/xtensa/cpu.h (revision f15f7273ea55472d5904c53566c82369d81214c1)
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  enum {
38      /* Additional instructions */
39      XTENSA_OPTION_CODE_DENSITY,
40      XTENSA_OPTION_LOOP,
41      XTENSA_OPTION_EXTENDED_L32R,
42      XTENSA_OPTION_16_BIT_IMUL,
43      XTENSA_OPTION_32_BIT_IMUL,
44      XTENSA_OPTION_32_BIT_IMUL_HIGH,
45      XTENSA_OPTION_32_BIT_IDIV,
46      XTENSA_OPTION_MAC16,
47      XTENSA_OPTION_MISC_OP_NSA,
48      XTENSA_OPTION_MISC_OP_MINMAX,
49      XTENSA_OPTION_MISC_OP_SEXT,
50      XTENSA_OPTION_MISC_OP_CLAMPS,
51      XTENSA_OPTION_COPROCESSOR,
52      XTENSA_OPTION_BOOLEAN,
53      XTENSA_OPTION_FP_COPROCESSOR,
54      XTENSA_OPTION_DFP_COPROCESSOR,
55      XTENSA_OPTION_DFPU_SINGLE_ONLY,
56      XTENSA_OPTION_MP_SYNCHRO,
57      XTENSA_OPTION_CONDITIONAL_STORE,
58      XTENSA_OPTION_ATOMCTL,
59      XTENSA_OPTION_DEPBITS,
60  
61      /* Interrupts and exceptions */
62      XTENSA_OPTION_EXCEPTION,
63      XTENSA_OPTION_RELOCATABLE_VECTOR,
64      XTENSA_OPTION_UNALIGNED_EXCEPTION,
65      XTENSA_OPTION_INTERRUPT,
66      XTENSA_OPTION_HIGH_PRIORITY_INTERRUPT,
67      XTENSA_OPTION_TIMER_INTERRUPT,
68  
69      /* Local memory */
70      XTENSA_OPTION_ICACHE,
71      XTENSA_OPTION_ICACHE_TEST,
72      XTENSA_OPTION_ICACHE_INDEX_LOCK,
73      XTENSA_OPTION_DCACHE,
74      XTENSA_OPTION_DCACHE_TEST,
75      XTENSA_OPTION_DCACHE_INDEX_LOCK,
76      XTENSA_OPTION_IRAM,
77      XTENSA_OPTION_IROM,
78      XTENSA_OPTION_DRAM,
79      XTENSA_OPTION_DROM,
80      XTENSA_OPTION_XLMI,
81      XTENSA_OPTION_HW_ALIGNMENT,
82      XTENSA_OPTION_MEMORY_ECC_PARITY,
83  
84      /* Memory protection and translation */
85      XTENSA_OPTION_REGION_PROTECTION,
86      XTENSA_OPTION_REGION_TRANSLATION,
87      XTENSA_OPTION_MPU,
88      XTENSA_OPTION_MMU,
89      XTENSA_OPTION_CACHEATTR,
90  
91      /* Other */
92      XTENSA_OPTION_WINDOWED_REGISTER,
93      XTENSA_OPTION_PROCESSOR_INTERFACE,
94      XTENSA_OPTION_MISC_SR,
95      XTENSA_OPTION_THREAD_POINTER,
96      XTENSA_OPTION_PROCESSOR_ID,
97      XTENSA_OPTION_DEBUG,
98      XTENSA_OPTION_TRACE_PORT,
99      XTENSA_OPTION_EXTERN_REGS,
100  };
101  
102  enum {
103      EXPSTATE = 230,
104      THREADPTR = 231,
105      FCR = 232,
106      FSR = 233,
107  };
108  
109  enum {
110      LBEG = 0,
111      LEND = 1,
112      LCOUNT = 2,
113      SAR = 3,
114      BR = 4,
115      LITBASE = 5,
116      SCOMPARE1 = 12,
117      ACCLO = 16,
118      ACCHI = 17,
119      MR = 32,
120      PREFCTL = 40,
121      WINDOW_BASE = 72,
122      WINDOW_START = 73,
123      PTEVADDR = 83,
124      MMID = 89,
125      RASID = 90,
126      MPUENB = 90,
127      ITLBCFG = 91,
128      DTLBCFG = 92,
129      MPUCFG = 92,
130      ERACCESS = 95,
131      IBREAKENABLE = 96,
132      MEMCTL = 97,
133      CACHEATTR = 98,
134      CACHEADRDIS = 98,
135      ATOMCTL = 99,
136      DDR = 104,
137      MEPC = 106,
138      MEPS = 107,
139      MESAVE = 108,
140      MESR = 109,
141      MECR = 110,
142      MEVADDR = 111,
143      IBREAKA = 128,
144      DBREAKA = 144,
145      DBREAKC = 160,
146      CONFIGID0 = 176,
147      EPC1 = 177,
148      DEPC = 192,
149      EPS2 = 194,
150      CONFIGID1 = 208,
151      EXCSAVE1 = 209,
152      CPENABLE = 224,
153      INTSET = 226,
154      INTCLEAR = 227,
155      INTENABLE = 228,
156      PS = 230,
157      VECBASE = 231,
158      EXCCAUSE = 232,
159      DEBUGCAUSE = 233,
160      CCOUNT = 234,
161      PRID = 235,
162      ICOUNT = 236,
163      ICOUNTLEVEL = 237,
164      EXCVADDR = 238,
165      CCOMPARE = 240,
166      MISC = 244,
167  };
168  
169  #define PS_INTLEVEL 0xf
170  #define PS_INTLEVEL_SHIFT 0
171  
172  #define PS_EXCM 0x10
173  #define PS_UM 0x20
174  
175  #define PS_RING 0xc0
176  #define PS_RING_SHIFT 6
177  
178  #define PS_OWB 0xf00
179  #define PS_OWB_SHIFT 8
180  #define PS_OWB_LEN 4
181  
182  #define PS_CALLINC 0x30000
183  #define PS_CALLINC_SHIFT 16
184  #define PS_CALLINC_LEN 2
185  
186  #define PS_WOE 0x40000
187  
188  #define DEBUGCAUSE_IC 0x1
189  #define DEBUGCAUSE_IB 0x2
190  #define DEBUGCAUSE_DB 0x4
191  #define DEBUGCAUSE_BI 0x8
192  #define DEBUGCAUSE_BN 0x10
193  #define DEBUGCAUSE_DI 0x20
194  #define DEBUGCAUSE_DBNUM 0xf00
195  #define DEBUGCAUSE_DBNUM_SHIFT 8
196  
197  #define DBREAKC_SB 0x80000000
198  #define DBREAKC_LB 0x40000000
199  #define DBREAKC_SB_LB (DBREAKC_SB | DBREAKC_LB)
200  #define DBREAKC_MASK 0x3f
201  
202  #define MEMCTL_INIT 0x00800000
203  #define MEMCTL_IUSEWAYS_SHIFT 18
204  #define MEMCTL_IUSEWAYS_LEN 5
205  #define MEMCTL_IUSEWAYS_MASK 0x007c0000
206  #define MEMCTL_DALLOCWAYS_SHIFT 13
207  #define MEMCTL_DALLOCWAYS_LEN 5
208  #define MEMCTL_DALLOCWAYS_MASK 0x0003e000
209  #define MEMCTL_DUSEWAYS_SHIFT 8
210  #define MEMCTL_DUSEWAYS_LEN 5
211  #define MEMCTL_DUSEWAYS_MASK 0x00001f00
212  #define MEMCTL_ISNP 0x4
213  #define MEMCTL_DSNP 0x2
214  #define MEMCTL_IL0EN 0x1
215  
216  #define MAX_INSN_LENGTH 64
217  #define MAX_INSNBUF_LENGTH \
218      ((MAX_INSN_LENGTH + sizeof(xtensa_insnbuf_word) - 1) / \
219       sizeof(xtensa_insnbuf_word))
220  #define MAX_INSN_SLOTS 32
221  #define MAX_OPCODE_ARGS 16
222  #define MAX_NAREG 64
223  #define MAX_NINTERRUPT 32
224  #define MAX_NLEVEL 6
225  #define MAX_NNMI 1
226  #define MAX_NCCOMPARE 3
227  #define MAX_TLB_WAY_SIZE 8
228  #define MAX_NDBREAK 2
229  #define MAX_NIBREAK 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  
243  enum {
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  
264  enum {
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  
294  typedef 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  
309  typedef struct CPUArchState CPUXtensaState;
310  
311  typedef 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  
319  typedef struct xtensa_tlb {
320      unsigned nways;
321      const unsigned way_size[10];
322      bool varway56;
323      unsigned nrefillentries;
324  } xtensa_tlb;
325  
326  typedef struct xtensa_mpu_entry {
327      uint32_t vaddr;
328      uint32_t attr;
329  } xtensa_mpu_entry;
330  
331  typedef struct XtensaGdbReg {
332      int targno;
333      unsigned flags;
334      int type;
335      int group;
336      unsigned size;
337  } XtensaGdbReg;
338  
339  typedef 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  
346  typedef struct XtensaCcompareTimer {
347      CPUXtensaState *env;
348      QEMUTimer *timer;
349  } XtensaCcompareTimer;
350  
351  typedef struct XtensaMemory {
352      unsigned num;
353      struct XtensaMemoryRegion {
354          uint32_t addr;
355          uint32_t size;
356      } location[MAX_NMEMORY];
357  } XtensaMemory;
358  
359  typedef 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  
367  typedef struct DisasContext DisasContext;
368  typedef void (*XtensaOpcodeOp)(DisasContext *dc, const OpcodeArg arg[],
369                                 const uint32_t par[]);
370  typedef uint32_t (*XtensaOpcodeUintTest)(DisasContext *dc,
371                                           const OpcodeArg arg[],
372                                           const uint32_t par[]);
373  
374  enum {
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  
408  typedef 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  
418  typedef struct XtensaOpcodeTranslators {
419      unsigned num_opcodes;
420      const XtensaOpcodeOps *opcode;
421  } XtensaOpcodeTranslators;
422  
423  extern const XtensaOpcodeTranslators xtensa_core_opcodes;
424  extern const XtensaOpcodeTranslators xtensa_fpu2000_opcodes;
425  extern const XtensaOpcodeTranslators xtensa_fpu_opcodes;
426  
427  typedef struct 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  } XtensaConfig;
491  
492  typedef struct XtensaConfigList {
493      const XtensaConfig *config;
494      struct XtensaConfigList *next;
495  } XtensaConfigList;
496  
497  #if HOST_BIG_ENDIAN
498  enum {
499      FP_F32_HIGH,
500      FP_F32_LOW,
501  };
502  #else
503  enum {
504      FP_F32_LOW,
505      FP_F32_HIGH,
506  };
507  #endif
508  
509  struct CPUArchState {
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      /* Breakpoints for IBREAK registers */
549      struct CPUBreakpoint *cpu_breakpoint[MAX_NIBREAK];
550  };
551  
552  /**
553   * XtensaCPU:
554   * @env: #CPUXtensaState
555   *
556   * An Xtensa CPU.
557   */
558  struct ArchCPU {
559      CPUState parent_obj;
560  
561      CPUXtensaState env;
562      Clock *clock;
563  };
564  
565  /**
566   * XtensaCPUClass:
567   * @parent_realize: The parent class' realize handler.
568   * @parent_phases: The parent class' reset phase handlers.
569   * @config: The CPU core configuration.
570   *
571   * An Xtensa CPU model.
572   */
573  struct XtensaCPUClass {
574      CPUClass parent_class;
575  
576      DeviceRealize parent_realize;
577      ResettablePhases parent_phases;
578  
579      const XtensaConfig *config;
580  };
581  
582  #ifndef CONFIG_USER_ONLY
583  bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
584                           MMUAccessType access_type, int mmu_idx,
585                           bool probe, uintptr_t retaddr);
586  void xtensa_cpu_do_interrupt(CPUState *cpu);
587  bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
588  void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
589                                        unsigned size, MMUAccessType access_type,
590                                        int mmu_idx, MemTxAttrs attrs,
591                                        MemTxResult response, uintptr_t retaddr);
592  hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
593  bool xtensa_debug_check_breakpoint(CPUState *cs);
594  #endif
595  void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
596  void xtensa_count_regs(const XtensaConfig *config,
597                         unsigned *n_regs, unsigned *n_core_regs);
598  int xtensa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
599  int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
600  G_NORETURN void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
601                                                 MMUAccessType access_type, int mmu_idx,
602                                                 uintptr_t retaddr);
603  
604  #define CPU_RESOLVING_TYPE TYPE_XTENSA_CPU
605  
606  #if TARGET_BIG_ENDIAN
607  #define XTENSA_DEFAULT_CPU_MODEL "fsf"
608  #define XTENSA_DEFAULT_CPU_NOMMU_MODEL "fsf"
609  #else
610  #define XTENSA_DEFAULT_CPU_MODEL "dc232b"
611  #define XTENSA_DEFAULT_CPU_NOMMU_MODEL "de212"
612  #endif
613  #define XTENSA_DEFAULT_CPU_TYPE \
614      XTENSA_CPU_TYPE_NAME(XTENSA_DEFAULT_CPU_MODEL)
615  #define XTENSA_DEFAULT_CPU_NOMMU_TYPE \
616      XTENSA_CPU_TYPE_NAME(XTENSA_DEFAULT_CPU_NOMMU_MODEL)
617  
618  void xtensa_collect_sr_names(const XtensaConfig *config);
619  void xtensa_translate_init(void);
620  void **xtensa_get_regfile_by_name(const char *name, int entries, int bits);
621  void xtensa_breakpoint_handler(CPUState *cs);
622  void xtensa_register_core(XtensaConfigList *node);
623  void xtensa_sim_open_console(Chardev *chr);
624  void check_interrupts(CPUXtensaState *s);
625  void xtensa_irq_init(CPUXtensaState *env);
626  qemu_irq *xtensa_get_extints(CPUXtensaState *env);
627  qemu_irq xtensa_get_runstall(CPUXtensaState *env);
628  void xtensa_sync_window_from_phys(CPUXtensaState *env);
629  void xtensa_sync_phys_from_window(CPUXtensaState *env);
630  void xtensa_rotate_window(CPUXtensaState *env, uint32_t delta);
631  void xtensa_restore_owb(CPUXtensaState *env);
632  void debug_exception_env(CPUXtensaState *new_env, uint32_t cause);
633  
xtensa_select_static_vectors(CPUXtensaState * env,unsigned n)634  static inline void xtensa_select_static_vectors(CPUXtensaState *env,
635                                                  unsigned n)
636  {
637      assert(n < 2);
638      env->static_vectors = n;
639  }
640  void xtensa_runstall(CPUXtensaState *env, bool runstall);
641  
642  #define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
643  #define XTENSA_OPTION_ALL (~(uint64_t)0)
644  
xtensa_option_bits_enabled(const XtensaConfig * config,uint64_t opt)645  static inline bool xtensa_option_bits_enabled(const XtensaConfig *config,
646          uint64_t opt)
647  {
648      return (config->options & opt) != 0;
649  }
650  
xtensa_option_enabled(const XtensaConfig * config,int opt)651  static inline bool xtensa_option_enabled(const XtensaConfig *config, int opt)
652  {
653      return xtensa_option_bits_enabled(config, XTENSA_OPTION_BIT(opt));
654  }
655  
xtensa_get_cintlevel(const CPUXtensaState * env)656  static inline int xtensa_get_cintlevel(const CPUXtensaState *env)
657  {
658      int level = (env->sregs[PS] & PS_INTLEVEL) >> PS_INTLEVEL_SHIFT;
659      if ((env->sregs[PS] & PS_EXCM) && env->config->excm_level > level) {
660          level = env->config->excm_level;
661      }
662      return level;
663  }
664  
xtensa_get_ring(const CPUXtensaState * env)665  static inline int xtensa_get_ring(const CPUXtensaState *env)
666  {
667      if (xtensa_option_bits_enabled(env->config,
668                                     XTENSA_OPTION_BIT(XTENSA_OPTION_MMU) |
669                                     XTENSA_OPTION_BIT(XTENSA_OPTION_MPU))) {
670          return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
671      } else {
672          return 0;
673      }
674  }
675  
xtensa_get_cring(const CPUXtensaState * env)676  static inline int xtensa_get_cring(const CPUXtensaState *env)
677  {
678      if (xtensa_option_bits_enabled(env->config,
679                                     XTENSA_OPTION_BIT(XTENSA_OPTION_MMU) |
680                                     XTENSA_OPTION_BIT(XTENSA_OPTION_MPU)) &&
681          (env->sregs[PS] & PS_EXCM) == 0) {
682          return (env->sregs[PS] & PS_RING) >> PS_RING_SHIFT;
683      } else {
684          return 0;
685      }
686  }
687  
688  #ifndef CONFIG_USER_ONLY
689  int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb,
690          uint32_t vaddr, int is_write, int mmu_idx,
691          uint32_t *paddr, uint32_t *page_size, unsigned *access);
692  void reset_mmu(CPUXtensaState *env);
693  void dump_mmu(CPUXtensaState *env);
694  
xtensa_get_er_region(CPUXtensaState * env)695  static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env)
696  {
697      return env->system_er;
698  }
699  #else
700  void xtensa_set_abi_call0(void);
701  bool xtensa_abi_call0(void);
702  #endif
703  
xtensa_replicate_windowstart(CPUXtensaState * env)704  static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env)
705  {
706      return env->sregs[WINDOW_START] |
707          (env->sregs[WINDOW_START] << env->config->nareg / 4);
708  }
709  
710  /* MMU modes definitions */
711  #define MMU_USER_IDX 3
712  
713  #define XTENSA_TBFLAG_RING_MASK 0x3
714  #define XTENSA_TBFLAG_EXCM 0x4
715  #define XTENSA_TBFLAG_LITBASE 0x8
716  #define XTENSA_TBFLAG_DEBUG 0x10
717  #define XTENSA_TBFLAG_ICOUNT 0x20
718  #define XTENSA_TBFLAG_CPENABLE_MASK 0x3fc0
719  #define XTENSA_TBFLAG_CPENABLE_SHIFT 6
720  #define XTENSA_TBFLAG_WINDOW_MASK 0x18000
721  #define XTENSA_TBFLAG_WINDOW_SHIFT 15
722  #define XTENSA_TBFLAG_YIELD 0x20000
723  #define XTENSA_TBFLAG_CWOE 0x40000
724  #define XTENSA_TBFLAG_CALLINC_MASK 0x180000
725  #define XTENSA_TBFLAG_CALLINC_SHIFT 19
726  
727  #define XTENSA_CSBASE_LEND_MASK 0x0000ffff
728  #define XTENSA_CSBASE_LEND_SHIFT 0
729  #define XTENSA_CSBASE_LBEG_OFF_MASK 0x00ff0000
730  #define XTENSA_CSBASE_LBEG_OFF_SHIFT 16
731  
732  #include "exec/cpu-all.h"
733  
cpu_get_tb_cpu_state(CPUXtensaState * env,vaddr * pc,uint64_t * cs_base,uint32_t * flags)734  static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, vaddr *pc,
735                                          uint64_t *cs_base, uint32_t *flags)
736  {
737      *pc = env->pc;
738      *cs_base = 0;
739      *flags = 0;
740      *flags |= xtensa_get_ring(env);
741      if (env->sregs[PS] & PS_EXCM) {
742          *flags |= XTENSA_TBFLAG_EXCM;
743      } else if (xtensa_option_enabled(env->config, XTENSA_OPTION_LOOP)) {
744          target_ulong lend_dist =
745              env->sregs[LEND] - (env->pc & -(1u << TARGET_PAGE_BITS));
746  
747          /*
748           * 0 in the csbase_lend field means that there may not be a loopback
749           * for any instruction that starts inside this page. Any other value
750           * means that an instruction that ends at this offset from the page
751           * start may loop back and will need loopback code to be generated.
752           *
753           * lend_dist is 0 when LEND points to the start of the page, but
754           * no instruction that starts inside this page may end at offset 0,
755           * so it's still correct.
756           *
757           * When an instruction ends at a page boundary it may only start in
758           * the previous page. lend_dist will be encoded as TARGET_PAGE_SIZE
759           * for the TB that contains this instruction.
760           */
761          if (lend_dist < (1u << TARGET_PAGE_BITS) + env->config->max_insn_size) {
762              target_ulong lbeg_off = env->sregs[LEND] - env->sregs[LBEG];
763  
764              *cs_base = lend_dist;
765              if (lbeg_off < 256) {
766                  *cs_base |= lbeg_off << XTENSA_CSBASE_LBEG_OFF_SHIFT;
767              }
768          }
769      }
770      if (xtensa_option_enabled(env->config, XTENSA_OPTION_EXTENDED_L32R) &&
771              (env->sregs[LITBASE] & 1)) {
772          *flags |= XTENSA_TBFLAG_LITBASE;
773      }
774      if (xtensa_option_enabled(env->config, XTENSA_OPTION_DEBUG)) {
775          if (xtensa_get_cintlevel(env) < env->config->debug_level) {
776              *flags |= XTENSA_TBFLAG_DEBUG;
777          }
778          if (xtensa_get_cintlevel(env) < env->sregs[ICOUNTLEVEL]) {
779              *flags |= XTENSA_TBFLAG_ICOUNT;
780          }
781      }
782      if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) {
783          *flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT;
784      }
785      if (xtensa_option_enabled(env->config, XTENSA_OPTION_WINDOWED_REGISTER) &&
786          (env->sregs[PS] & (PS_WOE | PS_EXCM)) == PS_WOE) {
787          uint32_t windowstart = xtensa_replicate_windowstart(env) >>
788              (env->sregs[WINDOW_BASE] + 1);
789          uint32_t w = ctz32(windowstart | 0x8);
790  
791          *flags |= (w << XTENSA_TBFLAG_WINDOW_SHIFT) | XTENSA_TBFLAG_CWOE;
792          *flags |= extract32(env->sregs[PS], PS_CALLINC_SHIFT,
793                              PS_CALLINC_LEN) << XTENSA_TBFLAG_CALLINC_SHIFT;
794      } else {
795          *flags |= 3 << XTENSA_TBFLAG_WINDOW_SHIFT;
796      }
797      if (env->yield_needed) {
798          *flags |= XTENSA_TBFLAG_YIELD;
799      }
800  }
801  
802  XtensaCPU *xtensa_cpu_create_with_clock(const char *cpu_type,
803                                          Clock *cpu_refclk);
804  
805  /*
806   * Set the NaN propagation rule for future FPU operations:
807   * use_first is true to pick the first NaN as the result if both
808   * inputs are NaNs, false to pick the second.
809   */
810  void xtensa_use_first_nan(CPUXtensaState *env, bool use_first);
811  #endif
812