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

📄 cpu_support.s

📁 日本著名的的嵌入式实时操作系统T-Kernel的源码及用户手册。
💻 S
📖 第 1 页 / 共 3 页
字号:
/* *---------------------------------------------------------------------- *    T-Kernel * *    Copyright (C) 2004 by Ken Sakamura. All rights reserved. *    T-Kernel is distributed under the T-License. *---------------------------------------------------------------------- * *    Version:   1.01.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2004/6/28. * *---------------------------------------------------------------------- *//* *	cpu_support.S (VR5500) *	Device-Dependent CPU Operation */#define	_in_asm_source_#include <machine.h>#include <tk/errno.h>#include <tk/sysdef.h>#include <tk/asm.h>#include <sys/sysinfo.h>#include "config.h"#include "cpu_conf.h"#include "isysconf.h"#include "tkdev_conf.h"#include "offset.h"/* * IMPORT declaration of external variables *	.extern declaration indicates that the 'gp' register is properly used *	when the program is assembled. */	.extern	Csym(ctxtsk), 4	.extern	Csym(schedtsk), 4	.extern Csym(lowpow_discnt), 4	.extern	Csym(int_stack_top), 4	.extern	Csym(svc_call_limit), 4#if TA_FPU	.extern	Csym(fpu_ctxtsk), 4#endif/* ------------------------------------------------------------------------ *//* * Dispatcher *	dispatch_to_schedtsk: *		Throw away the current contexts and forcibly dispatch to *		'schedtsk.' *		Called directly by the jump order but do not return. *		Called on the undefined stack state (undefined 'ssp'). *		Called on the interrupt disable state. *	_dispatch_entry: *		Normal dispatch processing. Called by the delayed interrupt. * *	Contexts to save *	Save registers except for 'ssp' to a stack. Save 'ssp' to TCB. * *		+---------------+ *	ssp ->	| hi		| *	  +8	| lo		| *	  +16	| at		| *	  +24	| v0-v1		| *	  +40	| a0-a3		| *	  +72	| t0-t7		| *	  +136	| s0-s7		| *	  +200	| fp		| *	  +208	| ra		| *	  +216	| gp		| *		+---------------+			 - *	  +224	| t8		|			 | *	  +232	| t9		|			 | *	  +240	| EPC		|			 | Move from interrupt *	  +248	| PSR||taskmode	| High:PSR  Low:taskmode | stack *		+---------------+			 | *	  +256	| usp		| Only RNG 1-3		 | *		+---------------+			 - */	/* Temporal stack used when 'dispatch_to_schedtsk' is called	 */#define	TMP_STACK_SZ	(8*1024)#define	TMP_STACK_TOP	(tmp_stack + TMP_STACK_SZ)	.lcomm	tmp_stack, TMP_STACK_SZ	.text	.balign	4	.globl	Csym(dispatch_to_schedtsk)	.type	Csym(dispatch_to_schedtsk), %functionCsym(dispatch_to_schedtsk):	/* During interrupt disable PSR.EXL=0, IE=0, IM1=1 */	/* When 'tk_ext_tsk' and 'tk_exd_tsk' are called from invalid	   contexts, it may be called on IM1=0 state */	.set	noat	lui	$at, %hi(TMP_STACK_TOP)	addiu	$sp, $at, %lo(TMP_STACK_TOP)	// Set temporal stack	.set	at#if USE_DBGSPT	lw	$s0, Csym(ctxtsk)		// s0 = ctxtsk#endif	sw	$zero, Csym(ctxtsk)		// ctxtsk = NULL	mfc0	$t8, $CP0_PSR			// Dispatch disable/Interrupt enable	and	$t8, $t8, ~SR_IM(1)	or	$t8, $t8, SR_IE	mtc0	$t8, $CP0_PSR			// EXL=0, IE=1, IM1=0	j	l_dispatch0_dispatch_entry:	/* During interrupt disable PSR.EXL=0, IE=0, IM1=0	   (Dispatch disable state) */	.set	noat	mfc0	$t8, $CP0_PSR	xor	$t8, $t8, SR_IE			// Interrupt enable EXL=0, IE=1, IM1=0	mtc0	$t8, $CP0_PSR	/* During interrupt enable PSR.EXL=0, IE=1, IM1=0 */	subu	$sp, $sp, 28*8			// Context save 	mfhi	$t8	mflo	$t9	sd	$t8,  0*8($sp)	sd	$t9,  1*8($sp)	sd	$at,  2*8($sp)	sd	$v0,  3*8($sp)	sd	$v1,  4*8($sp)	sd	$a0,  5*8($sp)	sd	$a1,  6*8($sp)	sd	$a2,  7*8($sp)	sd	$a3,  8*8($sp)	sd	$t0,  9*8($sp)	sd	$t1, 10*8($sp)	sd	$t2, 11*8($sp)	sd	$t3, 12*8($sp)	sd	$t4, 13*8($sp)	sd	$t5, 14*8($sp)	sd	$t6, 15*8($sp)	sd	$t7, 16*8($sp)	sd	$s0, 17*8($sp)	sd	$s1, 18*8($sp)	sd	$s2, 19*8($sp)	sd	$s3, 20*8($sp)	sd	$s4, 21*8($sp)	sd	$s5, 22*8($sp)	sd	$s6, 23*8($sp)	sd	$s7, 24*8($sp)	sd	$fp, 25*8($sp)	sd	$ra, 26*8($sp)	sd	$gp, 27*8($sp)	.set	at	la	$gp, _gp	lw	$s0, Csym(ctxtsk)		// s0 = ctxtsk	sd	$sp, TCB_tskctxb+CTXB_ssp($s0)	// Save 'ssp' to TCB	sw	$zero, Csym(ctxtsk)		// ctxtsk = NULL  l_dispatch0:	/* During interrupt enable PSR.EXL=0, IE=1, IM1=0 */#if USE_DBGSPT	lw	$t0, hook_stop_jmp		// Hook processing	jr	$t0  ret_hook_stop:#endif	mfc0	$s7, $CP0_PSR		// s7 = Interrupt enable EXL=0, IE=1, IM1=0	xor	$s6, $s7, SR_IE		// s6 = Interrupt disable EXL=0, IE=0, IM1=0  l_dispatch1:	mtc0	$s6, $CP0_PSR			// Interrupt disable	NOP(HzD_MTC0 - HzS_INT)	lw	$s0, Csym(schedtsk)		// s0 = schedtsk	bnez	$s0, l_dispatch2		// Is there 'schedtsk'?	/* Because there is no task that should be executed,	   move to the power saving mode */	lw	$t0, Csym(lowpow_discnt)	// Is 'low_pow' disabled?	bnez	$t0, l_nolowpow	subu	$sp, $sp, 4*8	jal	Csym(low_pow)			// call low_pow()	addu	$sp, $sp, 4*8  l_nolowpow:	mtc0	$s7, $CP0_PSR			// Interrupt enable	NOP(HzD_MTC0 - HzS_INT)	j	l_dispatch1  l_dispatch2:					// Switch to 'schedtsk'	/* During interrupt disable PSR.EXL=0, IE=0, IM1=0 */	sw	$s0, Csym(ctxtsk)		// ctxtsk = schedtsk	ld	$sp, TCB_tskctxb+CTXB_ssp($s0)	// Restore 'ssp' from TCB	lw	$t1, TCB_isstack($s0)	sw	$t1, SSTKTOP			// Switch system stack top	/* Switch task eigenspace */	lw	$t0, TCB_tskctxb+CTXB_lsid($s0)	dmtc0	$t0, $CP0_EHI			// Entry Hi.ASID = lsid#if TA_FPU	/* Switch FPU context */	lw	$t1, Csym(fpu_ctxtsk)	beq	$t1, $s0, l_same_fpuctx	lb	$t0, 248+7($sp)			// PSR	and	$t0, $t0, ~(SR_CU1 >> 24) & 0xff	sb	$t0, 248+7($sp)			// PSR.CU1 = 0  l_same_fpuctx:#endif#if USE_DBGSPT	lw	$t0, hook_exec_jmp		// Hook processing	jr	$t0  ret_hook_exec:#endif	lw	$t8, TCB_reqdct($s0)		// DCT request	.set	noat	ld	$t0,  0*8($sp)			// Context restore 	ld	$t1,  1*8($sp)	mthi	$t0	mtlo	$t1	ld	$at,  2*8($sp)	ld	$v0,  3*8($sp)	ld	$v1,  4*8($sp)	ld	$a0,  5*8($sp)	ld	$a1,  6*8($sp)	ld	$a2,  7*8($sp)	ld	$a3,  8*8($sp)	ld	$t0,  9*8($sp)	ld	$t1, 10*8($sp)	ld	$t2, 11*8($sp)	ld	$t3, 12*8($sp)	ld	$t4, 13*8($sp)	ld	$t5, 14*8($sp)	ld	$t6, 15*8($sp)	ld	$t7, 16*8($sp)	ld	$s0, 17*8($sp)	ld	$s1, 18*8($sp)	ld	$s2, 19*8($sp)	ld	$s3, 20*8($sp)	ld	$s4, 21*8($sp)	ld	$s5, 22*8($sp)	ld	$s6, 23*8($sp)	ld	$s7, 24*8($sp)	ld	$fp, 25*8($sp)	ld	$ra, 26*8($sp)	ld	$gp, 27*8($sp)	addu	$sp, $sp, 28*8	li	$t9, 1	bne	$t8, $t9, l_nodct_dispatch	// Is there a DCT request?	ld	$t9, 3*8($sp)	and	$t9, $t9, TMF_CPL(3)		// If the protected level is 0, DCT disable	beqz	$t9, l_nodct_dispatch	mfc0	$t8, $CP0_PSR	xor	$t8, $t8, SR_IM(1)		// Dispatch enable 	mtc0	$t8, $CP0_PSR	j	dct_startup			// To DCT processing  l_nodct_dispatch:	/* The Interrupt and dispatch are enabled because PSR is	   resorted by returning from the handler.*/	MOVE_SSP_ISP dispatch	EIT_RETURN dispatch	.set	at#if USE_DBGSPT/* * Task dispatcher hook routine call *	void stop( ID tskid, INT lsid, UINT tskstat ) *	void exec( ID tskid, INT lsid ) */	.extern	Csym(hook_stopfn), 4	.extern Csym(hook_execfn), 4	.extern	Csym(hook_dsp_gp), 4	.text	.balign	4hook_stop:	beqz	$s0, l_notask			// s0 = ctxtsk	subu	$sp, $sp, 5*8	sd	$gp, 4*8($sp)	lbu	$a2, TCB_state($s0)		// tskstat	sll	$a2, $a2, 1	lw	$a1, TCB_tskctxb+CTXB_lsid($s0)	// lsid	lw	$a0, TCB_tskid($s0)		// tskid	lw	$t0, Csym(hook_stopfn)	lw	$gp, Csym(hook_dsp_gp)	jalr	$t0			// call stop(tskid, lsid, tskstat)	ld	$gp, 4*8($sp)	addu	$sp, $sp, 5*8  l_notask:	j	ret_hook_stophook_exec:	subu	$sp, $sp, 5*8	sd	$gp, 4*8($sp)						// s0 = ctxtsk	lw	$a1, TCB_tskctxb+CTXB_lsid($s0)	// lsid	lw	$a0, TCB_tskid($s0)		// tskid	lw	$t0, Csym(hook_execfn)	lw	$gp, Csym(hook_dsp_gp)	jalr	$t0				// call exec(tskid, lsid)	ld	$gp, 4*8($sp)	addu	$sp, $sp, 5*8	j	ret_hook_exec/* * Set/Free task dispatcher hook routine */	.text	.balign	4	.globl	Csym(hook_dsp)	.type	Csym(hook_dsp), %functionCsym(hook_dsp):	la	$t0, hook_exec	la	$t1, hook_stop	sw	$t0, hook_exec_jmp	sw	$t1, hook_stop_jmp	jr	$ra	.globl	Csym(unhook_dsp)	.type	Csym(unhook_dsp), %functionCsym(unhook_dsp):	la	$t0, ret_hook_exec	la	$t1, ret_hook_stop	sw	$t0, hook_exec_jmp	sw	$t1, hook_stop_jmp	jr	$ra			.sdata			.balign	4  hook_exec_jmp:	.int	ret_hook_exec  hook_stop_jmp:	.int	ret_hook_stop#endif /* USE_DBGSPT *//* ------------------------------------------------------------------------ *//* * Delayed interrupt handler *		+---------------+ *	isp ->	| t8		| *	   +8	| t9		| *	   +16	| EPC		| *	   +24	| PSR||taskmode	| High:PSR  Low:taskmode *		+---------------+ *	   +32	| usp		| Only RNG 1-3 *		+---------------+ */	.text	.balign	4	.globl	Csym(delayed_interrupt)	.type	Csym(delayed_interrupt), %functionCsym(delayed_interrupt):	.set	noat	/* Interrupt disable PSR.EXL=1, IE=1, IM1=0		(IM1,IM0 is disabled by exception entry processing) */	lui	$t8, %hi(Csym(int_stack_top))	lw	$t8, %lo(Csym(int_stack_top))($t8)	lw	$t9, ISTKPOS		// t9 = isp	subu	$t8, $t8, 5*8	sltu	$t8, $t9, $t8		// Dispatch disable if it is a nesting interrupt	bnez	$t8, l_nodispatch1	mfc0	$t8, $CP0_OCC	xor	$t8, OC_IP(1)		// Clear delayed interrupt request IP1 = 0	mtc0	$t8, $CP0_OCC	lui	$t8, %hi(Csym(ctxtsk))		// If ctxtsk == schedtsk,	lui	$t9, %hi(Csym(schedtsk))	// dispatch not required.	lw	$t8, %lo(Csym(ctxtsk))($t8)	lw	$t9, %lo(Csym(schedtsk))($t9)	beq	$t8, $t9, l_nodispatch2	mfc0	$t8, $CP0_PSR	xor	$t8, $t8, SR_IM(0)|SR_EXL|SR_IE	// EXL=0, IE=0, IM1=0, IM0=1	mtc0	$t8, $CP0_PSR	MOVE_ISP_SSP delayed_interrupt	j	_dispatch_entry		// To dispatch processing  l_nodispatch1:	lw	$t8, 3*8+4($t9)		// PSR	xor	$t8, $t8, SR_IM(1)	// By returning from a delayed interrupt,	sw	$t8, 3*8+4($t9)		// Disable IP1 so that a delayed interrupt will not occur again  l_nodispatch2:	EIT_RETURN delayed_interrupt	.set	at/* ------------------------------------------------------------------------ */#if TA_FPU/* * Coprocessor disable exception *	FPU context switch *		+---------------+ *	isp ->	| t8		| *	   +8	| t9		| *	   +16	| EPC		| *	   +24	| PSR||taskmode	| High:PSR  Low:taskmode *		+---------------+ *	   +32	| usp		| Only RNG 1-3 *		+---------------+ *	t8 = Vector table address */	.text	.balign	4	.globl	Csym(unavailable_cop)	.type	Csym(unavailable_cop), %functionCsym(unavailable_cop):	.set	noat	/* Interrupt disable PSR.EXL=1, IE=? */	mfc0	$kt0, $CP0_OCC		// Exceptions, except for CP1(FPU), are	srl	$kt0, $kt0, 28		// Invalid use of coprocessor	and	$kt0, $kt0, OC_CE >> 28	subu	$kt0, $kt0, 1	bnez	$kt0, l_goto_defaulthdr1	mfc0	$t9, $CP0_PSR		// t9 = PSR	li	$kt0, ~(SR_EXL|SR_IE)	and	$kt0, $t9, $kt0		// EXL=0, IE=0	mtc0	$kt0, $CP0_PSR	subu	$sp, $sp, 3*8		// Save register for work	sd	$t0, 0*8($sp)	sd	$t1, 1*8($sp)	sd	$gp, 2*8($sp)	la	$gp, _gp	lw	$t0, Csym(ctxtsk)	// t0 = ctxtsk	beqz	$t0, l_goto_defaulthdr2	// If ctxtsk == NULL, invalid use of FPU.	lw	$t1, TCB_tskatr($t0)	// If TA_FPU attribute is not specified,	and	$t1, $t1, TA_FPU	// invalid use of FPU.	beqz	$t1, l_goto_defaulthdr2	mfc0	$t9, $CP0_PSR	li	$t8, SR_CU1|SR_FR	or	$t9, $t9, $t8	mtc0	$t9, $CP0_PSR		// FPU enable CU1=1, FR=1	lw	$t9, Csym(fpu_ctxtsk)	// t9 = fpu_ctxtsk	beq	$t9, $t0, l_nosw_fpu	// If fpu_ctxtsk == ctxtsk,					// do not need to switch FPU context.	beqz	$t9, l_nosave_fpu	// If fpu_ctxtsk == NULL,					// do not need to save FPU context.	lw	$t1, TCB_isstack($t9)	// Save FPU context	sdc1	$f0,   0*8($t1)	sdc1	$f1,   1*8($t1)	sdc1	$f2,   2*8($t1)	sdc1	$f3,   3*8($t1)	sdc1	$f4,   4*8($t1)	sdc1	$f5,   5*8($t1)	sdc1	$f6,   6*8($t1)	sdc1	$f7,   7*8($t1)	sdc1	$f8,   8*8($t1)	sdc1	$f9,   9*8($t1)	sdc1	$f10, 10*8($t1)	sdc1	$f11, 11*8($t1)	sdc1	$f12, 12*8($t1)	sdc1	$f13, 13*8($t1)	sdc1	$f14, 14*8($t1)	sdc1	$f15, 15*8($t1)	sdc1	$f16, 16*8($t1)	sdc1	$f17, 17*8($t1)	sdc1	$f18, 18*8($t1)	sdc1	$f19, 19*8($t1)	sdc1	$f20, 20*8($t1)

⌨️ 快捷键说明

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