low.s

Upload User: acmefrp
Upload Date: 2010-03-06
Package Size: 23768k
Code Size: 5k
Category: OS Develop
Development Platform: C/C++
  1. .seg "data"
  2. .asciz  "@(#) low.s 1.1 92/07/30"
  3. .align 4
  4. .seg "text"
  5. ! Copyright (C) 1987 by Sun Microsystems, Inc.
  6. #include <sun4/trap.h>
  7. #include <sun4/asm_linkage.h>
  8. #include <sun4/psl.h>
  9. #include <machlwp/low.h>
  10. #include "assym.s"
  11. .seg "text"
  12. .global  ___schedule
  13. .global  ___Curproc
  14. .global  ___NuggetSP
  15. .global ___lwpkill
  16. ! assembly language support routines
  17. !
  18. ! %sp (%o6) is stack pointer and points to register save area for current win.
  19. ! %i7 is return address (ret will add 8 to be correct) to caller.
  20. ! %o7 is return address from call of leaf routine (use retl).
  21. ! %fp (%i6) points to previous frame.
  22. ! %g's are treated as temps by the compiler -- if they become truely global,
  23. ! it may not be nec. to save/restore all of them since they behave like
  24. ! shared memory.
  25. ! %sp must point to a valid save area (16 words) when save is called.
  26. ! %fp must point to a valid save area (16 words) when restore is called.
  27. ! save/restore use %src in old window and %dst in new window
  28. ! %sp MUST ALWAYS be valid. If you try to to sigcleanup() or restore
  29. ! with a funky %sp, the kernel will do strange things. Note that
  30. ! C assumes a valid %fp and can generate access to addresses above it.
  31. ! __checkpoint()
  32. ! Save context and reschedule.
  33. ! The return address to the caller of checkpoint is in %o7.
  34. ! Eventually, schedule calls swtch which
  35. ! returns to the caller of checkpoint.
  36. ! locals and ins are saved in register save area.
  37. ! Since we call checkpoint voluntarily, %g's, %o's and %y need not be saved.
  38. !
  39. LENTRY(checkpoint)
  40. mov %psr, %g2 ! save the psr
  41. or %g2, PSR_PIL, %g1 ! splhigh
  42. mov %g1, %psr
  43. nop; nop
  44. sethi %hi(___Curproc), %o2
  45. ld [%o2 + %lo(___Curproc)], %o1 ! %o1 = __Curproc
  46. st %o7, [%o1+PC_OFFSET] ! pc when this thread resumes
  47. st %sp, [%o1+SP_OFFSET] ! save sp
  48. save %sp, -SA(MINFRAME), %sp
  49. call _flush_windows ! save all registers
  50. nop
  51. sethi %hi(___NuggetSP), %o1 ! get nugget stack
  52. ld [%o1 + %lo(___NuggetSP)], %fp ! switch stacks
  53. mov %psr, %g1 ! restore processor priority
  54. andn %g1, PSR_PIL, %g1
  55. and %g2, PSR_PIL, %g2
  56. or %g1, %g2, %g2
  57. mov %g2, %psr
  58. ba ___schedule + 4 ! add 4 to skip save at the beginning
  59. sub %fp, SA(MINFRAME), %sp ! safely switch
  60. nop
  61. ! NOTREACHED
  62. ! __swtch()
  63. ! Restore to pc and sp. Switch to new thread. Although this code is called 
  64. ! in __schedule, there are 2 circumstances. First, when the thread runs the 
  65. ! first  time, and secondly when checkpoint branches schedule which then 
  66. ! calls  __swtch
  67. ! We are splling while changing sp and pc. Note a side effect of 
  68. ! flush windows is to set the WIM to be CWP + 1. The restore causes an
  69. ! underflow which moves the previously saved in's and locals from memory to
  70. ! the register file. The outs are the current window's ins.
  71. !
  72. LENTRY(swtch)
  73. mov %psr, %g2 ! save the psr
  74. or %g2, PSR_PIL, %g1 ! splhigh
  75. mov %g1, %psr
  76. nop; nop
  77. save %sp, -SA(MINFRAME), %sp
  78. call _flush_windows
  79. nop
  80. sethi %hi(___Curproc), %o2
  81. ld [%o2 + %lo(___Curproc)], %o1 ! %o1 = __Curproc
  82. ld [%o1+PC_OFFSET], %i7 ! restore pc into HIS %o7
  83. ld [%o1+SP_OFFSET], %fp ! restore sp into HIS %o6
  84. mov %psr, %g1 ! restore processor priority
  85. andn %g1, PSR_PIL, %g1
  86. and %g2, PSR_PIL, %g2
  87. or %g1, %g2, %g2
  88. mov %g2, %psr
  89. nop; nop
  90. restore ! checkpoint
  91. ! get back to the window where
  92. ! checkpoint was called, with underflow
  93. ! restoring %i's and %l's
  94. ! ASSERT(%sp is valid) before restore
  95. 1: retl ! jump to lowinit or back to caller of
  96. nop
  97. ! __lowinit()
  98. ! Control gets here from returning from swtch() the first time a thread runs.
  99. ! We copy the %i's (parameters to thread initial routine) to the %o's
  100. ! to make it look like we are calling the thread with these args.
  101. ! The frame is already set up to have any additional args on it, etc.
  102. !
  103. LENTRY(lowinit)
  104. mov %i0, %o0 ! put parameters to right place
  105. mov %i1, %o1
  106. mov %i2, %o2
  107. mov %i3, %o3
  108. mov %i4, %o4
  109. mov %i5, %o5
  110. set ___lwpkill - 8, %o7 ! When dying, go here: %i7 of thread
  111. jmp %i7 ! load pc
  112. mov %i6, %o6 !  and sp
  113. ! __stacksafe()
  114. ! __stacksafe returns 1 if the stack is safe, else 0.
  115. ! "safe" means that the sp is not below the
  116. ! base of the stack (___CurStack + CKSTKOVERHEAD).
  117. ! It is used by check macro.
  118. !
  119. LENTRY(stacksafe)
  120. sethi %hi(___CurStack), %o1 ! CurStack is cur. thread stack bottom
  121. ld [%lo(___CurStack) + %o1], %o2 ! %o2 = __CurStack
  122. sethi %hi(CKSTKOVERHEAD), %o3
  123. or %o3, %lo(CKSTKOVERHEAD), %o3
  124. add %o2, %o3, %o2 ! if stack is shrunk by CKSTKOVERHEAD
  125. cmp %sp, %o2 ! %sp - %o2 > 0 means safe
  126. bg 1f
  127. retl
  128. mov %g0, %o0 ! not safe, return 0
  129. 1: retl
  130. mov 1, %o0 ! safe, return 1
  131. ! __setstack()
  132. ! Give the nugget a stack to use when no lwps are running
  133. ! Flush is necessary in case we later remove stack, nugget
  134. ! overflows its windows, and tries to flush.
  135. !
  136. LENTRY(setstack)
  137. sethi %hi(___NuggetSP), %o1
  138. retl
  139. ld [%lo(___NuggetSP) + %o1], %sp