1 | // Copyright 2019 The Marl Authors. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #if defined(__aarch64__) |
16 | |
17 | #define MARL_BUILD_ASM 1 |
18 | #include "osfiber_asm_aarch64.h" |
19 | |
20 | |
21 | #if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT |
22 | // ENABLE_PAUTH must be defined to 1 since this value will be used in |
23 | // bitwise-shift later! |
24 | #define ENABLE_PAUTH 1 |
25 | |
26 | #if ((__ARM_FEATURE_PAC_DEFAULT & ((1 << 0) | (1 << 1))) == 0) |
27 | #error Pointer authentication defines no valid key! |
28 | #endif |
29 | #else |
30 | #define ENABLE_PAUTH 0 |
31 | #endif |
32 | |
33 | #if defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT == 1) |
34 | // ENABLE_BTI must be defined to 1 since this value will be used in |
35 | // bitwise-shift later! |
36 | #define ENABLE_BTI 1 |
37 | #else |
38 | #define ENABLE_BTI 0 |
39 | #endif |
40 | |
41 | // Although Pointer Authentication and Branch Target Instructions are |
42 | // technically seperate features they work together, i.e. the paciasp and |
43 | // pacibsp instructions serve as BTI landing pads. Therefore PA-instructions are |
44 | // enabled when PA _or_ BTI is enabled! |
45 | #if ENABLE_PAUTH || ENABLE_BTI |
46 | // See section "Pointer Authentication" of |
47 | // https://developer.arm.com/documentation/101028/0012/5--Feature-test-macros |
48 | // for details how to interpret __ARM_FEATURE_PAC_DEFAULT |
49 | #if (__ARM_FEATURE_PAC_DEFAULT & (1 << 0)) |
50 | #define PAUTH_SIGN_SP paciasp |
51 | #define PAUTH_AUTH_SP autiasp |
52 | #else |
53 | #define PAUTH_SIGN_SP pacibsp |
54 | #define PAUTH_AUTH_SP autibsp |
55 | #endif |
56 | #else |
57 | #define PAUTH_SIGN_SP |
58 | #define PAUTH_AUTH_SP |
59 | #endif |
60 | |
61 | |
62 | // void marl_fiber_swap(marl_fiber_context* from, const marl_fiber_context* to) |
63 | // x0: from |
64 | // x1: to |
65 | .text |
66 | .global MARL_ASM_SYMBOL(marl_fiber_swap) |
67 | .align 4 |
68 | MARL_ASM_SYMBOL(marl_fiber_swap): |
69 | |
70 | // Save context 'from' |
71 | // TODO: pairs of str can be combined with stp. |
72 | |
73 | PAUTH_SIGN_SP |
74 | |
75 | // Store special purpose registers |
76 | str x16, [x0, #MARL_REG_r16] |
77 | str x17, [x0, #MARL_REG_r17] |
78 | str x18, [x0, #MARL_REG_r18] |
79 | |
80 | // Store callee-preserved registers |
81 | str x19, [x0, #MARL_REG_r19] |
82 | str x20, [x0, #MARL_REG_r20] |
83 | str x21, [x0, #MARL_REG_r21] |
84 | str x22, [x0, #MARL_REG_r22] |
85 | str x23, [x0, #MARL_REG_r23] |
86 | str x24, [x0, #MARL_REG_r24] |
87 | str x25, [x0, #MARL_REG_r25] |
88 | str x26, [x0, #MARL_REG_r26] |
89 | str x27, [x0, #MARL_REG_r27] |
90 | str x28, [x0, #MARL_REG_r28] |
91 | str x29, [x0, #MARL_REG_r29] |
92 | |
93 | str d8, [x0, #MARL_REG_v8] |
94 | str d9, [x0, #MARL_REG_v9] |
95 | str d10, [x0, #MARL_REG_v10] |
96 | str d11, [x0, #MARL_REG_v11] |
97 | str d12, [x0, #MARL_REG_v12] |
98 | str d13, [x0, #MARL_REG_v13] |
99 | str d14, [x0, #MARL_REG_v14] |
100 | str d15, [x0, #MARL_REG_v15] |
101 | |
102 | // Store sp and lr |
103 | mov x2, sp |
104 | str x2, [x0, #MARL_REG_SP] |
105 | str x30, [x0, #MARL_REG_LR] |
106 | |
107 | // Load context 'to' |
108 | mov x7, x1 |
109 | |
110 | // Load special purpose registers |
111 | ldr x16, [x7, #MARL_REG_r16] |
112 | ldr x17, [x7, #MARL_REG_r17] |
113 | ldr x18, [x7, #MARL_REG_r18] |
114 | |
115 | // Load callee-preserved registers |
116 | ldr x19, [x7, #MARL_REG_r19] |
117 | ldr x20, [x7, #MARL_REG_r20] |
118 | ldr x21, [x7, #MARL_REG_r21] |
119 | ldr x22, [x7, #MARL_REG_r22] |
120 | ldr x23, [x7, #MARL_REG_r23] |
121 | ldr x24, [x7, #MARL_REG_r24] |
122 | ldr x25, [x7, #MARL_REG_r25] |
123 | ldr x26, [x7, #MARL_REG_r26] |
124 | ldr x27, [x7, #MARL_REG_r27] |
125 | ldr x28, [x7, #MARL_REG_r28] |
126 | ldr x29, [x7, #MARL_REG_r29] |
127 | |
128 | ldr d8, [x7, #MARL_REG_v8] |
129 | ldr d9, [x7, #MARL_REG_v9] |
130 | ldr d10, [x7, #MARL_REG_v10] |
131 | ldr d11, [x7, #MARL_REG_v11] |
132 | ldr d12, [x7, #MARL_REG_v12] |
133 | ldr d13, [x7, #MARL_REG_v13] |
134 | ldr d14, [x7, #MARL_REG_v14] |
135 | ldr d15, [x7, #MARL_REG_v15] |
136 | |
137 | // Load parameter registers |
138 | ldr x0, [x7, #MARL_REG_r0] |
139 | ldr x1, [x7, #MARL_REG_r1] |
140 | |
141 | // Load sp and lr |
142 | ldr x30, [x7, #MARL_REG_LR] |
143 | ldr x2, [x7, #MARL_REG_SP] |
144 | mov sp, x2 |
145 | |
146 | PAUTH_AUTH_SP |
147 | |
148 | ret |
149 | |
150 | #if ENABLE_PAUTH || ENABLE_BTI |
151 | // see |
152 | // https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst#program-property |
153 | .pushsection .note.gnu.property, "a" ; |
154 | .balign 8 |
155 | .long 4 |
156 | .long 0x10 |
157 | .long 0x5 |
158 | .asciz "GNU" |
159 | .long 0xc0000000 /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ |
160 | .long 4 |
161 | .long ((ENABLE_PAUTH)<<1) | ((ENABLE_BTI)<<0) /* PAuth and BTI */ |
162 | .long 0 |
163 | .popsection |
164 | #endif |
165 | |
166 | #endif // defined(__aarch64__) |
167 | |