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

📄 cpu_support.s

📁 日本著名的的嵌入式实时操作系统T-Kernel的源码及用户手册。
💻 S
📖 第 1 页 / 共 3 页
字号:
	addu	$sp, $sp, 4*8	j	l_retsvc  l_illegal_svc:	li	$v0, E_RSFN	j	l_retsvc  l_oacv_err:	li	$v0, E_OACV	j	l_retsvc#if USE_DBGSPT/* * System call/Extended SVC hook routine call *	VP enter( FN fncd, TD_CALINF *calinf, ... ) *	void leave( FN fncd, INT ret, VP exinf ) * *	typedef struct td_calinf { *		DW	ssp;	System stack pointer *		DW	ra;	Return address when calling *		DW	fp;	Flame pointer when calling *	} TD_CALINF; */	.extern	Csym(hook_enterfn), 4	.extern	Csym(hook_leavefn), 4	.extern	Csym(hook_svc_gp), 4	.text	.balign	4hook_enter:	subu	$sp, $sp, 9*8	sd	$a0, 3*8($sp)		// Save argument 	sd	$a1, 4*8($sp)	sd	$a2, 5*8($sp)	sd	$a3, 6*8($sp)	sd	$s1, 7*8($sp)		// Save register for work	sd	$t8, 8*8($sp)	move	$s1, $sp		// s1 = &TD_CALINF	addu	$t0, $fp, 2*8		// Create TD_CALINF	sd	$t0, 0*8($sp)		// ssp	sd	$ra, 1*8($sp)		// ra	ld	$t0, 0*8($fp)	sd	$t0, 2*8($sp)		// fp	bgez	$s0, l_enter_p1		// s0 = Function code					//	<0: System call					//	>=0: Extended SVC	lw	$t1, 3*8($fp)		// taskmode	srl	$t3, $s0, 8	and	$t3, $t3, 0xff		// t3 = Number of arguments	and	$t1, $t1, TMF_PPL(3)	// t1 = Protected level when calling	addu	$t4, $fp, 4*8		// t4 = ssp Argument stack position (RNG0)	beqz	$t1, l_enter1	ld	$t4, 4*8($fp)		// t4 = usp Argument stack position (RNG1-3)  l_enter1:	bltu	$t3, 5, l_enter_p4	ld	$t0, 4*8($t4)	subu	$sp, $sp, 1*8	sd	$t0, ($sp)		// Fifth argument  l_enter_p4:	bltu	$t3, 4, l_enter_p3	subu	$sp, $sp, 1*8	sd	$a3, ($sp)		// Fourth argument  l_enter_p3:	bltu	$t3, 3, l_enter_p2	subu	$sp, $sp, 1*8	sd	$a2, ($sp)		// Third argument  l_enter_p2:	move	$a3, $a1		// Second argument  l_enter_p1:	move	$a2, $a0		// First argument	move	$a1, $s1		// calinf	move	$a0, $s0		// fncd	subu	$sp, $sp, 4*8	lw	$t0, Csym(hook_enterfn)	lw	$gp, Csym(hook_svc_gp)	jalr	$t0			// exinf = enter(fncd, ...)	la	$gp, _gp	move	$sp, $s1		// Return stack position	ld	$a0, 3*8($sp)		// Restore argument	ld	$a1, 4*8($sp)	ld	$a2, 5*8($sp)	ld	$a3, 6*8($sp)	ld	$s1, 7*8($sp)		// Restore register for work	ld	$t8, 8*8($sp)	sd	$v0, 8*8($sp)		// 'exinf' save	addu	$sp, $sp, 8*8		// Save and leave 'exinf'	j	ret_hook_enterhook_leave:	li	$a2, 0			// exinf = 0	subu	$t0, $fp, $sp		// Whether 'hook_enter' is executed	beq	$t0, 2*8, l_leave1	// Check by stack usage					// 'hook_enter' is called	ld	$a2, ($sp)		// exinf	addu	$sp, $sp, 1*8  l_leave1:	move	$a1, $v0		// ret	move	$a0, $s0		// fncd	move	$s0, $v0		// s0 = Return value 'ret' save	lw	$t0, Csym(hook_leavefn)	lw	$gp, Csym(hook_svc_gp)	subu	$sp, $sp, 4*8	jalr	$t0			// call leave(fncd, ret, exinf)	addu	$sp, $sp, 4*8	la	$gp, _gp	move	$v0, $s0		// v0 = Return value 'ret' restore	j	ret_hook_leave/* * Set/Free system call/extended SVC hook routine  */	.text	.balign	4	.globl	Csym(hook_svc)	.type	Csym(hook_svc), %functionCsym(hook_svc):	la	$t0, hook_enter	la	$t1, hook_leave	sw	$t0, hook_enter_jmp	sw	$t1, hook_leave_jmp	jr	$ra	.globl	Csym(unhook_svc)	.type	Csym(unhook_svc), %functionCsym(unhook_svc):	la	$t0, ret_hook_enter	la	$t1, ret_hook_leave	sw	$t0, hook_enter_jmp	sw	$t1, hook_leave_jmp	jr	$ra			.sdata			.balign	4  hook_enter_jmp:	.int	ret_hook_enter  hook_leave_jmp:	.int	ret_hook_leave#endif /* USE_DBGSPT *//* ------------------------------------------------------------------------ */#if USE_DBGSPT/* * Debugger support function service call entry table */	.text	.balign	4	.type	_tdsvctbl, %object_tdsvctbl:	.int	Csym(no_support)#include <sys/svc/tdsvctbl.h>/* * Debugger support function service call entry *		+---------------+ *   isp/ssp ->	| t8		| (Overwrite and save 'gp')  *	   +8	| t9		| (Overwrite and save 'ra') *	   +16	| EPC		| *	   +24	| PSR||taskmode	| High:PSR  Low:taskmode *		+---------------+ *	   +32	| usp		| Only RNG 1-3 *		+---------------+ */	.text	.balign	4	.globl	Csym(call_dbgspt)	.type	Csym(call_dbgspt), %functionCsym(call_dbgspt):	/* During interrupt disable PSR.EXL=1, IE=? */	mfc0	$t0, $CP0_PSR	and	$t1, $t0, ~(SR_EXL|SR_IE)	mtc0	$t1, $CP0_PSR		// EXL=0, IE=0 Interrupt disable	MOVE_ISP_SSP call_dbgspt	and	$t1, $t0, ~SR_EXL	mtc0	$t1, $CP0_PSR		// EXL=0, IE=? caller's state	sd	$gp, 0*8($sp)		// gp save (overwrite 't8')	sd	$ra, 1*8($sp)		// ra save (overwrite 't9')	move	$t8, $gp		// t8 = Caller gp	la	$gp, _gp	lw	$t1, 3*8($sp)			// 'taskmode' when calling	lw	$t0, Csym(svc_call_limit)	// Call protected level limit	and	$t1, $t1, TMF_CPL(3)	// t1 = Protected level when calling	bgt	$t1, $t0, b_oacv_err	sra	$t2, $v0, 16		// t2 = Function number	bgt	$t2, N_TDFN - 0x8000, b_illegal_svc	sll	$t2, $t2, 2	lw	$t0, _tdsvctbl - (-0x8000 << 2)($t2)	subu	$sp, $sp, 6*8		// Always set number of arguments to 6 	sd	$t8, 5*8($sp)		// Sixth argument = Caller gp	jalr	$t0			// T-Kernel/DS service call	addu	$sp, $sp, 6*8  b_retsvc:	ld	$gp, 0*8($sp)		// Restore register for work	ld	$ra, 1*8($sp)	MOVE_SSP_ISP call_dbgspt	CALL_RETURN call_dbgspt  b_illegal_svc:	li	$v0, E_RSFN	j	b_retsvc  b_oacv_err:	li	$v0, E_OACV	j	b_retsvc#endif /* USE_DBGSPT *//* ------------------------------------------------------------------------ *//* * High level programming language routine for timer handler */	.text	.balign	4	.globl	Csym(timer_handler_startup)	.type	Csym(timer_handler_startup), %functionCsym(timer_handler_startup):	/* During interrupt disable PSR.EXL=1 IE=1 */	.set	noat	mfc0	$kt0, $CP0_PSR	li	$kt1, SR_DS|SR_IMMSK	and	$kt0, $kt0, $kt1	li	$kt1, SR_XX|SR_FR|SR_KX|SR_SX|SR_UX	or	$kt0, $kt0, $kt1	mtc0	$kt0, $CP0_PSR		// PSR setting EXL=0, IE=0 interrupt disable	subu	$sp, $sp, 24*8		// Register save	sd	$at,  4*8($sp)	sd	$v0,  5*8($sp)	sd	$v1,  6*8($sp)	sd	$a0,  7*8($sp)	sd	$a1,  8*8($sp)	sd	$a2,  9*8($sp)	sd	$a3, 10*8($sp)	sd	$t0, 11*8($sp)	sd	$t1, 12*8($sp)	sd	$t2, 13*8($sp)	sd	$t3, 14*8($sp)	sd	$t4, 15*8($sp)	sd	$t5, 16*8($sp)	sd	$t6, 17*8($sp)	sd	$t7, 18*8($sp)	sd	$gp, 19*8($sp)	sd	$fp, 20*8($sp)	sd	$ra, 21*8($sp)	mfhi	$t0	mflo	$t1	sd	$t0, 22*8($sp)	sd	$t1, 23*8($sp)	.set	at	la	$gp, _gp	jal	Csym(timer_handler)	// call timer_handler()	/* Return by interrupt enable */	.set	noat	ld	$at,  4*8($sp)		// Register restore	ld	$v0,  5*8($sp)	ld	$v1,  6*8($sp)	ld	$a0,  7*8($sp)	ld	$a1,  8*8($sp)	ld	$a2,  9*8($sp)	ld	$a3, 10*8($sp)	ld	$t0, 11*8($sp)	ld	$t1, 12*8($sp)	ld	$t2, 13*8($sp)	ld	$t3, 14*8($sp)	ld	$t4, 15*8($sp)	ld	$t5, 16*8($sp)	ld	$t6, 17*8($sp)	ld	$t7, 18*8($sp)	ld	$gp, 19*8($sp)	ld	$fp, 20*8($sp)	ld	$ra, 21*8($sp)	ld	$t8, 22*8($sp)	ld	$t9, 23*8($sp)	mthi	$t8	mtlo	$t9	addu	$sp, $sp, 24*8	EIT_RETURN timer_handler_startup	.set	at/* ------------------------------------------------------------------------ *//* * Delayed context trap (DCT) *	Task exception handler startup *	When called, the system stack is configured as shown below. *		+---------------+ *	ssp ->	| t8		| *	   +8	| t9		| *	   +16	| EPC		| *	   +24	| PSR||taskmode	| High:PSR  Low:taskmode *	   +32	| usp		| *		+---------------+ */	.text	.balign	4dct_startup:	/* During Interrupt disable */	.set	noat	subu	$sp, $sp, 23*8			// Register save	mfhi	$t8	mflo	$t9	sd	$t8,  4*8($sp)	sd	$t9,  5*8($sp)	sd	$at,  6*8($sp)	sd	$v0,  7*8($sp)	sd	$v1,  8*8($sp)	sd	$a0,  9*8($sp)	sd	$a1, 10*8($sp)	sd	$a2, 11*8($sp)	sd	$a3, 12*8($sp)	sd	$t0, 13*8($sp)	sd	$t1, 14*8($sp)	sd	$t2, 15*8($sp)	sd	$t3, 16*8($sp)	sd	$t4, 17*8($sp)	sd	$t5, 18*8($sp)	sd	$t6, 19*8($sp)	sd	$t7, 20*8($sp)	sd	$ra, 21*8($sp)	sd	$gp, 22*8($sp)	.set	at	la	$gp, _gp	addu	$a0, $sp, 23*8	jal	Csym(setup_texhdr)	// call setup_texhdr(ssp)	/* Return in interrupt enable state */	.set	noat	ld	$t8,  4*8($sp)			// Register restore	ld	$t9,  5*8($sp)	mthi	$t8	mtlo	$t9	ld	$at,  6*8($sp)	ld	$v0,  7*8($sp)	ld	$v1,  8*8($sp)	ld	$a0,  9*8($sp)	ld	$a1, 10*8($sp)	ld	$a2, 11*8($sp)	ld	$a3, 12*8($sp)	ld	$t0, 13*8($sp)	ld	$t1, 14*8($sp)	ld	$t2, 15*8($sp)	ld	$t3, 16*8($sp)	ld	$t4, 17*8($sp)	ld	$t5, 18*8($sp)	ld	$t6, 19*8($sp)	ld	$t7, 20*8($sp)	ld	$ra, 21*8($sp)	ld	$gp, 22*8($sp)	addu	$sp, $sp, 23*8	MOVE_SSP_ISP dct_startup	EIT_RETURN dct_startup	.set	at/* * Return from task exception handler *		+---------------+ *	usp ->	| PC		| Return address from task exception handler *		+---------------+ * *		+---------------+ *  ssp/isp ->	| t8		| *	   +8	| t9		| *	   +16	| EPC		| *	   +24	| PSR||taskmode	| High:PSR  Low:taskmode *	   +32	| usp		| *		+---------------+ * *	If the call is invalid, call the default handler. */	.text	.balign	4	.globl	Csym(rettex_entry)	.type	Csym(rettex_entry), %functionCsym(rettex_entry):	/* Interrupt disable PSR.EXL=1, IE=1 */	.set	noat	mfc0	$t9, $CP0_PSR	and	$kt0, $t9, SR_IE	// A call from interrupt disable state is invalid	beqz	$kt0, l_illegal_rettex	lw	$kt1, ISTKPOS	lw	$kt0, 3*8($kt1)		// taskmode	and	$kt0, $kt0, TMF_CPL(3)	// A call from protected level 0 is invalid.	beqz	$kt0, l_illegal_rettex	xor	$kt0, $t9, SR_EXL	mtc0	$kt0, $CP0_PSR		// EXL=0, IE=1 Interrupt enable 	/* To access the user stack,	it must not be the task independent part */	MOVE_ISP_SSP rettex_entry	ld	$t9, 4*8($sp)		// usp	ld	$t8, ($t9)		// PC	sd	$t8, 2*8($sp)		// EPC = PC	addu	$t9, $t9, 1*8		// usp++	sd	$t9, 4*8($sp)		// Delete PC from stack	MOVE_SSP_ISP rettex_entry	CALL_RETURN rettex_entry  l_illegal_rettex:	lw	$kt0, EITVEC(EIT_DEFAULT)	jr	$kt0	.set	at/* ------------------------------------------------------------------------ *//* * User defined handler call *	INT CallUserHandler( INT p1, INT p2, INT p3, FP hdr, VP gp ) */	.text	.balign	4	.globl	Csym(CallUserHandler)	.type	Csym(CallUserHandler), %functionCsym(CallUserHandler):	subu	$sp, $sp, 6*8	sd	$gp, 4*8($sp)	sd	$ra, 5*8($sp)	lw	$gp, (6+4)*8($sp)	jalr	$a3	ld	$gp, 4*8($sp)	ld	$ra, 5*8($sp)	addu	$sp, $sp, 6*8	jr	$ra/* ------------------------------------------------------------------------ *//* * Device driver call  *	INT _CallDeviceDriver( INT p1, INT p2, INT p3, INT p4, FP drv, VP gp ) */	.text	.balign	4	.globl	Csym(_CallDeviceDriver)	.type	Csym(_CallDeviceDriver), %functionCsym(_CallDeviceDriver):	subu	$sp, $sp, 6*8	sd	$gp, 4*8($sp)	sd	$ra, 5*8($sp)	lw	$t9, (6+4)*8($sp)	lw	$gp, (6+5)*8($sp)	jalr	$t9	ld	$gp, 4*8($sp)	ld	$ra, 5*8($sp)	addu	$sp, $sp, 6*8	jr	$ra

⌨️ 快捷键说明

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