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

📄 bcopy.s

📁 开放源码实时操作系统源码.
💻 S
📖 第 1 页 / 共 3 页
字号:


	ALIGN_TEXT

fastmove_tail:

	movl	_curpcb,%eax

	movl	$fastmove_tail_fault,PCB_ONFAULT(%eax)



	movb	%cl,%al

	shrl	$2,%ecx				/* copy longword-wise */

	cld

	rep

	movsl

	movb	%al,%cl

	andb	$3,%cl				/* copy remaining bytes */

	rep

	movsb



	movl	%ebp,%esp

	popl	%ebp

	ret



	ALIGN_TEXT

fastmove_fault:

	movl	_curpcb,%edi

	addl	$PCB_SAVEFPU,%edi

	movl	%esp,%esi

	cld

	movl	$PCB_SAVEFPU_SIZE>>2,%ecx

	rep

	movsl



	smsw	%ax

	orb	$CR0_TS,%al

	lmsw	%ax

	movl	$0,_npxproc



fastmove_tail_fault:

	movl	%ebp,%esp

	popl	%ebp

	addl	$8,%esp

	popl	%ebx

	popl	%edi

	popl	%esi

	movl	_curpcb,%edx

	movl	$0,PCB_ONFAULT(%edx)

	movl	$EFAULT,%eax

	ret

#endif /* I586_CPU && NNPX > 0 */



/*

 * fu{byte,sword,word} : fetch a byte (sword, word) from user memory

 */

ENTRY(fuword)

	movl	_curpcb,%ecx

	movl	$fusufault,PCB_ONFAULT(%ecx)

	movl	4(%esp),%edx			/* from */



	cmpl	$VM_MAXUSER_ADDRESS-4,%edx	/* verify address is valid */

	ja	fusufault



	movl	(%edx),%eax

	movl	$0,PCB_ONFAULT(%ecx)

	ret



/*

 * These two routines are called from the profiling code, potentially

 * at interrupt time. If they fail, that's okay, good things will

 * happen later. Fail all the time for now - until the trap code is

 * able to deal with this.

 */

ALTENTRY(suswintr)

ENTRY(fuswintr)

	movl	$-1,%eax

	ret



ENTRY(fusword)

	movl	_curpcb,%ecx

	movl	$fusufault,PCB_ONFAULT(%ecx)

	movl	4(%esp),%edx



	cmpl	$VM_MAXUSER_ADDRESS-2,%edx

	ja	fusufault



	movzwl	(%edx),%eax

	movl	$0,PCB_ONFAULT(%ecx)

	ret



ENTRY(fubyte)

	movl	_curpcb,%ecx

	movl	$fusufault,PCB_ONFAULT(%ecx)

	movl	4(%esp),%edx



	cmpl	$VM_MAXUSER_ADDRESS-1,%edx

	ja	fusufault



	movzbl	(%edx),%eax

	movl	$0,PCB_ONFAULT(%ecx)

	ret



	ALIGN_TEXT

fusufault:

	movl	_curpcb,%ecx

	xorl	%eax,%eax

	movl	%eax,PCB_ONFAULT(%ecx)

	decl	%eax

	ret



/*

 * su{byte,sword,word}: write a byte (word, longword) to user memory

 */

ENTRY(suword)

	movl	_curpcb,%ecx

	movl	$fusufault,PCB_ONFAULT(%ecx)

	movl	4(%esp),%edx



#if defined(I386_CPU)



#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)

	cmpl	$CPUCLASS_386,_cpu_class

	jne	2f				/* we only have to set the right segment selector */

#endif /* I486_CPU || I586_CPU || I686_CPU */



	/* XXX - page boundary crossing is still not handled */

	movl	%edx,%eax

	shrl	$IDXSHIFT,%edx

	andb	$0xfc,%dl



	leal	_PTmap(%edx),%ecx

	shrl	$IDXSHIFT,%ecx

	andb	$0xfc,%cl

	testb	$PG_V,_PTmap(%ecx)		/* PTE page must be valid */

	je	4f

	movb	_PTmap(%edx),%dl

	andb	$PG_V|PG_RW|PG_U,%dl		/* page must be valid and user writable */

	cmpb	$PG_V|PG_RW|PG_U,%dl

	je	1f



4:

	/* simulate a trap */

	pushl	%eax

	call	_trapwrite

	popl	%edx				/* remove junk parameter from stack */

	testl	%eax,%eax

	jnz	fusufault

1:

	movl	4(%esp),%edx

#endif



2:

	cmpl	$VM_MAXUSER_ADDRESS-4,%edx	/* verify address validity */

	ja	fusufault



	movl	8(%esp),%eax

	movl	%eax,(%edx)

	xorl	%eax,%eax

	movl	_curpcb,%ecx

	movl	%eax,PCB_ONFAULT(%ecx)

	ret



ENTRY(susword)

	movl	_curpcb,%ecx

	movl	$fusufault,PCB_ONFAULT(%ecx)

	movl	4(%esp),%edx



#if defined(I386_CPU)



#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)

	cmpl	$CPUCLASS_386,_cpu_class

	jne	2f

