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

📄 except.s

📁 可用于嵌入式编程学习
💻 S
📖 第 1 页 / 共 4 页
字号:
	sw	t4, CxIntT4(sp)
	sw	t5, CxIntT5(sp)
	sw	t6, CxIntT6(sp)
	sw	t7, CxIntT7(sp)
	sw	t8, CxIntT8(sp)
	sw	t0, CxIntHi(sp)	// save HI mul/div register
	sw	t1, CxIntLo(sp)	// save LO mul/div register
	sw	t9, CxIntT9(sp)
	sw	ra, CxFir(sp)		// fixed up by ExceptionDispatch
	sw	zero, CxIntZero(sp)
        PROLOGUE_END
	li	t0, CONTEXT_FULL
	sw	t0, CxContextFlags(sp)
	jal	ExceptionDispatch
	move	a0, sp			// (a0) = context record argument

// Reload updated context and resume thread execution.

	lw	s0, CxIntS0(sp)	// Restore thread's permanent registers
	lw	s1, CxIntS1(sp)
	lw	s2, CxIntS2(sp)
	lw	s3, CxIntS3(sp)
	lw	s4, CxIntS4(sp)
	lw	s5, CxIntS5(sp)
	lw	s6, CxIntS6(sp)
	lw	s7, CxIntS7(sp)
	lw	s8, CxIntS8(sp)
	lw	t0, CxIntHi(sp)	// (t0) = HI mul/div register
	lw	t1, CxIntLo(sp)	// (t1) = LO mul/div register
	mthi	t0
	mtlo	t1
	lw	v1, CxIntV1(sp)
	lw	t0, CxIntT0(sp)
	lw	t1, CxIntT1(sp)
	lw	t2, CxIntT2(sp)
	lw	t3, CxIntT3(sp)
	lw	t4, CxIntT4(sp)
	lw	t5, CxIntT5(sp)
	lw	t6, CxIntT6(sp)
	lw	t7, CxIntT7(sp)
	lw	t8, CxIntT8(sp)
	lw	t9, CxIntT9(sp)
	lw	AT, CxIntAt(sp)

	mtc0	zero, psr		// all interrupts off!
	lw	a3, CxIntA3(sp)		// restore regs while		
	lw	a2, CxIntA2(sp)		//  waiting for interruts to
	lw	a1, CxIntA1(sp)		//  be disabled.
	lw	a0, BasePSR		// (a0) = global default status value
	lw	v0, CxPsr(sp)		// (v0) = thread's default status
	lw	ra, CxIntRa(sp)
	or	v0, a0			// (v0) = thread + global status
#if R4000
#ifdef MIPS_HAS_FPU
	lw a0, g_CurFPUOwner
	lw gp, CurThdPtr
	bne a0,gp, ccnofp
	lui a0, 0x2000
	or v0, a0
ccnofp:
#endif
	sw		v0, SaveK0
#else
	mtc0	v0, psr			// restore status
#endif
	lw	a0, CxIntA0(sp)
	lw	k0, CxFir(sp)		// (k0) = exception return address
	lw	gp, CxIntGp(sp)
	lw	v0, CxIntV0(sp)	// restore return value
	lw	sp, CxIntSp(sp)	// restore stack pointer
#if R4000
	mtc0    k0, epc			// set continuation address
	lw		k0, SaveK0
	mtc0	k0, psr
	nop
	nop
	eret				// restore user status
	nop
	nop
	eret
#elif R3000
	j	k0
	rfe
#else
  #error Unknown processor type
#endif
	.set at
	.set reorder

	.end xxCaptureContext

//
// Define call frame for calling exception handlers.
//

        .struct 0
CfArg:  .space  4 * 4                   // argument register save area
        .space  3 * 4                   // fill for alignment
CfRa:   .space  4                       // saved return address
CfCstk:	.space	((CstkSizeof + 4) & ~7)	// CALLSTACK object for SYSCALL_RETURN
										// Must be 8 byte aligned
CfFrameLength:                          // length of stack frame
CfA0:   .space  4                       // caller argument save area
CfA1:   .space  4                       //
CfA2:   .space  4                       //
CfA3:   .space  4                       //
CfExr:  .space  4                       // address of exception routine
CfPsr:	.space	4			// mode to execute handler in

        SBTTL("Execute Handler for Exception")
