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

📄 shexcept.src

📁 windows ce 3.00 嵌入式操作系统源代码
💻 SRC
📖 第 1 页 / 共 5 页
字号:
	mov	r6, r5
	dt	r0
	bf/s	kc50			; already in non-preemtible state
	mov	r7, r6

; Entering non-preemptible state. We must switch onto the kernel stack
; before setting KNest in case an interrupt occurs during the switch.

	mov	r15, r2			; (r2) = original stack pointer
	mov	#_KStack, r15		; switch to kernel stack
	mov.b	r0, @(1,r1)		; enter non-preemtible state (KNest = 0)
	sts	PR, r0
	mov.l	r2, @(20,r15)		; save thread's stack pointer
	jsr	@r3			; invoke non-preemtible function
	mov.l	r0, @(16,r15)		; save return address

; Function complete. Return to preemtible state then check if a reschedule
; is needed.

	mov	#_KData+bResched, r1
	mov	r0, r3			; (r3) = function return value
	mov.l	@(16,r15), r2		; (r2) = return address
	mov.l	@(20,r15), r5		; (r5) = original stack pointer
	mov	#PR_B0_IM, r7		; (r7) = new status: bank0, priv, ints masked
	stc	SR, r6			; (r6) = old status
	ldc	r7, SR			; mask all interrtupts

	mov.b	@r1, r0			; (r0) = reschedule flag
	lds	r2, pr
	cmp/eq	#1, r0
	bt	kc20			; reschedule required.

	mov @(dwKCRes-bResched,r1), r0
	cmp/eq #1, r0
	bt	kc20

	mov	#1, r0
	mov.b	r0, @(1,r1)		; leave non-preemtible state
	mov	r3, r0			; (r0) = function return value
	ldc	r6, SR			; restore interrupt mask state
	rts
	mov	r5, r15			; restore stack pointer
	.nopool


; ReschedFlag set, so must run the scheduler to find which thread
; to dispatch next.
;
;	(r1) = ptr to bResched in KPage
;	(r2) = return address
;	(r3) = KCall return value
;	(r5) = original stack pointer
;	(r6) = old status register value

kc20:	ldc	r6, SR			; restore interrupt mask state
	mov.l	@(pCurThd-bResched, r1), r4	; (r4) = ptr to current THREAD
	mov	r4, r1
	add	#THREAD_CONTEXT_OFFSET, r1	; (r1) = ptr to thread's register context
	mov.l	r3, @(CtxR0, r1)	; save return value
	add	#CtxR8, r1		; (r1) = ptr to thread's R8
	mov	#PR_B0_IE, r3		; (r3) = kernel mode PSR
	mov.l	r2, @(CtxFir-CtxR8, r1)	; thread resumes at the return address
	mov.l	r3, @(CtxPsr-CtxR8, r1)	;   & in kernel mode.
	mov.l	r14, @(CtxR14-CtxR8, r1); save thread's R14
	mov.l	r5, @(CtxR15-CtxR8, r1)	; save thread's stack pointer
	bra	SaveAndResched
	mov	r4, r14			; (r14) = ptr to current THREAD

kc25:	bra	resched
	mov	#0, r14			; no current thread

; Nested KCall. Just invoke the function directly.
;
;	(r3) = function address
;	(r4) = 1st function argument
;	(r5) = 2nd function argument
;	(r6) = 3rd function argument

