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