microblaze: Add infrastructure for supporting hw exceptions.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
This commit is contained in:
		
							parent
							
								
									a75cf0c52d
								
							
						
					
					
						commit
						cedb936bfc
					
				@ -38,6 +38,7 @@ struct CPUMBState;
 | 
				
			|||||||
#define EXCP_IRQ        3
 | 
					#define EXCP_IRQ        3
 | 
				
			||||||
#define EXCP_BREAK      4
 | 
					#define EXCP_BREAK      4
 | 
				
			||||||
#define EXCP_HW_BREAK   5
 | 
					#define EXCP_HW_BREAK   5
 | 
				
			||||||
 | 
					#define EXCP_HW_EXCP    6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Register aliases. R0 - R15 */
 | 
					/* Register aliases. R0 - R15 */
 | 
				
			||||||
#define R_SP     1
 | 
					#define R_SP     1
 | 
				
			||||||
@ -77,7 +78,18 @@ struct CPUMBState;
 | 
				
			|||||||
#define          ESR_DIZ       (1<<11) /* Zone Protection */
 | 
					#define          ESR_DIZ       (1<<11) /* Zone Protection */
 | 
				
			||||||
#define          ESR_S         (1<<10) /* Store instruction */
 | 
					#define          ESR_S         (1<<10) /* Store instruction */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define          ESR_EC_FSL             0
 | 
				
			||||||
 | 
					#define          ESR_EC_UNALIGNED_DATA  1
 | 
				
			||||||
 | 
					#define          ESR_EC_ILLEGAL_OP      2
 | 
				
			||||||
 | 
					#define          ESR_EC_INSN_BUS        3
 | 
				
			||||||
 | 
					#define          ESR_EC_DATA_BUS        4
 | 
				
			||||||
 | 
					#define          ESR_EC_DIVZERO         5
 | 
				
			||||||
 | 
					#define          ESR_EC_FPU             6
 | 
				
			||||||
 | 
					#define          ESR_EC_PRIVINSN        7
 | 
				
			||||||
 | 
					#define          ESR_EC_DATA_STORAGE    8
 | 
				
			||||||
 | 
					#define          ESR_EC_INSN_STORAGE    9
 | 
				
			||||||
 | 
					#define          ESR_EC_DATA_TLB        10
 | 
				
			||||||
 | 
					#define          ESR_EC_INSN_TLB        11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Version reg.  */
 | 
					/* Version reg.  */
 | 
				
			||||||
/* Basic PVR mask */
 | 
					/* Basic PVR mask */
 | 
				
			||||||
@ -198,13 +210,15 @@ typedef struct CPUMBState {
 | 
				
			|||||||
    uint32_t sregs[24];
 | 
					    uint32_t sregs[24];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Internal flags.  */
 | 
					    /* Internal flags.  */
 | 
				
			||||||
#define IMM_FLAG	4	
 | 
					#define IMM_FLAG	4
 | 
				
			||||||
 | 
					#define MSR_EE_FLAG     (1 << 8)
 | 
				
			||||||
#define DRTI_FLAG	(1 << 16)
 | 
					#define DRTI_FLAG	(1 << 16)
 | 
				
			||||||
#define DRTE_FLAG	(1 << 17)
 | 
					#define DRTE_FLAG	(1 << 17)
 | 
				
			||||||
#define DRTB_FLAG	(1 << 18)
 | 
					#define DRTB_FLAG	(1 << 18)
 | 
				
			||||||
#define D_FLAG		(1 << 19)  /* Bit in ESR.  */
 | 
					#define D_FLAG		(1 << 19)  /* Bit in ESR.  */
 | 
				
			||||||
/* TB dependant CPUState.  */
 | 
					/* TB dependant CPUState.  */
 | 
				
			||||||
#define IFLAGS_TB_MASK	(D_FLAG | IMM_FLAG | DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)
 | 
					#define IFLAGS_TB_MASK  (D_FLAG | IMM_FLAG | DRTI_FLAG \
 | 
				
			||||||
 | 
					                         | DRTE_FLAG | DRTB_FLAG | MSR_EE_FLAG)
 | 
				
			||||||
    uint32_t iflags;
 | 
					    uint32_t iflags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct {
 | 
					    struct {
 | 
				
			||||||
@ -306,6 +320,7 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    *pc = env->sregs[SR_PC];
 | 
					    *pc = env->sregs[SR_PC];
 | 
				
			||||||
    *cs_base = 0;
 | 
					    *cs_base = 0;
 | 
				
			||||||
 | 
					    env->iflags |= env->sregs[SR_MSR] & MSR_EE;
 | 
				
			||||||
    *flags = env->iflags & IFLAGS_TB_MASK;
 | 
					    *flags = env->iflags & IFLAGS_TB_MASK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -126,6 +126,37 @@ void do_interrupt(CPUState *env)
 | 
				
			|||||||
    assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)));
 | 
					    assert(!(env->iflags & (DRTI_FLAG | DRTE_FLAG | DRTB_FLAG)));
 | 
				
			||||||
/*    assert(env->sregs[SR_MSR] & (MSR_EE)); Only for HW exceptions.  */
 | 
					/*    assert(env->sregs[SR_MSR] & (MSR_EE)); Only for HW exceptions.  */
 | 
				
			||||||
    switch (env->exception_index) {
 | 
					    switch (env->exception_index) {
 | 
				
			||||||
 | 
					        case EXCP_HW_EXCP:
 | 
				
			||||||
 | 
					            if (!(env->pvr.regs[0] & PVR0_USE_EXC_MASK)) {
 | 
				
			||||||
 | 
					                qemu_log("Exception raised on system without exceptions!\n");
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            env->regs[17] = env->sregs[SR_PC] + 4;
 | 
				
			||||||
 | 
					            env->sregs[SR_ESR] &= ~(1 << 12);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Exception breaks branch + dslot sequence?  */
 | 
				
			||||||
 | 
					            if (env->iflags & D_FLAG) {
 | 
				
			||||||
 | 
					                env->sregs[SR_ESR] |= 1 << 12 ;
 | 
				
			||||||
 | 
					                env->sregs[SR_BTR] = env->btarget;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Disable the MMU.  */
 | 
				
			||||||
 | 
					            t = (env->sregs[SR_MSR] & (MSR_VM | MSR_UM)) << 1;
 | 
				
			||||||
 | 
					            env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
 | 
				
			||||||
 | 
					            env->sregs[SR_MSR] |= t;
 | 
				
			||||||
 | 
					            /* Exception in progress.  */
 | 
				
			||||||
 | 
					            env->sregs[SR_MSR] |= MSR_EIP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            qemu_log_mask(CPU_LOG_INT,
 | 
				
			||||||
 | 
					                          "hw exception at pc=%x ear=%x esr=%x iflags=%x\n",
 | 
				
			||||||
 | 
					                          env->sregs[SR_PC], env->sregs[SR_EAR],
 | 
				
			||||||
 | 
					                          env->sregs[SR_ESR], env->iflags);
 | 
				
			||||||
 | 
					            log_cpu_state_mask(CPU_LOG_INT, env, 0);
 | 
				
			||||||
 | 
					            env->iflags &= ~(IMM_FLAG | D_FLAG);
 | 
				
			||||||
 | 
					            env->sregs[SR_PC] = 0x20;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case EXCP_MMU:
 | 
					        case EXCP_MMU:
 | 
				
			||||||
            env->regs[17] = env->sregs[SR_PC];
 | 
					            env->regs[17] = env->sregs[SR_PC];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user