//++
//
// EXCEPTION_DISPOSITION
// RtlpExecuteHandlerForException (
//    IN PEXCEPTION_RECORD ExceptionRecord,
//    IN ULONG EstablisherFrame,
//    IN OUT PCONTEXT ContextRecord,
//    IN OUT PDISPATCHER_CONTEXT DispatcherContext,
//    IN PEXCEPTION_ROUTINE ExceptionRoutine
//    )
//
// Routine Description:
//
//    This function allocates a call frame, stores the establisher frame
//    pointer in the frame, establishes an exception handler, and then calls
//    the specified exception handler as an exception handler. If a nested
//    exception occurs, then the exception handler of this function is called
//    and the establisher frame pointer is returned to the exception dispatcher
//    via the dispatcher context parameter. If control is returned to this
//    routine, then the frame is deallocated and the disposition status is
//    returned to the exception dispatcher.
//
// Arguments:
//
//    ExceptionRecord (a0) - Supplies a pointer to an exception record.
//
//    EstablisherFrame (a1) - Supplies the frame pointer of the establisher
//       of the exception handler that is to be called.
//
//    ContextRecord (a2) - Supplies a pointer to a context record.
//
//    DispatcherContext (a3) - Supplies a pointer to the dispatcher context
//       record.
//
//    ExceptionRoutine (4 * 4(sp)) - supplies a pointer to the exception handler
//       that is to be called.
//
//    ExceptionMode (5 * 4(sp)) - PSR value for running ExceptionRoutine
//
// Return Value:
//
//    The disposition value returned by the specified exception handler is
//    returned as the function value.
//
//--

        EXCEPTION_HANDLER(RtlpExceptionHandler)

        NESTED_ENTRY(RtlpExecuteHandlerForException, CfFrameLength, zero)

        subu    sp,sp,CfFrameLength     // allocate stack frame
        sw      ra,CfRa(sp)             // save return address
        PROLOGUE_END

        lw	t1, CfPsr(sp)		// (t1) = target status
        lw      t0,CfExr(sp)            // get address of exception routine
        and	t2, t1, 1 << PSR_PMODE	// (t2) = previous execution mode
        sw      a3,CfA3(sp)             // save address of dispatcher context
	bne	t2, zero, 20f		// must switch to user mode
        jal     t0                      // call exception exception handler
10:     lw      ra,CfRa(sp)             // restore return address
        addu    sp,sp,CfFrameLength     // deallocate stack frame
        j       ra                      // return

        .set    noreorder
20:	mtc0	zero, psr		// disable interrupts
	lw	t4, CurThdPtr		// (t4) = ptr to current THREAD struct
	la	t2, 10b			// (t2) = address to return to
	lw	t4, ThPcstkTop(t4)

	// Link a CALLSTACK object to the thread for the SYSCALL_RETURN
	addu	t3, sp, CfCstk		// t3 = pointer to our CALLSTACK object
	sw		t4, CstkNext(t3)	// t3->pcstkNext = pCurThread->pcstkTop
	lw		t4, CurThdPtr		// t4 = pCurThread
	sw		t3, ThPcstkTop(t4)	// pCurThread->pcstkTop = t3
	move	t4, t3				// t4 = pCurThread->pcstkTop

	lw	t3, BasePSR
	sw	t2, CstkRa(t4)
	li	t2, 0xFFFF89AB
	sw	t2, CstkAkyLast(t4)
	li	t2, KERNEL_MODE
	sw	t2, CstkPrcLast(t4)	// return to kernel mode
	or	t3, t1
	mtc0	t3, psr
	li	ra, SYSCALL_RETURN
#if R4000
	mtc0	t0, epc
	sw	zero, CstkAkyLast(t4)
	nop
	eret				// switch to user mode & jump to handler
	nop		//
	nop		// errata
	eret		//
#elif R3000
	sw	zero, CstkAkyLast(t4)
	j	t0
	rfe
#else
  #error Unknown processor type
#endif
	.set reorder

        .end    RtlpExecuteHandlerForException

        SBTTL("Local Exception Handler")
