fixed_code.S 3.3 KB

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