⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu_asm.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
📖 第 1 页 / 共 2 页
字号:
/* determine if an interrupt generated this exception */	mfc0 k0,C0_CAUSE	and k1,k0,CAUSE_EXCMASK	bnez k1,_ISR_Handler_prom_exit /* not an external interrupt, pass exception to Monitor */	mfc0 k1,C0_SR	and k0,k1	and k0,CAUSE_IPMASK	beq k0,zero,_ISR_Handler_quick_exit /* external interrupt not enabled, ignore */	nop  /*   *  save some or all context on stack   *  may need to save some special interrupt information for exit   *   *  #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )   *    if ( _ISR_Nest_level == 0 )   *      switch to software interrupt stack   *  #endif   */#if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )	lint t0,_ISR_Nest_level	beq t0, zero,  _ISR_Handler_1	nop	/* switch stacks */	_ISR_Handler_1:#else	lint t0,_ISR_Nest_level#endif  /*   *  _ISR_Nest_level++;   */	addi t0,t0,1	sint t0,_ISR_Nest_level  /*   *  _Thread_Dispatch_disable_level++;   */	lint t1,_Thread_Dispatch_disable_level	addi t1,t1,1	sint t1,_Thread_Dispatch_disable_level#if 0	nop	j _ISR_Handler_4	nop  /*   *  while ( interrupts_pending(cause_reg) ) {   *     vector = BITFIELD_TO_INDEX(cause_reg);   *     (*_ISR_Vector_table[ vector ])( vector );   *  }   */_ISR_Handler_2:/* software interrupt priorities can be applied here */	li t1,-1/* convert bit field into interrupt index */_ISR_Handler_3:	andi t2,t0,1	addi t1,1	beql t2,zero,_ISR_Handler_3	dsrl t0,1	li t1,7	dsll t1,3			/* convert index to byte offset (*8) */	la t3,_ISR_Vector_table	intadd t1,t3	lint t1,(t1)	jalr t1	nop	j _ISR_Handler_5	nop_ISR_Handler_4:	mfc0 t0,C0_CAUSE	andi t0,CAUSE_IPMASK	bne t0,zero,_ISR_Handler_2	dsrl t0,t0,8_ISR_Handler_5:#else	nop	li t1,7	dsll t1,t1,SZ_INT_POW2	la t3,_ISR_Vector_table	intadd t1,t3	lint t1,(t1)	jalr t1	nop#endif  /*   *  --_ISR_Nest_level;   */        lint t2,_ISR_Nest_level	addi t2,t2,-1        sint t2,_ISR_Nest_level  /*   *  --_Thread_Dispatch_disable_level;   */	lint t1,_Thread_Dispatch_disable_level	addi t1,t1,-1	sint t1,_Thread_Dispatch_disable_level  /*   *  if ( _Thread_Dispatch_disable_level || _ISR_Nest_level )   *    goto the label "exit interrupt (simple case)"   */	or t0,t2,t1	bne t0,zero,_ISR_Handler_exit	nop  /*   *  #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )   *    restore stack   *  #endif   *     *  if ( !_Context_Switch_necessary && !_ISR_Signals_to_thread_executing )   *    goto the label "exit interrupt (simple case)"   */	lint t0,_Context_Switch_necessary	lint t1,_ISR_Signals_to_thread_executing	or t0,t0,t1	beq t0,zero,_ISR_Handler_exit	nop  /*   *  call _Thread_Dispatch() or prepare to return to _ISR_Dispatch   */	jal _Thread_Dispatch	nop  /*   *  prepare to get out of interrupt   *  return from interrupt  (maybe to _ISR_Dispatch)   *   *  LABEL "exit interrupt (simple case):   *  prepare to get out of interrupt   *  return from interrupt   */_ISR_Handler_exit:	ld ra,32(sp)	stackadd sp,sp,40/* restore interrupt context from stack */	lreg    k0, R_MDLO*R_SZ(sp)	mtlo    k0	lreg    k0, R_MDHI*R_SZ(sp)	lreg    a2, R_A2*R_SZ(sp)	mthi    k0	lreg    a3, R_A3*R_SZ(sp)	lreg    t0, R_T0*R_SZ(sp)	lreg    t1, R_T1*R_SZ(sp)	lreg    t2, R_T2*R_SZ(sp)	lreg    t3, R_T3*R_SZ(sp)	lreg    t4, R_T4*R_SZ(sp)	lreg    t5, R_T5*R_SZ(sp)	lreg    t6, R_T6*R_SZ(sp)	lreg    t7, R_T7*R_SZ(sp)	lreg    t8, R_T8*R_SZ(sp)	lreg    t9, R_T9*R_SZ(sp)	lreg    gp, R_GP*R_SZ(sp)	lreg    fp, R_FP*R_SZ(sp)	lreg    ra, R_RA*R_SZ(sp)	lreg    a0, R_A0*R_SZ(sp)	lreg    a1, R_A1*R_SZ(sp)	lreg    v1, R_V1*R_SZ(sp)	lreg    v0, R_V0*R_SZ(sp)	.set noat	lreg    AT, R_AT*R_SZ(sp)	.set at	stackadd sp,sp,EXCP_STACK_SIZE /* store ra on the stack */#if USE_IDTKIT/* we handled exception, so return non-zero value */	li v0,1#endif_ISR_Handler_quick_exit:#ifdef USE_IDTKIT	j ra#else	eret#endif	nop_ISR_Handler_prom_exit:#ifdef CPU_R3000	la      k0, (R_VEC+((48)*8))#endif#ifdef CPU_R4000	la      k0, (R_VEC+((112)*8)) /* R4000 Sim's location is different */#endif	j       k0	nop       .set    reorderENDFRAME(_ISR_Handler)FRAME(mips_enable_interrupts,sp,0,ra)	mfc0 t0,C0_SR		/* get status reg */	nop	or t0,t0,a0		 	mtc0 t0,C0_SR		/* save updated status reg */	j ra	nopENDFRAME(mips_enable_interrupts)FRAME(mips_disable_interrupts,sp,0,ra)	mfc0 v0,C0_SR		/* get status reg */	li t1,SR_IMASK		/* t1 = load interrupt mask word */	not t0,t1		/* t0 = ~t1 */	and t0,v0		/* clear imask bits */	mtc0 t0,C0_SR		/* save status reg */	and v0,t1		/* mask return value (only return imask bits) */	jr ra	nopENDFRAME(mips_disable_interrupts)FRAME(mips_enable_global_interrupts,sp,0,ra)	mfc0 t0,C0_SR		/* get status reg */	nop	ori t0,SR_IE	mtc0 t0,C0_SR		/* save updated status reg */	j ra	nopENDFRAME(mips_enable_global_interrupts)FRAME(mips_disable_global_interrupts,sp,0,ra)	li t1,SR_IE	mfc0 t0,C0_SR		/* get status reg */	not t1	and t0,t1	mtc0 t0,C0_SR		/* save updated status reg */	j ra	nopENDFRAME(mips_disable_global_interrupts)/* return the value of the status register in v0.  Used for debugging */FRAME(mips_get_sr,sp,0,ra)	mfc0 v0,C0_SR	j ra	nopENDFRAME(mips_get_sr)FRAME(mips_break,sp,0,ra)#if 1	break 0x0	j mips_break#else	j ra#endif	nopENDFRAME(mips_break)/*PAGE * *  _CPU_Internal_threads_Idle_thread_body * *  NOTES: * *  1. This is the same as the regular CPU independent algorithm. * *  2. If you implement this using a "halt", "idle", or "shutdown" *     instruction, then don't forget to put it in an infinite loop. * *  3. Be warned. Some processors with onboard DMA have been known *     to stop the DMA if the CPU were put in IDLE mode.  This might *     also be a problem with other on-chip peripherals.  So use this *     hook with caution. */FRAME(_CPU_Thread_Idle_body,sp,0,ra)	wait			/* enter low power mode */	j _CPU_Thread_Idle_body	nopENDFRAME(_CPU_Thread_Idle_body)#define VEC_CODE_LENGTH 10*4/******************************************************************************	init_exc_vecs() - moves the exception code into the addresses**			  reserved for exception vectors****	UTLB Miss exception vector at address 0x80000000****	General exception vector at address 0x80000080****	RESET exception vector is at address 0xbfc00000*****************************************************************************/#define INITEXCFRM ((2*4)+4)		/* ra + 2 arguments */FRAME(init_exc_vecs,sp,0,ra)/* This code yanked from SIM */#if defined(CPU_R3000)	.set	noreorder	la	t1,exc_utlb_code	la	t2,exc_norm_code	li	t3,UT_VEC	li	t4,E_VEC	li	t5,VEC_CODE_LENGTH1:	lw	t6,0(t1)	lw	t7,0(t2)	sw	t6,0(t3)	sw	t7,0(t4)	addiu	t1,4	addiu	t3,4	addiu	t4,4	subu	t5,4	bne	t5,zero,1b	addiu	t2,4	move	t5,ra		# assumes clear_cache doesnt use t5	li	a0,UT_VEC	jal	clear_cache	li	a1,VEC_CODE_LENGTH	nop	li	a0,E_VEC	jal	clear_cache	li	a1,VEC_CODE_LENGTH	move	ra,t5		# restore ra	j	ra	nop	.set	reorder#endif#if defined(CPU_R4000)	.set reorder	move	t5,ra		# assumes clear_cache doesnt use t5	/* TLB exception vector */	la	t1,exc_tlb_code	li	t2,T_VEC |K1BASE	li	t3,VEC_CODE_LENGTH1:	lw	t6,0(t1)	addiu	t1,4	subu	t3,4	sw	t6,0(t2)	addiu	t2,4	bne	t3,zero,1b	li	a0,T_VEC	li	a1,VEC_CODE_LENGTH	jal	clear_cache	la	t1,exc_xtlb_code	li	t2,X_VEC |K1BASE	li	t3,VEC_CODE_LENGTH1:	lw	t6,0(t1)	addiu	t1,4	subu	t3,4	sw	t6,0(t2)	addiu	t2,4	bne	t3,zero,1b	/* extended TLB exception vector */	li	a0,X_VEC	li	a1,VEC_CODE_LENGTH	jal	clear_cache	/* cache error exception vector */	la	t1,exc_cache_code	li	t2,C_VEC |K1BASE	li	t3,VEC_CODE_LENGTH1:	lw	t6,0(t1)	addiu	t1,4	subu	t3,4	sw	t6,0(t2)	addiu	t2,4	bne	t3,zero,1b	li	a0,C_VEC	li	a1,VEC_CODE_LENGTH	jal	clear_cache	/* normal exception vector */	la	t1,exc_norm_code	li	t2,E_VEC |K1BASE	li	t3,VEC_CODE_LENGTH1:	lw	t6,0(t1)	addiu	t1,4	subu	t3,4	sw	t6,0(t2)	addiu	t2,4	bne	t3,zero,1b	li	a0,E_VEC	li	a1,VEC_CODE_LENGTH	jal	clear_cache	move	ra,t5		# restore ra	j	ra#endifENDFRAME(init_exc_vecs)#if defined(CPU_R4000)FRAME(exc_tlb_code,sp,0,ra)#ifdef CPU_R3000        la      k0, (R_VEC+((48)*8))#endif#ifdef CPU_R4000        la      k0, (R_VEC+((112)*8)) /* R4000 Sim's location is different */#endif        j       k0	nopENDFRAME(exc_tlb_code)FRAME(exc_xtlb_code,sp,0,ra)#ifdef CPU_R3000        la      k0, (R_VEC+((48)*8))#endif#ifdef CPU_R4000        la      k0, (R_VEC+((112)*8)) /* R4000 Sim's location is different */#endif        j       k0	nopENDFRAME(exc_xtlb_code)FRAME(exc_cache_code,sp,0,ra)#ifdef CPU_R3000        la      k0, (R_VEC+((48)*8))#endif#ifdef CPU_R4000        la      k0, (R_VEC+((112)*8)) /* R4000 Sim's location is different */#endif        j       k0	nopENDFRAME(exc_cache_code)FRAME(exc_norm_code,sp,0,ra)	la	k0, _ISR_Handler /* generic external int hndlr */	j	k0	nop	subu	sp, EXCP_STACK_SIZE		/* set up local stack frame */ENDFRAME(exc_norm_code)#endif/****************************************************************************** enable_int(mask) - enables interrupts - mask is positioned so it only**                      needs to be or'ed into the status reg. This**                      also does some other things !!!! caution should**                      be used if invoking this while in the middle**                      of a debugging session where the client may have**                      nested interrupts.******************************************************************************/FRAME(enable_int,sp,0,ra)        .set    noreorder        mfc0    t0,C0_SR        or      a0,1        or      t0,a0        mtc0    t0,C0_SR        j       ra        nop        .set    reorderENDFRAME(enable_int)/*******************************************************************************      disable_int(mask) - disable the interrupt - mask is the complement**                          of the bits to be cleared - i.e. to clear ext int**                          5 the mask would be - 0xffff7fff******************************************************************************/FRAME(disable_int,sp,0,ra)        .set    noreorder        mfc0    t0,C0_SR        nop        and     t0,a0        mtc0    t0,C0_SR        j       ra        nopENDFRAME(disable_int)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -