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

📄 interrupt.s

📁 C++ 编写的EROS RTOS
💻 S
📖 第 1 页 / 共 5 页
字号:
	movl	$0,4(%edi)	movl	$0,8(%edi)	movl	$0,12(%edi)	jmp	zap_resume_keyszap_done:	/* migrate the thread */	movl	PR_OFF_curThread(%eax),%ebx	movl	$0,PR_OFF_curThread(%eax)	movl	%ebx,PR_OFF_curThread(%ebp)		movl	%ebp,OFF_THRD_CTXT(%ebx)	/* update context pointer */#if 0	jmp	dump_state#endif	#if 0	mov	$0x10,%cx	mov	%cx,%ds#endif	#if 0	jmp	dump_state#endif		/* FIX:	set up recipient process code/data segments here!!!	   Limit is expressed in pages.		      offset sz (bits)   field        new value	      0      16          seg.loLimit  (nPages & 0xffffu);	      2      16          seg.loBase   (linearBase & 0xffffu);	      4      8           seg.midBase  (linearBase >> 16) & 0xffu;	      6      4           seg.hiLimit  ((nPages >> 16) & 0xfu);	      7      8           seg.hiBase   (linearBase >> 24) & 0xffu;	 */	/* Load pointer to domain code GDT entry: */	movl	$EXT(_3GDT.GdtTable),%ebx	addl	$0x20,%ebx		/* set all base and limit fields to zero */	movl	$0,(%ebx)		/* domain code seg */	andl	$0x00f0ff00,4(%ebx)	/* domain code seg */	movl	$0,8(%ebx)		/* domain data seg */	andl	$0x00f0ff00,12(%ebx)	/* domain data seg */	#ifdef OPTION_SMALL_SPACES	movl	PR_OFF_bias(%ebp),%ecx	testl	%ecx,%ecx	jz	large_space_seg	small_space_seg:	/* Set base to value of bias.	   Set (inclusive) limit to 31 pages */	movw	%cx,2(%ebx)		/* domain code seg loBase*/	movw	%cx,8+2(%ebx)		/* domain data seg loBase */	shrl	$16,%ecx	movb	%cl,4(%ebx)		/* domain code seg midBase*/	movb	%cl,8+4(%ebx)		/* domain data seg midBase*/	movb	%ch,7(%ebx)		/* domain code seg hiBase*/	movb	%ch,8+7(%ebx)		/* domain data seg hiBase*/		movw	$31,(%ebx)	movw	$31,8(%ebx)		jmp	user_seg_adjusted#endiflarge_space_seg:	/* Base is already set to zero.  	   Set (inclusive) limit to 0xCFFFF pages */	movw	$0xffff,(%ebx)	orl	$0xc0000,4(%ebx)	movw	$0xffff,8(%ebx)	orl	$0xc0000,12(%ebx)	user_seg_adjusted:#if 1	smsw	%ax	cmpl	%ebp,_7Process.fpuOwner	je	fpu_enablefpu_disable:	orl	$0xa,%ax	jmp	reload_fpufpu_enable:       andl	$0xfff1,%eaxreload_fpu:	lmsw	%axfpu_adjusted:#endif#ifdef FAST_IPC_STATS	incl	EXT(nFastIpcEnd)#endif	#ifndef FAST_IPC_RETURN	pushl	%ebp	call	EXT(resume_process)#else	movl	%ebp,%esp		/*	 * We are now on our way back to whatever we interrupted.  If the	 * interrupt routine enabled interrupts, it was responsible for	 * disabling them before returning, so interrupts are now	 * disabled.	 *	 * %esp holds a pointer to the bottom of the context we are	 * restoring from.	 */#if 0	/*	 * Decrement the interrupt depth counter here.  Doing this from 	 * the assembly code eliminates the need to play sleazy games in 	 * the C part of the return path.	 */	decl	EXT(_3IRQ.DisableDepth);#endif		/* ANY CHANGE TO THIS PATH FROM HERE DOWN SHOULD BE	   IMPLEMENTED IN THE FAST_GATE_PATH AS WELL */		/* PROCESS_SIZE */	leal	PR_OFF_INTR_SP(%ESP),%EDX	movl	%EDX,4+EXT(_3TSS.TaskTable)	/* PROCESS_SIZE */	addl	$PR_OFF_MappingTable,%ESP	/* find base of save area */#if defined(DOMAIN_TRACING)	/* ESP POINTS TO BOTTOM OF SAVE AREA */	cmpl	$5,EXT(CpuType)	jb	1f		/* don't call it if not supported */		.byte 0x0f	.byte 0x31		/* RDTSC instr - results to %edx:%eax */		movl %eax,EXT(DomainTracingScratchpad)	movl %edx,EXT(DomainTracingScratchpad)+41:	#endif		/* Reload target address space:	 */	movl	%cr3,%ebx	#ifdef OPTION_SMALL_SPACES	cmpl	$0,PR_OFF_bias-PR_OFF_MappingTable(%esp)	jnz	1f#endif		cmpl	%ebx,(%esp)	je      1f		movl	(%esp),%ebx	movl	%ebx,%cr3  /* restore user address space */	1:	movl	%EBX,28+EXT(_3TSS.TaskTable)	movl	%ebx,(%esp)	addl	$4,%esp	popa#if 0	movl	$EXT(InterruptStackTop),%esp	jmp	dump_state#endif		/*	 * Skip over the pushed error number and exception number:	 */      	addl	$8,%esp	/*	 * Reload the segment registers by reaching up past the critical 	 * stuff with movl  so that if we fault we always defecate at the	 * same point on the stack:	 */L_fast_reload_es:		movl	FX_OFF_ES-FX_OFF_EIP(%esp),%esL_fast_reload_ds:		movl	FX_OFF_DS-FX_OFF_EIP(%esp),%dsL_fast_reload_fs:		movl	FX_OFF_FS-FX_OFF_EIP(%esp),%fsL_fast_reload_gs:		movl	FX_OFF_GS-FX_OFF_EIP(%esp),%gs		/*	 * ONCE BELOW THIS POINT, ALL REFERENCES MUST BE TO THE CODE	 * OR STACK SEGMENTS.  BECAUSE DS NOW HOLDS THE USER DATA	 * SEGMENT, WE CANNOT TRUST THAT THE DATA SEGMENT IS VALID.	 */	#if 0	movl	$EXT(InterruptStackTop),%esp	jmp	dump_state#endif		/*	 * Sayonara, interrupt context.  The iret will restore interrupts	 * automagically.	 */L_fast_iret_pc:	iret#endif /* FAST_IPC_RETURN */#endif /* FAST_IPC */	kern_seg_load:	/*	 * Now load the kernel segments.  We will continue to run code	 * out of the Window.	 */	mov	$0x10,%cx	mov	%cx,%ds	mov	%cx,%es			/* for string copies */Standard_Gate_Path:	/*	 * Bump the interrupt depth counter here.  All of our entry 	 * points use interrupt gates, so interrupts are definitely 	 * disabled.  Doing this from the assembly code eliminates	 * the need to play sleazy games in the C part of the return 	 * path.	 *	 * Doing this AFTER the %ESP adjustment allows the SUBL to settle, 	 * preventing subsequent AGEN interlocks on Pentium and later 	 * processors.	 */		movl	$1,EXT(_3IRQ.DisableDepth)		/*	 * Call the interrupt dispatch routine, passing it a pointer	 * to the register save area.  It is entirely up to the interrupt	 * routines to decide whether or not to re-enable interrupts.	 */		pushl	%eax		call	EXT(OnKeyInvocationTrap__3IDTP9fixregs_t)	/* This should NEVER return */	jmp	EXT(halt)	#if defined(FAST_IPC_REDSEG)	/* VARIOUS OUT OF LINE CODE FOR THE FAST PATH. */maybe_red_seg:	/* ON ENTRY:			       %eax	points to the invoking process's fixregs 	                structure.	       %ecx	points to the invoked key, which is prepared.	                and may or may not be a red segment key.	       %ebx     contains the first word of that key.  	           ON EXIT:	       either branches to Standard_Gate_Path, in which case %eax	       must not be diddled but nothing else really matters.  If	       it proves to be a fast-path case, however:	       %eax	points to the invoking process's fixregs 	                structure.	       %ecx     should point to the keeper key.	       %ebx     should contain the first word of that key.		   We must first verify that the key type makes it a red segmode	   key.  If it is, we must examine the format key and decide what	   to do about it (if anything).		   STALE (applied while there were still Capability Pages):		     A prepared red SEGMENT key will have a keyType field of 0x94, 	     a subtype field of 0x00, and a keyInfo field of 0x1: 0x00010094	     A prepared red NODE key will have a keyType field of 0x90, 	     a subtype field of 0x00, and a keyInfo field of 0x1: 0x00010090	   CORRECT (now that Capability Pages are gone):		     A prepared red SEGMENT key will have a keyType field of 0x90, 	     a subtype field of 0x00, and a keyInfo field of 0x1: 0x00010090	     A prepared red NODE key will have a keyType field of 0x8C, 	     a subtype field of 0x00, and a keyInfo field of 0x1: 0x0001008C         */	cmpl	$0x10090,%ebx	jne	Standard_Gate_Path#if 0	cmpl	$0x1008c,%ebx	jne	Standard_Gate_Path#endif	#ifdef FAST_IPC_STATS	incl	EXT(nFastIpcOK)#endif	/* We now know that this is a prepared red segmode key.  We need to 	   determine if this segment has a keeper, and if so, whether that	   keeper is a gate key (and therefore eligable for the fast path	   logic).	 */	movl	12(%ecx),%ebp		/* ptr to node */	/* Check if key in format slot is a number key.  Format slot is 31.	   Node has ObHdr + callCount (1 word) before the actual key slots.	   We are going to need to do a bunch of arithmetic around that,	   so make %ebp point to base of key array:	 */	leal	4+OBHDR_SZ(%ebp),%ebp	cmpb	$0x20,0x1F0(%ebp)	jne	Standard_Gate_Path	/* not number key */	/* Load format word */	movl	4+0x1F0(%ebp),%edx	movl	$0,rednodekey		/* until proven otherwise */		/* check sendnode: */	andl	$0x3E0,%edx	jz	no_sendnode		cmpl	$0x20,%edx	jne	Standard_Gate_Path	/* malformed format key */#if defined(FAST_IPC_BPT) && 0	int3#endif	/* we are sending a node key in slot 3. */	movl	%ecx,rednodekey	no_sendnode:	/* Load w1 value */	movl	8+0x1F0(%ebp),%edx	movl	%edx,redw1		/* Find the keeper key, if any. */	movl	4+0x1F0(%ebp),%edx	/* format word */	shrl	$6,%edx			/* right shift 10 bits to get field.	                                   left shift 4 bits to compute slot	                                   offset */	andl	$0x1f0,%edx		/* want ONLY this field */	cmpl	$0x1f0,%edx	je	Standard_Gate_Path	/* no keeper key! */	/* we have found the keeper key.  Get pointer to it into %ecx	   where it belongs. */	leal	(%ebp,%edx),%ecx	movl	(%ecx),%ebx		/* load first word */	/* Provided the gate key is prepared, we can now branch back	   to the main path and let that path complete the key type 	   checks. */	movl	$1,redflags#ifdef FAST_IPC_STATS	incl	EXT(nFastIpcRedSeg)#endif	testl	$0x80,%ebx	jnz	examine_invoked_key	#ifdef FAST_IPC_STATS	decl	EXT(nFastIpcRedSeg)#endif	jmp	Standard_Gate_Path	/* not prepared */#endif			/* THINGS THAT CAN GO WRONG IN THE MAIN IPC PATH GO HERE	 *	 * These are taken out of line in the interest of locality.	 */bogus_ipc_arg_block:	ss	movl	FX_OFF_EIP(%eax),%ebx	ss	movl	$FC_BadEntryBlock,PR_OFF_faultCode-PR_OFF_FIXREGS(%eax)	ss	movl	%ebx,PR_OFF_faultInfo-PR_OFF_FIXREGS(%eax)		jmp	kern_seg_load		/* 	 * Following code implements the string move probe portion of	 * the invocation.  It is out of line because slightly less than 	 * 50% of all invocations move a string	 */		/* INTERRUPTS MUST BE DISABLED ON ENTRY TO THIS FUNCTION */	.align 16ENTRY(resume_process)	pushl	%ebp	movl	%esp,%ebp	movl	0x8(%ebp),%esp	/*	 * We are now on our way back to whatever we interrupted.  If the	 * interrupt routine enabled interrupts, it was responsible for	 * disabling them before returning, so interrupts are now	 * disabled.	 *	 * %esp holds a pointer to the bottom of the context we are	 * restoring from.	 */	/*	 * Decrement the interrupt depth counter here.  Doing this from 	 * the assembly code eliminates the need to play sleazy games in 	 * the C part of the return path.	 */	decl	EXT(_3IRQ.DisableDepth);		/* ANY CHANGE TO THIS PATH FROM HERE DOWN SHOULD BE	   IMPLEMENTED IN THE FAST_GATE_PATH AS WELL */		/* PROCESS_SIZE */	leal	PR_OFF_INTR_SP(%ESP),%EDX	movl	%EDX,4+EXT(_3TSS.TaskTable)	/* PROCESS_SIZE */	addl	$PR_OFF_MappingTable,%ESP	/* find base of save area */	#if defined(DOMAIN_TRACING)	/* ESP POINTS TO BOTTOM OF SAVE AREA */	cmpl	$5,EXT(CpuType)	jb	1f		/* don't call it if not supported */		.byte 0x0f	.byte 0x31		/* RDTSC instr - results to %edx:%eax */		movl %eax,EXT(DomainTracingScratchpad)	movl %edx,EXT(DomainTracingScratchpad)+41:	#endif		/* Reload target address space:	 */	movl	%cr3,%ebx	#ifdef OPTION_SMALL_SPACES	cmpl	$0,PR_OFF_bias-PR_OFF_MappingTable(%esp)	jnz	1f#endif		cmpl	%ebx,(%esp)	je      1f		movl	(%esp),%ebx	movl	%ebx,%cr3  /* restore user address space */	1:	movl	%EBX,28+EXT(_3TSS.TaskTable)	movl	%ebx,(%esp)	addl	$4,%esp		popa	/*	 * Skip over the pushed error number and exception number:	 */      	addl	$8,%esp	/*	 * Reload the segment registers by reaching up past the critical 	 * stuff with movl  so that if we fault we always defecate at the	 * same point on the stack:	 */L_reload_es:		movl	FX_OFF_ES-FX_OFF_EIP(%esp),%esL_reload_ds:		movl	FX_OFF_DS-FX_OFF_EIP(%esp),%dsL_reload_fs:		movl	FX_OFF_FS-FX_OFF_EIP(%esp),%fsL_reload_gs:		movl	FX_OFF_GS-FX_OFF_EIP(%esp),%gs		/*	 * ONCE BELOW THIS POINT, ALL REFERENCES MUST BE TO THE CODE	 * OR STACK SEGMENTS.  BECAUSE DS NOW HOLDS THE USER DATA	 * SEGMENT, WE CANNOT TRUST THAT THE DATA SEGMENT IS VALID.	 */		/*	 

⌨️ 快捷键说明

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