1 /******************************************************************************
2  * @file     pac_armv81.h
3  * @brief    CMSIS PAC key functions for Armv8.1-M PAC extension
4  * @version  V1.0.0
5  * @date     23. March 2022
6  ******************************************************************************/
7 /*
8  * Copyright (c) 2022 Arm Limited. All rights reserved.
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  *
12  * Licensed under the Apache License, Version 2.0 (the License); you may
13  * not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  * www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
20  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  */
24 
25 #if   defined ( __ICCARM__ )
26   #pragma system_include         /* treat file as system include file for MISRA check */
27 #elif defined (__clang__)
28   #pragma clang system_header    /* treat file as system include file */
29 #endif
30 
31 #ifndef PAC_ARMV81_H
32 #define PAC_ARMV81_H
33 
34 
35 /* ###################  PAC Key functions  ########################### */
36 /**
37   \ingroup  CMSIS_Core_FunctionInterface
38   \defgroup CMSIS_Core_PacKeyFunctions PAC Key functions
39   \brief    Functions that access the PAC keys.
40   @{
41  */
42 
43 #if (defined (__ARM_FEATURE_PAUTH) && (__ARM_FEATURE_PAUTH == 1))
44 
45 /**
46   \brief   read the PAC key used for privileged mode
47   \details Reads the PAC key stored in the PAC_KEY_P registers.
48   \param [out]    pPacKey  128bit PAC key
49  */
__get_PAC_KEY_P(uint32_t * pPacKey)50 __STATIC_FORCEINLINE void __get_PAC_KEY_P (uint32_t* pPacKey) {
51   __ASM volatile (
52   "mrs   r1, pac_key_p_0\n"
53   "str   r1,[%0,#0]\n"
54   "mrs   r1, pac_key_p_1\n"
55   "str   r1,[%0,#4]\n"
56   "mrs   r1, pac_key_p_2\n"
57   "str   r1,[%0,#8]\n"
58   "mrs   r1, pac_key_p_3\n"
59   "str   r1,[%0,#12]\n"
60   : : "r" (pPacKey) : "memory", "r1"
61   );
62 }
63 
64 /**
65   \brief   write the PAC key used for privileged mode
66   \details writes the given PAC key to the PAC_KEY_P registers.
67   \param [in]    pPacKey  128bit PAC key
68  */
__set_PAC_KEY_P(uint32_t * pPacKey)69 __STATIC_FORCEINLINE void __set_PAC_KEY_P (uint32_t* pPacKey) {
70   __ASM volatile (
71   "ldr   r1,[%0,#0]\n"
72   "msr   pac_key_p_0, r1\n"
73   "ldr   r1,[%0,#4]\n"
74   "msr   pac_key_p_1, r1\n"
75   "ldr   r1,[%0,#8]\n"
76   "msr   pac_key_p_2, r1\n"
77   "ldr   r1,[%0,#12]\n"
78   "msr   pac_key_p_3, r1\n"
79   : : "r" (pPacKey) : "memory", "r1"
80   );
81 }
82 
83 /**
84   \brief   read the PAC key used for unprivileged mode
85   \details Reads the PAC key stored in the PAC_KEY_U registers.
86   \param [out]    pPacKey  128bit PAC key
87  */
__get_PAC_KEY_U(uint32_t * pPacKey)88 __STATIC_FORCEINLINE void __get_PAC_KEY_U (uint32_t* pPacKey) {
89   __ASM volatile (
90   "mrs   r1, pac_key_u_0\n"
91   "str   r1,[%0,#0]\n"
92   "mrs   r1, pac_key_u_1\n"
93   "str   r1,[%0,#4]\n"
94   "mrs   r1, pac_key_u_2\n"
95   "str   r1,[%0,#8]\n"
96   "mrs   r1, pac_key_u_3\n"
97   "str   r1,[%0,#12]\n"
98   : : "r" (pPacKey) : "memory", "r1"
99   );
100 }
101 
102 /**
103   \brief   write the PAC key used for unprivileged mode
104   \details writes the given PAC key to the PAC_KEY_U registers.
105   \param [in]    pPacKey  128bit PAC key
106  */
__set_PAC_KEY_U(uint32_t * pPacKey)107 __STATIC_FORCEINLINE void __set_PAC_KEY_U (uint32_t* pPacKey) {
108   __ASM volatile (
109   "ldr   r1,[%0,#0]\n"
110   "msr   pac_key_u_0, r1\n"
111   "ldr   r1,[%0,#4]\n"
112   "msr   pac_key_u_1, r1\n"
113   "ldr   r1,[%0,#8]\n"
114   "msr   pac_key_u_2, r1\n"
115   "ldr   r1,[%0,#12]\n"
116   "msr   pac_key_u_3, r1\n"
117   : : "r" (pPacKey) : "memory", "r1"
118   );
119 }
120 
121 #if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3))
122 
123 /**
124   \brief   read the PAC key used for privileged mode (non-secure)
125   \details Reads the PAC key stored in the non-secure PAC_KEY_P registers when in secure mode.
126   \param [out]    pPacKey  128bit PAC key
127  */
__TZ_get_PAC_KEY_P_NS(uint32_t * pPacKey)128 __STATIC_FORCEINLINE void __TZ_get_PAC_KEY_P_NS (uint32_t* pPacKey) {
129   __ASM volatile (
130   "mrs   r1, pac_key_p_0_ns\n"
131   "str   r1,[%0,#0]\n"
132   "mrs   r1, pac_key_p_1_ns\n"
133   "str   r1,[%0,#4]\n"
134   "mrs   r1, pac_key_p_2_ns\n"
135   "str   r1,[%0,#8]\n"
136   "mrs   r1, pac_key_p_3_ns\n"
137   "str   r1,[%0,#12]\n"
138   : : "r" (pPacKey) : "memory", "r1"
139   );
140 }
141 
142 /**
143   \brief   write the PAC key used for privileged mode (non-secure)
144   \details writes the given PAC key to the non-secure PAC_KEY_P registers when in secure mode.
145   \param [in]    pPacKey  128bit PAC key
146  */
__TZ_set_PAC_KEY_P_NS(uint32_t * pPacKey)147 __STATIC_FORCEINLINE void __TZ_set_PAC_KEY_P_NS (uint32_t* pPacKey) {
148   __ASM volatile (
149   "ldr   r1,[%0,#0]\n"
150   "msr   pac_key_p_0_ns, r1\n"
151   "ldr   r1,[%0,#4]\n"
152   "msr   pac_key_p_1_ns, r1\n"
153   "ldr   r1,[%0,#8]\n"
154   "msr   pac_key_p_2_ns, r1\n"
155   "ldr   r1,[%0,#12]\n"
156   "msr   pac_key_p_3_ns, r1\n"
157   : : "r" (pPacKey) : "memory", "r1"
158   );
159 }
160 
161 /**
162   \brief   read the PAC key used for unprivileged mode (non-secure)
163   \details Reads the PAC key stored in the non-secure PAC_KEY_U registers when in secure mode.
164   \param [out]    pPacKey  128bit PAC key
165  */
__TZ_get_PAC_KEY_U_NS(uint32_t * pPacKey)166 __STATIC_FORCEINLINE void __TZ_get_PAC_KEY_U_NS (uint32_t* pPacKey) {
167   __ASM volatile (
168   "mrs   r1, pac_key_u_0_ns\n"
169   "str   r1,[%0,#0]\n"
170   "mrs   r1, pac_key_u_1_ns\n"
171   "str   r1,[%0,#4]\n"
172   "mrs   r1, pac_key_u_2_ns\n"
173   "str   r1,[%0,#8]\n"
174   "mrs   r1, pac_key_u_3_ns\n"
175   "str   r1,[%0,#12]\n"
176   : : "r" (pPacKey) : "memory", "r1"
177   );
178 }
179 
180 /**
181   \brief   write the PAC key used for unprivileged mode (non-secure)
182   \details writes the given PAC key to the non-secure PAC_KEY_U registers when in secure mode.
183   \param [in]    pPacKey  128bit PAC key
184  */
__TZ_set_PAC_KEY_U_NS(uint32_t * pPacKey)185 __STATIC_FORCEINLINE void __TZ_set_PAC_KEY_U_NS (uint32_t* pPacKey) {
186   __ASM volatile (
187   "ldr   r1,[%0,#0]\n"
188   "msr   pac_key_u_0_ns, r1\n"
189   "ldr   r1,[%0,#4]\n"
190   "msr   pac_key_u_1_ns, r1\n"
191   "ldr   r1,[%0,#8]\n"
192   "msr   pac_key_u_2_ns, r1\n"
193   "ldr   r1,[%0,#12]\n"
194   "msr   pac_key_u_3_ns, r1\n"
195   : : "r" (pPacKey) : "memory", "r1"
196   );
197 }
198 
199 #endif /* (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) */
200 
201 #endif /* (defined (__ARM_FEATURE_PAUTH) && (__ARM_FEATURE_PAUTH == 1)) */
202 
203 /*@} end of CMSIS_Core_PacKeyFunctions */
204 
205 
206 #endif /* PAC_ARMV81_H */
207