1 /*
2  * Copyright (c) 2017-2020 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 cache_drv.h
19  * \brief Driver for L1 instruction cache based on SSE-200 version r1p0
20  */
21 
22 #ifndef ARM_CACHE_DRV_H
23 #define ARM_CACHE_DRV_H
24 
25 #include <stdbool.h>
26 #include <stdint.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /**
33  * \brief L1 cache configuration structure
34  */
35 struct arm_cache_dev_cfg_t {
36     const uint32_t base;     /*!< L1 cache base address */
37 };
38 
39 /**
40  * \brief L1 cache device structure
41  */
42 struct arm_cache_dev_t {
43     const struct arm_cache_dev_cfg_t* const cfg;  /*!< L1 cache configuration */
44 };
45 
46 #define ARM_CACHEICHWPARAMS_CSIZE_OFF       0x0U
47                                 /*!< Instruction cache size bit field offset */
48 #define ARM_CACHEICHWPARAMS_STATS_OFF       0x4U
49                                 /*!< Statistic functionality bit field offset */
50 #define ARM_CACHEICHWPARAMS_DMA_OFF         0x5U
51                                 /*!< DMA engine bit field offset */
52 #define ARM_CACHEICHWPARAMS_INVMAT_OFF      0x6U
53                                 /*!< Bit field offset to indicates whether
54                                  * invalidate cache line on write match is
55                                  * enabled */
56 #define ARM_CACHEICHWPARAMS_COFFSIZE_OFF    0xCU
57                                 /*!< Cacheable Block Size bit field offset */
58 #define ARM_CACHEICHWPARAMS_COFFSET_OFF     0x10U
59                                 /*!< Cacheable Offset Addr bit field offset */
60 
61 #define ARM_CACHEICCTRL_CACHEEN_OFF         0x0U
62                                 /*!< Cache enable bit field offset */
63 #define ARM_CACHEICCTRL_FINV_OFF            0x2U
64                                 /*!< Full invalidate bit field offset */
65 #define ARM_CACHEICCTRL_STATEN_OFF          0x3U
66                                 /*!< Enable Statistic bit field offset */
67 #define ARM_CACHEICCTRL_STATC_OFF           0x4U
68                                 /*!< Clear Statistic bit field offset */
69 #define ARM_CACHEICCTRL_HALLOC_OFF          0x5U
70                                 /*!< Enable handler alloc bit field offset */
71 
72 #define ARM_CACHE_INTR_IC_OFF   0x0U /*!< Invalidate Complete IRQ offset */
73 #define ARM_CACHE_INTR_CDC_OFF  0x1U /*!< Cache Disable Complete IRQ offset */
74 #define ARM_CACHE_INTR_CEC_OFF  0x2U /*!< Cache Enable Complete IRQ offset */
75 #define ARM_CACHE_INTR_CFE_OFF  0x3U /*!< Cache Fill Error IRQ offset */
76 #define ARM_CACHE_INTR_SV_OFF   0x4U /*!< Security violation IRQ offset */
77 #define ARM_CACHE_INTR_SS_OFF   0x5U /*!< Statistics Saturated IRQ offset */
78 
79 /**
80  * \brief L1 Cache Interrupt data structure
81  */
82 enum arm_cache_intr_t {
83   arm_cache_ic_intr_mask  = (0x1U<<ARM_CACHE_INTR_IC_OFF),
84                                   /*!< Invalidate Complete IRQ Mask */
85   arm_cache_cdc_intr_mask = (0x1U<<ARM_CACHE_INTR_CDC_OFF),
86                                   /*!< Cache Disable Complete IRQ Mask */
87   arm_cache_cec_intr_mask = (0x1U<<ARM_CACHE_INTR_CEC_OFF),
88                                   /*!< Cache Enable Complete IRQ Mask */
89   arm_cache_cfe_intr_mask = (0x1U<<ARM_CACHE_INTR_CFE_OFF),
90                                   /*!< Cache Fill Error IRQ Mask */
91   arm_cache_sv_intr_mask  = (0x1U<<ARM_CACHE_INTR_SV_OFF),
92                                   /*!< Security violation IRQ Mask */
93   arm_cache_ss_intr_mask  = (0x1U<<ARM_CACHE_INTR_SS_OFF),
94                                   /*!< Statistics Saturated IRQ Mask */
95 };
96 
97 /**
98  * \brief L1 Cache size data structure
99  */
100 enum arm_cache_size_t {
101   arm_cache_size_err = 0,     /*!< Invalid Cache size*/
102   arm_cache_size_512B = 9,    /*!< Cache size 512 byte*/
103   arm_cache_size_1KB = 10,    /*!< Cache size 1KB*/
104   arm_cache_size_2KB = 11,    /*!< Cache size 2KB*/
105   arm_cache_size_4KB = 12,    /*!< Cache size 4KB*/
106   arm_cache_size_8KB = 13,    /*!< Cache size 8KB*/
107   arm_cache_size_16KB = 14   /*!< Cache size 16KB*/
108 };
109 
110 /**
111  * \brief Returns cache size
112  *
113  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
114  *
115  * \return Returns cache size struct \ref arm_cache_size_t
116  *
117  * \note This function doesn't check if dev is NULL.
118  */
119 enum arm_cache_size_t arm_cache_get_size(struct arm_cache_dev_t* dev);
120 
121 /**
122  * \brief Check if statistic functionality is available in Icache
123  *
124  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
125  *
126  * \return Returns bool, true if statistic functionality is available,
127  * false otherwise
128  *
129  * \note This function doesn't check if dev is NULL.
130  */
131 bool arm_cache_is_stat_func_available(struct arm_cache_dev_t* dev);
132 
133 /**
134  * \brief Check if invalidate cache line on write match is enabled
135  *
136  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
137  *
138  * \return Returns bool, true if invalidate cache line is enabled,
139  * false otherwise
140  *
141  * \note This function doesn't check if dev is NULL.
142  */
143 bool arm_cache_is_invalidate_cache_line_enabled(struct arm_cache_dev_t* dev);
144 
145 /**
146  * \brief Enables cache in ARM SSE-200.
147  *
148  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
149  *
150  * \note This function doesn't check if dev is NULL.
151  */
152 void arm_cache_enable(struct arm_cache_dev_t* dev);
153 
154 /**
155  * \brief Enables cache, returns when enable action is completed.
156  *
157  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
158  *
159  * \note Ensure that Cache Enable Interrupt is cleared before calling this API,
160  *       \ref arm_cache_clear_intr()
161  * \note This is a blocking API, returns when the cache is enabled
162  * \note This function doesn't check if dev is NULL.
163  */
164 void arm_cache_enable_blocking(struct arm_cache_dev_t* dev);
165 
166 /**
167  * \brief Disables cache in ARM SSE-200.
168  *
169  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
170  *
171  * \note This function doesn't check if dev is NULL.
172  */
173 void arm_cache_disable(struct arm_cache_dev_t* dev);
174 
175 /**
176  * \brief Disables cache, returns when disable action is completed.
177  *
178  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
179  *
180  * \note Ensure that Cache Disable Interrupt is cleared before calling this API,
181  *       \ref arm_cache_clear_intr()
182  * \note This is a blocking API, returns when the cache is disabled
183  * \note This function doesn't check if dev is NULL.
184  */
185 void arm_cache_disable_blocking(struct arm_cache_dev_t* dev);
186 
187 /**
188  * \brief Check if cache is enabled.
189  *
190  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
191  *
192  * \return Returns bool, true if cache is enabled, false otherwise
193  *
194  * \note This function doesn't check if dev is NULL.
195  */
196 bool arm_cache_is_enabled(struct arm_cache_dev_t* dev);
197 
198 /**
199  * \brief Invalidates full cache in ARM SSE-200.
200  *
201  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
202  *
203  * \note Calling this API will trigger the Instruction cache to invalidate
204  *       all cache lines.
205  * \note This function doesn't check if dev is NULL.
206  */
207 void arm_cache_full_invalidate(struct arm_cache_dev_t* dev);
208 
209 /**
210  * \brief Invalidates full cache, returns when invalidated action is completed.
211  *
212  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
213  *
214  * \note Ensure that Invalidate Complete Intr is cleared before calling this API
215  *       \ref arm_cache_clear_intr()
216  * \note This is a blocking API, returns when the cache is invalidated
217  * \note Calling this API will trigger the Instruction cache to invalidate
218  *       all cache lines.
219  * \note This function doesn't check if dev is NULL.
220  */
221 void arm_cache_full_invalidate_blocking(struct arm_cache_dev_t* dev);
222 
223 /**
224  * \brief Enables statistic function for cache in ARM SSE-200.
225  *
226  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
227  *
228  * \note This function doesn't check if dev is NULL.
229  */
230 void arm_cache_statistic_enable(struct arm_cache_dev_t* dev);
231 
232 /**
233  * \brief Disables statistic function for cache in ARM SSE-200.
234  *
235  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
236  *
237  * \note This function doesn't check if dev is NULL.
238  */
239 void arm_cache_statistic_disable(struct arm_cache_dev_t* dev);
240 
241 /**
242  * \brief Clear statistic values for cache in ARM SSE-200.
243  *
244  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
245  *
246  * \note This function doesn't check if dev is NULL.
247  */
248 void arm_cache_clear_statistic_value(struct arm_cache_dev_t* dev);
249 
250 /**
251  * \brief Enables handler allocation function for cache in ARM SSE-200.
252  *
253  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
254  *
255  * \note This function doesn't check if dev is NULL.
256  */
257 void arm_cache_handler_alloc_enable(struct arm_cache_dev_t* dev);
258 
259 /**
260  * \brief Disables handler allocation function for cache in ARM SSE-200.
261  *
262  * \param[in] dev         L1 cache device struct \ref arm_cache_dev_t
263  *
264  * \note This function doesn't check if dev is NULL.
265  */
266 void arm_cache_handler_alloc_disable(struct arm_cache_dev_t* dev);
267 
268 /**
269  * \brief Enables cache interrupts
270  *
271  * \param[in] dev    Cache device struct \ref arm_cache_dev_t
272  * \param[in] mask   Bit mask for enabling interrupts \ref arm_cache_intr_t
273  *
274  * \note User is responsible to set mask accordingly. Mask set to 0 will not
275  *       have any effect.
276  * \note User is responsible to configure the interrupt vector and
277  *       the interrupt controller.
278  * \note This function doesn't check if dev is NULL.
279  */
280 void arm_cache_enable_intr(struct arm_cache_dev_t* dev,
281                     enum arm_cache_intr_t mask);
282 
283 /**
284  * \brief Disables cache interrupts
285  *
286  * \param[in] dev    Cache device struct \ref arm_cache_dev_t
287  * \param[in] mask   Bit mask for disabling interrupts \ref arm_cache_intr_t
288  *
289  * \note User is responsible to set mask accordingly. Mask set to 0 will not
290  *       have any effect.
291  * \note This function doesn't check if dev is NULL.
292  */
293 void arm_cache_disable_intr(struct arm_cache_dev_t* dev,
294                     enum arm_cache_intr_t mask);
295 
296 /**
297  * \brief Clears cache Interrupt
298  *
299  * \param[in] dev  Cache device struct \ref arm_cache_dev_t
300  * \param[in] mask Bit mask for clearing interrupts \ref arm_cache_intr_t
301  *
302  * \note This function doesn't check if dev is NULL.
303  */
304 void arm_cache_clear_intr(struct arm_cache_dev_t* dev,
305                     enum arm_cache_intr_t mask);
306 
307 /**
308  * \brief Returns the cache Masked interrupt status
309  *
310  * \param[in] dev  Cache device struct \ref arm_cache_dev_t
311  *
312  * \return Masked interrupt status \ref arm_cache_intr_t
313  *
314  * \note This function doesn't check if dev is NULL.
315  */
316 enum arm_cache_intr_t arm_cache_get_masked_intr_status(
317                     struct arm_cache_dev_t* dev);
318 
319 /**
320  * \brief Returns the cache Raw interrupt status
321  *
322  * \param[in] dev  Cache device struct \ref arm_cache_dev_t
323  *
324  * \return Raw interrupt status \ref arm_cache_intr_t
325  *
326  * \note This function doesn't check if dev is NULL.
327  */
328 enum arm_cache_intr_t arm_cache_get_raw_intr_status(
329                     struct arm_cache_dev_t* dev);
330 
331 /**
332  * \brief Returns the debug fill error address
333  *
334  * \param[in] dev  Cache device struct \ref arm_cache_dev_t
335  *
336  * \return Address that is involved in a recent fill error
337  *
338  * \note This function doesn't check if dev is NULL.
339  */
340 uint32_t arm_cache_get_debug_fill_address(struct  arm_cache_dev_t* dev);
341 
342 /**
343  * \brief Returns the Icache hit counter value
344  *
345  * \param[in] dev  Cache device struct \ref arm_cache_dev_t
346  *
347  * \return Icache hit counter value since the last counter clear operation
348  *
349  * \note This function doesn't check if dev is NULL.
350  */
351 uint32_t arm_cache_get_hit_count(struct  arm_cache_dev_t* dev);
352 
353 /**
354  * \brief Returns the Icache miss counter value
355  *
356  * \param[in] dev  Cache device struct \ref arm_cache_dev_t
357  *
358  * \return Icache miss counter value since the last counter clear operation
359  *
360  * \note This function doesn't check if dev is NULL.
361  */
362 uint32_t arm_cache_get_miss_count(struct  arm_cache_dev_t* dev);
363 
364 /**
365  * \brief Returns the Icache uncached access counter value
366  *
367  * \param[in] dev  Cache device struct \ref arm_cache_dev_t
368  *
369  * \return Icache uncached counter value since the last counter clear operation
370  *
371  * \note This function doesn't check if dev is NULL.
372  */
373 uint32_t arm_cache_get_uncached_count(struct  arm_cache_dev_t* dev);
374 
375 #ifdef __cplusplus
376 }
377 #endif
378 #endif /* ARM_CACHE_DRV_H */
379 
380