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