home *** CD-ROM | disk | FTP | other *** search
/ ftp.ee.pdx.edu / 2014.02.ftp.ee.pdx.edu.tar / ftp.ee.pdx.edu / pub / users / Harry / Blitz / OSProject / p6 / Switch.s < prev    next >
Text File  |  2009-06-03  |  7KB  |  225 lines

  1. ! BLITZ OS - Switch.s
  2. !
  3. ! Harry Porter  -  12/07/03
  4. !                  03/24/09
  5. !
  6. ! The following functions are implemented in this file:
  7. !
  8.     .export    Switch
  9.     .export    ThreadStartUp
  10.     .export    GetOldUserPCFromSystemStack
  11.     .export    LoadPageTableRegs
  12.     .export SaveUserRegs
  13.     .export RestoreUserRegs
  14.     .export BecomeUserThread
  15. !
  16. ! The following functions are imported:
  17. !
  18.     .import    _P_Kernel_ThreadStartMain
  19.     .import    _P_Kernel_ThreadFinish
  20. !
  21.     .text
  22.  
  23.  
  24. ! ===============  ThreadStartUp  ===============
  25. ! external ThreadStartUp ()
  26. !
  27. ! This routine is where each Thread begins execution.  The Fork function
  28. ! will place the starting address of this routine into the Thread object
  29. ! so that Switch will "return" to this address, thereby making a jump to
  30. ! the first instruction of this routine.  This routine will initialize
  31. ! all registers needed by high-level KPL code (namely r12 & r14) and will
  32. ! then call the KPL function "ThreadStartMain".  ThreadStartMain will invoke
  33. ! the "main" function of the thread. ThreadStartMain  will never return.
  34. ThreadStartUp:
  35.         mov    r0,r14                ! Clear the FP register
  36.         mov    r0,r12                ! Clear the Catch Stack pointer
  37.         call    _P_Kernel_ThreadStartMain    ! Call ThreadStartMain
  38. ThreadHang:    debug                    ! Should never reach this point
  39.         jmp    ThreadHang            ! .
  40.  
  41.  
  42.  
  43. ! ===============  Switch  ===============
  44. ! external Switch (prevThread, nextThread: ptr to Thread)
  45. !
  46. ! This routine is passed ptrs to 2 Thread objects.  Each Thread object
  47. ! contains a place to store the state of the machine.  This includes:
  48. !    r2-r14
  49. !    stackTop (r15)
  50. ! This routine switches the state from one thread to the next and returns.
  51. ! Of course it will be returning to a different invocation, since the thread
  52. ! will have been switched.
  53. !
  54. ! This routine trashes r1.
  55. Switch:
  56.         load    [r15+4],r1        ! Move the prevThread into r1
  57.         add    r1,16,r1        ! Make r1 point to r1.regs
  58.         store    r2,[r1+0]        ! Save r2..r14 in r1.regs
  59.         store    r3,[r1+4]        ! .
  60.         store    r4,[r1+8]        ! .
  61.         store    r5,[r1+12]        ! .
  62.         store    r6,[r1+16]        ! .
  63.         store    r7,[r1+20]        ! .
  64.         store    r8,[r1+24]        ! .
  65.         store    r9,[r1+28]        ! .
  66.         store    r10,[r1+32]        ! .
  67.         store    r11,[r1+36]        ! .
  68.         store    r12,[r1+40]        ! .
  69.         store    r13,[r1+44]        ! .
  70.         store    r14,[r1+48]        ! .
  71.         store    r15,[r1+52]        ! Save r15 in r1.stackTop
  72.  
  73.         load    [r15+8],r1        ! Move the nextThread into r1
  74.         add    r1,16,r1        ! Make r1 point to r1.regs
  75.         load    [r1+0],r2        ! Restore r2..r14 from r1.regs
  76.         load    [r1+4],r3        ! .
  77.         load    [r1+8],r4        ! .
  78.         load    [r1+12],r5        ! .
  79.         load    [r1+16],r6        ! .
  80.         load    [r1+20],r7        ! .
  81.         load    [r1+24],r8        ! .
  82.         load    [r1+28],r9        ! .
  83.         load    [r1+32],r10        ! .
  84.         load    [r1+36],r11        ! .
  85.         load    [r1+40],r12        ! .
  86.         load    [r1+44],r13        ! .
  87.         load    [r1+48],r14        ! .
  88.         load    [r1+52],r15        ! Restore r15 from r1.stackTop
  89.         ret
  90.  
  91.  
  92.  
  93. ! ===============  GetOldUserPCFromSystemStack  ===============
  94. ! external GetOldUserPCFromSystemStack () returns int
  95. !
  96. ! This routine is called by the kernel after a syscall has occurred.  It expects
  97. ! the assembly SyscallTrapHandler to have called the high-level SyscallTrapHandler,
  98. ! which then called Handle_Sys_Fork.  It expects to be called from Handle_Sys_Fork,
  99. ! and will not work properly otherwise.
  100. !
  101. ! This routine looks down into stuff buried in the system stack and finds the
  102. ! exception block that was pushed onto the stack at the time of the syscall.
  103. ! From that, it retrieves the user-mode PC, which points to the instruction
  104. ! the kernel must return to after the syscall.
  105. GetOldUserPCFromSystemStack:
  106.         load    [r14],r1        ! r1 = ptr to frame of SyscallTrapHandler
  107.         load    [r1+28],r1        ! r1 = pc from interrupt block
  108.         store    r1,[r15+4]
  109.         ret
  110.  
  111.  
  112.  
  113. ! =====================  LoadPageTableRegs  =====================
  114. ! external LoadPageTableRegs (ptbr, ptlr: int)
  115. !
  116. ! This routine will load the Page Table Base Register (PTBR) and the
  117. ! Page Table Length Register (PTLR).
  118. LoadPageTableRegs:
  119.         load    [r15+4],r1    ! Get arg1
  120.         ldptbr    r1        ! Move it to PTBR
  121.         load    [r15+8],r1    ! Get arg2
  122.         ldptlr    r1        ! Move it to PTLR
  123.         ret            ! return
  124.  
  125.  
  126.  
  127. ! =====================  SaveUserRegs  =====================
  128. ! external SaveUserRegs (ptr to int)
  129. !
  130. ! This routine is passed a pointer to a block of memory.  It is called
  131. ! while in System Mode.  It copies the user registers to the block of memory.
  132. !
  133. SaveUserRegs:
  134.         load    [r15+4],r1        ! Move ptr to memory into r1
  135.         readu    r1,[r1+0]        ! Copy user registers to memory
  136.         readu    r2,[r1+4]        ! .
  137.         readu    r3,[r1+8]        ! .
  138.         readu    r4,[r1+12]        ! .
  139.         readu    r5,[r1+16]        ! .
  140.         readu    r6,[r1+20]        ! .
  141.         readu    r7,[r1+24]        ! .
  142.         readu    r8,[r1+28]        ! .
  143.         readu    r9,[r1+32]        ! .
  144.         readu    r10,[r1+36]        ! .
  145.         readu    r11,[r1+40]        ! .
  146.         readu    r12,[r1+44]        ! .
  147.         readu    r13,[r1+48]        ! .
  148.         readu    r14,[r1+52]        ! .
  149.         readu    r15,[r1+56]        ! .
  150.         ret                ! Return
  151.  
  152.  
  153.  
  154. ! =====================  RestoreUserRegs  =====================
  155. ! external RestoreUserRegs (ptr to int)
  156. !
  157. ! This routine is passed a pointer to a block of memory.  It is called
  158. ! while in System Mode.  It copies data from memory into the user registers.
  159. !
  160. RestoreUserRegs:
  161.         load    [r15+4],r1        ! Move ptr to memory into r1
  162.         writeu    [r1+0],r1        ! Copy data to user registers
  163.         writeu    [r1+4],r2        ! .
  164.         writeu    [r1+8],r3        ! .
  165.         writeu    [r1+12],r4        ! .
  166.         writeu    [r1+16],r5        ! .
  167.         writeu    [r1+20],r6        ! .
  168.         writeu    [r1+24],r7        ! .
  169.         writeu    [r1+28],r8        ! .
  170.         writeu    [r1+32],r9        ! .
  171.         writeu    [r1+36],r10        ! .
  172.         writeu    [r1+40],r11        ! .
  173.         writeu    [r1+44],r12        ! .
  174.         writeu    [r1+48],r13        ! .
  175.         writeu    [r1+52],r14        ! .
  176.         writeu    [r1+56],r15        ! .
  177.         ret                ! Return
  178.  
  179.  
  180.  
  181. ! =====================  BecomeUserThread  =====================
  182. ! external BecomeUserThread (initStack, initPC, initSystemStack: int)
  183. !
  184. ! This routine changes the mode from system-mode to user-mode.  It
  185. ! also enables interrupts and paging.  It is passed the initial value
  186. ! for the user stack and the initial address to branch to.  The user
  187. ! thread will never "return" (it must execute something like
  188. ! Syscall_Exit).  However, the user thread will execute syscalls from
  189. ! time to time.  Thus, the system stack as it exists now will be pushed
  190. ! onto when ever this thread does a syscall.
  191. !
  192. ! Note that 0x00000020 is a StatusRegister (interrupts, user mode, paging off).
  193. ! Note that 0x00000028 is a StatusRegister (interrupts, user mode, paging on).
  194. !
  195. BecomeUserThread:
  196.         load    [r15+4],r3        ! r3 := initStack
  197.         writeu    r3,r15            ! Store stack-ptr in user reg r15
  198.         load    [r15+8],r2        ! Move initPC into r2
  199.         load    [r15+12],r15        ! Move initSystemStack into r15
  200.         push    r0            ! Push a fake interrupt block
  201.         mov    0x00000028,r4        ! .  onto the system stack
  202.         push    r4            ! .
  203.         push    r2            ! .
  204.         clr    r1            ! Set user reg r1 to zero
  205.         writeu    r1,r1            ! .
  206.         reti                ! "return" from interrupt
  207.