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

📄 low.s

📁 操作系统SunOS 4.1.3版本的源码
💻 S
📖 第 1 页 / 共 2 页
字号:
!	12: old pc!	16: old npc!	20: old psr!	24: old g1!	28: old o0!! We are in the old window with windows flushed. We first do a save in which we! bump the sp down by enough to have an area to save the old globals (%g2-%g7)! and the normal frame. We don't save fp state here (32 fp regs, %fsr).! We aren't allowed to clobber anything (like globals) in Curproc if LOCKED,! so we have to (potentially) copy globals twice: once on the stack, another! time in the lwp context if not in a critical section.! E.g., suppose we are LOCKED in lwp_setregs. An interrupt would then change! the values we wanted to set if we stored state directly into the context.! We could optimise this further by testing for LOCKED here; if not! locked, then we could store the registers directly into the context (XXX).! The %i's and %l's of the interrupted process were flushed by UNIX:! the interrupted guy's windows were flushed.! We need to save globals and interrupted guy's %o's (my %i's).! We pass real_sig the address of the saved registers so it can copy them! into the context if not LOCKED.! This would all be better if UNIX passed us all of the registers in the! sigcontext.! Note that we don't need to restore the %o's if we return immediately! since we don't touch %i's (after save, his %o's) here and! if we return there is no need to save state. If we don't return,! because the interrupt stack is not part of context, we must save the %o's.!LENTRY(interrupt)	save	%sp, -(SA(MINFRAME)+SA(7*8)), %sp ! make frame on (new) stack						! and avoid touching his %o's	std	%g2, [%sp + SA(MINFRAME)+(0*8)] ! save globals and o's	std	%g4, [%sp + SA(MINFRAME)+(1*8)]	std	%g6, [%sp + SA(MINFRAME)+(2*8)]	std	%i0, [%sp + SA(MINFRAME)+(3*8)]	std	%i2, [%sp + SA(MINFRAME)+(4*8)]	std	%i4, [%sp + SA(MINFRAME)+(5*8)]	std	%i6, [%sp + SA(MINFRAME)+(6*8)]	ld	[%fp + 64], %o0		! get signal number	ld	[%fp + 68], %o1		! get code	ld	[%fp + 72], %o2		! get ptr to sigcontext	ld	[%fp + 76], %o3		! get addr	clr	%o4	mov	%y, %l1	mov	%l1, %o5	call	___real_sig	! __real_sig(sig,code,&sc,addr,regaddr,%y)	add	%sp, (SA(MINFRAME) + (0*8)), %o4	! address of saved %'s	! MAYRETURN	! Restore state if needed -- e.g., if LOCKED.	mov	%l1, %y	ld	[%fp + 72], %i0		! set sigcontext-> in %o0 of old window	ldd	[%sp + SA(MINFRAME)+(0*8)], %g2 ! restore globals	ldd	[%sp + SA(MINFRAME)+(1*8)], %g4	ldd	[%sp + SA(MINFRAME)+(2*8)], %g6! note that I'm in his (interrupted guy's) window. Thus, sigcleanup! needs to restore %o0 used for sigcontext arg. %g1 is used for syscall #'s! so it is also part of the sigcontext.	restore	%g0, 139, %g1		! sigcleanup system call	ta	ST_SYSCALL		! in old window now	unimp	0			! just in case it returns	/*NOTREACHED*/! __rti()! rti() is called from full_swtch().! Don't touch %o6 -- it will be reset by sigcleanup and we need! a valid stack to run on now.! Restore %g's and %o's and let sigcleanup restore everything else.! We're in the same window before and after calling sigcleanup.!LENTRY(rti)	sethi	%hi(___Curproc), %l5	ld	[%lo(___Curproc) + %l5], %l4	! %l4 = __Curproc	ldd	[%l4+G2_OFFSET+(0*8)], %g2	! restore %g;s and %o's	ldd	[%l4+G2_OFFSET+(1*8)], %g4	ldd	[%l4+G2_OFFSET+(2*8)], %g6	ldd	[%l4+O0_OFFSET+(0*8)], %o0;	ldd	[%l4+O0_OFFSET+(1*8)], %o2;	ldd	[%l4+O0_OFFSET+(2*8)], %o4;	ld	[%l4+O0_OFFSET+(3*8)+4], %o7;	ld	[%l4+Y_OFFSET], %g1;	mov	%g1, %y	set	___Context, %o0		! argument to sigccleanup	mov	139, %g1		! sigcleanup call	ta	ST_SYSCALL	unimp	0	! NOTREACHED! __exc_longjmp(pattern, sp, pc)! flush windows so we can fault in his window set.! restore his sp and pc and restore to underflow into the window! of the corresponding exc_handle.LENTRY(exc_longjmp)	ta	ST_FLUSH_WINDOWS	mov	%o1, %fp		! restore sp in previous window (%o6)	sub	%fp, WINDOWSIZE, %sp	! paranoid	mov	%o2, %o7	retl	restore				! o0 is return value! exc_jmpandclean(pattern, sp, pc, prevretadr)! same as exc_longjmp, but restore the saved return address! (which was replaced by exc_cleanup). LENTRY(exc_jmpandclean)	ta	ST_FLUSH_WINDOWS	mov	%o0, %i0		! return value	mov	%o1, %i6		! restore sp in previous window (%o6)	mov	%o2, %i7		! set up his retl	mov	%o3, %i5		! his saved return pc	restore				! underflow into his window	retl				! reset his PC	mov	%o5, %i7		! reset his real return address! __exccleanup()! When an exit or exception handler is installed, this routine ! replaces the normal return address. It will call exchelpclean()! to flush exception handlers at or below our level, reinstall! the correct return pc (supplied by exchelpclean()), and return! normally.LENTRY(exccleanup)	save	%sp, -SA(MINFRAME), %sp	! let's be a real procedure (not a leaf)					! to preserve real return value too	call	___exchelpclean		! this guy restores the return addr	nop	mov	%o0, %i7		! put return addr to where it should be	ret				! return normally	restore! __exc_getclient()! A client routine C called an exception handling routine E.! E can get C's return address (pointing at the call instruction -- need! to add 8 to it) and C's sp into the globals __ClientSp and __ClientRetAdr! respectively.! We flush the windows so the exception code can grovel around in! the saved register areas of old client frames.!LENTRY(exc_getclient)	ta	ST_FLUSH_WINDOWS	set	___ClientSp, %o0	! %fp(%i6) == caller's sp	st	%fp, [%o0]	set	___ClientRetAdr, %o0	! %i7 == caller's ret. addr	retl	st	%i7, [%o0]! __sparcfpp_save(vec)! routines to save the floating point state: %fsr, 32 fp regs.! The vec arg points to a struct containing 16 doubles for the %f's,! and a long for the %fsr.! There is a problem here in that saving the fsr could expose a! fp exception in the fpa queue. As a result, we could generate! the exception for the wrong thread if special contexts are optimised! for the fpa. We take the easy way out and don't optimise.! We should be fancy and see if __Curproc == self. If not,! pend the trap for self. To pend the trap, use save_event.! Save fsr first to cause fpu to reach equiblibrium.! XXX May need to make save_event part of the interface.LENTRY(sparcfpp_save)	st	%fsr, [%o0 + (16*8)]	! save %fsr FIRST	std	%f0, [%o0 + (0*8)]	! save all fp registers	std	%f2, [%o0 + (1*8)]	std	%f4, [%o0 + (2*8)]	std	%f6, [%o0 + (3*8)]	std	%f8, [%o0 + (4*8)]	std	%f10, [%o0 + (5*8)]	std	%f12, [%o0 + (6*8)]	std	%f14, [%o0 + (7*8)]	std	%f16, [%o0 + (8*8)]	std	%f18, [%o0 + (9*8)]	std	%f20, [%o0 + (10*8)]	std	%f22, [%o0 + (11*8)]	std	%f24, [%o0 + (12*8)]	std	%f26, [%o0 + (13*8)]	std	%f28, [%o0 + (14*8)]	retl	std	%f30, [%o0 + (15*8)]! __sparcfpp_restore(vec)! restore floating point stateLENTRY(sparcfpp_restore)	ldd	[%o0 + (0*8)], %f0	! restore all fp registers	ldd	[%o0 + (1*8)], %f2	ldd	[%o0 + (2*8)], %f4	ldd	[%o0 + (3*8)], %f6	ldd	[%o0 + (4*8)], %f8	ldd	[%o0 + (5*8)], %f10	ldd	[%o0 + (6*8)], %f12	ldd	[%o0 + (7*8)], %f14	ldd	[%o0 + (8*8)], %f16	ldd	[%o0 + (9*8)], %f18	ldd	[%o0 + (10*8)], %f20	ldd	[%o0 + (11*8)], %f22	ldd	[%o0 + (12*8)], %f24	ldd	[%o0 + (13*8)], %f26	ldd	[%o0 + (14*8)], %f28	ldd	[%o0 + (15*8)], %f30	retl	ld	[%o0 + (16*8)], %fsr! __sigtrap()! If traps are handled, return here instead of real client return address! from the UNIX signal.! On the client stack we pushed the real return pc and the signal number. ! Call exc_trap(signum) to raise the exception.! Then, pop the args real_sig() pushed on the stack and restore the! real return address.LENTRY(sigtrap)	save	%sp, -SA(MINFRAME), %sp	! save to avoid messing up client's %o's	ld	[%fp], %o0		! signum is at %fp->	call	___exc_trap		! process the trap	ld	[%fp + 4], %l1		! interrupted user pc	add	%fp, 8, %fp		! pop signum and pc from user stack	mov	%o0, %i0		! return value from sigtrap	jmp	%l1			! return normally	restore				! and return to client's window! __stacksafe()! __stacksafe returns 1 if the stack is safe, else 0.! "safe" means that the sp is not below the! base of the stack (___CurStack + CKSTKOVERHEAD). ! It is used by CHECK macro.! LENTRY(stacksafe)	sethi	%hi(___CurStack), %o1	! CurStack is current thread stack bottom	ld	[%lo(___CurStack) + %o1], %o2		! %o2 = __CurStack	sethi	%hi(CKSTKOVERHEAD), %o3	or	%o3, %lo(CKSTKOVERHEAD), %o3	add	%o2, %o3, %o2		! if stack is shrunk by CKSTKOVERHEAD	cmp	%sp, %o2		! %sp - %o2 > 0 means safe	bg	1f	retl	mov	%g0, %o0		! not safe, return 01:	retl	mov	1, %o0			! safe, return 1

⌨️ 快捷键说明

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