kc50:	jmp	@r3
	nop

	.endf

  .aif SH_CPU eq h'40

	LEAF_ENTRY _GetAndClearFloatCode
	sts.l	fpscr, r1
	mov	r1, r0
	mov #h'3f000, r2
	and r2, r0
	not r2, r2
	and r2, r1
	lds r1, fpscr
	shlr8 r0
	shlr2 r0
	shlr2 r0
	rts
	nop

	LEAF_ENTRY _GetCauseFloatCode
	sts.l	fpscr, r0
	mov #h'3f000, r2
	and r2, r0
	shlr8 r0
	shlr2 r0
	rts
	shlr2 r0

	.endf

	LEAF_ENTRY _SaveFloatContext
	stc	SR, r0
	mov #h'ffff7fff, r1
	and r0, r1
	ldc	r1, SR	
	add #THREAD_CONTEXT_OFFSET, r4
	add #CtxFpul+4, r4
	sts.l	fpul, @-r4
	sts.l	fpscr, @-r4
	add	#(4*16)+8, r4	; (r4) = ptr to end of CtxFRegs
  	add	#(4*16), r4	; (r4) = ptr to end of CtxXFregs
  	mov	#0, r1
  	lds	r1, fpscr
  	.data.w h'FBFD		; frchg instr.
	fmov.s	fr15, @-r4
	fmov.s	fr14, @-r4
	fmov.s	fr13, @-r4
	fmov.s	fr12, @-r4
	fmov.s	fr11, @-r4
	fmov.s	fr10, @-r4
	fmov.s	fr9, @-r4
	fmov.s	fr8, @-r4
	fmov.s	fr7, @-r4
	fmov.s	fr6, @-r4
	fmov.s	fr5, @-r4
	fmov.s	fr4, @-r4
	fmov.s	fr3, @-r4
	fmov.s	fr2, @-r4
	fmov.s	fr1, @-r4
	fmov.s	fr0, @-r4
	.data.w h'FBFD		; frchg instr.
	fmov.s	fr15, @-r4
	fmov.s	fr14, @-r4
	fmov.s	fr13, @-r4
	fmov.s	fr12, @-r4
	fmov.s	fr11, @-r4
	fmov.s	fr10, @-r4
	fmov.s	fr9, @-r4
	fmov.s	fr8, @-r4
	fmov.s	fr7, @-r4
	fmov.s	fr6, @-r4
	fmov.s	fr5, @-r4
	fmov.s	fr4, @-r4
	fmov.s	fr3, @-r4
	fmov.s	fr2, @-r4
	fmov.s	fr1, @-r4
	fmov.s	fr0, @-r4
	ldc	r0, SR	
	rts
	nop
	.endf

	LEAF_ENTRY _RestoreFloatContext
	stc	SR, r0
	mov #h'ffff7fff, r1
	and r0, r1
	ldc	r1, SR
	add #THREAD_CONTEXT_OFFSET, r4
	add #CtxFpscr, r4
	mov.l	@r4+, r2		; (r2) = new value for FPSCR
	mov.l	@r4+, r3		; (r3) = new value for FPUL
	mov	#0, r1
	lds	r1, fpscr
	fmov.s	@r4+, fr0
	fmov.s	@r4+, fr1
	fmov.s	@r4+, fr2
	fmov.s	@r4+, fr3
	fmov.s	@r4+, fr4
	fmov.s	@r4+, fr5
	fmov.s	@r4+, fr6
	fmov.s	@r4+, fr7
	fmov.s	@r4+, fr8
	fmov.s	@r4+, fr9
	fmov.s	@r4+, fr10
	fmov.s	@r4+, fr11
	fmov.s	@r4+, fr12
	fmov.s	@r4+, fr13
	fmov.s	@r4+, fr14
	fmov.s	@r4+, fr15
	.data.w h'FBFD		; frchg instr.
	fmov.s	@r4+, fr0
	fmov.s	@r4+, fr1
	fmov.s	@r4+, fr2
	fmov.s	@r4+, fr3
	fmov.s	@r4+, fr4
	fmov.s	@r4+, fr5
	fmov.s	@r4+, fr6
	fmov.s	@r4+, fr7
	fmov.s	@r4+, fr8
	fmov.s	@r4+, fr9
	fmov.s	@r4+, fr10
	fmov.s	@r4+, fr11
	fmov.s	@r4+, fr12
	fmov.s	@r4+, fr13
	fmov.s	@r4+, fr14
	fmov.s	@r4+, fr15
	lds	r2, fpscr
	lds	r3, fpul
	ldc	r0, SR	
	rts
	nop
	.endf

  .aelse
