fixed_code.S 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * This file contains sequences of code that will be copied to a
  3. * fixed location, defined in <asm/fixed_code.h>. The interrupt
  4. * handlers ensure that these sequences appear to be atomic when
  5. * executed from userspace.
  6. * These are aligned to 16 bytes, so that we have some space to replace
  7. * these sequences with something else (e.g. kernel traps if we ever do
  8. * BF561 SMP).
  9. */
  10. #include <linux/linkage.h>
  11. #include <linux/init.h>
  12. #include <linux/unistd.h>
  13. #include <asm/entry.h>
  14. __INIT
  15. ENTRY(_fixed_code_start)
  16. .align 16
  17. ENTRY(_sigreturn_stub)
  18. P0 = __NR_rt_sigreturn;
  19. EXCPT 0;
  20. /* Speculative execution paranoia. */
  21. 0: JUMP.S 0b;
  22. ENDPROC (_sigreturn_stub)
  23. .align 16
  24. /*
  25. * Atomic swap, 8 bit.
  26. * Inputs: P0: memory address to use
  27. * R1: value to store
  28. * Output: R0: old contents of the memory address, zero extended.
  29. */
  30. ENTRY(_atomic_xchg32)
  31. R0 = [P0];
  32. [P0] = R1;
  33. rts;
  34. ENDPROC (_atomic_xchg32)
  35. .align 16
  36. /*
  37. * Compare and swap, 32 bit.
  38. * Inputs: P0: memory address to use
  39. * R1: compare value
  40. * R2: new value to store
  41. * The new value is stored if the contents of the memory
  42. * address is equal to the compare value.
  43. * Output: R0: old contents of the memory address.
  44. */
  45. ENTRY(_atomic_cas32)
  46. R0 = [P0];
  47. CC = R0 == R1;
  48. IF !CC JUMP 1f;
  49. [P0] = R2;
  50. 1:
  51. rts;
  52. ENDPROC (_atomic_cas32)
  53. .align 16
  54. /*
  55. * Atomic add, 32 bit.
  56. * Inputs: P0: memory address to use
  57. * R0: value to add
  58. * Outputs: R0: new contents of the memory address.
  59. * R1: previous contents of the memory address.
  60. */
  61. ENTRY(_atomic_add32)
  62. R1 = [P0];
  63. R0 = R1 + R0;
  64. [P0] = R0;
  65. rts;
  66. ENDPROC (_atomic_add32)
  67. .align 16
  68. /*
  69. * Atomic sub, 32 bit.
  70. * Inputs: P0: memory address to use
  71. * R0: value to subtract
  72. * Outputs: R0: new contents of the memory address.
  73. * R1: previous contents of the memory address.
  74. */
  75. ENTRY(_atomic_sub32)
  76. R1 = [P0];
  77. R0 = R1 - R0;
  78. [P0] = R0;
  79. rts;
  80. ENDPROC (_atomic_sub32)
  81. .align 16
  82. /*
  83. * Atomic ior, 32 bit.
  84. * Inputs: P0: memory address to use
  85. * R0: value to ior
  86. * Outputs: R0: new contents of the memory address.
  87. * R1: previous contents of the memory address.
  88. */
  89. ENTRY(_atomic_ior32)
  90. R1 = [P0];
  91. R0 = R1 | R0;
  92. [P0] = R0;
  93. rts;
  94. ENDPROC (_atomic_ior32)
  95. .align 16
  96. /*
  97. * Atomic and, 32 bit.
  98. * Inputs: P0: memory address to use
  99. * R0: value to and
  100. * Outputs: R0: new contents of the memory address.
  101. * R1: previous contents of the memory address.
  102. */
  103. ENTRY(_atomic_and32)
  104. R1 = [P0];
  105. R0 = R1 & R0;
  106. [P0] = R0;
  107. rts;
  108. ENDPROC (_atomic_and32)
  109. .align 16
  110. /*
  111. * Atomic xor, 32 bit.
  112. * Inputs: P0: memory address to use
  113. * R0: value to xor
  114. * Outputs: R0: new contents of the memory address.
  115. * R1: previous contents of the memory address.
  116. */
  117. ENTRY(_atomic_xor32)
  118. R1 = [P0];
  119. R0 = R1 ^ R0;
  120. [P0] = R0;
  121. rts;
  122. ENDPROC (_atomic_xor32)
  123. .align 16
  124. /*
  125. * safe_user_instruction
  126. * Four NOPS are enough to allow the pipeline to speculativily load
  127. * execute anything it wants. After that, things have gone bad, and
  128. * we are stuck - so panic. Since we might be in user space, we can't
  129. * call panic, so just cause a unhandled exception, this should cause
  130. * a dump of the trace buffer so we can tell were we are, and a reboot
  131. */
  132. ENTRY(_safe_user_instruction)
  133. NOP; NOP; NOP; NOP;
  134. EXCPT 0x4;
  135. ENDPROC(_safe_user_instruction)
  136. ENTRY(_fixed_code_end)
  137. __FINIT