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

📄 workqalib.s

📁 This the architeture source of the arm of VxWorks 5.5. This Zip file contain ARM archetitectire spec
💻 S
字号:
/* workQALib.s - internal VxWorks kernel work queue assembler library *//* Copyright 1996-1998 Wind River Systems, Inc. *//*modification history--------------------01h,17oct01,t_m  convert to FUNC_LABEL:01g,11oct01,jb  Enabling removal of pre-pended underscores for new compilers                 (Diab/Gnu elf)01f,25feb99,nps  remove obsolete scrPad references.01e,10aug98,pr   commenting out WV code. To be removed after porting WV20 01d,27feb98,cdp  rewritten and instrumented.01c,27oct97,kkk  took out "***EOF***" line from end of file.01b,19may97,jpd  Amalgamated into VxWorks.01a,08jul96,apl  Written.*//*DESCRIPTIONThis module contains internals to the VxWorks kernel.These routines have been coded in assembler because they are optimized forperformance.The work queue is single reader, multiple writer, so interrupts must belocked when writing into the ring but, because the reader can neverinterrupt the writer, interrupts need only be locked while actuallyadvancing the write queue index.Note that workQAdd0/1/2 all bump workQWriteIx even if the workQ isoverflowing.  This differs from what the 68K code does but is thesame as the portable code.*/#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h"#include "private/workQLibP.h"#include "arch/arm/arm.h"	.data	.globl	FUNC(copyright_wind_river)	.long	FUNC(copyright_wind_river)#if (defined(PORTABLE))#define workQALib_PORTABLE#endif#ifndef PORTABLE/* globals */	.globl	FUNC(workQAdd0)	/* Add function to workQ */	.globl	FUNC(workQAdd1)	/* Add function and 1 arg to workQ */	.globl	FUNC(workQAdd2)	/* Add function and 2 args to workQ */	.globl	FUNC(workQDoWork)	/* Do all queued work in a workQ *//* externals */	.extern	FUNC(workQPanic)	.extern	FUNC(errno)	.extern	FUNC(pJobPool)	.extern	FUNC(workQReadIx)	.extern	FUNC(workQWriteIx)	.extern	FUNC(workQIsEmpty)	.text	.balign	4/******************************************************************************//* * PC-relative-addressable pointers - LDR Rn,=sym was (is?) broken * note "_" after "$" to stop preprocessor performing substitution */L$_errno:	.long	FUNC(errno)L$_pJobPool:	.long	FUNC(pJobPool)L$_workQReadIx:	.long	FUNC(workQReadIx)L$_workQWriteIx:	.long	FUNC(workQWriteIx)L$_workQIsEmpty:	.long	FUNC(workQIsEmpty)/********************************************************************************* workQAdd0 - Add a function with no arguments to the work queue.** RETURNS: N/A** NOMANUAL* void workQAdd0*	(*	FUNCPTR	func	/@ function to invoke @/*	)*/FUNC_LABEL(workQAdd0)	LDR	r12, L$_workQWriteIx	/* r12-> workQWriteIx */	MRS	r3, cpsr		/* LOCK INTERRUPTS */	ORR	r2, r3, #I_BIT	MSR	cpsr, r2	/* get write index and advance it (4 words per entry) */	LDRB	r1, [r12]		/* r1 = write index */	ADD	r2, r1, #4		/* r2 = advanced write index */	STRB	r2, [r12]		/* update write index */	/* check for overflow */	AND	r2, r2, #0xFF		/* mask to byte for comparison */	LDR	r12, L$_workQReadIx	/* r12-> workQReadIx */	LDRB	r12, [r12]		/* r12 = read index */	TEQS	r12, r2	BLEQ	FUNC(workQPanic)		/* overwrites LR but doesn't return */	/* no overflow - put job in pool */	MSR	cpsr, r3		/* UNLOCK INTERRUPTS */	LDR	r12, L$_workQIsEmpty	/* r12-> workQIsEmpty */	MOV	r3, #FALSE		/* workQIsEmpty := FALSE */	STR	r3, [r12]	LDR	r12, L$_pJobPool	/* r12-> pJobPool */	STR	r0, [r12, r1, LSL #2]	/* put fnptr in pool */	MOV	pc, lr/********************************************************************************* workQAdd1 - Add a function with one argument to the work queue.** RETURNS: N/A** NOMANUAL* void workQAdd1*	(*	FUNCPTR	func,	/@ function to invoke @/*	int	arg1	/@ parameter one to function @/*	)*/FUNC_LABEL(workQAdd1)	LDR	r12, L$_workQWriteIx	/* r12-> workQWriteIx */	MRS	r3, cpsr		/* LOCK INTERRUPTS */	ORR	r2, r3, #I_BIT	MSR	cpsr, r2	/* get write index and advance it (4 words per entry) */	LDRB	r2, [r12]		/* r2 = write index */	ADD	r2, r2, #4		/* r2 = advanced write index */	STRB	r2, [r12]		/* update write index */	/* check for overflow */	AND	r2, r2, #0xFF		/* mask to byte for comparison */	LDR	r12, L$_workQReadIx	/* r12-> workQReadIx */	LDRB	r12, [r12]		/* r12 = read index */	TEQS	r12, r2	BLEQ	FUNC(workQPanic)		/* overwrites LR but doesn't return */	/* no overflow - put job in pool */	MSR	cpsr, r3		/* UNLOCK INTERRUPTS */	LDR	r12, L$_workQIsEmpty	/* r12-> workQIsEmpty */	MOV	r3, #FALSE		/* workQIsEmpty := FALSE */	STR	r3, [r12]	LDR	r12, L$_pJobPool	/* r12-> pJobPool */	SUB	r2, r2, #4		/* step back index */	AND	r2, r2, #0xFF		/* mask to byte */	ADD	r12, r12, r2, LSL #2	STMIA	r12, {r0,r1}		/* put fnptr/arg in pool */	MOV	pc, lr/********************************************************************************* workQAdd2 - Add a function with two arguments to the work queue.** RETURNS: N/A** NOMANUAL* void workQAdd2*	(*	FUNCPTR	func,	/@ function to invoke @/*	int	arg1,	/@ parameter one to function @/*	int	arg2	/@ parameter two to function @/*	)*/FUNC_LABEL(workQAdd2)	STMFD	sp!, {lr}		/* save link */	LDR	r12, L$_workQWriteIx	/* r12-> workQWriteIx */	MRS	r3, cpsr		/* LOCK INTERRUPTS */	ORR	lr, r3, #I_BIT	MSR	cpsr, lr	/* get write index and advance it (4 words per entry) */	LDRB	lr, [r12]		/* lr = write index */	ADD	lr, lr, #4		/* lr = advanced write index */	STRB	lr, [r12]		/* update write index */	/* check for overflow */	AND	lr, lr, #0xFF		/* mask to byte for comparison */	LDR	r12, L$_workQReadIx	/* r12-> workQReadIx */	LDRB	r12, [r12]		/* r12 = read index */	TEQS	r12, lr	BLEQ	FUNC(workQPanic)		/* overwrites LR but doesn't return */	/* no overflow - put job in pool */	MSR	cpsr, r3		/* UNLOCK INTERRUPTS */	LDR	r12, L$_workQIsEmpty	/* r12-> workQIsEmpty */	MOV	r3, #FALSE		/* workQIsEmpty := FALSE */	STR	r3, [r12]	LDR	r12, L$_pJobPool	/* r12-> pJobPool */	SUB	lr, lr, #4		/* step back index */	AND	lr, lr, #0xFF		/* mask to byte */	ADD	r12, r12, lr, LSL #2	STMIA	r12, {r0-r2}		/* put fnptr/args in pool */	LDMFD	sp!, {pc}/********************************************************************************* workQDoWork - perform all the work queued in the kernel work queue** This routine empties all the deferred work in the work queue.  The global* variable errno is saved restored, so the work will not clobber it.** RETURNS: N/A** NOMANUAL* void workQDoWork ()*/FUNC_LABEL(workQDoWork)	/* check if work to do */	LDR	r2, L$_workQReadIx	/* r2-> workQReadIx */	LDR	r3, L$_workQWriteIx	/* r3-> workQWriteIx */	LDRB	r0, [r2]		/* r0 = workQReadIx */	LDRB	r1, [r3]		/* r1 = workQWriteIx */	TEQS	r0, r1			/* read index == write index? */	MOVEQ	pc, lr			/* quick return if no work */	/* work to do - save regs and set up "static" values */	STMFD	sp!, {r4-r8,lr}	MOV	r4, r2			/* r4-> workQReadIx */	MOV	r5, r3			/* r5-> workQWriteIx */	LDR	r12, L$_errno		/* save errno */	LDR	r6, [r12]		/* r6 = errno */	LDR	r7, L$_pJobPool		/* r7-> pJobPool */	LDR	r8, L$_workQIsEmpty	/* r8-> workQIsEmpty */L0_workQDoWork:	/*	 * r0 = workQReadIx	 * r1 = workQWriteIx	 * r4-> workQReadIx	 * r5-> workQWriteIx	 * r6 = errno	 * r7-> pJobPool	 * r8-> workQIsEmpty	 */	ADD	r12, r0, #4		/* bump read index - entry is 4 words */	STRB	r12, [r4]		/* update read index before calling fn*/	ADD	r12, r7, r0, LSL #2	/* r12-> job */	LDMIB	r12, {r0,r1}		/* get args */	MOV	lr, pc			/* set link */	LDR	pc, [r12]		/* call function */	/* set workQIsEmpty := TRUE before checking indices */	MOV	r0, #TRUE	STR	r0, [r8]	/* check if more to do */	LDRB	r0, [r4]		/* r0 = workQReadIx */	LDRB	r1, [r5]		/* r1 = workQWriteIx */	TEQS	r0, r1			/* read index == write index? */	BNE	L0_workQDoWork	/* restore errno */	LDR	r12, L$_errno	STR	r6, [r12]	LDMFD	sp!, {r4-r8, pc}#endif /* ! workQALib_PORTABLE */

⌨️ 快捷键说明

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