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