microblaze: HW Exception fixes.
* Correct PVR checks for masking off individual exceptions. * Correct FPU exception code. * Set EAR on unaligned and unassigned exceptions. Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
This commit is contained in:
		
							parent
							
								
									487a4d60bc
								
							
						
					
					
						commit
						97f90cbfe8
					
				| @ -209,17 +209,18 @@ uint32_t helper_pcmpbf(uint32_t a, uint32_t b) | ||||
| void helper_memalign(uint32_t addr, uint32_t dr, uint32_t wr, uint32_t mask) | ||||
| { | ||||
|     if (addr & mask) { | ||||
|             qemu_log("unaligned access addr=%x mask=%x, wr=%d\n", | ||||
|                      addr, mask, wr); | ||||
|             if (!(env->sregs[SR_MSR] & MSR_EE)) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             qemu_log_mask(CPU_LOG_INT, | ||||
|                           "unaligned access addr=%x mask=%x, wr=%d dr=r%d\n", | ||||
|                           addr, mask, wr, dr); | ||||
|             env->sregs[SR_EAR] = addr; | ||||
|             env->sregs[SR_ESR] = ESR_EC_UNALIGNED_DATA | (wr << 10) \ | ||||
|                                  | (dr & 31) << 5; | ||||
|             if (mask == 3) { | ||||
|                 env->sregs[SR_ESR] |= 1 << 11; | ||||
|             } | ||||
|             if (!(env->sregs[SR_MSR] & MSR_EE)) { | ||||
|                 return; | ||||
|             } | ||||
|             helper_raise_exception(EXCP_HW_EXCP); | ||||
|     } | ||||
| } | ||||
| @ -245,19 +246,20 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, | ||||
|        generated code */ | ||||
|     saved_env = env; | ||||
|     env = cpu_single_env; | ||||
|     qemu_log("Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n", | ||||
|     qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n", | ||||
|              addr, is_write, is_exec); | ||||
|     if (!(env->sregs[SR_MSR] & MSR_EE)) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     env->sregs[SR_EAR] = addr; | ||||
|     if (is_exec) { | ||||
|         if (!(env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) { | ||||
|         if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) { | ||||
|             env->sregs[SR_ESR] = ESR_EC_INSN_BUS; | ||||
|             helper_raise_exception(EXCP_HW_EXCP); | ||||
|         } | ||||
|     } else { | ||||
|         if (!(env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) { | ||||
|         if ((env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) { | ||||
|             env->sregs[SR_ESR] = ESR_EC_DATA_BUS; | ||||
|             helper_raise_exception(EXCP_HW_EXCP); | ||||
|         } | ||||
|  | ||||
| @ -232,7 +232,7 @@ static void dec_pattern(DisasContext *dc) | ||||
|     int l1; | ||||
| 
 | ||||
|     if ((dc->tb_flags & MSR_EE_FLAG) | ||||
|           && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|           && !((dc->env->pvr.regs[2] & PVR2_USE_PCMP_INSTR))) { | ||||
|         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); | ||||
|         t_gen_raise_exception(dc, EXCP_HW_EXCP); | ||||
| @ -553,7 +553,7 @@ static void dec_mul(DisasContext *dc) | ||||
|     unsigned int subcode; | ||||
| 
 | ||||
|     if ((dc->tb_flags & MSR_EE_FLAG) | ||||
|          && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|          && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|          && !(dc->env->pvr.regs[0] & PVR0_USE_HW_MUL_MASK)) { | ||||
|         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); | ||||
|         t_gen_raise_exception(dc, EXCP_HW_EXCP); | ||||
| @ -610,7 +610,7 @@ static void dec_div(DisasContext *dc) | ||||
|     u = dc->imm & 2;  | ||||
|     LOG_DIS("div\n"); | ||||
| 
 | ||||
|     if (!(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|     if ((dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|           && !((dc->env->pvr.regs[0] & PVR0_USE_DIV_MASK))) { | ||||
|         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); | ||||
|         t_gen_raise_exception(dc, EXCP_HW_EXCP); | ||||
| @ -630,7 +630,7 @@ static void dec_barrel(DisasContext *dc) | ||||
|     unsigned int s, t; | ||||
| 
 | ||||
|     if ((dc->tb_flags & MSR_EE_FLAG) | ||||
|           && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|           && !(dc->env->pvr.regs[0] & PVR0_USE_BARREL_MASK)) { | ||||
|         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); | ||||
|         t_gen_raise_exception(dc, EXCP_HW_EXCP); | ||||
| @ -804,7 +804,7 @@ static void dec_load(DisasContext *dc) | ||||
| 
 | ||||
|     size = 1 << (dc->opcode & 3); | ||||
|     if (size > 4 && (dc->tb_flags & MSR_EE_FLAG) | ||||
|           && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) { | ||||
|           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) { | ||||
|         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); | ||||
|         t_gen_raise_exception(dc, EXCP_HW_EXCP); | ||||
|         return; | ||||
| @ -856,7 +856,7 @@ static void dec_store(DisasContext *dc) | ||||
|     size = 1 << (dc->opcode & 3); | ||||
| 
 | ||||
|     if (size > 4 && (dc->tb_flags & MSR_EE_FLAG) | ||||
|           && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) { | ||||
|           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) { | ||||
|         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); | ||||
|         t_gen_raise_exception(dc, EXCP_HW_EXCP); | ||||
|         return; | ||||
| @ -1112,9 +1112,9 @@ static void dec_rts(DisasContext *dc) | ||||
| static void dec_fpu(DisasContext *dc) | ||||
| { | ||||
|     if ((dc->tb_flags & MSR_EE_FLAG) | ||||
|           && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|           && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|           && !((dc->env->pvr.regs[2] & PVR2_USE_FPU_MASK))) { | ||||
|         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); | ||||
|         tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_FPU); | ||||
|         t_gen_raise_exception(dc, EXCP_HW_EXCP); | ||||
|         return; | ||||
|     } | ||||
| @ -1171,8 +1171,8 @@ static inline void decode(DisasContext *dc) | ||||
|         dc->nr_nops = 0; | ||||
|     else { | ||||
|         if ((dc->tb_flags & MSR_EE_FLAG) | ||||
|               && !(dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|               && !(dc->env->pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) { | ||||
|               && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK) | ||||
|               && (dc->env->pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) { | ||||
|             tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP); | ||||
|             t_gen_raise_exception(dc, EXCP_HW_EXCP); | ||||
|             return; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Edgar E. Iglesias
						Edgar E. Iglesias