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

📄 interrupt.s

📁 C++ 编写的EROS RTOS
💻 S
📖 第 1 页 / 共 5 页
字号:
#if 0	jmp	dump_state#endif	jmp	fault_keynot_fault_key:	/* Save the keyInfo value. */	movl	%ebx,keyinfo	/* Recipient may be faulted. */	cmpl	$0,PR_OFF_processFlags(%ebp)	jnz	Standard_Gate_Path	/* recipient is faulted or hazarded */#if 1	/* verify that the exit block keys are well-formed */	testl	$0xe0e0e0e0,PR_OFF_rcvKeys(%ebp)	jnz	Standard_Gate_Path#endif	#if 0	/* if exit block accepts keys, take long path */	testl	$0x001f1f00,PR_OFF_rcvKeys(%ebp)	jnz	Standard_Gate_Path#endif	/* #define EXPERIMENT1 */#ifdef EXPERIMENT1	movl	PR_OFF_ESI(%ebp),%ecx	movl	PR_OFF_rcvKeys(%ebp),%edx	addl	%ecx,%edx	jnz	L_complex_case		subl	$PR_OFF_FIXREGS,%eax	jmp	done_keys	L_complex_case:	cmpl	%ecx,FX_OFF_sndLen(%eax)	jbe	got_str_len	movl	FX_OFF_sndLen(%eax),%ecx#else	movl	FX_OFF_sndLen(%eax),%ecx		cmpl	%ecx,PR_OFF_ESI(%ebp)	jae	got_str_len	movl	PR_OFF_ESI(%ebp),%ecx#endif	got_str_len:	/* I tried jecx here, but it did not work.  This is faster	   anyway. */	testl	%ecx,%ecx	jz	no_send_string#ifndef FAST_IPC_STRINGS	jmp	Standard_Gate_Path#else#ifdef FAST_IPC_STATS	incl	EXT(nFastIpcString)#endif	/* jmp	Standard_Gate_Path */	/* We know that the length is <= 64k (because we checked the send	   string length against this and %ecx now holds the shorter of	   the two lengths), verify that the recipient string is within 	   the proper bounds... */	movl	PR_OFF_EDI(%ebp),%edx#ifdef OPTION_SMALL_SPACES	cmpl	%edx,PR_OFF_limit(%ebp)	jb	Standard_Gate_Path	/* string bounds violation */#else	cmpl	$UMSGTOP,%edx	jae	Standard_Gate_Path	/* string bounds violation */#endif	addl	%edx,%ecx		/* establish upper bound */#ifdef OPTION_SMALL_SPACES	cmpl	%ecx,PR_OFF_limit(%ebp)	jb	Standard_Gate_Path	/* string bounds violation */#else	cmpl	$UMSGTOP,%ecx	jae	Standard_Gate_Path	/* string bounds violation */#endif		/* The OLD logic validated both the send string and the receive 	   string.  The NEW logic does not -- it simply cause both	   strings to be mapped and then optimistically does the copy.	   THE COPY MAY FAULT ON EITHER SENDER OR RECEIVER SIDE.	   A consequence of this design is that the string may be	   partially delivered, we may fault, and someone else may	   get scheduled with the data just sitting there. After	   discussion with Norm and the list, I've decided that this	   is okay.  Note that there is no real way to prevent this on	   an SMP machine, as some other processor might be diddling	   the mapping tables out from under us anyway. */		/* For mappping the receive string, there are three cases:	  	   1. Recipient space is small space	   2. Recipient space is large space same as current space	   3. Recipient space is large space different from current 	      space           Case (2) can currently be handled the same as case (1) OR 	   case (3).  The current code handles it like case (1)		   Note that we *could* make return to large space from 	   small space fall under case (2) by rewriting the address 	   space pointer here, but remapping the window is cheaper	   because it avoids taking TLB miss costs.	   */#ifdef OPTION_SMALL_SPACES	/* Yes, Mathilda, we really SHOULD be checking this before	   checking for KERNPAGEDIR, because it is okay for small spaces	   to run out of the kernel map. */	cmpl	$0,PR_OFF_bias(%ebp)	jnz	same_space#endif		cmpl	$KERNPAGEDIR,PR_OFF_MappingTable(%ebp)	jz	Standard_Gate_Path	#ifdef OPTION_SMALL_SPACES#if 1	/* Flip this ifdef to handle case 2 like case 3. It's rare	   enough that it may not be worth it. */	jmp	other_space#else	jnz	same_space	movl	FX_OFF_MappingTable(%eax),%ebx	cmpl	%ebx,PR_OFF_MappingTable(%ebp)	jnz	other_space#endif	same_space:#if defined(FAST_IPC_BPT) && 0	int3#endif#ifdef FAST_IPC_STATS	incl	EXT(nFastIpcSmallString)#endif	addl	PR_OFF_bias(%ebp),%ecx	addl	PR_OFF_bias(%ebp),%edx	addl	$KUVA,%ecx	addl	$KUVA,%edx	/* inherit %es as dest segment, which in theory still names active	   user space. */	jmp	probe_receive_string#endif /* OPTION_SMALL_SPACES */other_space:#if defined(FAST_IPC_BPT) && 0	int3#endif#ifdef FAST_IPC_STATS	incl	EXT(nFastIpcLargeString)#endif	/* Map the receive string into the kernel by copying the associated	   page *directory* entries.	   At this point, %EDX holds the properly biased start offset,	   so we can simply shift it to compute the PDE address.	   In principle, we need to check that the mappings are user mode,	   valid, and writable.  The first follows from the fact that they	   are mapped in the user portion of the address space.  The latter	   two will be tested by using a non-modifying probe instruction. */	#if 0	movl	_3PTE.kern_fstbuf,%edi#endif		subl	%edx,%ecx		/* recover xfer length */		movl	FX_OFF_MappingTable(%eax),%edi	addl	$0xff0,%edi	movl	PR_OFF_MappingTable(%ebp),%esi	shrl	$22,%edx	movl	(%esi,%edx,4),%ebx	/* load PDE */	movl	%ebx,(%edi)	movl	4(%esi,%edx,4),%ebx	/* load PDE */	movl	%ebx,4(%edi)	movl	PR_OFF_EDI(%ebp),%edx	andl	$0x3fffff,%edx	orl	$KVA_FSTBUF,%edx	addl	%edx,%ecx	probe_receive_string:	movl	%edx,%edi	/* save string start position */#ifdef ASM_VALIDATE_STRINGS	#if defined(FAST_IPC_BPT) && 0	int3#endif	/* %edx now holds string base, %ecx holds exclusive bound.	   Length is known to be nonzero. */#if 0	jmp	Standard_Gate_Path#endif				movl	%edx,%edi	/* save string start position */#if defined(FAST_IPC_BPT) && 0	int3#endifL_rcv_string_probe:#if defined(FAST_IPC_BPT)	int3#endif	andb	$0xff,(%edx)	addl	$EROS_PAGE_SIZE,%edx	cmpl	%edx,%ecx	ja	L_rcv_string_probeL_rcv_string_probe_resid:	andb	$0xff,-1(%ecx)#endif /* ASM_VALIDATE_STRINGS */		/* Receive string is valid.  DO THE COPY. EDI holds dest ptr	   from above. %DS and %ES hold kernel seg, so need to bias the 	   source address appropriately.  Doing so is much cheaper than	   reloading the segment register. */	movl	FX_OFF_sndPtr(%eax),%esi#ifdef OPTION_SMALL_SPACES	addl	PR_OFF_bias-PR_OFF_FIXREGS(%eax),%esi#endif	addl	$KUVA,%esi		subl	%edi,%ecx		/* recompute count */	pushl	%ecx		shrl	$2,%ecx	jz	move_bytes	/* Following relies on being able to use word move with misaligned	   data. */string_move:	rep	movslmove_bytes:		#if defined(FAST_IPC_BPT) && 0	int3#endif	movl	(%esp),%ecx	andl	$3,%ecx	jz	string_done	rep	movsb	string_done:	popl	%ecx	movl	%ecx,PR_OFF_ESI(%ebp)#ifdef FAST_IPC_STATS	decl	EXT(nFastIpcNoString)#endif#endif /* FAST_IPC_STRINGS */no_send_string:#ifdef FAST_IPC_STATS	incl	EXT(nFastIpcNoString)#endif	subl	$PR_OFF_FIXREGS,%eax	/* EAX NOW POINTS TO SOURCE ***PROCESS***	   	   We are now past all of the sanity checks, and we will	   be proceeding via the fast path. */		cmpl	$0,PR_OFF_rcvKeys(%ebp)	jz	done_keys	xorl	%ecx,%ecx	#define EXPERIMENT2#ifdef EXPERIMENT2	testl	$0xffffff,PR_OFF_rcvKeys(%ebp)	jnz	key_loop	movl	$2,%ecx	jmp	next_key#endif#if 0	addl	$PR_OFF_FIXREGS,%eax	jmp	Standard_Gate_Path#endifkey_loop:	movzbl	PR_OFF_rcvKeys(%ebp,%ecx),%edi	testl	%edi,%edi	jz	next_key		movzbl	PR_OFF_sndKeys(%eax,%ecx),%esi	/* slot no */	shll	$4,%edi	/* slot offset relative to key regs */	shll	$4,%esi	/* slot offset relative to key regs */	/* esi, edi now hold offsets within keyregs for send, received	   key slot respectively.  Convert these to slot pointers */	leal	PR_OFF_keyregs(%ebp,%edi),%edi	leal	PR_OFF_keyregs(%eax,%esi),%esi	/* If dest key is prepared, it must be unchained.  Since we	   are overwriting it, there is no need to mark the named	   object as now having on-disk keys.  */	testl	$0x80,(%edi)	jz	unchained	movl	4(%edi),%ebx	/* grab next ptr */	movl	8(%edi),%edx	/* grab prev ptr */	movl	%edx,8(%ebx)	/* next->prev = prev */	movl	%ebx,4(%edx)	/* prev->next = next */unchained:	/* next ptr and first word get unconditionally copied, as does	   last ptr */	movl	(%esi),%edx	/* first word */	movl	4(%esi),%ebx	/* next ptr */	movl	%edx,(%edi)	/* first word */	movl	%ebx,4(%edi)	/* next ptr */		testl	$0x80,%edx	/* check if this key is prepared */	jz	copy_unprepared_key	movl	%esi,8(%edi)	/* new key prev ptr is old key */	movl	%edi,4(%esi)	/* old key next ptr is new key */	movl	%edi,8(%ebx)	/* old next prev ptr is new key */		jmp	last_word	copy_unprepared_key:	movl	8(%esi),%ebx	/* prev ptr word */	movl	%ebx,8(%edi)	/* prev ptr word */	last_word:	movl	12(%esi),%ebx	/* object ptr */	movl	%ebx,12(%edi)	/* object ptr */	next_key:		incl	%ecx	cmpl	$3,%ecx	jb	key_loop	ja	done_keys	/* decide what to do about 4th key.  If this is a CALL operation,	   we need to fabricate a resume key. Otherwise we need to copy	   the key in slot 4. */	cmpl	$IT_Call,PR_OFF_invType(%eax)	jne	key_loop	/* normal key 3 */	/* It's a call.  Unprepare the destination key if needed and	   fabricate a resume key. */		movzbl	PR_OFF_rcvKeys(%ebp,%ecx),%edi	testl	%edi,%edi	jz	done_keys	/* resume key refused */		shll	$4,%edi	/* slot offset relative to key regs */	leal	PR_OFF_keyregs(%ebp,%edi),%edi	/* If dest key is prepared, it must be deprepared */	testl	$0x80,(%edi)	jz	make_resume_key		movl	4(%edi),%ebx	/* grab next ptr */	movl	8(%edi),%edx	/* grab prev ptr */	movl	%edx,8(%ebx)	/* next->prev = prev */	movl	%ebx,4(%edx)	/* prev->next = next */	make_resume_key:	movl	$0x84,(%edi)	/* prepped rsm, subtype=0, keydata=0 */	movl	%eax,4(%edi)	/* next = sender context */	movl	8(%eax),%ebx	/* fetch context prev ptr */	movl	%ebx,8(%edi)	/* prev = context->prev */	movl	%edi,4(%ebx)	/* context->prev->next = this */	movl	%edi,8(%eax)	/* context->prev = new key */	movl	%eax,12(%edi)	/* pContext = sender */	done_keys:	/* We have copied all the keys.  We now need to copy the register	   arguments.		   %ebp points to recipient process	   %eax points to sending process		 */	movl	PR_OFF_EAX(%eax),%ebx	movl	PR_OFF_EBX(%eax),%edx	movl	%ebx,PR_OFF_EAX(%ebp)	movl	%edx,PR_OFF_EBX(%ebp)		movl	PR_OFF_ECX(%eax),%ebx	movl	PR_OFF_EDX(%eax),%edx	movl	%ebx,PR_OFF_ECX(%ebp)	movl	%edx,PR_OFF_EDX(%ebp)	/* Also the KeyInfo field. */	movzwl	2+keyinfo,%ebx	movl	%bx,PR_OFF_EDI(%ebp)#if defined(FAST_IPC_REDSEG)#if defined(FAST_IPC_BPT) && 0	int3#endif	/* if we invoked a red segment, we now need to patch w1	   and possibly replace key argument 3. */	cmpl	$0,redflags	jz	fault_key	movl	redw1,%ebx	movl	%ebx,PR_OFF_EBX(%ebp)	/* might need to send a node key in rcv key 2 */	movl	rednodekey,%esi	cmpl	$0,%esi	jz	fault_key		movzbl	2+PR_OFF_rcvKeys(%ebp),%edi	testl	%edi,%edi	jz	fault_key		shll	$4,%edi		/* slot offset relative to key regs */	/* %edi now holds offset of rcv key 2 within keyregs. Convert this	   to a slot pointer */	leal	PR_OFF_keyregs(%ebp,%edi),%edi	/* If dest key is prepared, it must be unchained.  Since we	   are overwriting it, there is no need to mark the named	   object as now having on-disk keys.  */	testl	$0x80,(%edi)	jz	red_unchained	movl	4(%edi),%ebx	/* grab next ptr */	movl	8(%edi),%edx	/* grab prev ptr */	movl	%edx,8(%ebx)	/* next->prev = prev */	movl	%ebx,4(%edx)	/* prev->next = next */red_unchained:#if defined(FAST_IPC_BPT) && 0	int3#endif	/* We know that the source key is prepared, since it is the	   key we originally invoked.   Copy the first word and the next	   pointer. */		movl	(%esi),%edx	/* first word */	movl	4(%esi),%ebx	/* next ptr */	movl	%edx,(%edi)	/* first word */	movl	%ebx,4(%edi)	/* next ptr */	/* update the link pointers */		movl	%esi,8(%edi)	/* new key prev ptr is old key */	movl	%edi,4(%esi)	/* old key next ptr is new key */	movl	%edi,8(%ebx)	/* old next prev ptr is new key */		/* copy the last word */	movl	12(%esi),%ebx	/* object ptr */	movl	%ebx,12(%edi)	/* object ptr */	/* original key was either a NODE key or a SEGMENT key.	   make the result a NODE key. */	movb	$0x90,(%edi)#endif /* FAST_IPC_REDSEG */fault_key:	/* recipient runstate to RS_Running, sender runstate according	   to invType: */	movb	$RS_Running,PR_OFF_runState(%ebp)	movb	$0,PR_OFF_processFlags(%ebp)	movl	$0,PR_OFF_faultCode(%ebp)	movl	$0,PR_OFF_faultInfo(%ebp)	movb	PR_OFF_invType(%eax),%bl	movb	%bl,PR_OFF_runState(%eax)	/* kill all outstanding recipient resume keys */zap_resume_keys:	movl	8(%ebp),%edi		/* %edi = ctxt->prev */	cmpl	%ebp,%edi	je	zap_done		movb	(%edi),%dl		/* load type byte */	andb	$0xfc,%dl		/* mask out hazard bits */	cmpb	$0x84,%dl	jne	zap_done		/* looking at a resume key.  		   Revise the prev ptr in the context structure.	   Blow away this capability.	 */	movl	4(%edi),%ebx		/* next = key->next */	movl	8(%edi),%edx		/* prev = key->prev */	cmpl	%ebx,%ebp	je	nxt_ok	jmp	dump_statenxt_ok:		movl	%edx,8(%ebx)		/* next->prev = prev */	movl	%ebx,4(%edx)		/* prev->next = next */	andl	$0x3,(%edi)		/* preserve the hazard bits */	orl	$0x1330,(%edi)		/* void key:					0x13==MiscKeyType::Void					0x30==(KtMisc << 2) */	/* Following are not strictly necessary. */

⌨️ 快捷键说明

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