;
; SH3DSP DSP Context Save and restore
;

	LEAF_ENTRY _SaveSH3DSPContext

    stc     SR, r0
    mov     #h'1000, r1
    or      r0, r1
    ldc     r1, SR
    mov     #(THREAD_CONTEXT_OFFSET+CtxDSPRegs), r5
    add     r5, r4
    mov     r4, r5
    stc.l   RE, @-r5                ; Repeat End register
    stc.l   RS, @-r5                ; Repeat Start
    stc.l   MOD, @-r5               ; Modulo addressing register
    sts.l   DSR, @-r5               ; DSP Status register
    movs.l  A0, @r4+                ; Save DSP Regs A0,A1
    movs.l  A1, @r4+
    movs.l  M0, @r4+                ; M0, M1
    movs.l  M1, @r4+
    movs.l  X0, @r4+                ; X0, X1
    movs.l  X1, @r4+
    movs.l  Y0, @r4+                ; Y0, Y1
    movs.l  Y1, @r4+
    movs.w  A0G, @r4+               ; Save the guard bits.
    movs.w  A1G, @r4+

    ldc     r0, SR
	rts
	  nop

	.endf

	LEAF_ENTRY _RestoreSH3DSPContext

    stc     SR, r0
    mov     #h'1000, r1
    or      r0, r1
    ldc     r1, SR
    mov     #(THREAD_CONTEXT_OFFSET+CtxDsr), r5
    add     r5, r4

    lds.l   @r4+, DSR               ; DSP Status Register
    ldc.l   @r4+, MOD               ; Modulo addressing register
    ldc.l   @r4+, RS                ; Repeat Start
    ldc.l   @r4+, RE                ; Repeat End

    movs.l  @r4+, A0                ; Restore DSP registers A0, A1
    movs.l  @r4+, A1
    movs.l  @r4+, M0                ; M0, M1
    movs.l  @r4+, M1
    movs.l  @r4+, X0                ; X0, X1
    movs.l  @r4+, X1
    movs.l  @r4+, Y0                ; Y0, Y1
    movs.l  @r4+, Y1
    movs.w  @r4+, A0G               ; Restore the guard bits.
    movs.w  @r4+, A1G

    ldc     r0, SR
    rts
	  nop

	.endf


  .aendi

	.PAGE
; This code is copied to the kernel's data page so that it is accessible from
; the kernel & user code. The kernel checks if it is interrupting an interlocked
; api by range checking the PC to be between UserKPage+0x3c0 & UserKPage+0x400.
; The routines are organized such that they can be restarted by masking off the
; lower 3 bits of the PC. Each routine is at most 4 instructions with the store
; instruction as the last instruction in the 4 inst. block.

	.align	8
	LEAF_ENTRY _InterlockedAPIs
ILMaskByte:
	mov.b	@r4, r0			; (r0) = original byte value
	and	r5, r0			; clear some bits
	or	r6, r0			; set some bits
	mov.b	r0, @r4			; update byte value
	rts
	nop

	.align 8
ILPopList:
	mov.l	@r4, r0			; (r0) = ptr to item at head
	nop
	tst	r0, r0
	bf	popx			; list is not empty
	rts
	nop
	.align	8
	bra	ILPopList
	nop
popx:	mov.l	@r0, r1
	mov.l	r1, @r4
	rts
	nop

	.align	8
ILPushList:
	mov.l	@r4, r0			; (r0) = old head of list
	nop
	mov.l	r0, @r5			; store linkage
	mov.l	r5, @r4			; store new list head
	rts
	nop

	.align	8
ILExchange:
	mov.l	@r4, r0			; (r0) = original contents
	nop
	nop
	mov.l	r5, @r4			; store new contents
	rts
	nop

	.align	8
ILTestExchange:
	mov.l	@r4, r0			; (r0) = original contents
	cmp/eq	r0, r5
	bf	ITExEnd			; no match, skip store
	mov.l	r6, @r4			; store new contents
ITExEnd: rts
	nop

	.align	8
ILIncrement:
	mov.l	@r4, r0			; (r0) = original contents
	nop				; load delay + align end label
	add	#1, r0
	mov.l	r0, @r4			; store new contents
	rts
	nop

	.align	8