//++
//
// EXCEPTION_DISPOSITION
// RtlpExceptionHandler (
//    IN PEXCEPTION_RECORD ExceptionRecord,
//    IN ULONG EstablisherFrame,
//    IN OUT PCONTEXT ContextRecord,
//    IN OUT PDISPATCHER_CONTEXT DispatcherContext
//    )
//
// Routine Description:
//
//    This function is called when a nested exception occurs. Its function
//    is to retrieve the establisher frame pointer from its establisher's
//    call frame, store this information in the dispatcher context record,
//    and return a disposition value of nested exception.
//
// Arguments:
//
//    ExceptionRecord (a0) - Supplies a pointer to an exception record.
//
//    EstablisherFrame (a1) - Supplies the frame pointer of the establisher
//       of this exception handler.
//
//    ContextRecord (a2) - Supplies a pointer to a context record.
//
//    DispatcherContext (a3) - Supplies a pointer to the dispatcher context
//       record.
//
// Return Value:
//
//    A disposition value ExceptionNestedException is returned if an unwind
//    is not in progress. Otherwise a value of ExceptionContinueSearch is
//    returned.
//
//--

        LEAF_ENTRY(RtlpExceptionHandler)
	.set noreorder
        lw      t0,ErExceptionFlags(a0) // get exception flags
        nop
        and     t0,t0,EXCEPTION_UNWIND  // check if unwind in progress
        .set reorder
        bne     zero,t0,10f             // if neq, unwind in progress

//
// Unwind is not in progress - return nested exception disposition.
//

        lw      t0,CfA3 - CfA0(a1)      // get dispatcher context address
        li      v0,ExceptionNestedException // set disposition value
        .set noreorder
        lw      t1,DcEstablisherFrame(t0) // copy the establisher frame pointer
        nop
        sw      t1,DcEstablisherFrame(a3) // to current dispatcher context
        .set reorder
        j       ra                      // return

//
// Unwind is in progress - return continue search disposition.
//

10:     li      v0,ExceptionContinueSearch // set disposition value
        j       ra                      // return

        .end    RtlpExceptionHandler)

        SBTTL("Execute Handler for Unwind")
//++
//
// EXCEPTION_DISPOSITION
// RtlpExecuteHandlerForUnwind (
//    IN PEXCEPTION_RECORD ExceptionRecord,
//    IN PVOID EstablisherFrame,
//    IN OUT PCONTEXT ContextRecord,
//    IN OUT PVOID DispatcherContext,
//    IN PEXCEPTION_ROUTINE ExceptionRoutine
//    )
//
// Routine Description:
//
//    This function allocates a call frame, stores the establisher frame
//    pointer and the context record address in the frame, establishes an
//    exception handler, and then calls the specified exception handler as
//    an unwind handler. If a collided unwind occurs, then the exception
//    handler of of this function is called and the establisher frame pointer
//    and context record address are returned to the unwind dispatcher via
//    the dispatcher context parameter. If control is returned to this routine,
//    then the frame is deallocated and the disposition status is returned to
//    the unwind dispatcher.
//
// Arguments:
//
//    ExceptionRecord (a0) - Supplies a pointer to an exception record.
//
//    EstablisherFrame (a1) - Supplies the frame pointer of the establisher
//       of the exception handler that is to be called.
//
//    ContextRecord (a2) - Supplies a pointer to a context record.
//
//    DispatcherContext (a3) - Supplies a pointer to the dispatcher context
//       record.
//
//    ExceptionRoutine (4 * 4(sp)) - supplies a pointer to the exception handler
//       that is to be called.
//
// Return Value:
//
//    The disposition value returned by the specified exception handler is
//    returned as the function value.
//
//--

        EXCEPTION_HANDLER(RtlpUnwindHandler)

        NESTED_ENTRY(RtlpExecuteHandlerForUnwind, CfFrameLength, zero)

        subu    sp,sp,CfFrameLength     // allocate stack frame
        sw      ra,CfRa(sp)             // save return address
        PROLOGUE_END

        lw	t1, CxPsr(a2)		// (t1) = target status
        lw      t0,CfExr(sp)            // get address of exception routine
        and	t2, t1, 1 << PSR_PMODE	// (t2) = previous execution mode
        sw      a3,CfA3(sp)             // save address of dispatcher context
	bne	t2, zero, 20f		// must switch to user mode
        jal     t0                      // call exception exception handler
