syscall-abi-asm.S 8.0 KB

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