ILDecrement:
	mov.l	@r4, r0			; (r0) = original contents
	nop				; load delay + align end label
	add	#-1, r0
	mov.l	r0, @r4			; store new contents
	rts
	nop
	.align	8
	.export _InterlockedEnd
_InterlockedEnd:
	.endf

; CaptureContext is invoked in kernel context on the user thread's stack to
; build a context structure to be used for exception unwinding.
;
;	(r15) = aligned stack pointer
;	(r0-r14), etc. - CPU state at the time of exception

	LEAF_ENTRY _CaptureContext
  .aif SH_CPU eq h'40
	add	#h'80-CtxSizeof, r15	; must happen BEFORE the prolog
	add	#CtxR15-h'80, r15
  .aelse
	add	#CtxR15-CtxSizeof, r15	; must happen BEFORE the prolog
	nop
  .aendi
	.endf
	NESTED_ENTRY xxCaptureContext
	mov.l	r15, @(0,r15)		; for the unwinder (updated by EXceptionDispatch)
	mov.l	r14, @-r15
	stc	SPC, r14
	mov.l	r14, @(CtxFir-CtxR14,r15) ; for unwinding (updated by ExceptionDispatch)
	stc	SSR, r14
	mov.l	r14, @(CtxPsr-CtxR14,r15)
	mov.l	r13, @-r15
	mov.l	r12, @-r15
	mov.l	r11, @-r15
	mov.l	r10, @-r15
	mov.l	r9, @-r15
	mov.l	r8, @-r15
	mov.l	r7, @-r15
	mov.l	r6, @-r15
	mov.l	r5, @-r15
	mov.l	r4, @-r15
	mov.l	r3, @-r15
	mov.l	r2, @-r15
	mov.l	r1, @-r15
	mov.l	r0, @-r15
	stc	GBR, r2
	mov.l	r2, @-r15
	sts	MACL, r2
	mov.l	r2, @-r15
	mov	#CONTEXT_FULL, r1
	sts	MACH, r2
	mov.l	r2, @-r15
	sts	PR, @-r15
	mov	r15, r14		; (r14) = ptr to context.PR
        PROLOG_END

	mov.l	r1, @-r15		; set context flags
	mov	#_ExceptionDispatch, r0
	mov	r15, r4			; (r4) = arg1 = ptr to context structure
	jsr	@r0
	add	#-16, r15		; allocate argument save area

; Reload updated context and resume thread execution.
;
;	(r14) = ptr to context.PR

	lds	@r14+, PR
	lds	@r14+, MACH
	lds	@r14+, MACL
	ldc	@r14+, GBR
	mov.l	@r14+, r0
	mov.l	@r14+, r1
	mov.l	@r14+, r2
	mov.l	@r14+, r3
	mov.l	@r14+, r4
	mov.l	@r14+, r5
	mov.l	@r14+, r6
	mov.l	@r14+, r7
	mov.l	@r14+, r8
	mov.l	@r14+, r9
	mov.l	@r14+, r10

; Load Psr & Fir now just in case we're crossing a page boundary
; because TLB misses fail with exceptions blocked.
	mov	#PR_B0_IM, r15
	ldc	r15, SR

; handle fpu
  .aif SH_CPU eq h'40
	mov #_KData+g_CurFPUOwner, r12
	mov @r12, r12
	mov #_KData+pCurThd, r13
	mov @r13, r13
	cmp/eq r12,r13
	mov #h'0, r12
	bt cc2
	mov #h'8000, r12
    .aelse
    ;  SH3. Check for DSP owner in case of SH3DSP (else CurDSPOwner == 0)
    mov     #_KData+g_CurDSPOwner, r12
    mov     @r12, r12
    mov     #_KData+pCurThd, r13
    mov     @r13, r13
    cmp/eq  r12, r13
	mov     #h'0, r12
    bt      cc2
    mov     #h'1000, r12            ; DSP enable (bit 12)

⌨️ 快捷键说明

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