r4k_switch.S
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1994, 1995, 1996, 1998, 1999 by Ralf Baechle
  7.  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  8.  * Copyright (C) 1994, 1995, 1996, by Andreas Busse
  9.  * Copyright (C) 1999 Silicon Graphics, Inc.
  10.  * Copyright (C) 2000 MIPS Technologies, Inc.
  11.  *    written by Carsten Langgaard, carstenl@mips.com
  12.  */
  13. #include <linux/config.h>
  14. #include <asm/asm.h>
  15. #include <asm/cachectl.h>
  16. #include <asm/current.h>
  17. #include <asm/fpregdef.h>
  18. #include <asm/mipsregs.h>
  19. #include <asm/offset.h>
  20. #include <asm/page.h>
  21. #include <asm/pgtable-bits.h>
  22. #include <asm/processor.h>
  23. #include <asm/regdef.h>
  24. #include <asm/stackframe.h>
  25. #include <asm/asmmacro.h>
  26. /*
  27.  * task_struct *r4xx0_resume(task_struct *prev, task_struct *next)
  28.  */
  29. .set noreorder
  30. .align 5
  31. LEAF(resume)
  32. #ifndef CONFIG_CPU_HAS_LLSC
  33. sw      zero, ll_bit
  34. #endif
  35. mfc0 t1, CP0_STATUS
  36. sw t1, THREAD_STATUS(a0)
  37. CPU_SAVE_NONSCRATCH(a0)
  38. sw ra, THREAD_REG31(a0)
  39. /*
  40.  * The order of restoring the registers takes care of the race
  41.  * updating $28, $29 and kernelsp without disabling ints.
  42.  */
  43. move $28, a1
  44. CPU_RESTORE_NONSCRATCH($28)
  45. addiu t0, $28, KERNEL_STACK_SIZE-32
  46. #ifdef CONFIG_SMP
  47. mfc0 a3, CP0_CONTEXT
  48. la t1, kernelsp
  49. srl a3, 23
  50. sll a3, 2
  51. addu t1, a3, t1
  52. sw t0, (t1)
  53. #else
  54. sw t0, kernelsp
  55. #endif
  56. mfc0 t1, CP0_STATUS /* Do we really need this? */
  57. li a3, 0xff00
  58. and t1, a3
  59. lw a2, THREAD_STATUS($28)
  60. nor a3, $0, a3
  61. and a2, a3
  62. or a2, t1
  63. mtc0 a2, CP0_STATUS
  64. jr ra
  65.  move v0, a0
  66. END(resume)
  67. /*
  68.  * Do lazy fpu context switch.  Saves FPU context to the process in a0
  69.  * and loads the new context of the current process.
  70.  */
  71. #define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS)
  72. LEAF(lazy_fpu_switch)
  73. mfc0 t0, CP0_STATUS # enable cp1
  74. li t3, ST0_CU1
  75. or t0, t3
  76. mtc0 t0, CP0_STATUS
  77. FPU_ENABLE_HAZARD
  78. beqz a0, 2f # Save floating point state
  79.  nor t3, zero, t3
  80. lw t1, ST_OFF(a0) # last thread looses fpu
  81. and t1, t3
  82. sw t1, ST_OFF(a0)
  83. FPU_SAVE_DOUBLE(a0, t1) # clobbers t1
  84. 2:
  85. .set reorder
  86. FPU_RESTORE_DOUBLE($28, t0) # clobbers t0
  87. jr ra
  88. END(lazy_fpu_switch)
  89. /*
  90.  * Save a thread's fp context.
  91.  */
  92. LEAF(save_fp)
  93. FPU_SAVE_DOUBLE(a0, t1) # clobbers t1
  94. jr ra
  95. END(save_fp)
  96. /*
  97.  * Restore a thread's fp context.
  98.  */
  99. LEAF(restore_fp)
  100. FPU_RESTORE_DOUBLE(a0, t1) # clobbers t1
  101. jr ra
  102. END(restore_fp)
  103. /*
  104.  * Load the FPU with signalling NANS.  This bit pattern we're using has
  105.  * the property that no matter whether considered as single or as double
  106.  * precision represents signaling NANS.
  107.  *
  108.  * We initialize fcr31 to rounding to nearest, no exceptions.
  109.  */
  110. #define FPU_DEFAULT  0x00000000
  111. LEAF(init_fpu)
  112. .set mips3
  113. mfc0 t0, CP0_STATUS
  114. li t1, ST0_CU1
  115. or t0, t1
  116. mtc0 t0, CP0_STATUS
  117. FPU_ENABLE_HAZARD
  118. li t1, FPU_DEFAULT
  119. ctc1 t1, fcr31
  120. li t0, -1
  121. dmtc1 t0, $f0
  122. dmtc1 t0, $f2
  123. dmtc1 t0, $f4
  124. dmtc1 t0, $f6
  125. dmtc1 t0, $f8
  126. dmtc1 t0, $f10
  127. dmtc1 t0, $f12
  128. dmtc1 t0, $f14
  129. dmtc1 t0, $f16
  130. dmtc1 t0, $f18
  131. dmtc1 t0, $f20
  132. dmtc1 t0, $f22
  133. dmtc1 t0, $f24
  134. dmtc1 t0, $f26
  135. dmtc1 t0, $f28
  136. .set noreorder
  137. jr ra
  138.  dmtc1 t0, $f30
  139. .set reorder
  140. END(init_fpu)