#endif /* I486_CPU || I586_CPU || I686_CPU */



	/* XXX - page boundary crossing is still not handled */

	movl	%edx,%eax

	shrl	$IDXSHIFT,%edx

	andb	$0xfc,%dl



	leal	_PTmap(%edx),%ecx

	shrl	$IDXSHIFT,%ecx

	andb	$0xfc,%cl

	testb	$PG_V,_PTmap(%ecx)		/* PTE page must be valid */

	je	4f

	movb	_PTmap(%edx),%dl

	andb	$PG_V|PG_RW|PG_U,%dl		/* page must be valid and user writable */

	cmpb	$PG_V|PG_RW|PG_U,%dl

	je	1f



4:

	/* simulate a trap */

	pushl	%eax

	call	_trapwrite

	popl	%edx				/* remove junk parameter from stack */

	testl	%eax,%eax

	jnz	fusufault

1:

	movl	4(%esp),%edx

#endif



2:

	cmpl	$VM_MAXUSER_ADDRESS-2,%edx	/* verify address validity */

	ja	fusufault



	movw	8(%esp),%ax

	movw	%ax,(%edx)

	xorl	%eax,%eax

	movl	_curpcb,%ecx			/* restore trashed register */

	movl	%eax,PCB_ONFAULT(%ecx)

	ret



ALTENTRY(suibyte)

ENTRY(subyte)

	movl	_curpcb,%ecx

	movl	$fusufault,PCB_ONFAULT(%ecx)

	movl	4(%esp),%edx



#if defined(I386_CPU)



#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)

	cmpl	$CPUCLASS_386,_cpu_class

	jne	2f

#endif /* I486_CPU || I586_CPU || I686_CPU */



	movl	%edx,%eax

	shrl	$IDXSHIFT,%edx

	andb	$0xfc,%dl



	leal	_PTmap(%edx),%ecx

	shrl	$IDXSHIFT,%ecx

	andb	$0xfc,%cl

	testb	$PG_V,_PTmap(%ecx)		/* PTE page must be valid */

	je	4f

	movb	_PTmap(%edx),%dl

	andb	$PG_V|PG_RW|PG_U,%dl		/* page must be valid and user writable */

	cmpb	$PG_V|PG_RW|PG_U,%dl

	je	1f



4:

	/* simulate a trap */

	pushl	%eax

	call	_trapwrite

	popl	%edx				/* remove junk parameter from stack */

	testl	%eax,%eax

	jnz	fusufault

1:

	movl	4(%esp),%edx

#endif



2:

	cmpl	$VM_MAXUSER_ADDRESS-1,%edx	/* verify address validity */

	ja	fusufault



	movb	8(%esp),%al

	movb	%al,(%edx)

	xorl	%eax,%eax

	movl	_curpcb,%ecx			/* restore trashed register */

	movl	%eax,PCB_ONFAULT(%ecx)

	ret



/*

 * copyinstr(from, to, maxlen, int *lencopied)

 *	copy a string from from to to, stop when a 0 character is reached.

 *	return ENAMETOOLONG if string is longer than maxlen, and

 *	EFAULT on protection violations. If lencopied is non-zero,

 *	return the actual length in *lencopied.

 */

ENTRY(copyinstr)

	pushl	%esi

	pushl	%edi

	movl	_curpcb,%ecx

	movl	$cpystrflt,PCB_ONFAULT(%ecx)



	movl	12(%esp),%esi			/* %esi = from */

	movl	16(%esp),%edi			/* %edi = to */

	movl	20(%esp),%edx			/* %edx = maxlen */



	movl	$VM_MAXUSER_ADDRESS,%eax



	/* make sure 'from' is within bounds */

	subl	%esi,%eax

	jbe	cpystrflt



	/* restrict maxlen to <= VM_MAXUSER_ADDRESS-from */

	cmpl	%edx,%eax

	jae	1f

	movl	%eax,%edx

	movl	%eax,20(%esp)

1:

	incl	%edx

	cld



2:

	decl	%edx

	jz	3f



	lodsb

	stosb

	orb	%al,%al

	jnz	2b



	/* Success -- 0 byte reached */

	decl	%edx

	xorl	%eax,%eax

	jmp	cpystrflt_x

3:

	/* edx is zero - return ENAMETOOLONG or EFAULT */

	cmpl	$VM_MAXUSER_ADDRESS,%esi

	jae	cpystrflt

4:

	movl	$ENAMETOOLONG,%eax

	jmp	cpystrflt_x



cpystrflt:

	movl	$EFAULT,%eax



cpystrflt_x:

	/* set *lencopied and return %eax */

	movl	_curpcb,%ecx

	movl	$0,PCB_ONFAULT(%ecx)

	movl	20(%esp),%ecx

	subl	%edx,%ecx

	movl	24(%esp),%edx

	testl	%edx,%edx

	jz	1f

	movl	%ecx,(%edx)

1:

	popl	%edi

	popl	%esi

	ret





/*

 * copystr(from, to, maxlen, int *lencopied)

 */

