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

📄 shexcept.src

📁 windows ce 3.00 嵌入式操作系统源代码
💻 SRC
📖 第 1 页 / 共 5 页
字号:
	.aendi
cc2:

; Touch page 1, page 2, and then page 1 (assuming we span a page boundary)
; This will force both into the TLB

	mov.l	@r14+, r11
	mov	@(CtxFir-CtxR12,r14), r13
	mov	@(CtxPsr-CtxR12,r14), r15
; handle fpu
  .aif SH_CPU eq h'40
	or r12,r15
  .aelse
    not r12, r12
    and r12, r15                    ; clear DSP enable bit if not owner
  .aendi
	mov.l	@r14+, r12

; Reload final state with exceptions disabled.
;
;	(r13) = thread's Fir
;	(r14) = ptr to Context.R13
;	(r15) = thread's SR

; We should not take any exceptions below this point, but we don't bother blocking
; them to save instructions

	ldc	r13, SPC
	mov.l	@r14+, r13

	ldc	r15, SSR

	mov.l	@(4,r14), r15

	rte
	mov.l	@r14, r14
	.endf

;
; Define call frame for calling exception handlers.
;

CfArg:			.equ	0						; argument save area for exception handlers
CfCStk:			.equ	16						; CALLSTACK struct for mode switching
CfRa:			.equ	(CfCStk + CstkSizeof)	; saved return address

CfFrameLength	.equ	(CfCStk + CstkSizeof + 4)

CfA0:			.equ	(CfFrameLength + 0)		; caller argument save area
CfA1:			.equ	(CfFrameLength + 4)
CfA2:			.equ	(CfFrameLength + 8)
CfA3:			.equ	(CfFrameLength + 12)
CfExr:			.equ	(CfFrameLength + 16)	; address of exception routine
CfPsr:			.equ	(CfFrameLength + 20)	; mode to run exception routine in

;++
; 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 (r4) - Supplies a pointer to an exception record.
;
;    EstablisherFrame (r5) - Supplies the frame pointer of the establisher
;       of the exception handler that is to be called.
;
;    ContextRecord (r6) - Supplies a pointer to a context record.
;
;    DispatcherContext (r7) - Supplies a pointer to the dispatcher context
;       record.
;
;    ExceptionRoutine (4 * 4(r15)) - 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 RtlpExceptionHandler

	NESTED_ENTRY _RtlpExecuteHandlerForException
	sts	PR, @-r15		; save return address
	add	#CfArg-CfRa, r15	; allocate argument area

	PROLOG_END

	mov.l	@(CfPsr,r15), r1	; (r1) = target status
	mov.l	@(CfExr,r15), r0	; (r0) = address of exception routine
	addv	r1, r1			; 'T' set iff kernel mode
	bf/s	ehfe20			; must switch to user mode
	mov.l	r7, @(CfA3,r15)		; save address of dispatcher context
	jsr	@r0
	nop
ehfe10: mov.l	@(CfRa,r15), r3		; (r3) = return address
	lds	r3, PR			; restore return address
	rts				; return
	add	#CfFrameLength, r15	;  & deallocate stack frame

ehfe20:
	stc		r4_user, r2				; (r2) = pCurThread
	mov		r15, r3					; (r3) = sp
	mov.l	@(ThPcstkTop, r2), r2	; (r2) = pCurThread->pcstkTop
	add		#CfCStk, r3				; (r3) = pcstk (the one on the stack)
	mov.l	r2, @(CstkNext, r3)		; pcstk->pcstkNext = pCurThread->pcstkTop
	stc		r4_user, r2				; (r2) = pCurThread
	mov.l	r3, @(ThPcstkTop, r2)	; pCurThread->pcstkTop = pcstk
	mov		r3, r2

	mov	#ehfe10, r3				; (r3) = "return address" for mode switch
	mov.l r3, @(CstkRa,r2)		; set address to return to
	mov	#h'40, r3
	mov.l r3, @(CstkPrcLast,r2)	; set execution mode to return to
	mov	#0, r3
	mov.l r3, @(CstkAkyLast,r2)	; mark as exception call stack entry

	mov	#PR_B1_BK, r2
	shlr	r1			; (r1) = target status
	ldc	r2, SR			; (SR) = kmode, blocked, bank1

