1#if !defined (__MIPS_CPU_H__)
2#define __MIPS_CPU_H__
3
4#define TARGET_HAS_ICE 1
5
6#define ELF_MACHINE EM_MIPS
7
8#define CPUState struct CPUMIPSState
9
10#include "config.h"
11#include "mips-defs.h"
12#include "cpu-defs.h"
13#include "softfloat.h"
14
15
16
17#if defined(HOST_SOLARIS) && HOST_SOLARIS < 10
18typedef unsigned char uint_fast8_t;
19typedef unsigned int uint_fast16_t;
20#endif
21
22struct CPUMIPSState;
23
24typedef struct r4k_tlb_t r4k_tlb_t;
25struct r4k_tlb_t {
26 target_ulong VPN;
27 uint32_t PageMask;
28 uint_fast8_t ASID;
29 uint_fast16_t G:1;
30 uint_fast16_t C0:3;
31 uint_fast16_t C1:3;
32 uint_fast16_t V0:1;
33 uint_fast16_t V1:1;
34 uint_fast16_t D0:1;
35 uint_fast16_t D1:1;
36 target_ulong PFN[2];
37};
38
39typedef struct CPUMIPSTLBContext CPUMIPSTLBContext;
40struct CPUMIPSTLBContext {
41 uint32_t nb_tlb;
42 uint32_t tlb_in_use;
43 int (*map_address) (struct CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type);
44 void (*helper_tlbwi) (void);
45 void (*helper_tlbwr) (void);
46 void (*helper_tlbp) (void);
47 void (*helper_tlbr) (void);
48 union {
49 struct {
50 r4k_tlb_t tlb[MIPS_TLB_MAX];
51 } r4k;
52 } mmu;
53};
54
55typedef union fpr_t fpr_t;
56union fpr_t {
57 float64 fd;
58 float32 fs[2];
59 uint64_t d;
60 uint32_t w[2];
61};
62
63
64
65#if defined(WORDS_BIGENDIAN)
66# define FP_ENDIAN_IDX 1
67#else
68# define FP_ENDIAN_IDX 0
69#endif
70
71typedef struct CPUMIPSFPUContext CPUMIPSFPUContext;
72struct CPUMIPSFPUContext {
73
74 fpr_t fpr[32];
75 float_status fp_status;
76
77 uint32_t fcr0;
78#define FCR0_F64 22
79#define FCR0_L 21
80#define FCR0_W 20
81#define FCR0_3D 19
82#define FCR0_PS 18
83#define FCR0_D 17
84#define FCR0_S 16
85#define FCR0_PRID 8
86#define FCR0_REV 0
87
88 uint32_t fcr31;
89#define SET_FP_COND(num,env) do { ((env).fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
90#define CLEAR_FP_COND(num,env) do { ((env).fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
91#define GET_FP_COND(env) ((((env).fcr31 >> 24) & 0xfe) | (((env).fcr31 >> 23) & 0x1))
92#define GET_FP_CAUSE(reg) (((reg) >> 12) & 0x3f)
93#define GET_FP_ENABLE(reg) (((reg) >> 7) & 0x1f)
94#define GET_FP_FLAGS(reg) (((reg) >> 2) & 0x1f)
95#define SET_FP_CAUSE(reg,v) do { (reg) = ((reg) & ~(0x3f << 12)) | ((v & 0x3f) << 12); } while(0)
96#define SET_FP_ENABLE(reg,v) do { (reg) = ((reg) & ~(0x1f << 7)) | ((v & 0x1f) << 7); } while(0)
97#define SET_FP_FLAGS(reg,v) do { (reg) = ((reg) & ~(0x1f << 2)) | ((v & 0x1f) << 2); } while(0)
98#define UPDATE_FP_FLAGS(reg,v) do { (reg) |= ((v & 0x1f) << 2); } while(0)
99#define FP_INEXACT 1
100#define FP_UNDERFLOW 2
101#define FP_OVERFLOW 4
102#define FP_DIV0 8
103#define FP_INVALID 16
104#define FP_UNIMPLEMENTED 32
105};
106
107#define NB_MMU_MODES 3
108
109typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
110struct CPUMIPSMVPContext {
111 int32_t CP0_MVPControl;
112#define CP0MVPCo_CPA 3
113#define CP0MVPCo_STLB 2
114#define CP0MVPCo_VPC 1
115#define CP0MVPCo_EVP 0
116 int32_t CP0_MVPConf0;
117#define CP0MVPC0_M 31
118#define CP0MVPC0_TLBS 29
119#define CP0MVPC0_GS 28
120#define CP0MVPC0_PCP 27
121#define CP0MVPC0_PTLBE 16
122#define CP0MVPC0_TCA 15
123#define CP0MVPC0_PVPE 10
124#define CP0MVPC0_PTC 0
125 int32_t CP0_MVPConf1;
126#define CP0MVPC1_CIM 31
127#define CP0MVPC1_CIF 30
128#define CP0MVPC1_PCX 20
129#define CP0MVPC1_PCP2 10
130#define CP0MVPC1_PCP1 0
131};
132
133typedef struct mips_def_t mips_def_t;
134
135#define MIPS_SHADOW_SET_MAX 16
136#define MIPS_TC_MAX 5
137#define MIPS_FPU_MAX 1
138#define MIPS_DSP_ACC 4
139
140typedef struct TCState TCState;
141struct TCState {
142 target_ulong gpr[32];
143 target_ulong PC;
144 target_ulong HI[MIPS_DSP_ACC];
145 target_ulong LO[MIPS_DSP_ACC];
146 target_ulong ACX[MIPS_DSP_ACC];
147 target_ulong DSPControl;
148 int32_t CP0_TCStatus;
149#define CP0TCSt_TCU3 31
150#define CP0TCSt_TCU2 30
151#define CP0TCSt_TCU1 29
152#define CP0TCSt_TCU0 28
153#define CP0TCSt_TMX 27
154#define CP0TCSt_RNST 23
155#define CP0TCSt_TDS 21
156#define CP0TCSt_DT 20
157#define CP0TCSt_DA 15
158#define CP0TCSt_A 13
159#define CP0TCSt_TKSU 11
160#define CP0TCSt_IXMT 10
161#define CP0TCSt_TASID 0
162 int32_t CP0_TCBind;
163#define CP0TCBd_CurTC 21
164#define CP0TCBd_TBE 17
165#define CP0TCBd_CurVPE 0
166 target_ulong CP0_TCHalt;
167 target_ulong CP0_TCContext;
168 target_ulong CP0_TCSchedule;
169 target_ulong CP0_TCScheFBack;
170 int32_t CP0_Debug_tcstatus;
171};
172
173typedef struct CPUMIPSState CPUMIPSState;
174struct CPUMIPSState {
175 TCState active_tc;
176 CPUMIPSFPUContext active_fpu;
177
178 CPUMIPSMVPContext *mvp;
179 CPUMIPSTLBContext *tlb;
180 uint32_t current_tc;
181 uint32_t current_fpu;
182
183 uint32_t SEGBITS;
184 uint32_t PABITS;
185 target_ulong SEGMask;
186 target_ulong PAMask;
187
188 int32_t CP0_Index;
189
190 int32_t CP0_Random;
191 int32_t CP0_VPEControl;
192#define CP0VPECo_YSI 21
193#define CP0VPECo_GSI 20
194#define CP0VPECo_EXCPT 16
195#define CP0VPECo_TE 15
196#define CP0VPECo_TargTC 0
197 int32_t CP0_VPEConf0;
198#define CP0VPEC0_M 31
199#define CP0VPEC0_XTC 21
200#define CP0VPEC0_TCS 19
201#define CP0VPEC0_SCS 18
202#define CP0VPEC0_DSC 17
203#define CP0VPEC0_ICS 16
204#define CP0VPEC0_MVP 1
205#define CP0VPEC0_VPA 0
206 int32_t CP0_VPEConf1;
207#define CP0VPEC1_NCX 20
208#define CP0VPEC1_NCP2 10
209#define CP0VPEC1_NCP1 0
210 target_ulong CP0_YQMask;
211 target_ulong CP0_VPESchedule;
212 target_ulong CP0_VPEScheFBack;
213 int32_t CP0_VPEOpt;
214#define CP0VPEOpt_IWX7 15
215#define CP0VPEOpt_IWX6 14
216#define CP0VPEOpt_IWX5 13
217#define CP0VPEOpt_IWX4 12
218#define CP0VPEOpt_IWX3 11
219#define CP0VPEOpt_IWX2 10
220#define CP0VPEOpt_IWX1 9
221#define CP0VPEOpt_IWX0 8
222#define CP0VPEOpt_DWX7 7
223#define CP0VPEOpt_DWX6 6
224#define CP0VPEOpt_DWX5 5
225#define CP0VPEOpt_DWX4 4
226#define CP0VPEOpt_DWX3 3
227#define CP0VPEOpt_DWX2 2
228#define CP0VPEOpt_DWX1 1
229#define CP0VPEOpt_DWX0 0
230 target_ulong CP0_EntryLo0;
231 target_ulong CP0_EntryLo1;
232 target_ulong CP0_Context;
233 int32_t CP0_PageMask;
234 int32_t CP0_PageGrain;
235 int32_t CP0_Wired;
236 int32_t CP0_SRSConf0_rw_bitmask;
237 int32_t CP0_SRSConf0;
238#define CP0SRSC0_M 31
239#define CP0SRSC0_SRS3 20
240#define CP0SRSC0_SRS2 10
241#define CP0SRSC0_SRS1 0
242 int32_t CP0_SRSConf1_rw_bitmask;
243 int32_t CP0_SRSConf1;
244#define CP0SRSC1_M 31
245#define CP0SRSC1_SRS6 20
246#define CP0SRSC1_SRS5 10
247#define CP0SRSC1_SRS4 0
248 int32_t CP0_SRSConf2_rw_bitmask;
249 int32_t CP0_SRSConf2;
250#define CP0SRSC2_M 31
251#define CP0SRSC2_SRS9 20
252#define CP0SRSC2_SRS8 10
253#define CP0SRSC2_SRS7 0
254 int32_t CP0_SRSConf3_rw_bitmask;
255 int32_t CP0_SRSConf3;
256#define CP0SRSC3_M 31
257#define CP0SRSC3_SRS12 20
258#define CP0SRSC3_SRS11 10
259#define CP0SRSC3_SRS10 0
260 int32_t CP0_SRSConf4_rw_bitmask;
261 int32_t CP0_SRSConf4;
262#define CP0SRSC4_SRS15 20
263#define CP0SRSC4_SRS14 10
264#define CP0SRSC4_SRS13 0
265 int32_t CP0_HWREna;
266 target_ulong CP0_BadVAddr;
267 int32_t CP0_Count;
268 target_ulong CP0_EntryHi;
269 int32_t CP0_Compare;
270 int32_t CP0_Status;
271#define CP0St_CU3 31
272#define CP0St_CU2 30
273#define CP0St_CU1 29
274#define CP0St_CU0 28
275#define CP0St_RP 27
276#define CP0St_FR 26
277#define CP0St_RE 25
278#define CP0St_MX 24
279#define CP0St_PX 23
280#define CP0St_BEV 22
281#define CP0St_TS 21
282#define CP0St_SR 20
283#define CP0St_NMI 19
284#define CP0St_IM 8
285#define CP0St_KX 7
286#define CP0St_SX 6
287#define CP0St_UX 5
288#define CP0St_KSU 3
289#define CP0St_ERL 2
290#define CP0St_EXL 1
291#define CP0St_IE 0
292 int32_t CP0_IntCtl;
293#define CP0IntCtl_IPTI 29
294#define CP0IntCtl_IPPC1 26
295#define CP0IntCtl_VS 5
296 int32_t CP0_SRSCtl;
297#define CP0SRSCtl_HSS 26
298#define CP0SRSCtl_EICSS 18
299#define CP0SRSCtl_ESS 12
300#define CP0SRSCtl_PSS 6
301#define CP0SRSCtl_CSS 0
302 int32_t CP0_SRSMap;
303#define CP0SRSMap_SSV7 28
304#define CP0SRSMap_SSV6 24
305#define CP0SRSMap_SSV5 20
306#define CP0SRSMap_SSV4 16
307#define CP0SRSMap_SSV3 12
308#define CP0SRSMap_SSV2 8
309#define CP0SRSMap_SSV1 4
310#define CP0SRSMap_SSV0 0
311 int32_t CP0_Cause;
312#define CP0Ca_BD 31
313#define CP0Ca_TI 30
314#define CP0Ca_CE 28
315#define CP0Ca_DC 27
316#define CP0Ca_PCI 26
317#define CP0Ca_IV 23
318#define CP0Ca_WP 22
319#define CP0Ca_IP 8
320#define CP0Ca_IP_mask 0x0000FF00
321#define CP0Ca_EC 2
322 target_ulong CP0_EPC;
323 int32_t CP0_PRid;
324 int32_t CP0_EBase;
325 int32_t CP0_Config0;
326#define CP0C0_M 31
327#define CP0C0_K23 28
328#define CP0C0_KU 25
329#define CP0C0_MDU 20
330#define CP0C0_MM 17
331#define CP0C0_BM 16
332#define CP0C0_BE 15
333#define CP0C0_AT 13
334#define CP0C0_AR 10
335#define CP0C0_MT 7
336#define CP0C0_VI 3
337#define CP0C0_K0 0
338 int32_t CP0_Config1;
339#define CP0C1_M 31
340#define CP0C1_MMU 25
341#define CP0C1_IS 22
342#define CP0C1_IL 19
343#define CP0C1_IA 16
344#define CP0C1_DS 13
345#define CP0C1_DL 10
346#define CP0C1_DA 7
347#define CP0C1_C2 6
348#define CP0C1_MD 5
349#define CP0C1_PC 4
350#define CP0C1_WR 3
351#define CP0C1_CA 2
352#define CP0C1_EP 1
353#define CP0C1_FP 0
354 int32_t CP0_Config2;
355#define CP0C2_M 31
356#define CP0C2_TU 28
357#define CP0C2_TS 24
358#define CP0C2_TL 20
359#define CP0C2_TA 16
360#define CP0C2_SU 12
361#define CP0C2_SS 8
362#define CP0C2_SL 4
363#define CP0C2_SA 0
364 int32_t CP0_Config3;
365#define CP0C3_M 31
366#define CP0C3_DSPP 10
367#define CP0C3_LPA 7
368#define CP0C3_VEIC 6
369#define CP0C3_VInt 5
370#define CP0C3_SP 4
371#define CP0C3_MT 2
372#define CP0C3_SM 1
373#define CP0C3_TL 0
374 int32_t CP0_Config6;
375 int32_t CP0_Config7;
376
377 target_ulong CP0_LLAddr;
378 target_ulong llval;
379 target_ulong llnewval;
380 target_ulong llreg;
381 target_ulong CP0_WatchLo[8];
382 int32_t CP0_WatchHi[8];
383 target_ulong CP0_XContext;
384 int32_t CP0_Framemask;
385 int32_t CP0_Debug;
386#define CP0DB_DBD 31
387#define CP0DB_DM 30
388#define CP0DB_LSNM 28
389#define CP0DB_Doze 27
390#define CP0DB_Halt 26
391#define CP0DB_CNT 25
392#define CP0DB_IBEP 24
393#define CP0DB_DBEP 21
394#define CP0DB_IEXI 20
395#define CP0DB_VER 15
396#define CP0DB_DEC 10
397#define CP0DB_SSt 8
398#define CP0DB_DINT 5
399#define CP0DB_DIB 4
400#define CP0DB_DDBS 3
401#define CP0DB_DDBL 2
402#define CP0DB_DBp 1
403#define CP0DB_DSS 0
404 target_ulong CP0_DEPC;
405 int32_t CP0_Performance0;
406 int32_t CP0_TagLo;
407 int32_t CP0_DataLo;
408 int32_t CP0_TagHi;
409 int32_t CP0_DataHi;
410 target_ulong CP0_ErrorEPC;
411 int32_t CP0_DESAVE;
412
413 TCState tcs[MIPS_SHADOW_SET_MAX];
414 CPUMIPSFPUContext fpus[MIPS_FPU_MAX];
415
416 int error_code;
417 uint32_t hflags;
418
419#define MIPS_HFLAG_TMASK 0x03FF
420#define MIPS_HFLAG_MODE 0x0007
421
422
423
424#define MIPS_HFLAG_KSU 0x0003
425#define MIPS_HFLAG_UM 0x0002
426#define MIPS_HFLAG_SM 0x0001
427#define MIPS_HFLAG_KM 0x0000
428#define MIPS_HFLAG_DM 0x0004
429#define MIPS_HFLAG_64 0x0008
430#define MIPS_HFLAG_CP0 0x0010
431#define MIPS_HFLAG_FPU 0x0020
432#define MIPS_HFLAG_F64 0x0040
433
434
435
436#define MIPS_HFLAG_COP1X 0x0080
437#define MIPS_HFLAG_RE 0x0100
438#define MIPS_HFLAG_UX 0x0200
439
440
441
442
443#define MIPS_HFLAG_BMASK 0x1C00
444#define MIPS_HFLAG_B 0x0400
445#define MIPS_HFLAG_BC 0x0800
446#define MIPS_HFLAG_BL 0x0C00
447#define MIPS_HFLAG_BR 0x1000
448 target_ulong btarget;
449 target_ulong bcond;
450
451 int SYNCI_Step;
452 int CCRes;
453 uint32_t CP0_Status_rw_bitmask;
454 uint32_t CP0_TCStatus_rw_bitmask;
455 int insn_flags;
456
457 target_ulong tls_value;
458
459 CPU_COMMON
460
461 const mips_def_t *cpu_model;
462 void *irq[8];
463 struct QEMUTimer *timer;
464};
465
466int no_mmu_map_address (CPUMIPSState *env, target_ulong *physical, int *prot,
467 target_ulong address, int rw, int access_type);
468int fixed_mmu_map_address (CPUMIPSState *env, target_ulong *physical, int *prot,
469 target_ulong address, int rw, int access_type);
470int r4k_map_address (CPUMIPSState *env, target_ulong *physical, int *prot,
471 target_ulong address, int rw, int access_type);
472void r4k_helper_tlbwi (void);
473void r4k_helper_tlbwr (void);
474void r4k_helper_tlbp (void);
475void r4k_helper_tlbr (void);
476void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
477
478void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
479 int unused, int size);
480
481#define cpu_init cpu_mips_init
482#define cpu_exec cpu_mips_exec
483#define cpu_gen_code cpu_mips_gen_code
484#define cpu_signal_handler cpu_mips_signal_handler
485#define cpu_list mips_cpu_list
486
487#define CPU_SAVE_VERSION 3
488
489
490
491#define MMU_MODE0_SUFFIX _kernel
492#define MMU_MODE1_SUFFIX _super
493#define MMU_MODE2_SUFFIX _user
494#define MMU_USER_IDX 2
495static inline int cpu_mmu_index (CPUState *env)
496{
497 return env->hflags & MIPS_HFLAG_KSU;
498}
499
500static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
501{
502 if (newsp)
503 env->active_tc.gpr[29] = newsp;
504 env->active_tc.gpr[7] = 0;
505 env->active_tc.gpr[2] = 0;
506}
507
508#include "cpu-all.h"
509#include "exec-all.h"
510
511
512
513
514enum {
515
516 ACCESS_USER = 0x00,
517 ACCESS_SUPER = 0x01,
518
519 ACCESS_STORE = 0x02,
520
521 ACCESS_CODE = 0x10,
522 ACCESS_INT = 0x20,
523 ACCESS_FLOAT = 0x30,
524};
525
526
527enum {
528 EXCP_NONE = -1,
529 EXCP_RESET = 0,
530 EXCP_SRESET,
531 EXCP_DSS,
532 EXCP_DINT,
533 EXCP_DDBL,
534 EXCP_DDBS,
535 EXCP_NMI,
536 EXCP_MCHECK,
537 EXCP_EXT_INTERRUPT,
538 EXCP_DFWATCH,
539 EXCP_DIB,
540 EXCP_IWATCH,
541 EXCP_AdEL,
542 EXCP_AdES,
543 EXCP_TLBF,
544 EXCP_IBE,
545 EXCP_DBp,
546 EXCP_SYSCALL,
547 EXCP_BREAK,
548 EXCP_CpU,
549 EXCP_RI,
550 EXCP_OVERFLOW,
551 EXCP_TRAP,
552 EXCP_FPE,
553 EXCP_DWATCH,
554 EXCP_LTLBL,
555 EXCP_TLBL,
556 EXCP_TLBS,
557 EXCP_DBE,
558 EXCP_THREAD,
559 EXCP_MDMX,
560 EXCP_C2E,
561 EXCP_CACHE,
562
563 EXCP_LAST = EXCP_CACHE,
564};
565
566#define EXCP_SC 0x100
567
568int cpu_mips_exec(CPUMIPSState *s);
569CPUMIPSState *cpu_mips_init(const char *cpu_model);
570
571int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
572
573
574uint32_t cpu_mips_get_random (CPUState *env);
575uint32_t cpu_mips_get_count (CPUState *env);
576void cpu_mips_store_count (CPUState *env, uint32_t value);
577void cpu_mips_store_compare (CPUState *env, uint32_t value);
578void cpu_mips_start_count(CPUState *env);
579void cpu_mips_stop_count(CPUState *env);
580
581
582void cpu_mips_update_irq (CPUState *env);
583
584
585int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
586 int mmu_idx, int is_softmmu);
587void do_interrupt (CPUState *env);
588void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
589
590static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
591{
592 env->active_tc.PC = tb->pc;
593 env->hflags &= ~MIPS_HFLAG_BMASK;
594 env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
595}
596
597static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
598 target_ulong *cs_base, int *flags)
599{
600 *pc = env->active_tc.PC;
601 *cs_base = 0;
602 *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
603}
604
605static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
606{
607 env->tls_value = newtls;
608}
609
610#endif
611