syscall-abi-asm.S 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. // Copyright (C) 2021 ARM Limited.
  3. //
  4. // Assembly portion of the syscall ABI test
  5. //
  6. // Load values from memory into registers, invoke a syscall and save the
  7. // register values back to memory for later checking. The syscall to be
  8. // invoked is configured in x8 of the input GPR data.
  9. //
  10. // x0: SVE VL, 0 for FP only
  11. // x1: SME VL
  12. //
  13. // GPRs: gpr_in, gpr_out
  14. // FPRs: fpr_in, fpr_out
  15. // Zn: z_in, z_out
  16. // Pn: p_in, p_out
  17. // FFR: ffr_in, ffr_out
  18. // ZA: za_in, za_out
  19. // SVCR: svcr_in, svcr_out
  20. #include "syscall-abi.h"
  21. .arch_extension sve
  22. /*
  23. * LDR (vector to ZA array):
  24. * LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
  25. */
  26. .macro _ldr_za nw, nxbase, offset=0
  27. .inst 0xe1000000 \
  28. | (((\nw) & 3) << 13) \
  29. | ((\nxbase) << 5) \
  30. | ((\offset) & 7)
  31. .endm
  32. /*
  33. * STR (vector from ZA array):
  34. * STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
  35. */
  36. .macro _str_za nw, nxbase, offset=0
  37. .inst 0xe1200000 \
  38. | (((\nw) & 3) << 13) \
  39. | ((\nxbase) << 5) \
  40. | ((\offset) & 7)
  41. .endm
  42. .globl do_syscall
  43. do_syscall:
  44. // Store callee saved registers x19-x29 (80 bytes) plus x0 and x1
  45. stp x29, x30, [sp, #-112]!
  46. mov x29, sp
  47. stp x0, x1, [sp, #16]
  48. stp x19, x20, [sp, #32]
  49. stp x21, x22, [sp, #48]
  50. stp x23, x24, [sp, #64]
  51. stp x25, x26, [sp, #80]
  52. stp x27, x28, [sp, #96]
  53. // Set SVCR if we're doing SME
  54. cbz x1, 1f
  55. adrp x2, svcr_in
  56. ldr x2, [x2, :lo12:svcr_in]
  57. msr S3_3_C4_C2_2, x2
  58. 1:
  59. // Load ZA if it's enabled - uses x12 as scratch due to SME LDR
  60. tbz x2, #SVCR_ZA_SHIFT, 1f
  61. mov w12, #0
  62. ldr x2, =za_in
  63. 2: _ldr_za 12, 2
  64. add x2, x2, x1
  65. add x12, x12, #1
  66. cmp x1, x12
  67. bne 2b
  68. 1:
  69. // Load GPRs x8-x28, and save our SP/FP for later comparison
  70. ldr x2, =gpr_in
  71. add x2, x2, #64
  72. ldp x8, x9, [x2], #16
  73. ldp x10, x11, [x2], #16
  74. ldp x12, x13, [x2], #16
  75. ldp x14, x15, [x2], #16
  76. ldp x16, x17, [x2], #16
  77. ldp x18, x19, [x2], #16
  78. ldp x20, x21, [x2], #16
  79. ldp x22, x23, [x2], #16
  80. ldp x24, x25, [x2], #16
  81. ldp x26, x27, [x2], #16
  82. ldr x28, [x2], #8
  83. str x29, [x2], #8 // FP
  84. str x30, [x2], #8 // LR
  85. // Load FPRs if we're not doing SVE
  86. cbnz x0, 1f
  87. ldr x2, =fpr_in
  88. ldp q0, q1, [x2]
  89. ldp q2, q3, [x2, #16 * 2]
  90. ldp q4, q5, [x2, #16 * 4]
  91. ldp q6, q7, [x2, #16 * 6]
  92. ldp q8, q9, [x2, #16 * 8]
  93. ldp q10, q11, [x2, #16 * 10]
  94. ldp q12, q13, [x2, #16 * 12]
  95. ldp q14, q15, [x2, #16 * 14]
  96. ldp q16, q17, [x2, #16 * 16]
  97. ldp q18, q19, [x2, #16 * 18]
  98. ldp q20, q21, [x2, #16 * 20]
  99. ldp q22, q23, [x2, #16 * 22]
  100. ldp q24, q25, [x2, #16 * 24]
  101. ldp q26, q27, [x2, #16 * 26]
  102. ldp q28, q29, [x2, #16 * 28]
  103. ldp q30, q31, [x2, #16 * 30]
  104. 1:
  105. // Load the SVE registers if we're doing SVE/SME
  106. cbz x0, 1f
  107. ldr x2, =z_in
  108. ldr z0, [x2, #0, MUL VL]
  109. ldr z1, [x2, #1, MUL VL]
  110. ldr z2, [x2, #2, MUL VL]
  111. ldr z3, [x2, #3, MUL VL]
  112. ldr z4, [x2, #4, MUL VL]
  113. ldr z5, [x2, #5, MUL VL]
  114. ldr z6, [x2, #6, MUL VL]
  115. ldr z7, [x2, #7, MUL VL]
  116. ldr z8, [x2, #8, MUL VL]
  117. ldr z9, [x2, #9, MUL VL]
  118. ldr z10, [x2, #10, MUL VL]
  119. ldr z11, [x2, #11, MUL VL]
  120. ldr z12, [x2, #12, MUL VL]
  121. ldr z13, [x2, #13, MUL VL]
  122. ldr z14, [x2, #14, MUL VL]
  123. ldr z15, [x2, #15, MUL VL]
  124. ldr z16, [x2, #16, MUL VL]
  125. ldr z17, [x2, #17, MUL VL]
  126. ldr z18, [x2, #18, MUL VL]
  127. ldr z19, [x2, #19, MUL VL]
  128. ldr z20, [x2, #20, MUL VL]
  129. ldr z21, [x2, #21, MUL VL]
  130. ldr z22, [x2, #22, MUL VL]
  131. ldr z23, [x2, #23, MUL VL]
  132. ldr z24, [x2, #24, MUL VL]
  133. ldr z25, [x2, #25, MUL VL]
  134. ldr z26, [x2, #26, MUL VL]
  135. ldr z27, [x2, #27, MUL VL]
  136. ldr z28, [x2, #28, MUL VL]
  137. ldr z29, [x2, #29, MUL VL]
  138. ldr z30, [x2, #30, MUL VL]
  139. ldr z31, [x2, #31, MUL VL]
  140. // Only set a non-zero FFR, test patterns must be zero since the
  141. // syscall should clear it - this lets us handle FA64.
  142. ldr x2, =ffr_in
  143. ldr p0, [x2, #0]
  144. ldr x2, [x2, #0]
  145. cbz x2, 2f
  146. wrffr p0.b
  147. 2:
  148. ldr x2, =p_in
  149. ldr p0, [x2, #0, MUL VL]
  150. ldr p1, [x2, #1, MUL VL]
  151. ldr p2, [x2, #2, MUL VL]
  152. ldr p3, [x2, #3, MUL VL]
  153. ldr p4, [x2, #4, MUL VL]
  154. ldr p5, [x2, #5, MUL VL]
  155. ldr p6, [x2, #6, MUL VL]
  156. ldr p7, [x2, #7, MUL VL]
  157. ldr p8, [x2, #8, MUL VL]
  158. ldr p9, [x2, #9, MUL VL]
  159. ldr p10, [x2, #10, MUL VL]
  160. ldr p11, [x2, #11, MUL VL]
  161. ldr p12, [x2, #12, MUL VL]
  162. ldr p13, [x2, #13, MUL VL]
  163. ldr p14, [x2, #14, MUL VL]
  164. ldr p15, [x2, #15, MUL VL]
  165. 1:
  166. // Do the syscall
  167. svc #0
  168. // Save GPRs x8-x30
  169. ldr x2, =gpr_out
  170. add x2, x2, #64
  171. stp x8, x9, [x2], #16
  172. stp x10, x11, [x2], #16
  173. stp x12, x13, [x2], #16
  174. stp x14, x15, [x2], #16
  175. stp x16, x17, [x2], #16
  176. stp x18, x19, [x2], #16
  177. stp x20, x21, [x2], #16
  178. stp x22, x23, [x2], #16
  179. stp x24, x25, [x2], #16
  180. stp x26, x27, [x2], #16
  181. stp x28, x29, [x2], #16
  182. str x30, [x2]
  183. // Restore x0 and x1 for feature checks
  184. ldp x0, x1, [sp, #16]
  185. // Save FPSIMD state
  186. ldr x2, =fpr_out
  187. stp q0, q1, [x2]
  188. stp q2, q3, [x2, #16 * 2]
  189. stp q4, q5, [x2, #16 * 4]
  190. stp q6, q7, [x2, #16 * 6]
  191. stp q8, q9, [x2, #16 * 8]
  192. stp q10, q11, [x2, #16 * 10]
  193. stp q12, q13, [x2, #16 * 12]
  194. stp q14, q15, [x2, #16 * 14]
  195. stp q16, q17, [x2, #16 * 16]
  196. stp q18, q19, [x2, #16 * 18]
  197. stp q20, q21, [x2, #16 * 20]
  198. stp q22, q23, [x2, #16 * 22]
  199. stp q24, q25, [x2, #16 * 24]
  200. stp q26, q27, [x2, #16 * 26]
  201. stp q28, q29, [x2, #16 * 28]
  202. stp q30, q31, [x2, #16 * 30]
  203. // Save SVCR if we're doing SME
  204. cbz x1, 1f
  205. mrs x2, S3_3_C4_C2_2
  206. adrp x3, svcr_out
  207. str x2, [x3, :lo12:svcr_out]
  208. 1:
  209. // Save ZA if it's enabled - uses x12 as scratch due to SME STR
  210. tbz x2, #SVCR_ZA_SHIFT, 1f
  211. mov w12, #0
  212. ldr x2, =za_out
  213. 2: _str_za 12, 2
  214. add x2, x2, x1
  215. add x12, x12, #1
  216. cmp x1, x12
  217. bne 2b
  218. 1:
  219. // Save the SVE state if we have some
  220. cbz x0, 1f
  221. ldr x2, =z_out
  222. str z0, [x2, #0, MUL VL]
  223. str z1, [x2, #1, MUL VL]
  224. str z2, [x2, #2, MUL VL]
  225. str z3, [x2, #3, MUL VL]
  226. str z4, [x2, #4, MUL VL]
  227. str z5, [x2, #5, MUL VL]
  228. str z6, [x2, #6, MUL VL]
  229. str z7, [x2, #7, MUL VL]
  230. str z8, [x2, #8, MUL VL]
  231. str z9, [x2, #9, MUL VL]
  232. str z10, [x2, #10, MUL VL]
  233. str z11, [x2, #11, MUL VL]
  234. str z12, [x2, #12, MUL VL]
  235. str z13, [x2, #13, MUL VL]
  236. str z14, [x2, #14, MUL VL]
  237. str z15, [x2, #15, MUL VL]
  238. str z16, [x2, #16, MUL VL]
  239. str z17, [x2, #17, MUL VL]
  240. str z18, [x2, #18, MUL VL]
  241. str z19, [x2, #19, MUL VL]
  242. str z20, [x2, #20, MUL VL]
  243. str z21, [x2, #21, MUL VL]
  244. str z22, [x2, #22, MUL VL]
  245. str z23, [x2, #23, MUL VL]
  246. str z24, [x2, #24, MUL VL]
  247. str z25, [x2, #25, MUL VL]
  248. str z26, [x2, #26, MUL VL]
  249. str z27, [x2, #27, MUL VL]
  250. str z28, [x2, #28, MUL VL]
  251. str z29, [x2, #29, MUL VL]
  252. str z30, [x2, #30, MUL VL]
  253. str z31, [x2, #31, MUL VL]
  254. ldr x2, =p_out
  255. str p0, [x2, #0, MUL VL]
  256. str p1, [x2, #1, MUL VL]
  257. str p2, [x2, #2, MUL VL]
  258. str p3, [x2, #3, MUL VL]
  259. str p4, [x2, #4, MUL VL]
  260. str p5, [x2, #5, MUL VL]
  261. str p6, [x2, #6, MUL VL]
  262. str p7, [x2, #7, MUL VL]
  263. str p8, [x2, #8, MUL VL]
  264. str p9, [x2, #9, MUL VL]
  265. str p10, [x2, #10, MUL VL]
  266. str p11, [x2, #11, MUL VL]
  267. str p12, [x2, #12, MUL VL]
  268. str p13, [x2, #13, MUL VL]
  269. str p14, [x2, #14, MUL VL]
  270. str p15, [x2, #15, MUL VL]
  271. // Only save FFR if we wrote a value for SME
  272. ldr x2, =ffr_in
  273. ldr x2, [x2, #0]
  274. cbz x2, 1f
  275. ldr x2, =ffr_out
  276. rdffr p0.b
  277. str p0, [x2, #0]
  278. 1:
  279. // Restore callee saved registers x19-x30
  280. ldp x19, x20, [sp, #32]
  281. ldp x21, x22, [sp, #48]
  282. ldp x23, x24, [sp, #64]
  283. ldp x25, x26, [sp, #80]
  284. ldp x27, x28, [sp, #96]
  285. ldp x29, x30, [sp], #112
  286. // Clear SVCR if we were doing SME so future tests don't have ZA
  287. cbz x1, 1f
  288. msr S3_3_C4_C2_2, xzr
  289. 1:
  290. ret