1#if !defined (__MIPS_CPU_H__)
2#define __MIPS_CPU_H__
3
4
5
6#define ALIGNED_ONLY
7
8#define CPUArchState struct CPUMIPSState
9
10#include "qemu-common.h"
11#include "mips-defs.h"
12#include "exec/cpu-defs.h"
13#include "fpu/softfloat.h"
14
15struct CPUMIPSState;
16
17typedef struct r4k_tlb_t r4k_tlb_t;
18struct r4k_tlb_t {
19 target_ulong VPN;
20 uint32_t PageMask;
21 uint8_t ASID;
22 unsigned int G:1;
23 unsigned int C0:3;
24 unsigned int C1:3;
25 unsigned int V0:1;
26 unsigned int V1:1;
27 unsigned int D0:1;
28 unsigned int D1:1;
29 unsigned int XI0:1;
30 unsigned int XI1:1;
31 unsigned int RI0:1;
32 unsigned int RI1:1;
33 unsigned int EHINV:1;
34 uint64_t PFN[2];
35};
36
37#if !defined(CONFIG_USER_ONLY)
38typedef struct CPUMIPSTLBContext CPUMIPSTLBContext;
39struct CPUMIPSTLBContext {
40 uint32_t nb_tlb;
41 uint32_t tlb_in_use;
42 int (*map_address) (struct CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type);
43 void (*helper_tlbwi)(struct CPUMIPSState *env);
44 void (*helper_tlbwr)(struct CPUMIPSState *env);
45 void (*helper_tlbp)(struct CPUMIPSState *env);
46 void (*helper_tlbr)(struct CPUMIPSState *env);
47 void (*helper_tlbinv)(struct CPUMIPSState *env);
48 void (*helper_tlbinvf)(struct CPUMIPSState *env);
49 union {
50 struct {
51 r4k_tlb_t tlb[MIPS_TLB_MAX];
52 } r4k;
53 } mmu;
54};
55#endif
56
57
58#define MSA_WRLEN (128)
59
60enum CPUMIPSMSADataFormat {
61 DF_BYTE = 0,
62 DF_HALF,
63 DF_WORD,
64 DF_DOUBLE
65};
66
67typedef union wr_t wr_t;
68union wr_t {
69 int8_t b[MSA_WRLEN/8];
70 int16_t h[MSA_WRLEN/16];
71 int32_t w[MSA_WRLEN/32];
72 int64_t d[MSA_WRLEN/64];
73};
74
75typedef union fpr_t fpr_t;
76union fpr_t {
77 float64 fd;
78 float32 fs[2];
79 uint64_t d;
80 uint32_t w[2];
81
82 wr_t wr;
83};
84
85
86
87#if defined(HOST_WORDS_BIGENDIAN)
88# define FP_ENDIAN_IDX 1
89#else
90# define FP_ENDIAN_IDX 0
91#endif
92
93typedef struct CPUMIPSFPUContext CPUMIPSFPUContext;
94struct CPUMIPSFPUContext {
95
96 fpr_t fpr[32];
97 float_status fp_status;
98
99 uint32_t fcr0;
100#define FCR0_FREP 29
101#define FCR0_UFRP 28
102#define FCR0_HAS2008 23
103#define FCR0_F64 22
104#define FCR0_L 21
105#define FCR0_W 20
106#define FCR0_3D 19
107#define FCR0_PS 18
108#define FCR0_D 17
109#define FCR0_S 16
110#define FCR0_PRID 8
111#define FCR0_REV 0
112
113 uint32_t fcr31;
114#define FCR31_ABS2008 19
115#define FCR31_NAN2008 18
116#define SET_FP_COND(num,env) do { ((env).fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
117#define CLEAR_FP_COND(num,env) do { ((env).fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
118#define GET_FP_COND(env) ((((env).fcr31 >> 24) & 0xfe) | (((env).fcr31 >> 23) & 0x1))
119#define GET_FP_CAUSE(reg) (((reg) >> 12) & 0x3f)
120#define GET_FP_ENABLE(reg) (((reg) >> 7) & 0x1f)
121#define GET_FP_FLAGS(reg) (((reg) >> 2) & 0x1f)
122#define SET_FP_CAUSE(reg,v) do { (reg) = ((reg) & ~(0x3f << 12)) | ((v & 0x3f) << 12); } while(0)
123#define SET_FP_ENABLE(reg,v) do { (reg) = ((reg) & ~(0x1f << 7)) | ((v & 0x1f) << 7); } while(0)
124#define SET_FP_FLAGS(reg,v) do { (reg) = ((reg) & ~(0x1f << 2)) | ((v & 0x1f) << 2); } while(0)
125#define UPDATE_FP_FLAGS(reg,v) do { (reg) |= ((v & 0x1f) << 2); } while(0)
126#define FP_INEXACT 1
127#define FP_UNDERFLOW 2
128#define FP_OVERFLOW 4
129#define FP_DIV0 8
130#define FP_INVALID 16
131#define FP_UNIMPLEMENTED 32
132};
133
134#define NB_MMU_MODES 3
135#define TARGET_INSN_START_EXTRA_WORDS 2
136
137typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
138struct CPUMIPSMVPContext {
139 int32_t CP0_MVPControl;
140#define CP0MVPCo_CPA 3
141#define CP0MVPCo_STLB 2
142#define CP0MVPCo_VPC 1
143#define CP0MVPCo_EVP 0
144 int32_t CP0_MVPConf0;
145#define CP0MVPC0_M 31
146#define CP0MVPC0_TLBS 29
147#define CP0MVPC0_GS 28
148#define CP0MVPC0_PCP 27
149#define CP0MVPC0_PTLBE 16
150#define CP0MVPC0_TCA 15
151#define CP0MVPC0_PVPE 10
152#define CP0MVPC0_PTC 0
153 int32_t CP0_MVPConf1;
154#define CP0MVPC1_CIM 31
155#define CP0MVPC1_CIF 30
156#define CP0MVPC1_PCX 20
157#define CP0MVPC1_PCP2 10
158#define CP0MVPC1_PCP1 0
159};
160
161typedef struct mips_def_t mips_def_t;
162
163#define MIPS_SHADOW_SET_MAX 16
164#define MIPS_TC_MAX 5
165#define MIPS_FPU_MAX 1
166#define MIPS_DSP_ACC 4
167#define MIPS_KSCRATCH_NUM 6
168#define MIPS_MAAR_MAX 16
169
170typedef struct TCState TCState;
171struct TCState {
172 target_ulong gpr[32];
173 target_ulong PC;
174 target_ulong HI[MIPS_DSP_ACC];
175 target_ulong LO[MIPS_DSP_ACC];
176 target_ulong ACX[MIPS_DSP_ACC];
177 target_ulong DSPControl;
178 int32_t CP0_TCStatus;
179#define CP0TCSt_TCU3 31
180#define CP0TCSt_TCU2 30
181#define CP0TCSt_TCU1 29
182#define CP0TCSt_TCU0 28
183#define CP0TCSt_TMX 27
184#define CP0TCSt_RNST 23
185#define CP0TCSt_TDS 21
186#define CP0TCSt_DT 20
187#define CP0TCSt_DA 15
188#define CP0TCSt_A 13
189#define CP0TCSt_TKSU 11
190#define CP0TCSt_IXMT 10
191#define CP0TCSt_TASID 0
192 int32_t CP0_TCBind;
193#define CP0TCBd_CurTC 21
194#define CP0TCBd_TBE 17
195#define CP0TCBd_CurVPE 0
196 target_ulong CP0_TCHalt;
197 target_ulong CP0_TCContext;
198 target_ulong CP0_TCSchedule;
199 target_ulong CP0_TCScheFBack;
200 int32_t CP0_Debug_tcstatus;
201 target_ulong CP0_UserLocal;
202
203 int32_t msacsr;
204
205#define MSACSR_FS 24
206#define MSACSR_FS_MASK (1 << MSACSR_FS)
207#define MSACSR_NX 18
208#define MSACSR_NX_MASK (1 << MSACSR_NX)
209#define MSACSR_CEF 2
210#define MSACSR_CEF_MASK (0xffff << MSACSR_CEF)
211#define MSACSR_RM 0
212#define MSACSR_RM_MASK (0x3 << MSACSR_RM)
213#define MSACSR_MASK (MSACSR_RM_MASK | MSACSR_CEF_MASK | MSACSR_NX_MASK | \
214 MSACSR_FS_MASK)
215
216 float_status msa_fp_status;
217};
218
219typedef struct CPUMIPSState CPUMIPSState;
220struct CPUMIPSState {
221 TCState active_tc;
222 CPUMIPSFPUContext active_fpu;
223
224 uint32_t current_tc;
225 uint32_t current_fpu;
226
227 uint32_t SEGBITS;
228 uint32_t PABITS;
229#if defined(TARGET_MIPS64)
230# define PABITS_BASE 36
231#else
232# define PABITS_BASE 32
233#endif
234 target_ulong SEGMask;
235 uint64_t PAMask;
236#define PAMASK_BASE ((1ULL << PABITS_BASE) - 1)
237
238 int32_t msair;
239#define MSAIR_ProcID 8
240#define MSAIR_Rev 0
241
242 int32_t CP0_Index;
243
244 int32_t CP0_VPControl;
245#define CP0VPCtl_DIS 0
246 int32_t CP0_Random;
247 int32_t CP0_VPEControl;
248#define CP0VPECo_YSI 21
249#define CP0VPECo_GSI 20
250#define CP0VPECo_EXCPT 16
251#define CP0VPECo_TE 15
252#define CP0VPECo_TargTC 0
253 int32_t CP0_VPEConf0;
254#define CP0VPEC0_M 31
255#define CP0VPEC0_XTC 21
256#define CP0VPEC0_TCS 19
257#define CP0VPEC0_SCS 18
258#define CP0VPEC0_DSC 17
259#define CP0VPEC0_ICS 16
260#define CP0VPEC0_MVP 1
261#define CP0VPEC0_VPA 0
262 int32_t CP0_VPEConf1;
263#define CP0VPEC1_NCX 20
264#define CP0VPEC1_NCP2 10
265#define CP0VPEC1_NCP1 0
266 target_ulong CP0_YQMask;
267 target_ulong CP0_VPESchedule;
268 target_ulong CP0_VPEScheFBack;
269 int32_t CP0_VPEOpt;
270#define CP0VPEOpt_IWX7 15
271#define CP0VPEOpt_IWX6 14
272#define CP0VPEOpt_IWX5 13
273#define CP0VPEOpt_IWX4 12
274#define CP0VPEOpt_IWX3 11
275#define CP0VPEOpt_IWX2 10
276#define CP0VPEOpt_IWX1 9
277#define CP0VPEOpt_IWX0 8
278#define CP0VPEOpt_DWX7 7
279#define CP0VPEOpt_DWX6 6
280#define CP0VPEOpt_DWX5 5
281#define CP0VPEOpt_DWX4 4
282#define CP0VPEOpt_DWX3 3
283#define CP0VPEOpt_DWX2 2
284#define CP0VPEOpt_DWX1 1
285#define CP0VPEOpt_DWX0 0
286 uint64_t CP0_EntryLo0;
287 uint64_t CP0_EntryLo1;
288#if defined(TARGET_MIPS64)
289# define CP0EnLo_RI 63
290# define CP0EnLo_XI 62
291#else
292# define CP0EnLo_RI 31
293# define CP0EnLo_XI 30
294#endif
295 int32_t CP0_GlobalNumber;
296#define CP0GN_VPId 0
297 target_ulong CP0_Context;
298 target_ulong CP0_KScratch[MIPS_KSCRATCH_NUM];
299 int32_t CP0_PageMask;
300 int32_t CP0_PageGrain_rw_bitmask;
301 int32_t CP0_PageGrain;
302#define CP0PG_RIE 31
303#define CP0PG_XIE 30
304#define CP0PG_ELPA 29
305#define CP0PG_IEC 27
306 int32_t CP0_Wired;
307 int32_t CP0_SRSConf0_rw_bitmask;
308 int32_t CP0_SRSConf0;
309#define CP0SRSC0_M 31
310#define CP0SRSC0_SRS3 20
311#define CP0SRSC0_SRS2 10
312#define CP0SRSC0_SRS1 0
313 int32_t CP0_SRSConf1_rw_bitmask;
314 int32_t CP0_SRSConf1;
315#define CP0SRSC1_M 31
316#define CP0SRSC1_SRS6 20
317#define CP0SRSC1_SRS5 10
318#define CP0SRSC1_SRS4 0
319 int32_t CP0_SRSConf2_rw_bitmask;
320 int32_t CP0_SRSConf2;
321#define CP0SRSC2_M 31
322#define CP0SRSC2_SRS9 20
323#define CP0SRSC2_SRS8 10
324#define CP0SRSC2_SRS7 0
325 int32_t CP0_SRSConf3_rw_bitmask;
326 int32_t CP0_SRSConf3;
327#define CP0SRSC3_M 31
328#define CP0SRSC3_SRS12 20
329#define CP0SRSC3_SRS11 10
330#define CP0SRSC3_SRS10 0
331 int32_t CP0_SRSConf4_rw_bitmask;
332 int32_t CP0_SRSConf4;
333#define CP0SRSC4_SRS15 20
334#define CP0SRSC4_SRS14 10
335#define CP0SRSC4_SRS13 0
336 int32_t CP0_HWREna;
337 target_ulong CP0_BadVAddr;
338 uint32_t CP0_BadInstr;
339 uint32_t CP0_BadInstrP;
340 int32_t CP0_Count;
341 target_ulong CP0_EntryHi;
342#define CP0EnHi_EHINV 10
343 int32_t CP0_Compare;
344 int32_t CP0_Status;
345#define CP0St_CU3 31
346#define CP0St_CU2 30
347#define CP0St_CU1 29
348#define CP0St_CU0 28
349#define CP0St_RP 27
350#define CP0St_FR 26
351#define CP0St_RE 25
352#define CP0St_MX 24
353#define CP0St_PX 23
354#define CP0St_BEV 22
355#define CP0St_TS 21
356#define CP0St_SR 20
357#define CP0St_NMI 19
358#define CP0St_IM 8
359#define CP0St_KX 7
360#define CP0St_SX 6
361#define CP0St_UX 5
362#define CP0St_KSU 3
363#define CP0St_ERL 2
364#define CP0St_EXL 1
365#define CP0St_IE 0
366 int32_t CP0_IntCtl;
367#define CP0IntCtl_IPTI 29
368#define CP0IntCtl_IPPCI 26
369#define CP0IntCtl_VS 5
370 int32_t CP0_SRSCtl;
371#define CP0SRSCtl_HSS 26
372#define CP0SRSCtl_EICSS 18
373#define CP0SRSCtl_ESS 12
374#define CP0SRSCtl_PSS 6
375#define CP0SRSCtl_CSS 0
376 int32_t CP0_SRSMap;
377#define CP0SRSMap_SSV7 28
378#define CP0SRSMap_SSV6 24
379#define CP0SRSMap_SSV5 20
380#define CP0SRSMap_SSV4 16
381#define CP0SRSMap_SSV3 12
382#define CP0SRSMap_SSV2 8
383#define CP0SRSMap_SSV1 4
384#define CP0SRSMap_SSV0 0
385 int32_t CP0_Cause;
386#define CP0Ca_BD 31
387#define CP0Ca_TI 30
388#define CP0Ca_CE 28
389#define CP0Ca_DC 27
390#define CP0Ca_PCI 26
391#define CP0Ca_IV 23
392#define CP0Ca_WP 22
393#define CP0Ca_IP 8
394#define CP0Ca_IP_mask 0x0000FF00
395#define CP0Ca_EC 2
396 target_ulong CP0_EPC;
397 int32_t CP0_PRid;
398 int32_t CP0_EBase;
399 target_ulong CP0_CMGCRBase;
400 int32_t CP0_Config0;
401#define CP0C0_M 31
402#define CP0C0_K23 28
403#define CP0C0_KU 25
404#define CP0C0_MDU 20
405#define CP0C0_MM 18
406#define CP0C0_BM 16
407#define CP0C0_BE 15
408#define CP0C0_AT 13
409#define CP0C0_AR 10
410#define CP0C0_MT 7
411#define CP0C0_VI 3
412#define CP0C0_K0 0
413 int32_t CP0_Config1;
414#define CP0C1_M 31
415#define CP0C1_MMU 25
416#define CP0C1_IS 22
417#define CP0C1_IL 19
418#define CP0C1_IA 16
419#define CP0C1_DS 13
420#define CP0C1_DL 10
421#define CP0C1_DA 7
422#define CP0C1_C2 6
423#define CP0C1_MD 5
424#define CP0C1_PC 4
425#define CP0C1_WR 3
426#define CP0C1_CA 2
427#define CP0C1_EP 1
428#define CP0C1_FP 0
429 int32_t CP0_Config2;
430#define CP0C2_M 31
431#define CP0C2_TU 28
432#define CP0C2_TS 24
433#define CP0C2_TL 20
434#define CP0C2_TA 16
435#define CP0C2_SU 12
436#define CP0C2_SS 8
437#define CP0C2_SL 4
438#define CP0C2_SA 0
439 int32_t CP0_Config3;
440#define CP0C3_M 31
441#define CP0C3_BPG 30
442#define CP0C3_CMGCR 29
443#define CP0C3_MSAP 28
444#define CP0C3_BP 27
445#define CP0C3_BI 26
446#define CP0C3_IPLW 21
447#define CP0C3_MMAR 18
448#define CP0C3_MCU 17
449#define CP0C3_ISA_ON_EXC 16
450#define CP0C3_ISA 14
451#define CP0C3_ULRI 13
452#define CP0C3_RXI 12
453#define CP0C3_DSP2P 11
454#define CP0C3_DSPP 10
455#define CP0C3_LPA 7
456#define CP0C3_VEIC 6
457#define CP0C3_VInt 5
458#define CP0C3_SP 4
459#define CP0C3_CDMM 3
460#define CP0C3_MT 2
461#define CP0C3_SM 1
462#define CP0C3_TL 0
463 int32_t CP0_Config4;
464 int32_t CP0_Config4_rw_bitmask;
465#define CP0C4_M 31
466#define CP0C4_IE 29
467#define CP0C4_KScrExist 16
468#define CP0C4_MMUExtDef 14
469#define CP0C4_FTLBPageSize 8
470#define CP0C4_FTLBWays 4
471#define CP0C4_FTLBSets 0
472#define CP0C4_MMUSizeExt 0
473 int32_t CP0_Config5;
474 int32_t CP0_Config5_rw_bitmask;
475#define CP0C5_M 31
476#define CP0C5_K 30
477#define CP0C5_CV 29
478#define CP0C5_EVA 28
479#define CP0C5_MSAEn 27
480#define CP0C5_XNP 13
481#define CP0C5_UFE 9
482#define CP0C5_FRE 8
483#define CP0C5_VP 7
484#define CP0C5_SBRI 6
485#define CP0C5_MVH 5
486#define CP0C5_LLB 4
487#define CP0C5_MRP 3
488#define CP0C5_UFR 2
489#define CP0C5_NFExists 0
490 int32_t CP0_Config6;
491 int32_t CP0_Config7;
492 uint64_t CP0_MAAR[MIPS_MAAR_MAX];
493 int32_t CP0_MAARI;
494
495 uint64_t lladdr;
496 target_ulong llval;
497 target_ulong llnewval;
498 target_ulong llreg;
499 uint64_t CP0_LLAddr_rw_bitmask;
500 int CP0_LLAddr_shift;
501 target_ulong CP0_WatchLo[8];
502 int32_t CP0_WatchHi[8];
503 target_ulong CP0_XContext;
504 int32_t CP0_Framemask;
505 int32_t CP0_Debug;
506#define CP0DB_DBD 31
507#define CP0DB_DM 30
508#define CP0DB_LSNM 28
509#define CP0DB_Doze 27
510#define CP0DB_Halt 26
511#define CP0DB_CNT 25
512#define CP0DB_IBEP 24
513#define CP0DB_DBEP 21
514#define CP0DB_IEXI 20
515#define CP0DB_VER 15
516#define CP0DB_DEC 10
517#define CP0DB_SSt 8
518#define CP0DB_DINT 5
519#define CP0DB_DIB 4
520#define CP0DB_DDBS 3
521#define CP0DB_DDBL 2
522#define CP0DB_DBp 1
523#define CP0DB_DSS 0
524 target_ulong CP0_DEPC;
525 int32_t CP0_Performance0;
526 int32_t CP0_ErrCtl;
527#define CP0EC_WST 29
528#define CP0EC_SPR 28
529#define CP0EC_ITC 26
530 uint64_t CP0_TagLo;
531 int32_t CP0_DataLo;
532 int32_t CP0_TagHi;
533 int32_t CP0_DataHi;
534 target_ulong CP0_ErrorEPC;
535 int32_t CP0_DESAVE;
536
537 TCState tcs[MIPS_SHADOW_SET_MAX];
538 CPUMIPSFPUContext fpus[MIPS_FPU_MAX];
539
540 int error_code;
541#define EXCP_TLB_NOMATCH 0x1
542#define EXCP_INST_NOTAVAIL 0x2
543 uint32_t hflags;
544
545#define MIPS_HFLAG_TMASK 0xF5807FF
546#define MIPS_HFLAG_MODE 0x00007
547
548
549
550#define MIPS_HFLAG_KSU 0x00003
551#define MIPS_HFLAG_UM 0x00002
552#define MIPS_HFLAG_SM 0x00001
553#define MIPS_HFLAG_KM 0x00000
554#define MIPS_HFLAG_DM 0x00004
555#define MIPS_HFLAG_64 0x00008
556#define MIPS_HFLAG_CP0 0x00010
557#define MIPS_HFLAG_FPU 0x00020
558#define MIPS_HFLAG_F64 0x00040
559
560
561
562#define MIPS_HFLAG_COP1X 0x00080
563#define MIPS_HFLAG_RE 0x00100
564#define MIPS_HFLAG_AWRAP 0x00200
565#define MIPS_HFLAG_M16 0x00400
566#define MIPS_HFLAG_M16_SHIFT 10
567
568
569
570
571#define MIPS_HFLAG_BMASK_BASE 0x803800
572#define MIPS_HFLAG_B 0x00800
573#define MIPS_HFLAG_BC 0x01000
574#define MIPS_HFLAG_BL 0x01800
575#define MIPS_HFLAG_BR 0x02000
576
577#define MIPS_HFLAG_BMASK_EXT 0x7C000
578#define MIPS_HFLAG_B16 0x04000
579#define MIPS_HFLAG_BDS16 0x08000
580#define MIPS_HFLAG_BDS32 0x10000
581#define MIPS_HFLAG_BDS_STRICT 0x20000
582#define MIPS_HFLAG_BX 0x40000
583#define MIPS_HFLAG_BMASK (MIPS_HFLAG_BMASK_BASE | MIPS_HFLAG_BMASK_EXT)
584
585#define MIPS_HFLAG_DSP 0x080000
586#define MIPS_HFLAG_DSPR2 0x100000
587
588#define MIPS_HFLAG_HWRENA_ULR 0x200000
589#define MIPS_HFLAG_SBRI 0x400000
590#define MIPS_HFLAG_FBNSLOT 0x800000
591#define MIPS_HFLAG_MSA 0x1000000
592#define MIPS_HFLAG_FRE 0x2000000
593#define MIPS_HFLAG_ELPA 0x4000000
594#define MIPS_HFLAG_ITC_CACHE 0x8000000
595 target_ulong btarget;
596 target_ulong bcond;
597
598 int SYNCI_Step;
599 int CCRes;
600 uint32_t CP0_Status_rw_bitmask;
601 uint32_t CP0_TCStatus_rw_bitmask;
602 int insn_flags;
603
604 CPU_COMMON
605
606
607 CPUMIPSMVPContext *mvp;
608#if !defined(CONFIG_USER_ONLY)
609 CPUMIPSTLBContext *tlb;
610#endif
611
612 const mips_def_t *cpu_model;
613 void *irq[8];
614 QEMUTimer *timer;
615 MemoryRegion *itc_tag;
616};
617
618#include "cpu-qom.h"
619
620#if !defined(CONFIG_USER_ONLY)
621int no_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
622 target_ulong address, int rw, int access_type);
623int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
624 target_ulong address, int rw, int access_type);
625int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
626 target_ulong address, int rw, int access_type);
627void r4k_helper_tlbwi(CPUMIPSState *env);
628void r4k_helper_tlbwr(CPUMIPSState *env);
629void r4k_helper_tlbp(CPUMIPSState *env);
630void r4k_helper_tlbr(CPUMIPSState *env);
631void r4k_helper_tlbinv(CPUMIPSState *env);
632void r4k_helper_tlbinvf(CPUMIPSState *env);
633
634void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
635 bool is_write, bool is_exec, int unused,
636 unsigned size);
637#endif
638
639void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
640
641#define cpu_exec cpu_mips_exec
642#define cpu_signal_handler cpu_mips_signal_handler
643#define cpu_list mips_cpu_list
644
645extern void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env);
646extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
647
648
649
650#define MMU_MODE0_SUFFIX _kernel
651#define MMU_MODE1_SUFFIX _super
652#define MMU_MODE2_SUFFIX _user
653#define MMU_USER_IDX 2
654static inline int cpu_mmu_index (CPUMIPSState *env, bool ifetch)
655{
656 return env->hflags & MIPS_HFLAG_KSU;
657}
658
659static inline bool cpu_mips_hw_interrupts_enabled(CPUMIPSState *env)
660{
661 return (env->CP0_Status & (1 << CP0St_IE)) &&
662 !(env->CP0_Status & (1 << CP0St_EXL)) &&
663 !(env->CP0_Status & (1 << CP0St_ERL)) &&
664 !(env->hflags & MIPS_HFLAG_DM) &&
665
666
667
668 !(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT));
669}
670
671
672static inline bool cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
673{
674 int32_t pending;
675 int32_t status;
676 bool r;
677
678 pending = env->CP0_Cause & CP0Ca_IP_mask;
679 status = env->CP0_Status & CP0Ca_IP_mask;
680
681 if (env->CP0_Config3 & (1 << CP0C3_VEIC)) {
682
683
684
685 r = pending > status;
686 } else {
687
688
689
690 r = (pending & status) != 0;
691 }
692 return r;
693}
694
695#include "exec/cpu-all.h"
696
697
698
699
700enum {
701
702 ACCESS_USER = 0x00,
703 ACCESS_SUPER = 0x01,
704
705 ACCESS_STORE = 0x02,
706
707 ACCESS_CODE = 0x10,
708 ACCESS_INT = 0x20,
709 ACCESS_FLOAT = 0x30,
710};
711
712
713enum {
714 EXCP_NONE = -1,
715 EXCP_RESET = 0,
716 EXCP_SRESET,
717 EXCP_DSS,
718 EXCP_DINT,
719 EXCP_DDBL,
720 EXCP_DDBS,
721 EXCP_NMI,
722 EXCP_MCHECK,
723 EXCP_EXT_INTERRUPT,
724 EXCP_DFWATCH,
725 EXCP_DIB,
726 EXCP_IWATCH,
727 EXCP_AdEL,
728 EXCP_AdES,
729 EXCP_TLBF,
730 EXCP_IBE,
731 EXCP_DBp,
732 EXCP_SYSCALL,
733 EXCP_BREAK,
734 EXCP_CpU,
735 EXCP_RI,
736 EXCP_OVERFLOW,
737 EXCP_TRAP,
738 EXCP_FPE,
739 EXCP_DWATCH,
740 EXCP_LTLBL,
741 EXCP_TLBL,
742 EXCP_TLBS,
743 EXCP_DBE,
744 EXCP_THREAD,
745 EXCP_MDMX,
746 EXCP_C2E,
747 EXCP_CACHE,
748 EXCP_DSPDIS,
749 EXCP_MSADIS,
750 EXCP_MSAFPE,
751 EXCP_TLBXI,
752 EXCP_TLBRI,
753
754 EXCP_LAST = EXCP_TLBRI,
755};
756
757#define EXCP_SC 0x100
758
759
760
761
762
763
764
765#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
766
767int cpu_mips_exec(CPUState *cpu);
768void mips_tcg_init(void);
769MIPSCPU *cpu_mips_init(const char *cpu_model);
770int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
771
772#define cpu_init(cpu_model) CPU(cpu_mips_init(cpu_model))
773bool cpu_supports_cps_smp(const char *cpu_model);
774
775
776void cpu_state_reset(CPUMIPSState *s);
777
778
779uint32_t cpu_mips_get_random (CPUMIPSState *env);
780uint32_t cpu_mips_get_count (CPUMIPSState *env);
781void cpu_mips_store_count (CPUMIPSState *env, uint32_t value);
782void cpu_mips_store_compare (CPUMIPSState *env, uint32_t value);
783void cpu_mips_start_count(CPUMIPSState *env);
784void cpu_mips_stop_count(CPUMIPSState *env);
785
786
787void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level);
788
789
790int mips_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
791 int mmu_idx);
792#if !defined(CONFIG_USER_ONLY)
793void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra);
794hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
795 int rw);
796#endif
797target_ulong exception_resume_pc (CPUMIPSState *env);
798
799
800extern unsigned int ieee_rm[];
801int ieee_ex_to_mips(int xcpt);
802
803static inline void restore_rounding_mode(CPUMIPSState *env)
804{
805 set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3],
806 &env->active_fpu.fp_status);
807}
808
809static inline void restore_flush_mode(CPUMIPSState *env)
810{
811 set_flush_to_zero((env->active_fpu.fcr31 & (1 << 24)) != 0,
812 &env->active_fpu.fp_status);
813}
814
815static inline void restore_fp_status(CPUMIPSState *env)
816{
817 restore_rounding_mode(env);
818 restore_flush_mode(env);
819}
820
821static inline void restore_msa_fp_status(CPUMIPSState *env)
822{
823 float_status *status = &env->active_tc.msa_fp_status;
824 int rounding_mode = (env->active_tc.msacsr & MSACSR_RM_MASK) >> MSACSR_RM;
825 bool flush_to_zero = (env->active_tc.msacsr & MSACSR_FS_MASK) != 0;
826
827 set_float_rounding_mode(ieee_rm[rounding_mode], status);
828 set_flush_to_zero(flush_to_zero, status);
829 set_flush_inputs_to_zero(flush_to_zero, status);
830}
831
832static inline void restore_pamask(CPUMIPSState *env)
833{
834 if (env->hflags & MIPS_HFLAG_ELPA) {
835 env->PAMask = (1ULL << env->PABITS) - 1;
836 } else {
837 env->PAMask = PAMASK_BASE;
838 }
839}
840
841static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
842 target_ulong *cs_base, int *flags)
843{
844 *pc = env->active_tc.PC;
845 *cs_base = 0;
846 *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK |
847 MIPS_HFLAG_HWRENA_ULR);
848}
849
850static inline int mips_vpe_active(CPUMIPSState *env)
851{
852 int active = 1;
853
854
855 if (!(env->mvp->CP0_MVPControl & (1 << CP0MVPCo_EVP))) {
856 active = 0;
857 }
858
859 if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))) {
860 active = 0;
861 }
862
863
864
865
866
867
868
869 if (!(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_A))) {
870
871 active = 0;
872 }
873 if (env->active_tc.CP0_TCHalt & 1) {
874
875 active = 0;
876 }
877
878 return active;
879}
880
881static inline int mips_vp_active(CPUMIPSState *env)
882{
883 CPUState *other_cs = first_cpu;
884
885
886 if ((env->CP0_VPControl >> CP0VPCtl_DIS) & 1) {
887 return 1;
888 }
889
890
891 CPU_FOREACH(other_cs) {
892 MIPSCPU *other_cpu = MIPS_CPU(other_cs);
893 if ((&other_cpu->env != env) &&
894 ((other_cpu->env.CP0_VPControl >> CP0VPCtl_DIS) & 1)) {
895 return 0;
896 }
897 }
898 return 1;
899}
900
901#include "exec/exec-all.h"
902
903static inline void compute_hflags(CPUMIPSState *env)
904{
905 env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
906 MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
907 MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 |
908 MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE |
909 MIPS_HFLAG_ELPA);
910 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
911 !(env->CP0_Status & (1 << CP0St_ERL)) &&
912 !(env->hflags & MIPS_HFLAG_DM)) {
913 env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
914 }
915#if defined(TARGET_MIPS64)
916 if ((env->insn_flags & ISA_MIPS3) &&
917 (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
918 (env->CP0_Status & (1 << CP0St_PX)) ||
919 (env->CP0_Status & (1 << CP0St_UX)))) {
920 env->hflags |= MIPS_HFLAG_64;
921 }
922
923 if (!(env->insn_flags & ISA_MIPS3)) {
924 env->hflags |= MIPS_HFLAG_AWRAP;
925 } else if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
926 !(env->CP0_Status & (1 << CP0St_UX))) {
927 env->hflags |= MIPS_HFLAG_AWRAP;
928 } else if (env->insn_flags & ISA_MIPS64R6) {
929
930 if ((((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_SM) &&
931 !(env->CP0_Status & (1 << CP0St_SX))) ||
932 (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_KM) &&
933 !(env->CP0_Status & (1 << CP0St_KX)))) {
934 env->hflags |= MIPS_HFLAG_AWRAP;
935 }
936 }
937#endif
938 if (((env->CP0_Status & (1 << CP0St_CU0)) &&
939 !(env->insn_flags & ISA_MIPS32R6)) ||
940 !(env->hflags & MIPS_HFLAG_KSU)) {
941 env->hflags |= MIPS_HFLAG_CP0;
942 }
943 if (env->CP0_Status & (1 << CP0St_CU1)) {
944 env->hflags |= MIPS_HFLAG_FPU;
945 }
946 if (env->CP0_Status & (1 << CP0St_FR)) {
947 env->hflags |= MIPS_HFLAG_F64;
948 }
949 if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_KM) &&
950 (env->CP0_Config5 & (1 << CP0C5_SBRI))) {
951 env->hflags |= MIPS_HFLAG_SBRI;
952 }
953 if (env->insn_flags & ASE_DSPR2) {
954
955
956 if (env->CP0_Status & (1 << CP0St_MX)) {
957 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
958 }
959
960 } else if (env->insn_flags & ASE_DSP) {
961
962
963 if (env->CP0_Status & (1 << CP0St_MX)) {
964 env->hflags |= MIPS_HFLAG_DSP;
965 }
966
967 }
968 if (env->insn_flags & ISA_MIPS32R2) {
969 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
970 env->hflags |= MIPS_HFLAG_COP1X;
971 }
972 } else if (env->insn_flags & ISA_MIPS32) {
973 if (env->hflags & MIPS_HFLAG_64) {
974 env->hflags |= MIPS_HFLAG_COP1X;
975 }
976 } else if (env->insn_flags & ISA_MIPS4) {
977
978
979
980
981 if (env->CP0_Status & (1U << CP0St_CU3)) {
982 env->hflags |= MIPS_HFLAG_COP1X;
983 }
984 }
985 if (env->insn_flags & ASE_MSA) {
986 if (env->CP0_Config5 & (1 << CP0C5_MSAEn)) {
987 env->hflags |= MIPS_HFLAG_MSA;
988 }
989 }
990 if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
991 if (env->CP0_Config5 & (1 << CP0C5_FRE)) {
992 env->hflags |= MIPS_HFLAG_FRE;
993 }
994 }
995 if (env->CP0_Config3 & (1 << CP0C3_LPA)) {
996 if (env->CP0_PageGrain & (1 << CP0PG_ELPA)) {
997 env->hflags |= MIPS_HFLAG_ELPA;
998 }
999 }
1000}
1001
1002#ifndef CONFIG_USER_ONLY
1003static inline void cpu_mips_tlb_flush(CPUMIPSState *env, int flush_global)
1004{
1005 MIPSCPU *cpu = mips_env_get_cpu(env);
1006
1007
1008 tlb_flush(CPU(cpu), flush_global);
1009 env->tlb->tlb_in_use = env->tlb->nb_tlb;
1010}
1011
1012
1013static inline void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc)
1014{
1015 int32_t tcstatus, *tcst;
1016 uint32_t v = cpu->CP0_Status;
1017 uint32_t cu, mx, asid, ksu;
1018 uint32_t mask = ((1 << CP0TCSt_TCU3)
1019 | (1 << CP0TCSt_TCU2)
1020 | (1 << CP0TCSt_TCU1)
1021 | (1 << CP0TCSt_TCU0)
1022 | (1 << CP0TCSt_TMX)
1023 | (3 << CP0TCSt_TKSU)
1024 | (0xff << CP0TCSt_TASID));
1025
1026 cu = (v >> CP0St_CU0) & 0xf;
1027 mx = (v >> CP0St_MX) & 0x1;
1028 ksu = (v >> CP0St_KSU) & 0x3;
1029 asid = env->CP0_EntryHi & 0xff;
1030
1031 tcstatus = cu << CP0TCSt_TCU0;
1032 tcstatus |= mx << CP0TCSt_TMX;
1033 tcstatus |= ksu << CP0TCSt_TKSU;
1034 tcstatus |= asid;
1035
1036 if (tc == cpu->current_tc) {
1037 tcst = &cpu->active_tc.CP0_TCStatus;
1038 } else {
1039 tcst = &cpu->tcs[tc].CP0_TCStatus;
1040 }
1041
1042 *tcst &= ~mask;
1043 *tcst |= tcstatus;
1044 compute_hflags(cpu);
1045}
1046
1047static inline void cpu_mips_store_status(CPUMIPSState *env, target_ulong val)
1048{
1049 uint32_t mask = env->CP0_Status_rw_bitmask;
1050 target_ulong old = env->CP0_Status;
1051
1052 if (env->insn_flags & ISA_MIPS32R6) {
1053 bool has_supervisor = extract32(mask, CP0St_KSU, 2) == 0x3;
1054#if defined(TARGET_MIPS64)
1055 uint32_t ksux = (1 << CP0St_KX) & val;
1056 ksux |= (ksux >> 1) & val;
1057 ksux |= (ksux >> 1) & val;
1058 val = (val & ~(7 << CP0St_UX)) | ksux;
1059#endif
1060 if (has_supervisor && extract32(val, CP0St_KSU, 2) == 0x3) {
1061 mask &= ~(3 << CP0St_KSU);
1062 }
1063 mask &= ~(((1 << CP0St_SR) | (1 << CP0St_NMI)) & val);
1064 }
1065
1066 env->CP0_Status = (old & ~mask) | (val & mask);
1067#if defined(TARGET_MIPS64)
1068 if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) {
1069
1070 cpu_mips_tlb_flush(env, 1);
1071 }
1072#endif
1073 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
1074 sync_c0_status(env, env, env->current_tc);
1075 } else {
1076 compute_hflags(env);
1077 }
1078}
1079
1080static inline void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val)
1081{
1082 uint32_t mask = 0x00C00300;
1083 uint32_t old = env->CP0_Cause;
1084 int i;
1085
1086 if (env->insn_flags & ISA_MIPS32R2) {
1087 mask |= 1 << CP0Ca_DC;
1088 }
1089 if (env->insn_flags & ISA_MIPS32R6) {
1090 mask &= ~((1 << CP0Ca_WP) & val);
1091 }
1092
1093 env->CP0_Cause = (env->CP0_Cause & ~mask) | (val & mask);
1094
1095 if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
1096 if (env->CP0_Cause & (1 << CP0Ca_DC)) {
1097 cpu_mips_stop_count(env);
1098 } else {
1099 cpu_mips_start_count(env);
1100 }
1101 }
1102
1103
1104 for (i = 0 ; i < 2 ; i++) {
1105 if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
1106 cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i)));
1107 }
1108 }
1109}
1110#endif
1111
1112static inline void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env,
1113 uint32_t exception,
1114 int error_code,
1115 uintptr_t pc)
1116{
1117 CPUState *cs = CPU(mips_env_get_cpu(env));
1118
1119 if (exception < EXCP_SC) {
1120 qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n",
1121 __func__, exception, error_code);
1122 }
1123 cs->exception_index = exception;
1124 env->error_code = error_code;
1125
1126 cpu_loop_exit_restore(cs, pc);
1127}
1128
1129static inline void QEMU_NORETURN do_raise_exception(CPUMIPSState *env,
1130 uint32_t exception,
1131 uintptr_t pc)
1132{
1133 do_raise_exception_err(env, exception, 0, pc);
1134}
1135
1136#endif
1137