2 * Copyright (c) 2019 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #ifndef _ARM64_PAC_ASM_H_
30 #define _ARM64_PAC_ASM_H_
33 #error "This header should only be used in .s files"
36 #include <pexpert/arm64/board_config.h>
37 #include <arm64/proc_reg.h>
40 #if defined(HAS_APPLE_PAC)
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
47 /* BEGIN IGNORE CODESTYLE */
50 * IF_PAC_FAST_A_KEY_SWITCHING
52 * Branch to a specified label if this H13 model + revision supports fast A-key switching.
54 * label - label to branch to
55 * tmp - scratch register
57 .macro IF_PAC_FAST_A_KEY_SWITCHING label
, tmp
59 * start.s attempts to set APCTL_EL1.UserKeyEn. If this H13 CPU doesn't
60 * actually support this bit, it will be RaZ.
63 tbnz
\tmp
, #APCTL_EL1_UserKeyEn_OFFSET, \label
67 * IF_PAC_SLOW_A_KEY_SWITCHING
69 * Branch to a specified label if this H13 model + revision doesn't support fast A-key switching.
71 * label - label to branch to
72 * tmp - scratch register
74 .macro IF_PAC_SLOW_A_KEY_SWITCHING label
, tmp
76 tbz
\tmp
, #APCTL_EL1_UserKeyEn_OFFSET, \label
79 /* END IGNORE CODESTYLE */
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
85 .macro IF_PAC_FAST_A_KEY_SWITCHING label
, tmp
86 .error
"This macro should never need to be used on this CPU family."
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
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
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
101 .macro IF_PAC_SLOW_A_KEY_SWITCHING label
, tmp
102 .error
"This macro should never need to be used on this CPU family."
105 #endif /* defined(APPLEFIRESTORM) */
107 /* BEGIN IGNORE CODESTYLE */
112 * Reprograms the A-key registers if needed, and updates current_cpu_datap()->jop_key.
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.
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
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
126 SET_JOP_KEY_REGISTERS
\new_jop_key
, \tmp
127 str
\new_jop_key
, [\cpudatap
, CPU_JOP_KEY
]
131 * SET_JOP_KEY_REGISTERS
133 * Unconditionally reprograms the A-key registers. The caller is responsible for
134 * updating current_cpu_datap()->jop_key as needed.
136 * new_jop_key - new APIAKeyLo value
137 * tmp - scratch register
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 */
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
156 msr APDAKeyLo_EL1
, \tmp
158 msr APDAKeyHi_EL1
, \tmp
159 #endif /* HAS_PAC_SLOW_A_KEY_SWITCHING */
161 Lset_jop_key_registers_done_\@
:
164 /* END IGNORE CODESTYLE */
166 #endif /* defined(HAS_APPLE_PAC) */
168 #endif /* _ARM64_PAC_ASM_H_ */
170 /* vim: set ts=4 ft=asm: */