ENTRY(copystr)

	pushl	%esi

	pushl	%edi



	movl	12(%esp),%esi			/* %esi = from */

	movl	16(%esp),%edi			/* %edi = to */

	movl	20(%esp),%edx			/* %edx = maxlen */

	incl	%edx

	cld

1:

	decl	%edx

	jz	4f

	lodsb

	stosb

	orb	%al,%al

	jnz	1b



	/* Success -- 0 byte reached */

	decl	%edx

	xorl	%eax,%eax

	jmp	6f

4:

	/* edx is zero -- return ENAMETOOLONG */

	movl	$ENAMETOOLONG,%eax



6:

	/* set *lencopied and return %eax */

	movl	20(%esp),%ecx

	subl	%edx,%ecx

	movl	24(%esp),%edx

	testl	%edx,%edx

	jz	7f

	movl	%ecx,(%edx)

7:

	popl	%edi

	popl	%esi

	ret



ENTRY(bcmp)

	pushl	%edi

	pushl	%esi

	movl	12(%esp),%edi

	movl	16(%esp),%esi

	movl	20(%esp),%edx

	xorl	%eax,%eax



	movl	%edx,%ecx

	shrl	$2,%ecx

	cld					/* compare forwards */

	repe

	cmpsl

	jne	1f



	movl	%edx,%ecx

	andl	$3,%ecx

	repe

	cmpsb

	je	2f

1:

	incl	%eax

2:

	popl	%esi

	popl	%edi

	ret





/*

 * Handling of special 386 registers and descriptor tables etc

 */

/* void lgdt(struct region_descriptor *rdp); */

ENTRY(lgdt)

	/* reload the descriptor table */

	movl	4(%esp),%eax

	lgdt	(%eax)



	/* flush the prefetch q */

	jmp	1f

	nop

1:

	/* reload "stale" selectors */

	movl	$KDSEL,%eax

	movl	%ax,%ds

	movl	%ax,%es

	movl	%ax,%ss



	/* reload code selector by turning return into intersegmental return */

	movl	(%esp),%eax

	pushl	%eax

#	movl	$KCSEL,4(%esp)

	movl	$8,4(%esp)

	lret



/*

 * void lidt(struct region_descriptor *rdp);

 */

ENTRY(lidt)

	movl	4(%esp),%eax

	lidt	(%eax)

	ret



/*

 * void lldt(u_short sel)

 */

ENTRY(lldt)

	lldt	4(%esp)

	ret



/*

 * void ltr(u_short sel)

 */

ENTRY(ltr)

	ltr	4(%esp)

	ret



/* ssdtosd(*ssdp,*sdp) */

ENTRY(ssdtosd)

	pushl	%ebx

	movl	8(%esp),%ecx

	movl	8(%ecx),%ebx

	shll	$16,%ebx

	movl	(%ecx),%edx

	roll	$16,%edx

	movb	%dh,%bl

	movb	%dl,%bh

	rorl	$8,%ebx

	movl	4(%ecx),%eax

	movw	%ax,%dx

	andl	$0xf0000,%eax

	orl	%eax,%ebx

	movl	12(%esp),%ecx

	movl	%edx,(%ecx)

	movl	%ebx,4(%ecx)

	popl	%ebx

	ret



/* load_cr0(cr0) */

ENTRY(load_cr0)

	movl	4(%esp),%eax

	movl	%eax,%cr0

	ret



/* rcr0() */

ENTRY(rcr0)

	movl	%cr0,%eax

	ret



/* rcr3() */

ENTRY(rcr3)

	movl	%cr3,%eax

	ret



/* void load_cr3(caddr_t cr3) */

ENTRY(load_cr3)

	movl	4(%esp),%eax

	movl	%eax,%cr3

	ret





/*****************************************************************************/

/* setjump, longjump                                                         */

/*****************************************************************************/



ENTRY(setjmp)

	movl	4(%esp),%eax

	movl	%ebx,(%eax)			/* save ebx */

	movl	%esp,4(%eax)			/* save esp */

	movl	%ebp,8(%eax)			/* save ebp */

	movl	%esi,12(%eax)			/* save esi */

	movl	%edi,16(%eax)			/* save edi */

	movl	(%esp),%edx			/* get rta */

	movl	%edx,20(%eax)			/* save eip */

	xorl	%eax,%eax			/* return(0); */

	ret



ENTRY(longjmp)

	movl	4(%esp),%eax

	movl	(%eax),%ebx			/* restore ebx */

	movl	4(%eax),%esp			/* restore esp */

	movl	8(%eax),%ebp			/* restore ebp */

	movl	12(%eax),%esi			/* restore esi */

	movl	16(%eax),%edi			/* restore edi */

	movl	20(%eax),%edx			/* get rta */

	movl	%edx,(%esp)			/* put in return frame */

	xorl	%eax,%eax			/* return(1); */

	incl	%eax

	ret



/*

 * Here for doing BB-profiling (gcc -a).

 * We rely on the "bbset" instead, but need a dummy function.

 */

NON_GPROF_ENTRY(__bb_init_func)

	movl	4(%esp),%eax

	movl	$1,(%eax)

	.byte	0xc3				/* avoid macro for `ret' */

⌨️ 快捷键说明

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