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