home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / arch / mips / kernel / resume.S < prev    next >
Encoding:
Text File  |  1995-01-25  |  5.2 KB  |  251 lines

  1. /*
  2.  *  linux/kernel/mips/sys_call.S
  3.  *
  4.  *  Copyright (C) 1994, 1995 Waldorf Electronics
  5.  *  written by Ralf Baechle
  6.  */
  7.  
  8. /*
  9.  * sys_call.S  contains the system-call and fault low-level handling routines.
  10.  * This also contains the timer-interrupt handler, as well as all interrupts
  11.  * and faults that can result in a task-switch.
  12.  */
  13.  
  14. #include <asm/regdef.h>
  15. #include <asm/processor.h>
  16. #include <asm/mipsregs.h>
  17. #include <asm/mipsconfig.h>
  18.  
  19. /*
  20.  * These are offsets into the task-struct.
  21.  */
  22. state        =  0
  23. counter        =  4
  24. priority    =  8
  25. signal        = 12
  26. blocked        = 16
  27. flags        = 20
  28. errno        = 24            #/* MIPS OK */
  29. exec_domain    = 60            #/* ??? */
  30.  
  31. ENOSYS        = 38
  32.  
  33. /*
  34.  * Code necessary to switch tasks on an Linux/MIPS machine.
  35.  */
  36. MODE_ALIAS    =    0x0016            # uncachable
  37.  
  38.         .text
  39.         .set    noreorder
  40.         .set    at
  41.  
  42.         .globl    _resume
  43. _resume:
  44.         /*
  45.          * current task's task_struct
  46.          */
  47.         lui    t5,%hi(_current)
  48.         lw    t0,%lo(_current)(t5)
  49.  
  50.         /*
  51.          * Save status register
  52.          */
  53.         mfc0    t1,CP0_STATUS
  54.         addu    t0,a1            # Add tss offset
  55.         sw    t1,TOFF_CP0_STATUS(t0)
  56.  
  57.         /*
  58.          * Disable interrupts
  59.          */
  60.         ori    t2,t1,0x1f
  61.         xori    t2,0x1e
  62.         mtc0    t2,CP0_STATUS
  63.  
  64.         /*
  65.          * Save non-scratch registers
  66.          * All other registers have been saved on the kernel stack
  67.          */
  68.         sw    s0,TOFF_REG16(t0)
  69.         sw    s1,TOFF_REG17(t0)
  70.         sw    s2,TOFF_REG18(t0)
  71.         sw    s3,TOFF_REG19(t0)
  72.         sw    s4,TOFF_REG20(t0)
  73.         sw    s5,TOFF_REG21(t0)
  74.         sw    s6,TOFF_REG22(t0)
  75.         sw    s7,TOFF_REG23(t0)
  76.         sw    gp,TOFF_REG28(t0)
  77.         sw    sp,TOFF_REG29(t0)
  78.         sw    fp,TOFF_REG30(t0)
  79.         sw    ra,TOFF_REG31(t0)
  80.  
  81.         /*
  82.          * Save floating point state
  83.          */
  84.         srl    t2,t1,29
  85.         andi    t2,1
  86.         beqz    t2,2f
  87.         srl    t2,t1,26
  88.         andi    t2,1
  89.         beqz    t2,1f
  90.         sdc1    $f0,(TOFF_FPU+0)(t0)    # delay slot
  91.         /*
  92.          * Store the 16 odd double precision registers
  93.          */
  94.         sdc1    $f1,(TOFF_FPU+8)(t0)
  95.         sdc1    $f3,(TOFF_FPU+24)(t0)
  96.         sdc1    $f5,(TOFF_FPU+40)(t0)
  97.         sdc1    $f7,(TOFF_FPU+56)(t0)
  98.         sdc1    $f9,(TOFF_FPU+72)(t0)
  99.         sdc1    $f11,(TOFF_FPU+88)(t0)
  100.         sdc1    $f13,(TOFF_FPU+104)(t0)
  101.         sdc1    $f15,(TOFF_FPU+120)(t0)
  102.         sdc1    $f17,(TOFF_FPU+136)(t0)
  103.         sdc1    $f19,(TOFF_FPU+152)(t0)
  104.         sdc1    $f21,(TOFF_FPU+168)(t0)
  105.         sdc1    $f23,(TOFF_FPU+184)(t0)
  106.         sdc1    $f25,(TOFF_FPU+200)(t0)
  107.         sdc1    $f27,(TOFF_FPU+216)(t0)
  108.         sdc1    $f29,(TOFF_FPU+232)(t0)
  109.         sdc1    $f31,(TOFF_FPU+248)(t0)
  110.  
  111.         /*
  112.          * Store the 16 even double precision registers
  113.          */
  114. 1:        cfc1    t1,$31
  115.         sdc1    $f2,(TOFF_FPU+16)(t0)
  116.         sdc1    $f4,(TOFF_FPU+32)(t0)
  117.         sdc1    $f6,(TOFF_FPU+48)(t0)
  118.         sdc1    $f8,(TOFF_FPU+64)(t0)
  119.         sdc1    $f10,(TOFF_FPU+80)(t0)
  120.         sdc1    $f12,(TOFF_FPU+96)(t0)
  121.         sdc1    $f14,(TOFF_FPU+112)(t0)
  122.         sdc1    $f16,(TOFF_FPU+128)(t0)
  123.         sdc1    $f18,(TOFF_FPU+144)(t0)
  124.         sdc1    $f20,(TOFF_FPU+160)(t0)
  125.         sdc1    $f22,(TOFF_FPU+176)(t0)
  126.         sdc1    $f24,(TOFF_FPU+192)(t0)
  127.         sdc1    $f26,(TOFF_FPU+208)(t0)
  128.         sdc1    $f28,(TOFF_FPU+224)(t0)
  129.         sdc1    $f30,(TOFF_FPU+240)(t0)
  130.         sw    t1,(TOFF_FPU+256)(t0)
  131.  
  132.         /*
  133.          * Switch current task
  134.          */
  135. 2:        sw    a0,%lo(_current)(t5)
  136.         addu    a0,a1            # Add tss offset
  137.  
  138.         /*
  139.          * Switch address space
  140.          */
  141.  
  142.         /*
  143.          * (Choose new ASID for process)
  144.          */
  145.  
  146.         /*
  147.          * Switch the root pointer
  148.          */
  149.         lw    t0,TOFF_PG_DIR(a0)
  150.         la    t1,TLB_ROOT
  151.         mtc0    t1,CP0_ENTRYHI
  152.         mtc0    zero,CP0_INDEX
  153.         srl    t0,6
  154.         ori    t0,MODE_ALIAS
  155.         mtc0    t0,CP0_ENTRYLO0
  156.         mtc0    zero,CP0_ENTRYLO1
  157.         tlbwi
  158.  
  159.         /*
  160.          * Flush tlb (probably not needed)
  161.          * (Doesn't clobber a0-a3)
  162.          */
  163.         jal    _tlbflush
  164.         nop                     # delay slot
  165.  
  166.         lw    a2,TOFF_CP0_STATUS(a0)
  167.  
  168.         /*
  169.          * Restore fpu state:
  170.          *  - cp0 status register bits
  171.          *  - fp gp registers
  172.          *  - cp1 status/control register
  173.          */
  174.         ori    t1,a2,1                # pipeline magic
  175.         xori    t1,1
  176.         mtc0    t1,CP0_STATUS
  177.         srl    t0,a2,29
  178.         andi    t0,1
  179.         beqz    t0,2f
  180.         srl    t0,a2,26
  181.         andi    t0,1
  182.         beqz    t0,1f
  183.         ldc1    $f0,(TOFF_FPU+0)(a0)    # delay slot
  184.         /*
  185.          * Restore the 16 odd double precision registers only
  186.          * when enabled in the cp0 status register.
  187.          */
  188.         ldc1    $f1,(TOFF_FPU+8)(a0)
  189.         ldc1    $f3,(TOFF_FPU+24)(a0)
  190.         ldc1    $f5,(TOFF_FPU+40)(a0)
  191.         ldc1    $f7,(TOFF_FPU+56)(a0)
  192.         ldc1    $f9,(TOFF_FPU+72)(a0)
  193.         ldc1    $f11,(TOFF_FPU+88)(a0)
  194.         ldc1    $f13,(TOFF_FPU+104)(a0)
  195.         ldc1    $f15,(TOFF_FPU+120)(a0)
  196.         ldc1    $f17,(TOFF_FPU+136)(a0)
  197.         ldc1    $f19,(TOFF_FPU+152)(a0)
  198.         ldc1    $f21,(TOFF_FPU+168)(a0)
  199.         ldc1    $f23,(TOFF_FPU+184)(a0)
  200.         ldc1    $f25,(TOFF_FPU+200)(a0)
  201.         ldc1    $f27,(TOFF_FPU+216)(a0)
  202.         ldc1    $f29,(TOFF_FPU+232)(a0)
  203.         ldc1    $f31,(TOFF_FPU+248)(a0)
  204.  
  205.         /*
  206.          * Restore the 16 even double precision registers always
  207.          * when cp1 was enabled in the cp0 status register.
  208.          */
  209. 1:        lw    t0,(TOFF_FPU+256)(a0)
  210.         ldc1    $f2,(TOFF_FPU+16)(a0)
  211.         ldc1    $f4,(TOFF_FPU+32)(a0)
  212.         ldc1    $f6,(TOFF_FPU+48)(a0)
  213.         ldc1    $f8,(TOFF_FPU+64)(a0)
  214.         ldc1    $f10,(TOFF_FPU+80)(a0)
  215.         ldc1    $f12,(TOFF_FPU+96)(a0)
  216.         ldc1    $f14,(TOFF_FPU+112)(a0)
  217.         ldc1    $f16,(TOFF_FPU+128)(a0)
  218.         ldc1    $f18,(TOFF_FPU+144)(a0)
  219.         ldc1    $f20,(TOFF_FPU+160)(a0)
  220.         ldc1    $f22,(TOFF_FPU+176)(a0)
  221.         ldc1    $f24,(TOFF_FPU+192)(a0)
  222.         ldc1    $f26,(TOFF_FPU+208)(a0)
  223.         ldc1    $f28,(TOFF_FPU+224)(a0)
  224.         ldc1    $f30,(TOFF_FPU+240)(a0)
  225.         ctc1    t0,$31
  226.  
  227.         /*
  228.          * Restore non-scratch registers
  229.          */
  230. 2:        lw    s0,TOFF_REG16(a0)
  231.         lw    s1,TOFF_REG17(a0)
  232.         lw    s2,TOFF_REG18(a0)
  233.         lw    s3,TOFF_REG19(a0)
  234.         lw    s4,TOFF_REG20(a0)
  235.         lw    s5,TOFF_REG21(a0)
  236.         lw    s6,TOFF_REG22(a0)
  237.         lw    s7,TOFF_REG23(a0)
  238.         lw    gp,TOFF_REG28(a0)
  239.         lw    sp,TOFF_REG29(a0)
  240.         lw    fp,TOFF_REG30(a0)
  241.         lw    ra,TOFF_REG31(a0)
  242.  
  243.         /*
  244.          * Restore status register
  245.          */
  246.         lw    t0,TOFF_KSP(a0)
  247.         sw    t0,_kernelsp
  248.  
  249.         jr    ra
  250.         mtc0    a2,CP0_STATUS            # delay slot
  251.