; In register bank 1, so:
;	(r4) = current thread
;	(r0_user) = exception handler address
;	(r1_user) = exception handler mode

	mov	#SYSCALL_RETURN, r2
	lds	r2, PR			; setup "PSL return"

	stc	r0_user, r0		; (r0) = handler address
	stc	r1_user, r1		; (r1) = handler mode/status

	; handle fpu
  .aif SH_CPU eq h'40
	mov #_KData+g_CurFPUOwner, r3
	mov @r3, r3
	cmp/eq r3,r4
	bt ehfe21
	mov #h'8000, r3
	or r3, r1
    .aelse
    ;  SH3. Check for DSP owner in case of SH3DSP (else CurDSPOwner == 0)
    mov     #_KData+g_CurDSPOwner, r3
    mov     @r3, r3
    cmp/eq  r3, r4
    bf      ehfe21
    mov     #h'1000, r3             ; set DSP enable (bit 12)
    or      r3, r1
   .aendi
ehfe21:	

	ldc	r0, SPC
	ldc	r1, SSR
	rte				; invoke handler
	nop				;  & switch to user mode
        .endf

;++
; 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 (r4) - Supplies a pointer to an exception record.
;
;    EstablisherFrame (r5) - Supplies the frame pointer of the establisher
;       of this exception handler.
;
;    ContextRecord (r6) - Supplies a pointer to a context record.
;
;    DispatcherContext (r7) - 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
	mov.l	@(ErExceptionFlags,r4), r0	; (r0) = exception flags
	tst	#EXCEPTION_UNWIND, r0		; check if unwind in progress
	bf	reh10				; if non-zero, unwind in progress

; Unwind is not in progress - return nested exception disposition.
	mov.l	@(CfA3-CfA0,r5), r1		; (r1) = dispatcher context address
	mov	#ExceptionNestedException, r0	; set disposition value
	mov.l	@(DcEstablisherFrame,r1), r2	; copy the establisher frame pointer
	rts
	mov.l	r2, @(DcEstablisherFrame,r7)	; to current dispatcher context

; Unwind is in progress - return continue search disposition.

reh10:	rts					; return
	mov	#ExceptionContinueSearch, r0	; set disposition value
	.endf


;++
; 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 (r4) - Supplies a pointer to an exception record.
;
;    EstablisherFrame (r5) - Supplies the frame pointer of the establisher
;       of the exception handler that is to be called.
;
;    ContextRecord (r6) - Supplies a pointer to a context record.
;
;    DispatcherContext (r7) - Supplies a pointer to the dispatcher context
;       record.
;
;    ExceptionRoutine (4 * 4(r15)) - 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
	sts	PR, @-r15		; save return address
	add	#CfArg-CfRa, r15	; allocate argument area
	PROLOG_END

	mov	#CtxPsr, r0
	mov.l	@(r0,r6), r1		; (r1) = target status
	mov.l	@(CfExr,r15), r0	; (r0) = address of exception routine

	addv	r1, r1			; 'T' set iff kernel mode
	bf/s	ehfu20			; must switch to user mode
	mov.l	r7, @(CfA3,r15)		; save address of dispatcher context
	jsr	@r0
	nop
ehfu10:
	mov.l	@(CfRa,r15), r3		; (r3) = return address
	lds		r3, PR			; restore return address
	rts				; return
	add		#CfFrameLength, r15	;  & deallocate stack frame

ehfu20:
	; link a CALLSTACK struct to the thread's list
	stc		r4_user, r2				; (r2) = pCurThread

	mov		r15, r3					; (r3) = sp
	mov.l	@(ThPcstkTop, r2), r2	; (r2) = pCurThread->pcstkTop
	add		#CfCStk, r3				; (r3) = pcstk (the one on the stack)
	mov.l	r2, @(CstkNext, r3)		; pcstk->pcstkNext = pCurThread->pcstkTop

	stc		r4_user, r2				; (r2) = pCurThread
	mov.l	r3, @(ThPcstkTop, r2)	; pCurThread->pcstkTop = pcstk

; Switch banks	
	mov		#PR_B1_BK, r2
	shlr	r1			; (r1) = target status
	ldc	r2, SR			; (SR) = kmode, blocked, bank1

