1 /*
2 * Copyright (c) 2019 - 2024, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef NRF_CACHE_H__
35 #define NRF_CACHE_H__
36
37 #include <nrfx.h>
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /**
44 * @defgroup nrf_cache_hal CACHE HAL
45 * @{
46 * @ingroup nrf_cache
47 * @brief The hardware access layer for managing the CACHE peripheral.
48 */
49
50 #if defined(CACHEDATA_SET_WAY_DU_DATA_Data_Msk) || defined(CACHEDATA_SET_WAY_DATA0_Data_Msk) || \
51 defined(__NRFX_DOXYGEN__)
52 /** @brief Presence of the CACHEDATA feature. */
53 #define NRF_CACHE_HAS_CACHEDATA 1
54 #else
55 #define NRF_CACHE_HAS_CACHEDATA 0
56 #endif
57
58 #if defined(CACHEDATA_SET_WAY_DU_DATA_Data_Msk) || defined(__NRFX_DOXYGEN__)
59 /** @brief Presence of the CACHE data units feature. */
60 #define NRF_CACHE_HAS_CACHEDATA_DU 1
61 #else
62 #define NRF_CACHE_HAS_CACHEDATA_DU 0
63 #endif
64
65 #if defined(CACHEINFO_SET_WAY_INFO_TAG_Msk) || defined(CACHEINFO_SET_WAY_TAG_Msk) || \
66 defined(__NRFX_DOXYGEN__)
67 /** @brief Presence of the CACHEINFO feature. */
68 #define NRF_CACHE_HAS_CACHEINFO 1
69 #else
70 #define NRF_CACHE_HAS_CACHEINFO 0
71 #endif
72
73 #if defined(CACHE_TASKS_INVALIDATECACHE_TASKS_INVALIDATECACHE_Msk) || defined(__NRFX_DOXYGEN__)
74 /** @brief Symbol indicating whether cache tasks are supported. */
75 #define NRF_CACHE_HAS_TASKS 1
76 #else
77 #define NRF_CACHE_HAS_TASKS 0
78 #endif
79
80 #if defined(CACHE_TASKS_CLEANCACHE_TASKS_CLEANCACHE_Msk) || defined(__NRFX_DOXYGEN__)
81 /** @brief Symbol indicating whether the CLEAN cache/line tasks are supported. */
82 #define NRF_CACHE_HAS_TASK_CLEAN 1
83 #else
84 #define NRF_CACHE_HAS_TASK_CLEAN 0
85 #endif
86
87 #if defined(CACHE_TASKS_FLUSHCACHE_TASKS_FLUSHCACHE_Msk) || defined(__NRFX_DOXYGEN__)
88 /** @brief Symbol indicating whether the FLUSH cache/line tasks are supported. */
89 #define NRF_CACHE_HAS_TASK_FLUSH 1
90 #else
91 #define NRF_CACHE_HAS_TASK_FLUSH 0
92 #endif
93
94 #if defined(CACHE_TASKS_SAVE_TASKS_SAVE_Msk) || defined(__NRFX_DOXYGEN__)
95 /** @brief Symbol indicating whether save and restore tasks are supported. */
96 #define NRF_CACHE_HAS_TASK_SAVE_RESTORE 1
97 #else
98 #define NRF_CACHE_HAS_TASK_SAVE_RESTORE 0
99 #endif
100
101 #if defined(CACHE_STATUS_READY_Msk) || defined(CACHE_STATUS_BUSY_Msk) || defined(__NRFX_DOXYGEN__)
102 /** @brief Symbol indicating whether status check is supported. */
103 #define NRF_CACHE_HAS_STATUS 1
104 #else
105 #define NRF_CACHE_HAS_STATUS 0
106 #endif
107
108 #if defined(CACHE_MODE_MODE_Msk) || defined(__NRFX_DOXYGEN__)
109 /** @brief Symbol indicating whether splitting the dedicated RAM between cache and generic memory is supported. */
110 #define NRF_CACHE_HAS_RAM_MODE 1
111 #else
112 #define NRF_CACHE_HAS_RAM_MODE 0
113 #endif
114
115 #if defined(CACHE_MODE_RAMSIZE_Msk) || defined(__NRFX_DOXYGEN__)
116 /** @brief Symbol indicating whether configuration of split of dedicated RAM between cache and generic memory is supported. */
117 #define NRF_CACHE_HAS_RAMSIZE 1
118 #else
119 #define NRF_CACHE_HAS_RAMSIZE 0
120 #endif
121
122 #if defined(CACHEINFO_SET_WAY_D0_Msk) || defined(__NRFX_DOXYGEN__)
123 /** @brief Symbol indicating whether dirtiness check functionality for cache is supported. */
124 #define NRF_CACHE_HAS_CACHEINFO_DU_DIRTY 1
125 #else
126 #define NRF_CACHE_HAS_CACHEINFO_DU_DIRTY 0
127 #endif
128
129 #if defined(CACHEINFO_SET_WAY_DUV0_Msk) || defined(CACHEINFO_SET_WAY_INFO_DUV0_Msk) || defined(__NRFX_DOXYGEN__)
130 /** @brief Symbol indicating whether data unit validation functionality for cache is supported. */
131 #define NRF_CACHE_HAS_CACHEINFO_DU_VALIDATION 1
132 #else
133 #define NRF_CACHE_HAS_CACHEINFO_DU_VALIDATION 0
134 #endif
135
136 #if defined(CACHEINFO_SET_WAY_INFO_DUV0_Msk) || defined(__NRFX_DOXYGEN__)
137 /** @brief Symbol indicating whether cache info has INFO register. */
138 #define NRF_CACHE_HAS_CACHEINFO_SET_WAY_INFO 1
139 #else
140 #define NRF_CACHE_HAS_CACHEINFO_SET_WAY_INFO 0
141 #endif
142
143 #if NRF_CACHE_HAS_CACHEDATA
144 /** @brief Max number of words in CACHEDATA data units. */
145 #define NRF_CACHEDATA_DATA_WORDS_IN_UNIT_MAX CACHEDATA_SET_WAY_DU_DATA_MaxCount
146 /** @brief Max number of CACHEDATA data units. */
147 #define NRF_CACHEDATA_DATA_UNITS_MAX CACHEDATA_SET_WAY_DU_MaxCount
148 /** @brief Max number of CACHEDATA words. */
149 #define NRF_CACHEDATA_WORD_INDEX_MAX \
150 (NRF_CACHEDATA_DATA_WORDS_IN_UNIT_MAX * NRF_CACHEDATA_DATA_UNITS_MAX)
151 /** @brief Max number of CACHEDATA ways. */
152 #define NRF_CACHEDATA_WAY_INDEX_MAX CACHEDATA_SET_WAY_MaxCount
153 /** @brief Max number of CACHEDATA sets. */
154 #define NRF_CACHEDATA_SET_INDEX_MAX CACHEDATA_SET_MaxCount
155 #endif
156
157 #if NRF_CACHE_HAS_CACHEINFO
158 /** @brief Max number of words in CACHEINFO data units. */
159 #define NRF_CACHEINFO_DATA_WORDS_IN_UNIT_MAX CACHEDATA_SET_WAY_DU_DATA_MaxCount
160 /** @brief Max number of CACHEINFO data units. */
161 #define NRF_CACHEINFO_DATA_UNITS_MAX CACHEDATA_SET_WAY_DU_MaxCount
162 /** @brief Max number of CACHEINFO words. */
163 #define NRF_CACHEINFO_WORD_INDEX_MAX \
164 (NRF_CACHEINFO_DATA_WORDS_IN_UNIT_MAX * NRF_CACHEINFO_DATA_UNITS_MAX)
165 /** @brief Max number of CACHEINFO ways. */
166 #define NRF_CACHEINFO_WAY_INDEX_MAX CACHEINFO_SET_WAY_MaxCount
167 /** @brief Max number of CACHEINFO sets. */
168 #define NRF_CACHEINFO_SET_INDEX_MAX CACHEINFO_SET_MaxCount
169 #endif
170
171 #if NRF_CACHE_HAS_RAMSIZE
172 /** @brief Max enumerator value of RAMSIZE field. */
173 #define NRF_CACHE_MODE_RAMSIZE_MAX CACHE_MODE_RAMSIZE_Max
174 #endif
175
176 #if NRF_CACHE_HAS_TASKS
177 /** @brief CACHE tasks. */
178 typedef enum
179 {
180 #if NRF_CACHE_HAS_TASK_CLEAN
181 NRF_CACHE_TASK_CLEANCACHE = offsetof(NRF_CACHE_Type, TASKS_CLEANCACHE), /**< Clean the whole cache. */
182 NRF_CACHE_TASK_CLEANLINE = offsetof(NRF_CACHE_Type, TASKS_CLEANLINE), /**< Clean the cache line. */
183 #endif
184 #if NRF_CACHE_HAS_TASK_FLUSH
185 NRF_CACHE_TASK_FLUSHCACHE = offsetof(NRF_CACHE_Type, TASKS_FLUSHCACHE), /**< Flush the whole cache. */
186 NRF_CACHE_TASK_FLUSHLINE = offsetof(NRF_CACHE_Type, TASKS_FLUSHLINE), /**< Flush the cache line. */
187 #endif
188 #if NRF_CACHE_HAS_TASK_SAVE_RESTORE
189 NRF_CACHE_TASK_SAVE = offsetof(NRF_CACHE_Type, TASKS_SAVE), /**< Save the state to a retained memory space. */
190 NRF_CACHE_TASK_RESTORE = offsetof(NRF_CACHE_Type, TASKS_RESTORE), /**< Restore the state from a retained memory space. */
191 #endif
192 NRF_CACHE_TASK_INVALIDATECACHE = offsetof(NRF_CACHE_Type, TASKS_INVALIDATECACHE), /**< Invalidate the whole cache. */
193 NRF_CACHE_TASK_INVALIDATELINE = offsetof(NRF_CACHE_Type, TASKS_INVALIDATELINE), /**< Invalidate the cache line. */
194 NRF_CACHE_TASK_ERASE = offsetof(NRF_CACHE_Type, TASKS_ERASE), /**< Erase the whole cache. */
195 } nrf_cache_task_t;
196 #endif
197
198 /** @brief Cache regions. */
199 typedef enum
200 {
201 NRF_CACHE_REGION_FLASH = 0, ///< Cache region related to Flash access.
202 NRF_CACHE_REGION_XIP = 1, ///< Cache region related to XIP access.
203 } nrf_cache_region_t;
204
205 #if NRF_CACHE_HAS_RAMSIZE
206 /** @brief Dedicated RAM size used for cache memory. */
207 typedef enum
208 {
209 NRF_CACHE_RAMSIZE_ALL = CACHE_MODE_RAMSIZE_All, ///< All RAM is used for cache memory.
210 NRF_CACHE_RAMSIZE_HALF = CACHE_MODE_RAMSIZE_Half, ///< Half of the RAM is used for cache memory.
211 NRF_CACHE_RAMSIZE_QUARTER = CACHE_MODE_RAMSIZE_Quarter, ///< Quarter of the RAM is used for cache memory.
212 NRF_CACHE_RAMSIZE_NONE = CACHE_MODE_RAMSIZE_None ///< None of the RAM is used for cache memory.
213 } nrf_cache_ramsize_t;
214 #endif
215
216 /**
217 * @brief Function for enabling the CACHE peripheral.
218 *
219 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
220 */
221 NRF_STATIC_INLINE void nrf_cache_enable(NRF_CACHE_Type * p_reg);
222
223 /**
224 * @brief Function for disabling the CACHE peripheral.
225 *
226 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
227 */
228 NRF_STATIC_INLINE void nrf_cache_disable(NRF_CACHE_Type * p_reg);
229
230 /**
231 * @brief Function for checking if the CACHE peripheral is enabled.
232 *
233 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
234 *
235 * @retval true The CACHE is enabled.
236 * @retval false The CACHE is not enabled.
237 */
238 NRF_STATIC_INLINE bool nrf_cache_enable_check(NRF_CACHE_Type const * p_reg);
239
240 /**
241 * @brief Function for invalidating the cache content.
242 *
243 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
244 */
245 NRF_STATIC_INLINE void nrf_cache_invalidate(NRF_CACHE_Type * p_reg);
246
247 /**
248 * @brief Function for erasing the cache content.
249 *
250 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
251 */
252 NRF_STATIC_INLINE void nrf_cache_erase(NRF_CACHE_Type * p_reg);
253
254 /**
255 * @brief Function for checking the status of @ref nrf_cache_erase().
256 *
257 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
258 *
259 * @retval true Erase is finished.
260 * @retval false Erase is not complete or has not started.
261 */
262 NRF_STATIC_INLINE bool nrf_cache_erase_status_check(NRF_CACHE_Type const * p_reg);
263
264 /**
265 * @brief Function for clearing the status of the cache erase.
266 *
267 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
268 */
269 NRF_STATIC_INLINE void nrf_cache_erase_status_clear(NRF_CACHE_Type * p_reg);
270
271 /**
272 * @brief Function for setting the cache profiling.
273 *
274 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
275 * @param[in] enable True if cache profiling is to be enabled, false otherwise.
276 */
277 NRF_STATIC_INLINE void nrf_cache_profiling_set(NRF_CACHE_Type * p_reg, bool enable);
278
279 /**
280 * @brief Function for clearing the cache profiling counters.
281 *
282 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
283 */
284 NRF_STATIC_INLINE void nrf_cache_profiling_counters_clear(NRF_CACHE_Type * p_reg);
285
286 /**
287 * @brief Function for getting the number of cache hits for instruction fetch from the specified
288 * cache region.
289 *
290 * @note Separate counters are used for flash region and XIP region.
291 * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
292 *
293 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
294 * @param[in] region Cache region.
295 *
296 * @return Number of instruction fetch cache hits.
297 */
298 NRF_STATIC_INLINE uint32_t nrf_cache_instruction_hit_counter_get(NRF_CACHE_Type const * p_reg,
299 nrf_cache_region_t region);
300
301 /**
302 * @brief Function for getting the number of cache misses for instruction fetch from the specified
303 * cache region.
304 *
305 * @note Separate counters are used for flash region and XIP region.
306 * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
307 *
308 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
309 * @param[in] region Cache region.
310 *
311 * @return Number of instruction fetch cache misses.
312 */
313 NRF_STATIC_INLINE uint32_t nrf_cache_instruction_miss_counter_get(NRF_CACHE_Type const * p_reg,
314 nrf_cache_region_t region);
315
316 /**
317 * @brief Function for getting the number of cache hits for data fetch from the specified
318 * cache region.
319 *
320 * @note Separate counters are used for flash region and XIP region.
321 * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
322 *
323 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
324 * @param[in] region Cache region.
325 *
326 * @return Number of data fetch cache hits.
327 */
328 NRF_STATIC_INLINE uint32_t nrf_cache_data_hit_counter_get(NRF_CACHE_Type const * p_reg,
329 nrf_cache_region_t region);
330
331 /**
332 * @brief Function for getting the number of cache misses for data fetch from the specified
333 * cache region.
334 *
335 * @note Separate counters are used for flash region and XIP region.
336 * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
337 *
338 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
339 * @param[in] region Cache region.
340 *
341 * @return Number of data fetch cache misses.
342 */
343 NRF_STATIC_INLINE uint32_t nrf_cache_data_miss_counter_get(NRF_CACHE_Type const * p_reg,
344 nrf_cache_region_t region);
345
346 #if NRF_CACHE_HAS_RAM_MODE
347 /**
348 * @brief Function for setting the cache RAM mode.
349 *
350 * When configured in the RAM mode, the accesses to internal or external flash will not be cached.
351 * In this mode, the cache data contents can be used as the read/write RAM.
352 * Only the data content of the cache is available as RAM.
353 *
354 * @note Enabling the RAM mode causes the RAM to be cleared.
355 * @note Disabling the RAM mode causes the cache to be invalidated.
356 *
357 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
358 * @param[in] enable True if the cache RAM mode is to be enabled, false otherwise.
359 */
360 NRF_STATIC_INLINE void nrf_cache_ram_mode_set(NRF_CACHE_Type * p_reg, bool enable);
361
362 /**
363 * @brief Function for checking whether the cache is in RAM mode.
364 *
365 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
366 *
367 * @return True if the cache RAM mode is enabled, false otherwise.
368 */
369 NRF_STATIC_INLINE bool nrf_cache_ram_mode_check(NRF_CACHE_Type const * p_reg);
370 #endif
371
372 #if NRF_CACHE_HAS_RAMSIZE
373 /**
374 * @brief Function for setting the configuration of splitting the dedicated cache RAM.
375 *
376 * @details Dedicated cache RAM can be splitted into cache memory and generic memory.
377 * By default, all dedicated RAM is used for cache memory.
378 *
379 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
380 * @param[in] ramsize Dedicated cache RAM split configuration.
381 */
382 NRF_STATIC_INLINE void nrf_cache_ramsize_set(NRF_CACHE_Type * p_reg, nrf_cache_ramsize_t ramsize);
383
384 /**
385 * @brief Function for getting the configuration of splitting the dedicated cache RAM.
386 *
387 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
388 *
389 * @return Configuration of dedicated cache RAM split.
390 */
391 NRF_STATIC_INLINE nrf_cache_ramsize_t nrf_cache_ramsize_get(NRF_CACHE_Type const * p_reg);
392 #endif
393
394 /**
395 * @brief Function for blocking the cache content access.
396 *
397 * To unlock the cache content access, a reset has to be performed.
398 *
399 * @note Blocking is ignored in the RAM mode.
400 *
401 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
402 */
403 NRF_STATIC_INLINE void nrf_cache_read_lock_enable(NRF_CACHE_Type * p_reg);
404
405 /**
406 * @brief Function for blocking the cache content updates.
407 *
408 * Blocking of updates prevents updating of cache content on cache misses,
409 * but the peripheral will continue to check for instruction/data fetches
410 * in the content already present in the cache.
411 *
412 * @note Blocking is ignored in the RAM mode.
413 *
414 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
415 * @param[in] enable True if cache content update lock is to be enabled, false otherwise.
416 */
417 NRF_STATIC_INLINE void nrf_cache_update_lock_set(NRF_CACHE_Type * p_reg, bool enable);
418
419 #if NRF_CACHE_HAS_CACHEDATA
420 /**
421 * @brief Function for getting the cache data word.
422 *
423 * @note When operating in the RAM mode, the cache data is accessible as a general purpose RAM.
424 *
425 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
426 * @param[in] set Set that contains the data to get.
427 * @param[in] way Way that contains the data to get.
428 * @param[in] word Data word index to get.
429 *
430 * @return 32-bit data word.
431 */
432 NRF_STATIC_INLINE uint32_t nrf_cache_data_get(NRF_CACHEDATA_Type const * p_reg,
433 uint32_t set,
434 uint8_t way,
435 uint8_t word);
436 #endif
437
438 #if NRF_CACHE_HAS_CACHEINFO
439 /**
440 * @brief Function for getting the tag associated with the specified set and way.
441 *
442 * The tag is used to check if an entry in the cache matches the address that is being fetched.
443 *
444 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
445 * @param[in] set Set that contains the tag to get.
446 * @param[in] way Way that contains the tag to get.
447 *
448 * @return Tag value.
449 */
450 NRF_STATIC_INLINE uint32_t nrf_cache_tag_get(NRF_CACHEINFO_Type const * p_reg,
451 uint32_t set,
452 uint8_t way);
453
454 /**
455 * @brief Function for checking the validity of a cache line associated with the specified set and way.
456 *
457 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
458 * @param[in] set Set that contains the cache line to check.
459 * @param[in] way Way that contains the cache line to check.
460 *
461 * @retval true Cache line is valid.
462 * @retval false Cache line is invalid.
463 */
464 NRF_STATIC_INLINE bool nrf_cache_line_validity_check(NRF_CACHEINFO_Type const * p_reg,
465 uint32_t set,
466 uint8_t way);
467
468 /**
469 * @brief Function for getting the most recently used way in the specified set.
470 *
471 * The most recently used way is updated on each fetch from the cache and is used for the cache replacement policy.
472 *
473 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
474 * @param[in] set Specified set.
475 *
476 * @return The most recently used way in the specified set.
477 */
478 NRF_STATIC_INLINE uint8_t nrf_cache_mru_get(NRF_CACHEINFO_Type const * p_reg, uint32_t set);
479 #endif
480
481 #if NRF_CACHE_HAS_CACHEINFO_DU_VALIDATION
482 /**
483 * @brief Function for checking the validity of a data unit associated with the specified set, way and word.
484 *
485 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
486 * @param[in] set Set that contains the data unit to check.
487 * @param[in] way Way that contains the data unit to check.
488 * @param[in] word Data word index.
489 *
490 * @retval true Data unit is valid.
491 * @retval false Data unit is invalid.
492 */
493 NRF_STATIC_INLINE bool nrf_cache_data_unit_validity_check(NRF_CACHEINFO_Type const * p_reg,
494 uint32_t set,
495 uint8_t way,
496 uint8_t word);
497 #endif
498
499 #if NRF_CACHE_HAS_CACHEINFO_DU_DIRTY
500 /**
501 * @brief Function for checking the dirtiness of a data unit associated with the specified set, way and word.
502 *
503 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
504 * @param[in] set Set that contains the data unit to check.
505 * @param[in] way Way that contains the data unit to check.
506 * @param[in] word Data word index.
507 *
508 * @retval true Data unit is dirty.
509 * @retval false Data unit is clean.
510 */
511 NRF_STATIC_INLINE bool nrf_cache_is_data_unit_dirty_check(NRF_CACHEINFO_Type const * p_reg,
512 uint32_t set,
513 uint8_t way,
514 uint8_t word);
515 #endif
516
517 #if NRF_CACHE_HAS_TASKS
518 /**
519 * @brief Function to set the memory address covered by the line to be maintained.
520 *
521 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
522 * @param[in] addr Cache line adress.
523 */
524 NRF_STATIC_INLINE void nrf_cache_lineaddr_set(NRF_CACHE_Type * p_reg, uint32_t addr);
525
526 /**
527 * @brief Function to get the memory address covered by the line to be maintained.
528 *
529 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
530 *
531 * @return Cache line adress.
532 */
533 NRF_STATIC_INLINE uint32_t nrf_cache_lineaddr_get(NRF_CACHE_Type const * p_reg);
534
535 /**
536 * @brief Function for triggering the specified CACHE task.
537 *
538 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
539 * @param[in] task Task.
540 */
541 NRF_STATIC_INLINE void nrf_cache_task_trigger(NRF_CACHE_Type * p_reg, nrf_cache_task_t task);
542
543 /**
544 * @brief Function for returning the address of the specified task register.
545 *
546 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
547 * @param[in] task Task.
548 *
549 * @return Task address.
550 */
551 NRF_STATIC_INLINE uint32_t nrf_cache_task_address_get(NRF_CACHE_Type const * p_reg,
552 nrf_cache_task_t task);
553 #endif
554
555 #if NRF_CACHE_HAS_STATUS
556 /**
557 * @brief Function for checking if the cache is busy or not.
558 *
559 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
560 *
561 * @return True if the cache is busy, false otherwise.
562 */
563 NRF_STATIC_INLINE bool nrf_cache_busy_check(NRF_CACHE_Type const * p_reg);
564 #endif
565
566 #ifndef NRF_DECLARE_ONLY
567
nrf_cache_enable(NRF_CACHE_Type * p_reg)568 NRF_STATIC_INLINE void nrf_cache_enable(NRF_CACHE_Type * p_reg)
569 {
570 p_reg->ENABLE = CACHE_ENABLE_ENABLE_Enabled;
571 }
572
nrf_cache_disable(NRF_CACHE_Type * p_reg)573 NRF_STATIC_INLINE void nrf_cache_disable(NRF_CACHE_Type * p_reg)
574 {
575 p_reg->ENABLE = CACHE_ENABLE_ENABLE_Disabled;
576 }
577
nrf_cache_enable_check(NRF_CACHE_Type const * p_reg)578 NRF_STATIC_INLINE bool nrf_cache_enable_check(NRF_CACHE_Type const * p_reg)
579 {
580 return p_reg->ENABLE == CACHE_ENABLE_ENABLE_Enabled;
581 }
582
nrf_cache_invalidate(NRF_CACHE_Type * p_reg)583 NRF_STATIC_INLINE void nrf_cache_invalidate(NRF_CACHE_Type * p_reg)
584 {
585 #if NRF_CACHE_HAS_TASKS
586 nrf_cache_task_trigger(p_reg, NRF_CACHE_TASK_INVALIDATECACHE);
587 #else
588 p_reg->INVALIDATE = CACHE_INVALIDATE_INVALIDATE_Invalidate;
589 #endif
590 }
591
nrf_cache_erase(NRF_CACHE_Type * p_reg)592 NRF_STATIC_INLINE void nrf_cache_erase(NRF_CACHE_Type * p_reg)
593 {
594 #if NRF_CACHE_HAS_TASKS
595 nrf_cache_task_trigger(p_reg, NRF_CACHE_TASK_ERASE);
596 #else
597 p_reg->ERASE = CACHE_ERASE_ERASE_Erase;
598 #endif
599 }
600
nrf_cache_erase_status_check(NRF_CACHE_Type const * p_reg)601 NRF_STATIC_INLINE bool nrf_cache_erase_status_check(NRF_CACHE_Type const * p_reg)
602 {
603 #if NRF_CACHE_HAS_STATUS
604 return (!nrf_cache_busy_check(p_reg));
605 #else
606 return (p_reg->ERASESTATUS & CACHE_ERASESTATUS_ERASESTATUS_Msk) ==
607 (CACHE_ERASESTATUS_ERASESTATUS_Finished << CACHE_ERASESTATUS_ERASESTATUS_Pos);
608 #endif
609 }
610
nrf_cache_erase_status_clear(NRF_CACHE_Type * p_reg)611 NRF_STATIC_INLINE void nrf_cache_erase_status_clear(NRF_CACHE_Type * p_reg)
612 {
613 #if NRF_CACHE_HAS_TASKS
614 /* No task for erasing the status */
615 (void)p_reg;
616 #else
617 p_reg->ERASESTATUS = 0;
618 #endif
619 }
620
nrf_cache_profiling_set(NRF_CACHE_Type * p_reg,bool enable)621 NRF_STATIC_INLINE void nrf_cache_profiling_set(NRF_CACHE_Type * p_reg, bool enable)
622 {
623 #if defined(CACHE_PROFILINGENABLE_ENABLE_Msk)
624 p_reg->PROFILINGENABLE =
625 (enable ? CACHE_PROFILINGENABLE_ENABLE_Enable : CACHE_PROFILINGENABLE_ENABLE_Disable);
626 #elif defined(CACHE_PROFILING_ENABLE_ENABLE_Msk)
627 p_reg->PROFILING.ENABLE =
628 (enable ? CACHE_PROFILING_ENABLE_ENABLE_Enable : CACHE_PROFILING_ENABLE_ENABLE_Disable);
629 #endif
630 }
631
nrf_cache_profiling_counters_clear(NRF_CACHE_Type * p_reg)632 NRF_STATIC_INLINE void nrf_cache_profiling_counters_clear(NRF_CACHE_Type * p_reg)
633 {
634 #if defined(CACHE_PROFILINGCLEAR_CLEAR_Msk)
635 p_reg->PROFILINGCLEAR = (CACHE_PROFILINGCLEAR_CLEAR_Clear << CACHE_PROFILINGCLEAR_CLEAR_Pos);
636 #elif defined(CACHE_PROFILING_CLEAR_CLEAR_Msk)
637 p_reg->PROFILING.CLEAR = (CACHE_PROFILING_CLEAR_CLEAR_Clear << CACHE_PROFILING_CLEAR_CLEAR_Pos);
638 #endif
639 }
640
nrf_cache_instruction_hit_counter_get(NRF_CACHE_Type const * p_reg,nrf_cache_region_t region)641 NRF_STATIC_INLINE uint32_t nrf_cache_instruction_hit_counter_get(NRF_CACHE_Type const * p_reg,
642 nrf_cache_region_t region)
643 {
644 #if defined(CACHE_PROFILING_IHIT_HITS_Msk)
645 return p_reg->PROFILING[region].IHIT;
646 #elif defined(CACHE_PROFILING_HIT_HITS_Msk)
647 (void)region;
648 return p_reg->PROFILING.HIT;
649 #endif
650 }
651
nrf_cache_instruction_miss_counter_get(NRF_CACHE_Type const * p_reg,nrf_cache_region_t region)652 NRF_STATIC_INLINE uint32_t nrf_cache_instruction_miss_counter_get(NRF_CACHE_Type const * p_reg,
653 nrf_cache_region_t region)
654 {
655 #if defined(CACHE_PROFILING_IMISS_MISSES_Msk)
656 return p_reg->PROFILING[region].IMISS;
657 #elif defined(CACHE_PROFILING_MISS_MISSES_Msk)
658 (void)region;
659 return p_reg->PROFILING.MISS;
660 #endif
661 }
662
nrf_cache_data_hit_counter_get(NRF_CACHE_Type const * p_reg,nrf_cache_region_t region)663 NRF_STATIC_INLINE uint32_t nrf_cache_data_hit_counter_get(NRF_CACHE_Type const * p_reg,
664 nrf_cache_region_t region)
665 {
666 #if defined(CACHE_PROFILING_DHIT_HITS_Msk)
667 return p_reg->PROFILING[region].DHIT;
668 #elif defined(CACHE_PROFILING_HIT_HITS_Msk)
669 (void)region;
670 return p_reg->PROFILING.HIT;
671 #endif
672 }
673
nrf_cache_data_miss_counter_get(NRF_CACHE_Type const * p_reg,nrf_cache_region_t region)674 NRF_STATIC_INLINE uint32_t nrf_cache_data_miss_counter_get(NRF_CACHE_Type const * p_reg,
675 nrf_cache_region_t region)
676 {
677 #if defined(CACHE_PROFILING_DMISS_MISSES_Msk)
678 return p_reg->PROFILING[region].DMISS;
679 #elif defined(CACHE_PROFILING_MISS_MISSES_Msk)
680 (void)region;
681 return p_reg->PROFILING.MISS;
682 #endif
683 }
684
685 #if NRF_CACHE_HAS_RAM_MODE
nrf_cache_ram_mode_set(NRF_CACHE_Type * p_reg,bool enable)686 NRF_STATIC_INLINE void nrf_cache_ram_mode_set(NRF_CACHE_Type * p_reg, bool enable)
687 {
688 p_reg->MODE = ((p_reg->MODE & ~CACHE_MODE_MODE_Msk) |
689 ((enable ? CACHE_MODE_MODE_Ram : CACHE_MODE_MODE_Cache)
690 << CACHE_MODE_MODE_Pos));
691 }
692
nrf_cache_ram_mode_check(NRF_CACHE_Type const * p_reg)693 NRF_STATIC_INLINE bool nrf_cache_ram_mode_check(NRF_CACHE_Type const * p_reg)
694 {
695 return (p_reg->MODE & CACHE_MODE_MODE_Msk) == (CACHE_MODE_MODE_Ram << CACHE_MODE_MODE_Pos);
696 }
697 #endif
698
699 #if NRF_CACHE_HAS_RAMSIZE
nrf_cache_ramsize_set(NRF_CACHE_Type * p_reg,nrf_cache_ramsize_t ramsize)700 NRF_STATIC_INLINE void nrf_cache_ramsize_set(NRF_CACHE_Type * p_reg, nrf_cache_ramsize_t ramsize)
701 {
702 p_reg->MODE = ((p_reg->MODE & ~CACHE_MODE_RAMSIZE_Msk) | (ramsize << CACHE_MODE_RAMSIZE_Pos));
703 }
704
nrf_cache_ramsize_get(NRF_CACHE_Type const * p_reg)705 NRF_STATIC_INLINE nrf_cache_ramsize_t nrf_cache_ramsize_get(NRF_CACHE_Type const * p_reg)
706 {
707 return (nrf_cache_ramsize_t)((p_reg->MODE & CACHE_MODE_RAMSIZE_Msk) >> CACHE_MODE_RAMSIZE_Pos);
708 }
709 #endif
710
nrf_cache_read_lock_enable(NRF_CACHE_Type * p_reg)711 NRF_STATIC_INLINE void nrf_cache_read_lock_enable(NRF_CACHE_Type * p_reg)
712 {
713 p_reg->DEBUGLOCK = CACHE_DEBUGLOCK_DEBUGLOCK_Locked;
714 }
715
nrf_cache_update_lock_set(NRF_CACHE_Type * p_reg,bool enable)716 NRF_STATIC_INLINE void nrf_cache_update_lock_set(NRF_CACHE_Type * p_reg, bool enable)
717 {
718 p_reg->WRITELOCK =
719 (enable ? CACHE_WRITELOCK_WRITELOCK_Locked : CACHE_WRITELOCK_WRITELOCK_Unlocked);
720 }
721
722 #if NRF_CACHE_HAS_CACHEDATA
nrf_cache_data_get(NRF_CACHEDATA_Type const * p_reg,uint32_t set,uint8_t way,uint8_t word)723 NRF_STATIC_INLINE uint32_t nrf_cache_data_get(NRF_CACHEDATA_Type const * p_reg,
724 uint32_t set,
725 uint8_t way,
726 uint8_t word)
727 {
728 #if NRF_CACHE_HAS_CACHEDATA_DU
729 NRFX_ASSERT(word < NRF_CACHEDATA_WORD_INDEX_MAX);
730 NRFX_ASSERT(way < NRF_CACHEDATA_WAY_INDEX_MAX);
731 NRFX_ASSERT(set < NRF_CACHEDATA_SET_INDEX_MAX);
732
733 uint8_t du = (word / NRF_CACHEDATA_DATA_WORDS_IN_UNIT_MAX);
734 uint8_t data = (uint8_t)(word - (du * NRF_CACHEDATA_DATA_WORDS_IN_UNIT_MAX));
735
736 return p_reg->SET[set].WAY[way].DU[du].DATA[data];
737 #else
738 volatile CACHEDATA_SET_WAY_Type const * reg = &p_reg->SET[set].WAY[way];
739 switch (word)
740 {
741 case 0: return reg->DATA0;
742 case 1: return reg->DATA1;
743 case 2: return reg->DATA2;
744 case 3: return reg->DATA3;
745 default:
746 NRFX_ASSERT(false);
747 return 0;
748 }
749 #endif
750 }
751 #endif
752
753 #if NRF_CACHE_HAS_CACHEINFO
nrf_cache_tag_get(NRF_CACHEINFO_Type const * p_reg,uint32_t set,uint8_t way)754 NRF_STATIC_INLINE uint32_t nrf_cache_tag_get(NRF_CACHEINFO_Type const * p_reg,
755 uint32_t set,
756 uint8_t way)
757 {
758 #if defined(CACHEINFO_SET_WAY_INFO_TAG_Msk)
759 NRFX_ASSERT(way < NRF_CACHEINFO_WAY_INDEX_MAX);
760 NRFX_ASSERT(set < NRF_CACHEINFO_SET_INDEX_MAX);
761 return (p_reg->SET[set].WAY[way].INFO & CACHEINFO_SET_WAY_INFO_TAG_Msk);
762 #else
763 return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_TAG_Msk);
764 #endif
765 }
766
nrf_cache_line_validity_check(NRF_CACHEINFO_Type const * p_reg,uint32_t set,uint8_t way)767 NRF_STATIC_INLINE bool nrf_cache_line_validity_check(NRF_CACHEINFO_Type const * p_reg,
768 uint32_t set,
769 uint8_t way)
770 {
771 #if defined(CACHEINFO_SET_WAY_INFO_V_Msk)
772 NRFX_ASSERT(way < NRF_CACHEINFO_WAY_INDEX_MAX);
773 NRFX_ASSERT(set < NRF_CACHEINFO_SET_INDEX_MAX);
774 return (p_reg->SET[set].WAY[way].INFO & CACHEINFO_SET_WAY_INFO_V_Msk) ==
775 (CACHEINFO_SET_WAY_INFO_V_Valid << CACHEINFO_SET_WAY_INFO_V_Pos);
776 #else
777 return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_V_Msk) ==
778 (CACHEINFO_SET_WAY_V_Valid << CACHEINFO_SET_WAY_V_Pos);
779 #endif
780 }
781
nrf_cache_mru_get(NRF_CACHEINFO_Type const * p_reg,uint32_t set)782 NRF_STATIC_INLINE uint8_t nrf_cache_mru_get(NRF_CACHEINFO_Type const * p_reg, uint32_t set)
783 {
784 #if defined(CACHEINFO_SET_WAY_INFO_MRU_Pos)
785 NRFX_ASSERT(set < NRF_CACHEINFO_SET_INDEX_MAX);
786 return ((p_reg->SET[set].WAY[0].INFO & CACHEINFO_SET_WAY_INFO_MRU_Msk) >>
787 CACHEINFO_SET_WAY_INFO_MRU_Pos);
788 #else
789 return ((p_reg->SET[set].WAY[0] & CACHEINFO_SET_WAY_MRU_Msk) >> CACHEINFO_SET_WAY_MRU_Pos);
790 #endif
791 }
792
793 #if NRF_CACHE_HAS_CACHEINFO_DU_VALIDATION
nrf_cache_data_unit_validity_check(NRF_CACHEINFO_Type const * p_reg,uint32_t set,uint8_t way,uint8_t word)794 NRF_STATIC_INLINE bool nrf_cache_data_unit_validity_check(NRF_CACHEINFO_Type const * p_reg,
795 uint32_t set,
796 uint8_t way,
797 uint8_t word)
798 {
799 NRFX_ASSERT(word < NRF_CACHEINFO_WORD_INDEX_MAX);
800 NRFX_ASSERT(way < NRF_CACHEINFO_WAY_INDEX_MAX);
801 NRFX_ASSERT(set < NRF_CACHEINFO_SET_INDEX_MAX);
802
803 uint8_t du = (word / NRF_CACHEINFO_DATA_WORDS_IN_UNIT_MAX);
804 switch (du)
805 {
806 #if NRF_CACHE_HAS_CACHEINFO_SET_WAY_INFO
807 case 0:
808 return (p_reg->SET[set].WAY[way].INFO &
809 CACHEINFO_SET_WAY_INFO_DUV0_Msk) ==
810 (CACHEINFO_SET_WAY_INFO_DUV0_Valid << CACHEINFO_SET_WAY_INFO_DUV0_Pos);
811 case 1:
812 return (p_reg->SET[set].WAY[way].INFO &
813 CACHEINFO_SET_WAY_INFO_DUV1_Msk) ==
814 (CACHEINFO_SET_WAY_INFO_DUV1_Valid << CACHEINFO_SET_WAY_INFO_DUV1_Pos);
815 case 2:
816 return (p_reg->SET[set].WAY[way].INFO &
817 CACHEINFO_SET_WAY_INFO_DUV2_Msk) ==
818 (CACHEINFO_SET_WAY_INFO_DUV2_Valid << CACHEINFO_SET_WAY_INFO_DUV2_Pos);
819 case 3:
820 return (p_reg->SET[set].WAY[way].INFO &
821 CACHEINFO_SET_WAY_INFO_DUV3_Msk) ==
822 (CACHEINFO_SET_WAY_INFO_DUV3_Valid << CACHEINFO_SET_WAY_INFO_DUV3_Pos);
823 #else
824 case 0:
825 return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_DUV0_Msk) ==
826 (CACHEINFO_SET_WAY_DUV0_Valid << CACHEINFO_SET_WAY_DUV0_Pos);
827 case 1:
828 return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_DUV1_Msk) ==
829 (CACHEINFO_SET_WAY_DUV1_Valid << CACHEINFO_SET_WAY_DUV1_Pos);
830 case 2:
831 return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_DUV2_Msk) ==
832 (CACHEINFO_SET_WAY_DUV2_Valid << CACHEINFO_SET_WAY_DUV2_Pos);
833 case 3:
834 return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_DUV3_Msk) ==
835 (CACHEINFO_SET_WAY_DUV3_Valid << CACHEINFO_SET_WAY_DUV3_Pos);
836 #endif
837 default:
838 NRFX_ASSERT(false);
839 return false;
840 }
841 }
842 #endif // NRF_CACHE_HAS_CACHEINFO_DU_VALIDATION
843
844 #if NRF_CACHE_HAS_CACHEINFO_DU_DIRTY
nrf_cache_is_data_unit_dirty_check(NRF_CACHEINFO_Type const * p_reg,uint32_t set,uint8_t way,uint8_t word)845 NRF_STATIC_INLINE bool nrf_cache_is_data_unit_dirty_check(NRF_CACHEINFO_Type const * p_reg,
846 uint32_t set,
847 uint8_t way,
848 uint8_t word)
849 {
850 NRFX_ASSERT(word < NRF_CACHEINFO_WORD_INDEX_MAX);
851 NRFX_ASSERT(way < NRF_CACHEINFO_WAY_INDEX_MAX);
852 NRFX_ASSERT(set < NRF_CACHEINFO_SET_INDEX_MAX);
853
854 uint8_t du = (word / NRF_CACHEINFO_DATA_WORDS_IN_UNIT_MAX);
855 switch (du)
856 {
857 case 0:
858 /* FALLTHROUGH */
859 case 1:
860 return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_D0_Msk) ==
861 (CACHEINFO_SET_WAY_D0_Dirty << CACHEINFO_SET_WAY_D0_Pos);
862 case 2:
863 /* FALLTHROUGH */
864 case 3:
865 return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_D1_Msk) ==
866 (CACHEINFO_SET_WAY_D1_Dirty << CACHEINFO_SET_WAY_D1_Pos);
867 default:
868 NRFX_ASSERT(false);
869 return false;
870 }
871 }
872 #endif
873 #endif // NRF_CACHE_HAS_CACHEINFO
874
875 #if NRF_CACHE_HAS_TASKS
nrf_cache_lineaddr_set(NRF_CACHE_Type * p_reg,uint32_t addr)876 NRF_STATIC_INLINE void nrf_cache_lineaddr_set(NRF_CACHE_Type * p_reg, uint32_t addr)
877 {
878 p_reg->LINEADDR = addr;
879 }
880
nrf_cache_lineaddr_get(NRF_CACHE_Type const * p_reg)881 NRF_STATIC_INLINE uint32_t nrf_cache_lineaddr_get(NRF_CACHE_Type const * p_reg)
882 {
883 return p_reg->LINEADDR;
884 }
885
nrf_cache_task_trigger(NRF_CACHE_Type * p_reg,nrf_cache_task_t task)886 NRF_STATIC_INLINE void nrf_cache_task_trigger(NRF_CACHE_Type * p_reg, nrf_cache_task_t task)
887 {
888 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
889 }
890
nrf_cache_task_address_get(NRF_CACHE_Type const * p_reg,nrf_cache_task_t task)891 NRF_STATIC_INLINE uint32_t nrf_cache_task_address_get(NRF_CACHE_Type const * p_reg,
892 nrf_cache_task_t task)
893 {
894 return (uint32_t)p_reg + (uint32_t)task;
895 }
896 #endif
897
898 #if NRF_CACHE_HAS_STATUS
nrf_cache_busy_check(NRF_CACHE_Type const * p_reg)899 NRF_STATIC_INLINE bool nrf_cache_busy_check(NRF_CACHE_Type const * p_reg)
900 {
901 #if defined(CACHE_STATUS_READY_Msk)
902 return (p_reg->STATUS & CACHE_STATUS_READY_Msk) ==
903 (CACHE_STATUS_READY_Busy << CACHE_STATUS_READY_Pos);
904 #else
905 return (p_reg->STATUS & CACHE_STATUS_BUSY_Msk) ==
906 (CACHE_STATUS_BUSY_Busy << CACHE_STATUS_BUSY_Pos);
907 #endif
908 }
909 #endif
910
911 #endif // NRF_DECLARE_ONLY
912
913 /** @} */
914
915 #ifdef __cplusplus
916 }
917 #endif
918
919 #endif // NRF_CACHE_H__
920