Loading target-mips/cpu.h +55 −4 Original line number Diff line number Diff line Loading @@ -99,14 +99,16 @@ struct CPUMIPSState { #endif uint32_t CP0_index; uint32_t CP0_random; uint32_t CP0_EntryLo0; uint32_t CP0_EntryLo1; uint32_t CP0_Context; uint64_t CP0_EntryLo0; uint64_t CP0_EntryLo1; uint64_t CP0_Context; uint32_t CP0_PageMask; uint32_t CP0_PageGrain; uint32_t CP0_Wired; uint32_t CP0_HWREna; uint32_t CP0_BadVAddr; uint32_t CP0_Count; uint32_t CP0_EntryHi; uint64_t CP0_EntryHi; uint32_t CP0_Compare; uint32_t CP0_Status; #define CP0St_CU3 31 Loading @@ -116,19 +118,36 @@ struct CPUMIPSState { #define CP0St_RP 27 #define CP0St_FR 26 #define CP0St_RE 25 #define CP0St_MX 24 #define CP0St_PX 23 #define CP0St_BEV 22 #define CP0St_TS 21 #define CP0St_SR 20 #define CP0St_NMI 19 #define CP0St_IM 8 #define CP0St_KX 7 #define CP0St_SX 6 #define CP0St_UX 5 #define CP0St_UM 4 #define CP0St_R0 3 #define CP0St_ERL 2 #define CP0St_EXL 1 #define CP0St_IE 0 uint32_t CP0_IntCtl; uint32_t CP0_SRSCtl; uint32_t CP0_Cause; #define CP0Ca_BD 31 #define CP0Ca_TI 30 #define CP0Ca_CE 28 #define CP0Ca_DC 27 #define CP0Ca_PCI 26 #define CP0Ca_IV 23 #define CP0Ca_WP 22 #define CP0Ca_IP 8 #define CP0Ca_EC 2 uint32_t CP0_EPC; uint32_t CP0_PRid; uint32_t CP0_EBase; uint32_t CP0_Config0; #define CP0C0_M 31 #define CP0C0_K23 28 Loading @@ -140,8 +159,10 @@ struct CPUMIPSState { #define CP0C0_AT 13 #define CP0C0_AR 10 #define CP0C0_MT 7 #define CP0C0_VI 3 #define CP0C0_K0 0 uint32_t CP0_Config1; #define CP0C1_M 31 #define CP0C1_MMU 25 #define CP0C1_IS 22 #define CP0C1_IL 19 Loading @@ -149,14 +170,38 @@ struct CPUMIPSState { #define CP0C1_DS 13 #define CP0C1_DL 10 #define CP0C1_DA 7 #define CP0C1_C2 6 #define CP0C1_MD 5 #define CP0C1_PC 4 #define CP0C1_WR 3 #define CP0C1_CA 2 #define CP0C1_EP 1 #define CP0C1_FP 0 uint32_t CP0_Config2; #define CP0C2_M 31 #define CP0C2_TU 28 #define CP0C2_TS 24 #define CP0C2_TL 20 #define CP0C2_TA 16 #define CP0C2_SU 12 #define CP0C2_SS 8 #define CP0C2_SL 4 #define CP0C2_SA 0 uint32_t CP0_Config3; #define CP0C3_M 31 #define CP0C3_DSPP 10 #define CP0C3_LPA 7 #define CP0C3_VEIC 6 #define CP0C3_VInt 5 #define CP0C3_SP 4 #define CP0C3_MT 2 #define CP0C3_SM 1 #define CP0C3_TL 0 uint32_t CP0_LLAddr; uint32_t CP0_WatchLo; uint32_t CP0_WatchHi; uint32_t CP0_XContext; uint32_t CP0_Framemask; uint32_t CP0_Debug; #define CPDB_DBD 31 #define CP0DB_DM 30 Loading @@ -177,8 +222,11 @@ struct CPUMIPSState { #define CP0DB_DBp 1 #define CP0DB_DSS 0 uint32_t CP0_DEPC; uint32_t CP0_Performance0; uint32_t CP0_TagLo; uint32_t CP0_DataLo; uint32_t CP0_TagHi; uint32_t CP0_DataHi; uint32_t CP0_ErrorEPC; uint32_t CP0_DESAVE; /* Qemu */ Loading Loading @@ -211,6 +259,9 @@ struct CPUMIPSState { int halted; /* TRUE if the CPU is in suspend state */ int SYNCI_Step; /* Address step size for SYNCI */ int CCRes; /* Cycle count resolution/divisor */ CPU_COMMON int ram_size; Loading target-mips/exec.h +1 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ void do_msubu (void); #endif void do_mfc0_random(void); void do_mfc0_count(void); void do_mtc0_entryhi(uint32_t in); void do_mtc0_status_debug(uint32_t old, uint32_t val); void do_mtc0_status_irqraise_debug(void); void do_tlbwi (void); Loading target-mips/helper.c +0 −6 Original line number Diff line number Diff line Loading @@ -302,15 +302,9 @@ void do_interrupt (CPUState *env) #endif env->CP0_Wired = 0; env->CP0_Config0 = MIPS_CONFIG0; #if defined (MIPS_CONFIG1) env->CP0_Config1 = MIPS_CONFIG1; #endif #if defined (MIPS_CONFIG2) env->CP0_Config2 = MIPS_CONFIG2; #endif #if defined (MIPS_CONFIG3) env->CP0_Config3 = MIPS_CONFIG3; #endif env->CP0_WatchLo = 0; env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV); goto set_error_EPC; Loading target-mips/mips-defs.h +34 −16 Original line number Diff line number Diff line Loading @@ -29,26 +29,44 @@ * Define a major version 1, minor version 0. */ #define MIPS_FCR0 ((0 << 16) | (1 << 8) | (1 << 4) | 0) /* Have config1, uses TLB */ /* Have config1, is MIPS32R1, uses TLB, no virtual icache, uncached coherency */ #define MIPS_CONFIG0_1 \ ((1 << CP0C0_M) | (0 << CP0C0_K23) | (0 << CP0C0_KU) | \ (1 << CP0C0_MT) | (2 << CP0C0_K0)) ((1 << CP0C0_M) | (0x0 << CP0C0_K23) | (0x0 << CP0C0_KU) | \ (0x0 << CP0C0_AT) | (0x0 << CP0C0_AR) | (0x1 << CP0C0_MT) | \ (0x2 << CP0C0_K0)) #ifdef TARGET_WORDS_BIGENDIAN #define MIPS_CONFIG0 (MIPS_CONFIG0_1 | (1 << CP0C0_BE)) #else #define MIPS_CONFIG0 MIPS_CONFIG0_1 #endif /* 16 TLBs, 64 sets Icache, 16 bytes Icache line, 2-way Icache, * 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache, * no performance counters, watch registers present, no code compression, * EJTAG present, FPU enable bit depending on MIPS_USES_FPU */ #define MIPS_CONFIG1 \ ((15 << CP0C1_MMU) | \ (0x000 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x01 << CP0C1_IA) | \ (0x000 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x01 << CP0C1_DA) | \ (0 << CP0C1_PC) | (1 << CP0C1_WR) | (0 << CP0C1_CA) | \ (1 << CP0C1_EP) | (MIPS_USES_FPU << CP0C1_FP)) /* Have config2, 16 TLB entries, 64 sets Icache, 16 bytes Icache line, 2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache, no coprocessor2 attached, no MDMX support attached, no performance counters, watch registers present, no code compression, EJTAG present, FPU enable bit depending on MIPS_USES_FPU */ #define MIPS_CONFIG1_1 \ ((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \ (0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \ (0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \ (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP)) #ifdef MIPS_USES_FPU #define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (1 << CP0C1_FP)) #else #define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (0 << CP0C1_FP)) #endif /* Have config3, no tertiary/secondary caches implemented */ #define MIPS_CONFIG2 \ ((1 << CP0C2_M)) /* No config4, no DSP ASE, no large physaddr, no external interrupt controller, no vectored interupts, no 1kb pages, no MT ASE, no SmartMIPS ASE, no trace logic */ #define MIPS_CONFIG3 \ ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ (0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL)) #elif (MIPS_CPU == MIPS_R4Kp) /* 32 bits target */ #define TARGET_LONG_BITS 32 Loading @@ -60,7 +78,7 @@ #define MIPS_USES_R4K_FPM #else #error "MIPS CPU not defined" /* Remainder for other flags */ /* Reminder for other flags */ //#define TARGET_MIPS64 //#define MIPS_USES_FPU #endif Loading target-mips/op.c +345 −15 Original line number Diff line number Diff line Loading @@ -437,6 +437,18 @@ void op_srl (void) RETURN(); } void op_rotr (void) { target_ulong tmp; if (T1) { tmp = T0 << (0x20 - T1); T0 = (T0 >> T1) | tmp; } else T0 = T1; RETURN(); } void op_sllv (void) { T0 = T1 << (T0 & 0x1F); Loading @@ -455,6 +467,19 @@ void op_srlv (void) RETURN(); } void op_rotrv (void) { target_ulong tmp; T0 &= 0x1F; if (T0) { tmp = T1 << (0x20 - T0); T0 = (T1 >> T0) | tmp; } else T0 = T1; RETURN(); } void op_clo (void) { int n; Loading Loading @@ -602,6 +627,20 @@ void op_movz (void) RETURN(); } void op_movf (void) { if (!(env->fcr31 & PARAM1)) env->gpr[PARAM2] = env->gpr[PARAM3]; RETURN(); } void op_movt (void) { if (env->fcr31 & PARAM1) env->gpr[PARAM2] = env->gpr[PARAM3]; RETURN(); } /* Tests */ #define OP_COND(name, cond) \ void glue(op_, name) (void) \ Loading @@ -625,28 +664,32 @@ OP_COND(gtz, (int32_t)T0 > 0); OP_COND(lez, (int32_t)T0 <= 0); OP_COND(ltz, (int32_t)T0 < 0); /* Branchs */ /* Branches */ //#undef USE_DIRECT_JUMP void OPPROTO op_goto_tb0(void) { GOTO_TB(op_goto_tb0, PARAM1, 0); RETURN(); } void OPPROTO op_goto_tb1(void) { GOTO_TB(op_goto_tb1, PARAM1, 1); RETURN(); } /* Branch to register */ void op_save_breg_target (void) { env->btarget = T2; RETURN(); } void op_restore_breg_target (void) { T2 = env->btarget; RETURN(); } void op_breg (void) Loading Loading @@ -724,12 +767,24 @@ void op_mfc0_pagemask (void) RETURN(); } void op_mfc0_pagegrain (void) { T0 = env->CP0_PageGrain; RETURN(); } void op_mfc0_wired (void) { T0 = env->CP0_Wired; RETURN(); } void op_mfc0_hwrena (void) { T0 = env->CP0_HWREna; RETURN(); } void op_mfc0_badvaddr (void) { T0 = env->CP0_BadVAddr; Loading Loading @@ -766,6 +821,18 @@ void op_mfc0_status (void) RETURN(); } void op_mfc0_intctl (void) { T0 = env->CP0_IntCtl; RETURN(); } void op_mfc0_srsctl (void) { T0 = env->CP0_SRSCtl; RETURN(); } void op_mfc0_cause (void) { T0 = env->CP0_Cause; Loading @@ -784,6 +851,12 @@ void op_mfc0_prid (void) RETURN(); } void op_mfc0_ebase (void) { T0 = env->CP0_EBase; RETURN(); } void op_mfc0_config0 (void) { T0 = env->CP0_Config0; Loading @@ -796,24 +869,48 @@ void op_mfc0_config1 (void) RETURN(); } void op_mfc0_config2 (void) { T0 = env->CP0_Config2; RETURN(); } void op_mfc0_config3 (void) { T0 = env->CP0_Config3; RETURN(); } void op_mfc0_lladdr (void) { T0 = env->CP0_LLAddr >> 4; RETURN(); } void op_mfc0_watchlo (void) void op_mfc0_watchlo0 (void) { T0 = env->CP0_WatchLo; RETURN(); } void op_mfc0_watchhi (void) void op_mfc0_watchhi0 (void) { T0 = env->CP0_WatchHi; RETURN(); } void op_mfc0_xcontext (void) { T0 = env->CP0_XContext; RETURN(); } void op_mfc0_framemask (void) { T0 = env->CP0_Framemask; RETURN(); } void op_mfc0_debug (void) { T0 = env->CP0_Debug; Loading @@ -828,6 +925,12 @@ void op_mfc0_depc (void) RETURN(); } void op_mfc0_performance0 (void) { T0 = env->CP0_Performance0; RETURN(); } void op_mfc0_taglo (void) { T0 = env->CP0_TagLo; Loading @@ -840,6 +943,18 @@ void op_mfc0_datalo (void) RETURN(); } void op_mfc0_taghi (void) { T0 = env->CP0_TagHi; RETURN(); } void op_mfc0_datahi (void) { T0 = env->CP0_DataHi; RETURN(); } void op_mfc0_errorepc (void) { T0 = env->CP0_ErrorEPC; Loading @@ -854,37 +969,57 @@ void op_mfc0_desave (void) void op_mtc0_index (void) { env->CP0_index = (env->CP0_index & 0x80000000) | (T0 & 0x0000000F); env->CP0_index = (env->CP0_index & 0x80000000) | (T0 & (MIPS_TLB_NB - 1)); RETURN(); } void op_mtc0_entrylo0 (void) { env->CP0_EntryLo0 = T0 & 0x3FFFFFFF; /* Large physaddr not implemented */ /* 1k pages not implemented */ env->CP0_EntryLo0 = T0 & 0x3FFFFFFFUL; RETURN(); } void op_mtc0_entrylo1 (void) { env->CP0_EntryLo1 = T0 & 0x3FFFFFFF; /* Large physaddr not implemented */ /* 1k pages not implemented */ env->CP0_EntryLo1 = T0 & 0x3FFFFFFFUL; RETURN(); } void op_mtc0_context (void) { env->CP0_Context = (env->CP0_Context & 0xFF800000) | (T0 & 0x007FFFF0); env->CP0_Context = (env->CP0_Context & ~0x007FFFFF) | (T0 & 0x007FFFF0); RETURN(); } void op_mtc0_pagemask (void) { env->CP0_PageMask = T0 & 0x01FFE000; /* 1k pages not implemented */ env->CP0_PageMask = T0 & 0x1FFFE000; RETURN(); } void op_mtc0_pagegrain (void) { /* SmartMIPS not implemented */ /* Large physaddr not implemented */ /* 1k pages not implemented */ env->CP0_PageGrain = 0; RETURN(); } void op_mtc0_wired (void) { env->CP0_Wired = T0 & 0x0000000F; env->CP0_Wired = T0 & (MIPS_TLB_NB - 1); RETURN(); } void op_mtc0_hwrena (void) { env->CP0_HWREna = T0 & 0x0000000F; RETURN(); } Loading @@ -898,6 +1033,8 @@ void op_mtc0_entryhi (void) { uint32_t old, val; /* 1k pages not implemented */ /* Ignore MIPS64 TLB for now */ val = T0 & 0xFFFFE0FF; old = env->CP0_EntryHi; env->CP0_EntryHi = val; Loading Loading @@ -950,6 +1087,20 @@ void op_mtc0_status (void) RETURN(); } void op_mtc0_intctl (void) { /* vectored interrupts not implemented */ env->CP0_IntCtl = 0; RETURN(); } void op_mtc0_srsctl (void) { /* shadow registers not implemented */ env->CP0_SRSCtl = 0; RETURN(); } void op_mtc0_cause (void) { uint32_t val, old; Loading @@ -960,7 +1111,6 @@ void op_mtc0_cause (void) #if 0 { int i, mask; /* Check if we ever asserted a software IRQ */ for (i = 0; i < 2; i++) { mask = 0x100 << i; Loading @@ -978,28 +1128,56 @@ void op_mtc0_epc (void) RETURN(); } void op_mtc0_ebase (void) { /* vectored interrupts not implemented */ /* Multi-CPU not implemented */ env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000); RETURN(); } void op_mtc0_config0 (void) { #if defined(MIPS_USES_R4K_TLB) env->CP0_Config0 = (env->CP0_Config0 & 0x8017FF80) | (T0 & 0x7E000001); /* Fixed mapping MMU not implemented */ env->CP0_Config0 = (env->CP0_Config0 & 0x8017FF88) | (T0 & 0x00000001); #else env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF80) | (T0 & 0x00000001); env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF88) | (T0 & 0x00000001); #endif RETURN(); } void op_mtc0_watchlo (void) void op_mtc0_config2 (void) { /* tertiary/secondary caches not implemented */ env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF); RETURN(); } void op_mtc0_watchlo0 (void) { env->CP0_WatchLo = T0; RETURN(); } void op_mtc0_watchhi (void) void op_mtc0_watchhi0 (void) { env->CP0_WatchHi = T0 & 0x40FF0FF8; RETURN(); } void op_mtc0_xcontext (void) { env->CP0_XContext = T0; /* XXX */ RETURN(); } void op_mtc0_framemask (void) { env->CP0_Framemask = T0; /* XXX */ RETURN(); } void op_mtc0_debug (void) { env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120); Loading @@ -1016,12 +1194,36 @@ void op_mtc0_depc (void) RETURN(); } void op_mtc0_performance0 (void) { env->CP0_Performance0 = T0; /* XXX */ RETURN(); } void op_mtc0_taglo (void) { env->CP0_TagLo = T0 & 0xFFFFFCF6; RETURN(); } void op_mtc0_datalo (void) { env->CP0_DataLo = T0; /* XXX */ RETURN(); } void op_mtc0_taghi (void) { env->CP0_TagHi = T0; /* XXX */ RETURN(); } void op_mtc0_datahi (void) { env->CP0_DataHi = T0; /* XXX */ RETURN(); } void op_mtc0_errorepc (void) { env->CP0_ErrorEPC = T0; Loading Loading @@ -1422,6 +1624,42 @@ void op_tlbr (void) void op_pmon (void) { CALL_FROM_TB1(do_pmon, PARAM1); RETURN(); } void op_di (void) { uint32_t val; T0 = env->CP0_Status; val = T0 & ~(1 << CP0St_IE); if (val != T0) { env->interrupt_request &= ~CPU_INTERRUPT_HARD; env->CP0_Status = val; } RETURN(); } void op_ei (void) { uint32_t val; T0 = env->CP0_Status; val = T0 | (1 << CP0St_IE); if (val != T0) { const uint32_t mask = 0x0000FF00; env->CP0_Status = val; if (!(env->hflags & MIPS_HFLAG_EXL) && !(env->hflags & MIPS_HFLAG_ERL) && !(env->hflags & MIPS_HFLAG_DM) && (env->CP0_Status & env->CP0_Cause & mask)) { env->interrupt_request |= CPU_INTERRUPT_HARD; if (logfile) CALL_FROM_TB0(do_mtc0_status_irqraise_debug); } } RETURN(); } void op_trap (void) Loading @@ -1435,11 +1673,13 @@ void op_trap (void) void op_debug (void) { CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG); RETURN(); } void op_set_lladdr (void) { env->CP0_LLAddr = T2; RETURN(); } void debug_eret (void); Loading @@ -1456,12 +1696,50 @@ void op_eret (void) env->CP0_Status &= ~(1 << CP0St_EXL); } env->CP0_LLAddr = 1; RETURN(); } void op_deret (void) { CALL_FROM_TB0(debug_eret); env->PC = env->CP0_DEPC; RETURN(); } void op_rdhwr_cpunum(void) { if (env->CP0_HWREna & (1 << 0)) T0 = env->CP0_EBase & 0x2ff; else CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); RETURN(); } void op_rdhwr_synci_step(void) { if (env->CP0_HWREna & (1 << 1)) T0 = env->SYNCI_Step; else CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); RETURN(); } void op_rdhwr_cc(void) { if (env->CP0_HWREna & (1 << 2)) T0 = env->CP0_Count; else CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); RETURN(); } void op_rdhwr_ccres(void) { if (env->CP0_HWREna & (1 << 3)) T0 = env->CCRes; else CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); RETURN(); } void op_save_state (void) Loading Loading @@ -1491,10 +1769,62 @@ void op_raise_exception_err (void) void op_exit_tb (void) { EXIT_TB(); RETURN(); } void op_wait (void) { env->halted = 1; CALL_FROM_TB1(do_raise_exception, EXCP_HLT); RETURN(); } /* Bitfield operations. */ void op_ext(void) { unsigned int pos = PARAM1; unsigned int size = PARAM2; T0 = (T1 >> pos) & ((1 << size) - 1); RETURN(); } void op_ins(void) { unsigned int pos = PARAM1; unsigned int size = PARAM2; target_ulong mask = ((1 << size) - 1) << pos; T0 = (T2 & ~mask) | ((T1 << pos) & mask); RETURN(); } void op_wsbh(void) { T0 = ((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF); RETURN(); } void op_dsbh(void) { T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL); RETURN(); } void op_dshd(void) { T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL); RETURN(); } void op_seb(void) { T0 = ((T1 & 0xFF) ^ 0x80) - 0x80; RETURN(); } void op_seh(void) { T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000; RETURN(); } Loading
target-mips/cpu.h +55 −4 Original line number Diff line number Diff line Loading @@ -99,14 +99,16 @@ struct CPUMIPSState { #endif uint32_t CP0_index; uint32_t CP0_random; uint32_t CP0_EntryLo0; uint32_t CP0_EntryLo1; uint32_t CP0_Context; uint64_t CP0_EntryLo0; uint64_t CP0_EntryLo1; uint64_t CP0_Context; uint32_t CP0_PageMask; uint32_t CP0_PageGrain; uint32_t CP0_Wired; uint32_t CP0_HWREna; uint32_t CP0_BadVAddr; uint32_t CP0_Count; uint32_t CP0_EntryHi; uint64_t CP0_EntryHi; uint32_t CP0_Compare; uint32_t CP0_Status; #define CP0St_CU3 31 Loading @@ -116,19 +118,36 @@ struct CPUMIPSState { #define CP0St_RP 27 #define CP0St_FR 26 #define CP0St_RE 25 #define CP0St_MX 24 #define CP0St_PX 23 #define CP0St_BEV 22 #define CP0St_TS 21 #define CP0St_SR 20 #define CP0St_NMI 19 #define CP0St_IM 8 #define CP0St_KX 7 #define CP0St_SX 6 #define CP0St_UX 5 #define CP0St_UM 4 #define CP0St_R0 3 #define CP0St_ERL 2 #define CP0St_EXL 1 #define CP0St_IE 0 uint32_t CP0_IntCtl; uint32_t CP0_SRSCtl; uint32_t CP0_Cause; #define CP0Ca_BD 31 #define CP0Ca_TI 30 #define CP0Ca_CE 28 #define CP0Ca_DC 27 #define CP0Ca_PCI 26 #define CP0Ca_IV 23 #define CP0Ca_WP 22 #define CP0Ca_IP 8 #define CP0Ca_EC 2 uint32_t CP0_EPC; uint32_t CP0_PRid; uint32_t CP0_EBase; uint32_t CP0_Config0; #define CP0C0_M 31 #define CP0C0_K23 28 Loading @@ -140,8 +159,10 @@ struct CPUMIPSState { #define CP0C0_AT 13 #define CP0C0_AR 10 #define CP0C0_MT 7 #define CP0C0_VI 3 #define CP0C0_K0 0 uint32_t CP0_Config1; #define CP0C1_M 31 #define CP0C1_MMU 25 #define CP0C1_IS 22 #define CP0C1_IL 19 Loading @@ -149,14 +170,38 @@ struct CPUMIPSState { #define CP0C1_DS 13 #define CP0C1_DL 10 #define CP0C1_DA 7 #define CP0C1_C2 6 #define CP0C1_MD 5 #define CP0C1_PC 4 #define CP0C1_WR 3 #define CP0C1_CA 2 #define CP0C1_EP 1 #define CP0C1_FP 0 uint32_t CP0_Config2; #define CP0C2_M 31 #define CP0C2_TU 28 #define CP0C2_TS 24 #define CP0C2_TL 20 #define CP0C2_TA 16 #define CP0C2_SU 12 #define CP0C2_SS 8 #define CP0C2_SL 4 #define CP0C2_SA 0 uint32_t CP0_Config3; #define CP0C3_M 31 #define CP0C3_DSPP 10 #define CP0C3_LPA 7 #define CP0C3_VEIC 6 #define CP0C3_VInt 5 #define CP0C3_SP 4 #define CP0C3_MT 2 #define CP0C3_SM 1 #define CP0C3_TL 0 uint32_t CP0_LLAddr; uint32_t CP0_WatchLo; uint32_t CP0_WatchHi; uint32_t CP0_XContext; uint32_t CP0_Framemask; uint32_t CP0_Debug; #define CPDB_DBD 31 #define CP0DB_DM 30 Loading @@ -177,8 +222,11 @@ struct CPUMIPSState { #define CP0DB_DBp 1 #define CP0DB_DSS 0 uint32_t CP0_DEPC; uint32_t CP0_Performance0; uint32_t CP0_TagLo; uint32_t CP0_DataLo; uint32_t CP0_TagHi; uint32_t CP0_DataHi; uint32_t CP0_ErrorEPC; uint32_t CP0_DESAVE; /* Qemu */ Loading Loading @@ -211,6 +259,9 @@ struct CPUMIPSState { int halted; /* TRUE if the CPU is in suspend state */ int SYNCI_Step; /* Address step size for SYNCI */ int CCRes; /* Cycle count resolution/divisor */ CPU_COMMON int ram_size; Loading
target-mips/exec.h +1 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ void do_msubu (void); #endif void do_mfc0_random(void); void do_mfc0_count(void); void do_mtc0_entryhi(uint32_t in); void do_mtc0_status_debug(uint32_t old, uint32_t val); void do_mtc0_status_irqraise_debug(void); void do_tlbwi (void); Loading
target-mips/helper.c +0 −6 Original line number Diff line number Diff line Loading @@ -302,15 +302,9 @@ void do_interrupt (CPUState *env) #endif env->CP0_Wired = 0; env->CP0_Config0 = MIPS_CONFIG0; #if defined (MIPS_CONFIG1) env->CP0_Config1 = MIPS_CONFIG1; #endif #if defined (MIPS_CONFIG2) env->CP0_Config2 = MIPS_CONFIG2; #endif #if defined (MIPS_CONFIG3) env->CP0_Config3 = MIPS_CONFIG3; #endif env->CP0_WatchLo = 0; env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV); goto set_error_EPC; Loading
target-mips/mips-defs.h +34 −16 Original line number Diff line number Diff line Loading @@ -29,26 +29,44 @@ * Define a major version 1, minor version 0. */ #define MIPS_FCR0 ((0 << 16) | (1 << 8) | (1 << 4) | 0) /* Have config1, uses TLB */ /* Have config1, is MIPS32R1, uses TLB, no virtual icache, uncached coherency */ #define MIPS_CONFIG0_1 \ ((1 << CP0C0_M) | (0 << CP0C0_K23) | (0 << CP0C0_KU) | \ (1 << CP0C0_MT) | (2 << CP0C0_K0)) ((1 << CP0C0_M) | (0x0 << CP0C0_K23) | (0x0 << CP0C0_KU) | \ (0x0 << CP0C0_AT) | (0x0 << CP0C0_AR) | (0x1 << CP0C0_MT) | \ (0x2 << CP0C0_K0)) #ifdef TARGET_WORDS_BIGENDIAN #define MIPS_CONFIG0 (MIPS_CONFIG0_1 | (1 << CP0C0_BE)) #else #define MIPS_CONFIG0 MIPS_CONFIG0_1 #endif /* 16 TLBs, 64 sets Icache, 16 bytes Icache line, 2-way Icache, * 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache, * no performance counters, watch registers present, no code compression, * EJTAG present, FPU enable bit depending on MIPS_USES_FPU */ #define MIPS_CONFIG1 \ ((15 << CP0C1_MMU) | \ (0x000 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x01 << CP0C1_IA) | \ (0x000 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x01 << CP0C1_DA) | \ (0 << CP0C1_PC) | (1 << CP0C1_WR) | (0 << CP0C1_CA) | \ (1 << CP0C1_EP) | (MIPS_USES_FPU << CP0C1_FP)) /* Have config2, 16 TLB entries, 64 sets Icache, 16 bytes Icache line, 2-way Icache, 64 sets Dcache, 16 bytes Dcache line, 2-way Dcache, no coprocessor2 attached, no MDMX support attached, no performance counters, watch registers present, no code compression, EJTAG present, FPU enable bit depending on MIPS_USES_FPU */ #define MIPS_CONFIG1_1 \ ((1 << CP0C1_M) | ((MIPS_TLB_NB - 1) << CP0C1_MMU) | \ (0x0 << CP0C1_IS) | (0x3 << CP0C1_IL) | (0x1 << CP0C1_IA) | \ (0x0 << CP0C1_DS) | (0x3 << CP0C1_DL) | (0x1 << CP0C1_DA) | \ (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \ (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP)) #ifdef MIPS_USES_FPU #define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (1 << CP0C1_FP)) #else #define MIPS_CONFIG1 (MIPS_CONFIG1_1 | (0 << CP0C1_FP)) #endif /* Have config3, no tertiary/secondary caches implemented */ #define MIPS_CONFIG2 \ ((1 << CP0C2_M)) /* No config4, no DSP ASE, no large physaddr, no external interrupt controller, no vectored interupts, no 1kb pages, no MT ASE, no SmartMIPS ASE, no trace logic */ #define MIPS_CONFIG3 \ ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) | \ (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \ (0 << CP0C3_MT) | (0 << CP0C3_SM) | (0 << CP0C3_TL)) #elif (MIPS_CPU == MIPS_R4Kp) /* 32 bits target */ #define TARGET_LONG_BITS 32 Loading @@ -60,7 +78,7 @@ #define MIPS_USES_R4K_FPM #else #error "MIPS CPU not defined" /* Remainder for other flags */ /* Reminder for other flags */ //#define TARGET_MIPS64 //#define MIPS_USES_FPU #endif Loading
target-mips/op.c +345 −15 Original line number Diff line number Diff line Loading @@ -437,6 +437,18 @@ void op_srl (void) RETURN(); } void op_rotr (void) { target_ulong tmp; if (T1) { tmp = T0 << (0x20 - T1); T0 = (T0 >> T1) | tmp; } else T0 = T1; RETURN(); } void op_sllv (void) { T0 = T1 << (T0 & 0x1F); Loading @@ -455,6 +467,19 @@ void op_srlv (void) RETURN(); } void op_rotrv (void) { target_ulong tmp; T0 &= 0x1F; if (T0) { tmp = T1 << (0x20 - T0); T0 = (T1 >> T0) | tmp; } else T0 = T1; RETURN(); } void op_clo (void) { int n; Loading Loading @@ -602,6 +627,20 @@ void op_movz (void) RETURN(); } void op_movf (void) { if (!(env->fcr31 & PARAM1)) env->gpr[PARAM2] = env->gpr[PARAM3]; RETURN(); } void op_movt (void) { if (env->fcr31 & PARAM1) env->gpr[PARAM2] = env->gpr[PARAM3]; RETURN(); } /* Tests */ #define OP_COND(name, cond) \ void glue(op_, name) (void) \ Loading @@ -625,28 +664,32 @@ OP_COND(gtz, (int32_t)T0 > 0); OP_COND(lez, (int32_t)T0 <= 0); OP_COND(ltz, (int32_t)T0 < 0); /* Branchs */ /* Branches */ //#undef USE_DIRECT_JUMP void OPPROTO op_goto_tb0(void) { GOTO_TB(op_goto_tb0, PARAM1, 0); RETURN(); } void OPPROTO op_goto_tb1(void) { GOTO_TB(op_goto_tb1, PARAM1, 1); RETURN(); } /* Branch to register */ void op_save_breg_target (void) { env->btarget = T2; RETURN(); } void op_restore_breg_target (void) { T2 = env->btarget; RETURN(); } void op_breg (void) Loading Loading @@ -724,12 +767,24 @@ void op_mfc0_pagemask (void) RETURN(); } void op_mfc0_pagegrain (void) { T0 = env->CP0_PageGrain; RETURN(); } void op_mfc0_wired (void) { T0 = env->CP0_Wired; RETURN(); } void op_mfc0_hwrena (void) { T0 = env->CP0_HWREna; RETURN(); } void op_mfc0_badvaddr (void) { T0 = env->CP0_BadVAddr; Loading Loading @@ -766,6 +821,18 @@ void op_mfc0_status (void) RETURN(); } void op_mfc0_intctl (void) { T0 = env->CP0_IntCtl; RETURN(); } void op_mfc0_srsctl (void) { T0 = env->CP0_SRSCtl; RETURN(); } void op_mfc0_cause (void) { T0 = env->CP0_Cause; Loading @@ -784,6 +851,12 @@ void op_mfc0_prid (void) RETURN(); } void op_mfc0_ebase (void) { T0 = env->CP0_EBase; RETURN(); } void op_mfc0_config0 (void) { T0 = env->CP0_Config0; Loading @@ -796,24 +869,48 @@ void op_mfc0_config1 (void) RETURN(); } void op_mfc0_config2 (void) { T0 = env->CP0_Config2; RETURN(); } void op_mfc0_config3 (void) { T0 = env->CP0_Config3; RETURN(); } void op_mfc0_lladdr (void) { T0 = env->CP0_LLAddr >> 4; RETURN(); } void op_mfc0_watchlo (void) void op_mfc0_watchlo0 (void) { T0 = env->CP0_WatchLo; RETURN(); } void op_mfc0_watchhi (void) void op_mfc0_watchhi0 (void) { T0 = env->CP0_WatchHi; RETURN(); } void op_mfc0_xcontext (void) { T0 = env->CP0_XContext; RETURN(); } void op_mfc0_framemask (void) { T0 = env->CP0_Framemask; RETURN(); } void op_mfc0_debug (void) { T0 = env->CP0_Debug; Loading @@ -828,6 +925,12 @@ void op_mfc0_depc (void) RETURN(); } void op_mfc0_performance0 (void) { T0 = env->CP0_Performance0; RETURN(); } void op_mfc0_taglo (void) { T0 = env->CP0_TagLo; Loading @@ -840,6 +943,18 @@ void op_mfc0_datalo (void) RETURN(); } void op_mfc0_taghi (void) { T0 = env->CP0_TagHi; RETURN(); } void op_mfc0_datahi (void) { T0 = env->CP0_DataHi; RETURN(); } void op_mfc0_errorepc (void) { T0 = env->CP0_ErrorEPC; Loading @@ -854,37 +969,57 @@ void op_mfc0_desave (void) void op_mtc0_index (void) { env->CP0_index = (env->CP0_index & 0x80000000) | (T0 & 0x0000000F); env->CP0_index = (env->CP0_index & 0x80000000) | (T0 & (MIPS_TLB_NB - 1)); RETURN(); } void op_mtc0_entrylo0 (void) { env->CP0_EntryLo0 = T0 & 0x3FFFFFFF; /* Large physaddr not implemented */ /* 1k pages not implemented */ env->CP0_EntryLo0 = T0 & 0x3FFFFFFFUL; RETURN(); } void op_mtc0_entrylo1 (void) { env->CP0_EntryLo1 = T0 & 0x3FFFFFFF; /* Large physaddr not implemented */ /* 1k pages not implemented */ env->CP0_EntryLo1 = T0 & 0x3FFFFFFFUL; RETURN(); } void op_mtc0_context (void) { env->CP0_Context = (env->CP0_Context & 0xFF800000) | (T0 & 0x007FFFF0); env->CP0_Context = (env->CP0_Context & ~0x007FFFFF) | (T0 & 0x007FFFF0); RETURN(); } void op_mtc0_pagemask (void) { env->CP0_PageMask = T0 & 0x01FFE000; /* 1k pages not implemented */ env->CP0_PageMask = T0 & 0x1FFFE000; RETURN(); } void op_mtc0_pagegrain (void) { /* SmartMIPS not implemented */ /* Large physaddr not implemented */ /* 1k pages not implemented */ env->CP0_PageGrain = 0; RETURN(); } void op_mtc0_wired (void) { env->CP0_Wired = T0 & 0x0000000F; env->CP0_Wired = T0 & (MIPS_TLB_NB - 1); RETURN(); } void op_mtc0_hwrena (void) { env->CP0_HWREna = T0 & 0x0000000F; RETURN(); } Loading @@ -898,6 +1033,8 @@ void op_mtc0_entryhi (void) { uint32_t old, val; /* 1k pages not implemented */ /* Ignore MIPS64 TLB for now */ val = T0 & 0xFFFFE0FF; old = env->CP0_EntryHi; env->CP0_EntryHi = val; Loading Loading @@ -950,6 +1087,20 @@ void op_mtc0_status (void) RETURN(); } void op_mtc0_intctl (void) { /* vectored interrupts not implemented */ env->CP0_IntCtl = 0; RETURN(); } void op_mtc0_srsctl (void) { /* shadow registers not implemented */ env->CP0_SRSCtl = 0; RETURN(); } void op_mtc0_cause (void) { uint32_t val, old; Loading @@ -960,7 +1111,6 @@ void op_mtc0_cause (void) #if 0 { int i, mask; /* Check if we ever asserted a software IRQ */ for (i = 0; i < 2; i++) { mask = 0x100 << i; Loading @@ -978,28 +1128,56 @@ void op_mtc0_epc (void) RETURN(); } void op_mtc0_ebase (void) { /* vectored interrupts not implemented */ /* Multi-CPU not implemented */ env->CP0_EBase = 0x80000000 | (T0 & 0x3FFFF000); RETURN(); } void op_mtc0_config0 (void) { #if defined(MIPS_USES_R4K_TLB) env->CP0_Config0 = (env->CP0_Config0 & 0x8017FF80) | (T0 & 0x7E000001); /* Fixed mapping MMU not implemented */ env->CP0_Config0 = (env->CP0_Config0 & 0x8017FF88) | (T0 & 0x00000001); #else env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF80) | (T0 & 0x00000001); env->CP0_Config0 = (env->CP0_Config0 & 0xFE17FF88) | (T0 & 0x00000001); #endif RETURN(); } void op_mtc0_watchlo (void) void op_mtc0_config2 (void) { /* tertiary/secondary caches not implemented */ env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF); RETURN(); } void op_mtc0_watchlo0 (void) { env->CP0_WatchLo = T0; RETURN(); } void op_mtc0_watchhi (void) void op_mtc0_watchhi0 (void) { env->CP0_WatchHi = T0 & 0x40FF0FF8; RETURN(); } void op_mtc0_xcontext (void) { env->CP0_XContext = T0; /* XXX */ RETURN(); } void op_mtc0_framemask (void) { env->CP0_Framemask = T0; /* XXX */ RETURN(); } void op_mtc0_debug (void) { env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (T0 & 0x13300120); Loading @@ -1016,12 +1194,36 @@ void op_mtc0_depc (void) RETURN(); } void op_mtc0_performance0 (void) { env->CP0_Performance0 = T0; /* XXX */ RETURN(); } void op_mtc0_taglo (void) { env->CP0_TagLo = T0 & 0xFFFFFCF6; RETURN(); } void op_mtc0_datalo (void) { env->CP0_DataLo = T0; /* XXX */ RETURN(); } void op_mtc0_taghi (void) { env->CP0_TagHi = T0; /* XXX */ RETURN(); } void op_mtc0_datahi (void) { env->CP0_DataHi = T0; /* XXX */ RETURN(); } void op_mtc0_errorepc (void) { env->CP0_ErrorEPC = T0; Loading Loading @@ -1422,6 +1624,42 @@ void op_tlbr (void) void op_pmon (void) { CALL_FROM_TB1(do_pmon, PARAM1); RETURN(); } void op_di (void) { uint32_t val; T0 = env->CP0_Status; val = T0 & ~(1 << CP0St_IE); if (val != T0) { env->interrupt_request &= ~CPU_INTERRUPT_HARD; env->CP0_Status = val; } RETURN(); } void op_ei (void) { uint32_t val; T0 = env->CP0_Status; val = T0 | (1 << CP0St_IE); if (val != T0) { const uint32_t mask = 0x0000FF00; env->CP0_Status = val; if (!(env->hflags & MIPS_HFLAG_EXL) && !(env->hflags & MIPS_HFLAG_ERL) && !(env->hflags & MIPS_HFLAG_DM) && (env->CP0_Status & env->CP0_Cause & mask)) { env->interrupt_request |= CPU_INTERRUPT_HARD; if (logfile) CALL_FROM_TB0(do_mtc0_status_irqraise_debug); } } RETURN(); } void op_trap (void) Loading @@ -1435,11 +1673,13 @@ void op_trap (void) void op_debug (void) { CALL_FROM_TB1(do_raise_exception, EXCP_DEBUG); RETURN(); } void op_set_lladdr (void) { env->CP0_LLAddr = T2; RETURN(); } void debug_eret (void); Loading @@ -1456,12 +1696,50 @@ void op_eret (void) env->CP0_Status &= ~(1 << CP0St_EXL); } env->CP0_LLAddr = 1; RETURN(); } void op_deret (void) { CALL_FROM_TB0(debug_eret); env->PC = env->CP0_DEPC; RETURN(); } void op_rdhwr_cpunum(void) { if (env->CP0_HWREna & (1 << 0)) T0 = env->CP0_EBase & 0x2ff; else CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); RETURN(); } void op_rdhwr_synci_step(void) { if (env->CP0_HWREna & (1 << 1)) T0 = env->SYNCI_Step; else CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); RETURN(); } void op_rdhwr_cc(void) { if (env->CP0_HWREna & (1 << 2)) T0 = env->CP0_Count; else CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); RETURN(); } void op_rdhwr_ccres(void) { if (env->CP0_HWREna & (1 << 3)) T0 = env->CCRes; else CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); RETURN(); } void op_save_state (void) Loading Loading @@ -1491,10 +1769,62 @@ void op_raise_exception_err (void) void op_exit_tb (void) { EXIT_TB(); RETURN(); } void op_wait (void) { env->halted = 1; CALL_FROM_TB1(do_raise_exception, EXCP_HLT); RETURN(); } /* Bitfield operations. */ void op_ext(void) { unsigned int pos = PARAM1; unsigned int size = PARAM2; T0 = (T1 >> pos) & ((1 << size) - 1); RETURN(); } void op_ins(void) { unsigned int pos = PARAM1; unsigned int size = PARAM2; target_ulong mask = ((1 << size) - 1) << pos; T0 = (T2 & ~mask) | ((T1 << pos) & mask); RETURN(); } void op_wsbh(void) { T0 = ((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF); RETURN(); } void op_dsbh(void) { T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL); RETURN(); } void op_dshd(void) { T0 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL); RETURN(); } void op_seb(void) { T0 = ((T1 & 0xFF) ^ 0x80) - 0x80; RETURN(); } void op_seh(void) { T0 = ((T1 & 0xFFFF) ^ 0x8000) - 0x8000; RETURN(); }