fixed_code.S 3.2 KB

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