elf/Makefile: Split and sort PIE tests
[glibc.git] / sysdeps / aarch64 / __arm_za_disable.S
blob649891ea7fa55c0393555abc1943072fa6f91830
1 /* Libc internal support routine for SME.
2    Copyright (C) 2023 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library.  If not, see
18    <http://www.gnu.org/licenses/>.  */
20 #include <sysdep.h>
21 #include <rtld-global-offsets.h>
23 #define HWCAP2_SME_BIT 23
25 /* Disable ZA.  Call ABI:
26    - Private ZA, streaming-compatible.
27    - x0-x13, x19-x29, sp and fp regs are call preserved.
28    - On return tpidr2_el0 = 0, ZA = 0.
29    - Takes no argument.
30    - Does not return a value.
31    - Can abort on failure (then registers are not preserved).  */
33 ENTRY (__libc_arm_za_disable)
35         /* Check if SME is available.  */
36 #ifdef SHARED
37         /* In libc.so.  */
38         adrp    x14, :got:_rtld_global_ro
39         ldr     x14, [x14, :got_lo12:_rtld_global_ro]
40         ldr     x14, [x14, GLRO_DL_HWCAP2_OFFSET]
41 #else
42         /* In libc.a, may be PIC.  */
43         adrp    x14, _dl_hwcap2
44         ldr     x14, [x14, :lo12:_dl_hwcap2]
45 #endif
46         tbz     x14, HWCAP2_SME_BIT, L(end)
48         .inst   0xd53bd0ae  /* mrs      x14, tpidr2_el0  */
49         cbz     x14, L(end)
51         /* Check reserved bytes, abort on unknown extensions.  */
52         ldrh    w15, [x14, 10]
53         ldr     w16, [x14, 12]
54         orr     w15, w15, w16
55         cbnz    w15, L(fail)
57         ldr     x16, [x14]
58         cbz     x16, L(end)
59         ldrh    w17, [x14, 8]
60         cbz     w17, L(end)
62         /* x14: tpidr2, x15: 0,
63            x16: za_save_buffer, x17: num_za_save_slices.  */
65 L(save_loop):
66         .inst   0xe1206200  /* str      za[w15, 0], [x16]  */
67         .inst   0xe1206201  /* str      za[w15, 1], [x16, 1, mul vl] */
68         .inst   0xe1206202  /* str      za[w15, 2], [x16, 2, mul vl] */
69         .inst   0xe1206203  /* str      za[w15, 3], [x16, 3, mul vl] */
70         .inst   0xe1206204  /* str      za[w15, 4], [x16, 4, mul vl] */
71         .inst   0xe1206205  /* str      za[w15, 5], [x16, 5, mul vl] */
72         .inst   0xe1206206  /* str      za[w15, 6], [x16, 6, mul vl] */
73         .inst   0xe1206207  /* str      za[w15, 7], [x16, 7, mul vl] */
74         .inst   0xe1206208  /* str      za[w15, 8], [x16, 8, mul vl] */
75         .inst   0xe1206209  /* str      za[w15, 9], [x16, 9, mul vl] */
76         .inst   0xe120620a  /* str      za[w15, 10], [x16, 10, mul vl] */
77         .inst   0xe120620b  /* str      za[w15, 11], [x16, 11, mul vl] */
78         .inst   0xe120620c  /* str      za[w15, 12], [x16, 12, mul vl] */
79         .inst   0xe120620d  /* str      za[w15, 13], [x16, 13, mul vl] */
80         .inst   0xe120620e  /* str      za[w15, 14], [x16, 14, mul vl] */
81         .inst   0xe120620f  /* str      za[w15, 15], [x16, 15, mul vl] */
82         add     w15, w15, 16
83         .inst   0x04305a10  /* addsvl   x16, x16, 16  */
84         cmp     w17, w15
85         bhi     L(save_loop)
86         .inst   0xd51bd0bf  /* msr      tpidr2_el0, xzr  */
87         .inst   0xd503447f  /* smstop   za  */
88 L(end):
89         ret
90 L(fail):
91 #if HAVE_AARCH64_PAC_RET
92         PACIASP
93         cfi_window_save
94 #endif
95         stp     x29, x30, [sp, -32]!
96         cfi_adjust_cfa_offset (32)
97         cfi_rel_offset (x29, 0)
98         cfi_rel_offset (x30, 8)
99         mov     x29, sp
100         .inst   0x04e0e3f0  /* cntd     x16  */
101         str     x16, [sp, 16]
102         cfi_rel_offset (46, 16)
103         .inst   0xd503467f  /* smstop  */
104         adrp    x0, L(msg)
105         add     x0, x0, :lo12:L(msg)
106         bl      HIDDEN_JUMPTARGET (__libc_fatal)
107 END (__libc_arm_za_disable)
109         .section        .rodata
110         .align  3
111 L(msg):
112         .string "FATAL: __libc_arm_za_disable failed.\n"