10:     lw      ra,CfRa(sp)             // restore return address
        addu    sp,sp,CfFrameLength     // deallocate stack frame
        j       ra                      // return

        .set    noreorder
20:	mtc0	zero, psr		// disable interrupts
	lw	t4, CurThdPtr		// (t4) = ptr to current THREAD struct
	la	t2, 10b			// (t2) = address to return to
	lw	t4, ThPcstkTop(t4)

	// Link a CALLSTACK object to the thread for the SYSCALL_RETURN
	addu	t3, sp, CfCstk		// t3 = pointer to our CALLSTACK object
	sw		t4, CstkNext(t3)	// t3->pcstkNext = pCurThread->pcstkTop
	lw		t4, CurThdPtr		// t4 = pCurThread
	sw		t3, ThPcstkTop(t4)	// pCurThread->pcstkTop = t3
	move	t4, t3				// t4 = pCurThread->pcstkTop

	lw	t3, BasePSR
	sw	t2, CstkRa(t4)
	sw	zero, CstkAkyLast(t4)
	or	t3, t1
	mtc0	t3, psr
	li	ra, SYSCALL_RETURN
#if R4000
	mtc0	t0, epc
	li	t2, 0x03
	sw	t2, CstkPrcLast(t4)
	nop
	eret				// switch to user mode & jump to handler
	nop		//
	nop		// errata
	eret		//
#elif R3000
	li	t2, 0x14
	sw	t2, CstkPrcLast(t4)	// return to kernel mode
	j	t0
	rfe
#else
  #error Unknown processor type
#endif
	.set reorder

        .end    RtlpExecuteHandlerForUnwind

        SBTTL("Local Unwind Handler")
//++
//
// EXCEPTION_DISPOSITION
// RtlpUnwindHandler (
//    IN PEXCEPTION_RECORD ExceptionRecord,
//    IN PVOID EstablisherFrame,
//    IN OUT PCONTEXT ContextRecord,
//    IN OUT PVOID DispatcherContext
//    )
//
// Routine Description:
//
//    This function is called when a collided unwind occurs. Its function
//    is to retrieve the establisher dispatcher context, copy it to the
//    current dispatcher context, and return a disposition value of nested
//    unwind.
//
// Arguments:
//
//    ExceptionRecord (a0) - Supplies a pointer to an exception record.
//
//    EstablisherFrame (a1) - Supplies the frame pointer of the establisher
//       of this exception handler.
//
//    ContextRecord (a2) - Supplies a pointer to a context record.
//
//    DispatcherContext (a3) - Supplies a pointer to the dispatcher context
//       record.
//
// Return Value:
//
//    A disposition value ExceptionCollidedUnwind is returned if an unwind is
//    in progress. Otherwise, a value of ExceptionContinueSearch is returned.
//
//--

        LEAF_ENTRY(RtlpUnwindHandler)
	.set noreorder
        lw      t0,ErExceptionFlags(a0) // get exception flags
        nop
        and     t0,t0,EXCEPTION_UNWIND  // check if unwind in progress
        .set reorder
        beq     zero,t0,10f             // if eq, unwind not in progress

//
// Unwind is in progress - return collided unwind disposition.
//

        lw      t0,CfA3 - CfA0(a1)      // get dispatcher context address
        li      v0,ExceptionCollidedUnwind // set disposition value
        lw      t1,DcControlPc(t0)      // Copy the establisher frames'
        lw      t2,DcFunctionEntry(t0)  // dispatcher context to the current
        lw      t3,DcEstablisherFrame(t0) // dispatcher context
        lw      t4,DcContextRecord(t0)  //
        sw      t1,DcControlPc(a3)      //
        sw      t2,DcFunctionEntry(a3)  //
        sw      t3,DcEstablisherFrame(a3) //
        sw      t4,DcContextRecord(a3)  //
        j       ra                      // return

//
// Unwind is not in progress - return continue search disposition.
//

10:     li      v0,ExceptionContinueSearch // set disposition value
        j       ra                      // return
        .end    RtlpUnwindHandler

⌨️ 快捷键说明

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