; In register bank 1, so:
;	(r4) = current thread
;	(r0_user) = exception handler address
;	(r1_user) = exception handler mode

	; Set up the CALLSTACK for SYSCALL_RETURN
	mov	#SYSCALL_RETURN, r2
	mov	#ehfu10, r3		; (r3) = "return address" for mode switch
	lds	r2, PR			; setup "PSL return"

	mov.l	@(ThPcstkTop, r4), r2
	mov		#h'40, r1
	mov.l	r3, @(CstkRa,r2)	; set address to return to
	mov.l	r1, @(CstkPrcLast,r2)	; set execution mode to return to

	; Set up for an RTE to the handler
	stc	r0_user, r0		; (r0) = handler address
	stc	r1_user, r1		; (r1) = handler mode/status

	; handle fpu
  .aif SH_CPU eq h'40
	mov #_KData+g_CurFPUOwner, r3
	mov @r3, r3
	cmp/eq r3,r4
	bt ehfu21
	mov #h'8000, r3
	or r3, r1
    .aelse
    ;  SH3. Check for DSP owner in case of SH3DSP (else CurDSPOwner == 0)
    mov     #_KData+g_CurDSPOwner, r3
    mov     @r3, r3
    cmp/eq  r3, r4
    bf      ehfu21
    mov     #h'1000, r3             ; set DSP enable (bit 12)
    or      r3, r1
   .aendi
ehfu21:	

	ldc	r0, SPC
	ldc	r1, SSR
	mov	#0, r3
	mov.l	r3, @(CstkAkyLast,r2)	; mark as exception call stack entry
	rte				; invoke handler
	nop				;  & switch to user mode
        .endf

;++
; 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 (r4) - Supplies a pointer to an exception record.
;
;    EstablisherFrame (r5) - Supplies the frame pointer of the establisher
;       of this exception handler.
;
;    ContextRecord (r6) - Supplies a pointer to a context record.
;
;    DispatcherContext (r7) - 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
	mov.l	@(ErExceptionFlags,r4), r0	; (r0) = exception flags
	tst	#EXCEPTION_UNWIND, r0		; check if unwind in progress
	bt	ruh10				; if zero, unwind not in progress

; Unwind is not in progress - return nested exception disposition.
	mov.l	@(CfA3-CfA0,r5), r1		; (r1) = dispatcher context address
	mov	#ExceptionCollidedUnwind, r0	; set disposition value
	mov.l	@(DcControlPc,r1), r2		; Copy the establisher frames'
	mov.l	@(DcFunctionEntry,r1), r3	; dispatcher context to the current
	mov.l	r2, @(DcControlPc,r7)		;
	mov.l	r3, @(DcFunctionEntry,r7)	;
	mov.l	@(DcEstablisherFrame,r1), r2	; dispatcher context
	mov.l	@(DcContextRecord,r1), r3	;
	mov.l	r2, @(DcEstablisherFrame,r7)	;
	rts
	mov.l	r3, @(DcContextRecord,r7)	;

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

ruh10:	rts					; return
	mov	#ExceptionContinueSearch, r0	; set disposition value
        .endf

	.PAGE
; NULL section array
	.export	_NullSection
_NullSection: .datab.l	BLOCK_MASK+1, 0


	LEAF_ENTRY _RtlCaptureContext
; RtlCaptureContext is invoked in kernel context on the user thread's stack to
; build a limited context structure to be used for exception unwinding.
;
;	(r4) = ptr to CONTEXT


	mov.l	r10, @(CtxR10,r4)
	mov 	#CtxPsr, r10
	add	r4,r10
	sts.l	PR, @-r10  ;;Store RA as Fir to remove this frame
	mov.l	r15, @-r10
	mov.l	r14, @-r10
	mov.l	r13, @-r10
	mov.l	r12, @-r10
	mov.l	r11, @-r10
	add.l	#-4, r10  ;;Gets rid of r10's space
	mov.l	r9, @-r10
	mov.l	r8, @-r10
	mov.l	r7, @-r10
	mov.l	r6, @-r10
	mov.l	r5, @-r10
	mov.l	r4, @-r10
	mov.l	r3, @-r10
	mov.l	r2, @-r10
	mov.l	r1, @-r10
	mov.l	r0, @-r10
	stc.l	GBR, @-r10
	sts.l	MACL, @-r10
	sts.l	MACH, @-r10
	sts.l	PR, @-r10
 	mov	#CONTEXT_FULL, r10
	mov.l	r10,@r4
	rts
	mov.l	@(CtxR10,r4), r10
	.endf

  .aif SH_CPU ne h'40
; FlushCache - flush the cache & write back dirty lines
;
;	This function will invalidate the entire cache by writing 0's to the
; address information for each cache line in the memory mapped cache space.
; This will invaliate the entry and write it back if it is dirty.
;
;	Entry	none
;	Return	none
;	Uses	r0-r3

	LEAF_ENTRY _FlushCache
	mov		#h'F0000000, r1	; (r1) = ptr to memory mapped cache
   	mov     #_SH3CacheLines, r2
   	mov.l   @r2, r2        	; (r2) = # of cache entries
	mov	#0, r0				; (r0) = 0 for clearing cache tags
   	shlr2   r2	
   

⌨️ 快捷键说明

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