📄 low.s
字号:
! 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 + -