1 /*
2  * Copyright (c) 2019-2022 Arm Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * \file ppc_rss_drv.h
19  * \brief Generic driver for RSS Peripheral Protection Controllers (PPC).
20  */
21 
22 #ifndef __PPC_RSS_DRV_H__
23 #define __PPC_RSS_DRV_H__
24 
25 #include <stdint.h>
26 #include <stdbool.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /* RSS PPC names */
33 enum ppc_rss_name_t {
34     PPC_RSS_MAIN0 = 0,        /*!< MAIN PPC 0 */
35     PPC_RSS_MAIN_EXP0,        /*!< Expansion 0 MAIN PPC */
36     PPC_RSS_MAIN_EXP1,        /*!< Expansion 1 MAIN PPC */
37     PPC_RSS_MAIN_EXP2,        /*!< Expansion 2 MAIN PPC */
38     PPC_RSS_MAIN_EXP3,        /*!< Expansion 3 MAIN PPC */
39     PPC_RSS_PERIPH0,          /*!< PERIPH PPC0 */
40     PPC_RSS_PERIPH1,          /*!< PERIPH PPC1 */
41     PPC_RSS_PERIPH_EXP0,      /*!< Expansion 0 PERIPH PPC */
42     PPC_RSS_PERIPH_EXP1,      /*!< Expansion 1 PERIPH PPC */
43     PPC_RSS_PERIPH_EXP2,      /*!< Expansion 2 PERIPH PPC */
44     PPC_RSS_PERIPH_EXP3,      /*!< Expansion 3 PERIPH PPC */
45     RSS_PPC_MAX_NUM
46 };
47 
48 /* RSS PPC device configuration structure */
49 struct ppc_rss_dev_cfg_t {
50     uint32_t const sacfg_base;  /*!< Secure Privilege Control Block base */
51     uint32_t const nsacfg_base; /*!< Non-Secure Privilege Control Block base */
52     enum ppc_rss_name_t ppc_name;
53 };
54 
55 /* RSS PPC device data structure */
56 struct ppc_rss_dev_data_t {
57     volatile uint32_t* sacfg_ns_ppc;   /*!< Pointer to non-secure register */
58     volatile uint32_t* sacfg_sp_ppc;   /*!< Pointer to secure unprivileged
59                                              register */
60     volatile uint32_t* nsacfg_nsp_ppc; /*!< Pointer to non-secure unprivileged
61                                              register */
62     uint32_t int_bit_mask;              /*!< Interrupt bit mask */
63     bool is_initialized;                /*!< Indicates if the PPC driver
64                                              is initialized */
65 };
66 
67 /* RSS PPC device structure */
68 struct ppc_rss_dev_t {
69     const struct ppc_rss_dev_cfg_t* const cfg;  /*!< PPC configuration */
70     struct ppc_rss_dev_data_t* const data;      /*!< PPC data */
71 };
72 
73 /* Security attribute used to configure the peripherals */
74 enum ppc_rss_sec_attr_t {
75     PPC_RSS_SECURE_ACCESS = 0,    /*! Secure access */
76     PPC_RSS_NONSECURE_ACCESS,     /*! Non-secure access */
77 };
78 
79 /* Privilege attribute used to configure the peripherals */
80 enum ppc_rss_priv_attr_t {
81     PPC_RSS_PRIV_AND_NONPRIV_ACCESS = 0, /*! Privilege and NonPrivilege
82                                                 access */
83     PPC_RSS_PRIV_ONLY_ACCESS,            /*! Privilege only access */
84 };
85 
86 /* ARM PPC error codes */
87 enum ppc_rss_error_t {
88     PPC_RSS_ERR_NONE = 0,      /*!< No error */
89     PPC_RSS_ERR_INVALID_PARAM, /*!< PPC invalid parameter error */
90     PPC_RSS_ERR_NOT_INIT,      /*!< PPC not initialized */
91     PPC_RSS_ERR_NOT_PERMITTED  /*!< PPC Operation not permitted */
92 };
93 
94 /**
95  * \brief Initialize the PPC device.
96  *
97  * \param[in] dev       PPC device \ref ppc_rss_dev_t
98  *
99  * \return Returns error code as specified in \ref ppc_rss_error_t
100  *
101  * \note This function doesn't check if dev is NULL.
102  */
103 enum ppc_rss_error_t ppc_rss_init(struct ppc_rss_dev_t* dev);
104 
105 /**
106  * \brief Configures privilege attribute through the PPC device.
107  *
108  * \param[in] dev        PPC device \ref ppc_rss_dev_t
109  * \param[in] mask       Peripheral mask for the PPC.
110  * \param[in] sec_attr   Secure attribute value.
111  * \param[in] priv_attr  Privilege attribute value.
112  *
113  * \return Returns error code as specified in \ref ppc_rss_error_t
114  *
115  * \note This function doesn't check if dev is NULL.
116  */
117 enum ppc_rss_error_t
118 ppc_rss_config_privilege(struct ppc_rss_dev_t* dev, uint32_t mask,
119                             enum ppc_rss_sec_attr_t sec_attr,
120                             enum ppc_rss_priv_attr_t priv_attr);
121 
122 /**
123  * \brief Checks if the peripheral is configured as Privilege only or
124  *        Privilege and non-Privilege access mode.
125  *
126  * \param[in] dev     PPC device \ref ppc_rss_dev_t
127  * \param[in] mask    Peripheral mask for the PPC.
128  *
129  * \return Returns true for Privilege only configuration and false otherwise
130  *           - with non-secure caller in the non-secure domain
131  *           - with secure caller in the configured security domain
132  *         If the driver is not initialized the return value of this function is
133  *         true (Privilege only) as it is the default system configuration.
134  *
135  * \note This function doesn't check if dev is NULL.
136  */
137 bool ppc_rss_is_periph_priv_only(struct ppc_rss_dev_t* dev,
138                                     uint32_t mask);
139 
140 /* Secure only functions */
141 #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U))
142 
143 /**
144  * \brief Configures security attribute through the PPC device.
145  *
146  * \param[in] dev        PPC device \ref ppc_rss_dev_t
147  * \param[in] mask       Peripheral mask for the PPC.
148  * \param[in] sec_attr   Secure attribute value.
149  *
150  * \return Returns error code as specified in \ref ppc_rss_error_t
151  *
152  * \note This function doesn't check if dev is NULL.
153  */
154 enum ppc_rss_error_t
155 ppc_rss_config_security(struct ppc_rss_dev_t* dev, uint32_t mask,
156                            enum ppc_rss_sec_attr_t sec_attr);
157 
158 /**
159  * \brief Checks if the peripheral is configured as secure or non-secure.
160  *
161  * \param[in] dev     PPC device \ref ppc_rss_dev_t
162  * \param[in] mask    Peripheral mask for the PPC.
163  *
164  * \return Returns true for secure and false for non-secure.
165  *         If the driver is not initalized the return value is true (secure) as
166  *         it is the default system configuration.
167  *
168  * \note This function doesn't check if dev is NULL.
169  */
170 bool ppc_rss_is_periph_secure(struct ppc_rss_dev_t* dev,
171                                  uint32_t mask);
172 
173 /**
174  * \brief Enables PPC interrupt.
175  *
176  * \param[in] dev  PPC device \ref ppc_rss_dev_t
177  *
178  * \return Returns error code as specified in \ref ppc_rss_error_t
179  *
180  * \note This function doesn't check if dev is NULL.
181  */
182 enum ppc_rss_error_t ppc_rss_irq_enable(struct ppc_rss_dev_t* dev);
183 
184 /**
185  * \brief Disables PPC interrupt.
186  *
187  * \param[in] dev  PPC device \ref ppc_rss_dev_t
188  *
189  * \note This function doesn't check if dev is NULL.
190  */
191 void ppc_rss_irq_disable(struct ppc_rss_dev_t* dev);
192 
193 /**
194  * \brief Clears PPC interrupt.
195  *
196  * \param[in] dev  PPC device \ref ppc_rss_dev_t
197  *
198  * \note This function doesn't check if dev is NULL.
199  */
200 void ppc_rss_clear_irq(struct ppc_rss_dev_t* dev);
201 
202 /**
203  * \brief Returns the PPC interrupt state.
204  *
205  * \param[in] dev  PPC device \ref ppc_rss_dev_t
206  *
207  * \return Returns true if the interrupt is active and otherwise false.
208  *         If the driver is not initalized the return value of this function is
209  *         false (not active) as it is the default system configuration.
210  *
211  * \note This function doesn't check if dev is NULL.
212  */
213 bool ppc_rss_irq_state(struct ppc_rss_dev_t* dev);
214 
215 #endif /* (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)) */
216 
217 #ifdef __cplusplus
218 }
219 #endif
220 #endif /* __PPC_RSS_DRV_H__ */
221