diff options
Diffstat (limited to 'target-mips/cpu.h')
-rw-r--r-- | target-mips/cpu.h | 111 |
1 files changed, 90 insertions, 21 deletions
diff --git a/target-mips/cpu.h b/target-mips/cpu.h index ce3467f..aebb2d5 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -37,11 +37,11 @@ typedef struct CPUMIPSTLBContext CPUMIPSTLBContext; struct CPUMIPSTLBContext { uint32_t nb_tlb; uint32_t tlb_in_use; - int (*map_address) (struct CPUMIPSState *env, target_phys_addr_t *physical, int *prot, target_ulong address, int rw, int access_type); - void (*helper_tlbwi) (void); - void (*helper_tlbwr) (void); - void (*helper_tlbp) (void); - void (*helper_tlbr) (void); + int (*map_address) (struct CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type); + void (*helper_tlbwi)(struct CPUMIPSState *env); + void (*helper_tlbwr)(struct CPUMIPSState *env); + void (*helper_tlbp)(struct CPUMIPSState *env); + void (*helper_tlbr)(struct CPUMIPSState *env); union { struct { r4k_tlb_t tlb[MIPS_TLB_MAX]; @@ -415,7 +415,7 @@ struct CPUMIPSState { int error_code; uint32_t hflags; /* CPU State */ /* TMASK defines different execution modes */ -#define MIPS_HFLAG_TMASK 0x007FF +#define MIPS_HFLAG_TMASK 0xC07FF #define MIPS_HFLAG_MODE 0x00007 /* execution modes */ /* The KSU flags must be the lowest bits in hflags. The flag order must be the same as defined for CP0 Status. This allows to use @@ -453,6 +453,9 @@ struct CPUMIPSState { #define MIPS_HFLAG_BDS32 0x10000 /* branch requires 32-bit delay slot */ #define MIPS_HFLAG_BX 0x20000 /* branch exchanges execution mode */ #define MIPS_HFLAG_BMASK (MIPS_HFLAG_BMASK_BASE | MIPS_HFLAG_BMASK_EXT) + /* MIPS DSP resources access. */ +#define MIPS_HFLAG_DSP 0x40000 /* Enable access to MIPS DSP resources. */ +#define MIPS_HFLAG_DSPR2 0x80000 /* Enable access to MIPS DSPR2 resources. */ target_ulong btarget; /* Jump / branch target */ target_ulong bcond; /* Branch condition (if needed) */ @@ -479,18 +482,18 @@ struct CPUMIPSState { #include "cpu-qom.h" #if !defined(CONFIG_USER_ONLY) -int no_mmu_map_address (CPUMIPSState *env, target_phys_addr_t *physical, int *prot, +int no_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type); -int fixed_mmu_map_address (CPUMIPSState *env, target_phys_addr_t *physical, int *prot, +int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type); -int r4k_map_address (CPUMIPSState *env, target_phys_addr_t *physical, int *prot, +int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type); -void r4k_helper_tlbwi (void); -void r4k_helper_tlbwr (void); -void r4k_helper_tlbp (void); -void r4k_helper_tlbr (void); +void r4k_helper_tlbwi(CPUMIPSState *env); +void r4k_helper_tlbwr(CPUMIPSState *env); +void r4k_helper_tlbp(CPUMIPSState *env); +void r4k_helper_tlbr(CPUMIPSState *env); -void cpu_unassigned_access(CPUMIPSState *env, target_phys_addr_t addr, +void cpu_unassigned_access(CPUMIPSState *env, hwaddr addr, int is_write, int is_exec, int unused, int size); #endif @@ -610,8 +613,9 @@ enum { EXCP_MDMX, EXCP_C2E, EXCP_CACHE, /* 32 */ + EXCP_DSPDIS, - EXCP_LAST = EXCP_CACHE, + EXCP_LAST = EXCP_DSPDIS, }; /* Dummy exception for conditional stores. */ #define EXCP_SC 0x100 @@ -658,7 +662,7 @@ int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw, void do_interrupt (CPUMIPSState *env); #if !defined(CONFIG_USER_ONLY) void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra); -target_phys_addr_t cpu_mips_translate_address (CPUMIPSState *env, target_ulong address, +hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address, int rw); #endif @@ -706,16 +710,17 @@ static inline int mips_vpe_active(CPUMIPSState *env) return active; } -static inline int cpu_has_work(CPUMIPSState *env) +static inline bool cpu_has_work(CPUState *cpu) { - int has_work = 0; + CPUMIPSState *env = &MIPS_CPU(cpu)->env; + bool has_work = false; /* It is implementation dependent if non-enabled interrupts wake-up the CPU, however most of the implementations only check for interrupts that can be taken. */ if ((env->interrupt_request & CPU_INTERRUPT_HARD) && cpu_mips_hw_interrupts_pending(env)) { - has_work = 1; + has_work = true; } /* MIPS-MT has the ability to halt the CPU. */ @@ -723,11 +728,11 @@ static inline int cpu_has_work(CPUMIPSState *env) /* The QEMU model will issue an _WAKE request whenever the CPUs should be woken up. */ if (env->interrupt_request & CPU_INTERRUPT_WAKE) { - has_work = 1; + has_work = true; } if (!mips_vpe_active(env)) { - has_work = 0; + has_work = false; } } return has_work; @@ -742,4 +747,68 @@ static inline void cpu_pc_from_tb(CPUMIPSState *env, TranslationBlock *tb) env->hflags |= tb->flags & MIPS_HFLAG_BMASK; } +static inline void compute_hflags(CPUMIPSState *env) +{ + env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | + MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | + MIPS_HFLAG_UX); + if (!(env->CP0_Status & (1 << CP0St_EXL)) && + !(env->CP0_Status & (1 << CP0St_ERL)) && + !(env->hflags & MIPS_HFLAG_DM)) { + env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU; + } +#if defined(TARGET_MIPS64) + if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) || + (env->CP0_Status & (1 << CP0St_PX)) || + (env->CP0_Status & (1 << CP0St_UX))) { + env->hflags |= MIPS_HFLAG_64; + } + if (env->CP0_Status & (1 << CP0St_UX)) { + env->hflags |= MIPS_HFLAG_UX; + } +#endif + if ((env->CP0_Status & (1 << CP0St_CU0)) || + !(env->hflags & MIPS_HFLAG_KSU)) { + env->hflags |= MIPS_HFLAG_CP0; + } + if (env->CP0_Status & (1 << CP0St_CU1)) { + env->hflags |= MIPS_HFLAG_FPU; + } + if (env->CP0_Status & (1 << CP0St_FR)) { + env->hflags |= MIPS_HFLAG_F64; + } + if (env->insn_flags & ASE_DSPR2) { + /* Enables access MIPS DSP resources, now our cpu is DSP ASER2, + so enable to access DSPR2 resources. */ + if (env->CP0_Status & (1 << CP0St_MX)) { + env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2; + } + + } else if (env->insn_flags & ASE_DSP) { + /* Enables access MIPS DSP resources, now our cpu is DSP ASE, + so enable to access DSP resources. */ + if (env->CP0_Status & (1 << CP0St_MX)) { + env->hflags |= MIPS_HFLAG_DSP; + } + + } + if (env->insn_flags & ISA_MIPS32R2) { + if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { + env->hflags |= MIPS_HFLAG_COP1X; + } + } else if (env->insn_flags & ISA_MIPS32) { + if (env->hflags & MIPS_HFLAG_64) { + env->hflags |= MIPS_HFLAG_COP1X; + } + } else if (env->insn_flags & ISA_MIPS4) { + /* All supported MIPS IV CPUs use the XX (CU3) to enable + and disable the MIPS IV extensions to the MIPS III ISA. + Some other MIPS IV CPUs ignore the bit, so the check here + would be too restrictive for them. */ + if (env->CP0_Status & (1 << CP0St_CU3)) { + env->hflags |= MIPS_HFLAG_COP1X; + } + } +} + #endif /* !defined (__MIPS_CPU_H__) */ |