]> git.saurik.com Git - apple/xnu.git/blob - osfmk/arm64/pac_asm.h
9a3981d07129fd58ed89eeed14d9ee17f6606e6d
[apple/xnu.git] / osfmk / arm64 / pac_asm.h
1 /*
2 * Copyright (c) 2019 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #ifndef _ARM64_PAC_ASM_H_
30 #define _ARM64_PAC_ASM_H_
31
32 #ifndef __ASSEMBLER__
33 #error "This header should only be used in .s files"
34 #endif
35
36 #include <pexpert/arm64/board_config.h>
37 #include <arm64/proc_reg.h>
38 #include "assym.s"
39
40 #if defined(HAS_APPLE_PAC)
41
42 #if defined(APPLEFIRESTORM)
43 /* H13 may use either fast or slow A-key switching, depending on CPU model and revision */
44 #define HAS_PAC_FAST_A_KEY_SWITCHING 1
45 #define HAS_PAC_SLOW_A_KEY_SWITCHING 1
46
47 /* BEGIN IGNORE CODESTYLE */
48
49 /**
50 * IF_PAC_FAST_A_KEY_SWITCHING
51 *
52 * Branch to a specified label if this H13 model + revision supports fast A-key switching.
53 *
54 * label - label to branch to
55 * tmp - scratch register
56 */
57 .macro IF_PAC_FAST_A_KEY_SWITCHING label, tmp
58 /**
59 * start.s attempts to set APCTL_EL1.UserKeyEn. If this H13 CPU doesn't
60 * actually support this bit, it will be RaZ.
61 */
62 mrs \tmp, APCTL_EL1
63 tbnz \tmp, #APCTL_EL1_UserKeyEn_OFFSET, \label
64 .endmacro
65
66 /**
67 * IF_PAC_SLOW_A_KEY_SWITCHING
68 *
69 * Branch to a specified label if this H13 model + revision doesn't support fast A-key switching.
70 *
71 * label - label to branch to
72 * tmp - scratch register
73 */
74 .macro IF_PAC_SLOW_A_KEY_SWITCHING label, tmp
75 mrs \tmp, APCTL_EL1
76 tbz \tmp, #APCTL_EL1_UserKeyEn_OFFSET, \label
77 .endmacro
78
79 /* END IGNORE CODESTYLE */
80
81 #elif defined(HAS_APCTL_EL1_USERKEYEN)
82 #define HAS_PAC_FAST_A_KEY_SWITCHING 1
83 #define HAS_PAC_SLOW_A_KEY_SWITCHING 0
84
85 .macro IF_PAC_FAST_A_KEY_SWITCHING label, tmp
86 .error "This macro should never need to be used on this CPU family."
87 .endmacro
88
89 /* We know at compile time that this CPU family definitely doesn't need slow A-key switching */
90 .macro IF_PAC_SLOW_A_KEY_SWITCHING label, tmp
91 .endmacro
92
93 #else /* !defined(APPLEFIRESTORM) && !defined(HAS_APCTL_EL1_USERKEYEN) */
94 #define HAS_PAC_FAST_A_KEY_SWITCHING 0
95 #define HAS_PAC_SLOW_A_KEY_SWITCHING 1
96
97 /* We know at compile time that this CPU family definitely doesn't support fast A-key switching */
98 .macro IF_PAC_FAST_A_KEY_SWITCHING label, tmp
99 .endmacro
100
101 .macro IF_PAC_SLOW_A_KEY_SWITCHING label, tmp
102 .error "This macro should never need to be used on this CPU family."
103 .endmacro
104
105 #endif /* defined(APPLEFIRESTORM) */
106
107 /* BEGIN IGNORE CODESTYLE */
108
109 /**
110 * REPROGRAM_JOP_KEYS
111 *
112 * Reprograms the A-key registers if needed, and updates current_cpu_datap()->jop_key.
113 *
114 * On CPUs where fast A-key switching is implemented, this macro reprograms KERNKey_EL1.
115 * On other CPUs, it reprograms AP{D,I}AKey_EL1.
116 *
117 * skip_label - branch to this label if new_jop_key is already loaded into CPU
118 * new_jop_key - new APIAKeyLo value
119 * cpudatap - current cpu_data_t *
120 * tmp - scratch register
121 */
122 .macro REPROGRAM_JOP_KEYS skip_label, new_jop_key, cpudatap, tmp
123 ldr \tmp, [\cpudatap, CPU_JOP_KEY]
124 cmp \new_jop_key, \tmp
125 b.eq \skip_label
126 SET_JOP_KEY_REGISTERS \new_jop_key, \tmp
127 str \new_jop_key, [\cpudatap, CPU_JOP_KEY]
128 .endmacro
129
130 /**
131 * SET_JOP_KEY_REGISTERS
132 *
133 * Unconditionally reprograms the A-key registers. The caller is responsible for
134 * updating current_cpu_datap()->jop_key as needed.
135 *
136 * new_jop_key - new APIAKeyLo value
137 * tmp - scratch register
138 */
139 .macro SET_JOP_KEY_REGISTERS new_jop_key, tmp
140 #if HAS_PAC_FAST_A_KEY_SWITCHING
141 IF_PAC_SLOW_A_KEY_SWITCHING Lslow_reprogram_jop_keys_\@, \tmp
142 msr KERNKeyLo_EL1, \new_jop_key
143 add \tmp, \new_jop_key, #1
144 msr KERNKeyHi_EL1, \tmp
145 #endif /* HAS_PAC_FAST_A_KEY_SWITCHING */
146 #if HAS_PAC_FAST_A_KEY_SWITCHING && HAS_PAC_SLOW_A_KEY_SWITCHING
147 b Lset_jop_key_registers_done_\@
148 #endif /* HAS_PAC_FAST_A_KEY_SWITCHING && HAS_PAC_SLOW_A_KEY_SWITCHING */
149
150 #if HAS_PAC_SLOW_A_KEY_SWITCHING
151 Lslow_reprogram_jop_keys_\@:
152 msr APIAKeyLo_EL1, \new_jop_key
153 add \tmp, \new_jop_key, #1
154 msr APIAKeyHi_EL1, \tmp
155 add \tmp, \tmp, #1
156 msr APDAKeyLo_EL1, \tmp
157 add \tmp, \tmp, #1
158 msr APDAKeyHi_EL1, \tmp
159 #endif /* HAS_PAC_SLOW_A_KEY_SWITCHING */
160
161 Lset_jop_key_registers_done_\@:
162 .endmacro
163
164 /* END IGNORE CODESTYLE */
165
166 #endif /* defined(HAS_APPLE_PAC) */
167
168 #endif /* _ARM64_PAC_ASM_H_ */
169
170 /* vim: set ts=4 ft=asm: */