Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2019 - 2022, 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 : : /** @brief Cache regions. */
51 : : typedef enum
52 : : {
53 : : NRF_CACHE_REGION_FLASH = 0, ///< Cache region related to Flash access.
54 : : NRF_CACHE_REGION_XIP = 1, ///< Cache region related to XIP access.
55 : : } nrf_cache_region_t;
56 : :
57 : : /**
58 : : * @brief Function for enabling the CACHE peripheral.
59 : : *
60 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
61 : : */
62 : : NRF_STATIC_INLINE void nrf_cache_enable(NRF_CACHE_Type * p_reg);
63 : :
64 : : /**
65 : : * @brief Function for disabling the CACHE peripheral.
66 : : *
67 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
68 : : */
69 : : NRF_STATIC_INLINE void nrf_cache_disable(NRF_CACHE_Type * p_reg);
70 : :
71 : : /**
72 : : * @brief Function for invalidating the cache content.
73 : : *
74 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
75 : : */
76 : : NRF_STATIC_INLINE void nrf_cache_invalidate(NRF_CACHE_Type * p_reg);
77 : :
78 : : /**
79 : : * @brief Function for erasing the cache content.
80 : : *
81 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
82 : : */
83 : : NRF_STATIC_INLINE void nrf_cache_erase(NRF_CACHE_Type * p_reg);
84 : :
85 : : /**
86 : : * @brief Function for checking the status of @ref nrf_cache_erase().
87 : : *
88 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
89 : : *
90 : : * @retval true Erase is finished.
91 : : * @retval false Erase is not complete or has not started.
92 : : */
93 : : NRF_STATIC_INLINE bool nrf_cache_erase_status_check(NRF_CACHE_Type const * p_reg);
94 : :
95 : : /**
96 : : * @brief Function for clearing the status of the cache erase.
97 : : *
98 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
99 : : */
100 : : NRF_STATIC_INLINE void nrf_cache_erase_status_clear(NRF_CACHE_Type * p_reg);
101 : :
102 : : /**
103 : : * @brief Function for setting the cache profiling.
104 : : *
105 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
106 : : * @param[in] enable True if cache profiling is to be enabled, false otherwise.
107 : : */
108 : : NRF_STATIC_INLINE void nrf_cache_profiling_set(NRF_CACHE_Type * p_reg, bool enable);
109 : :
110 : : /**
111 : : * @brief Function for clearing the cache profiling counters.
112 : : *
113 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
114 : : */
115 : : NRF_STATIC_INLINE void nrf_cache_profiling_counters_clear(NRF_CACHE_Type * p_reg);
116 : :
117 : : /**
118 : : * @brief Function for getting the number of cache hits for instruction fetch from the specified
119 : : * cache region.
120 : : *
121 : : * @note Separate counters are used for flash region and XIP region.
122 : : * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
123 : : *
124 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
125 : : * @param[in] region Cache region.
126 : : *
127 : : * @return Number of instruction fetch cache hits.
128 : : */
129 : : NRF_STATIC_INLINE uint32_t nrf_cache_instruction_hit_counter_get(NRF_CACHE_Type const * p_reg,
130 : : nrf_cache_region_t region);
131 : :
132 : : /**
133 : : * @brief Function for getting the number of cache misses for instruction fetch from the specified
134 : : * cache region.
135 : : *
136 : : * @note Separate counters are used for flash region and XIP region.
137 : : * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
138 : : *
139 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
140 : : * @param[in] region Cache region.
141 : : *
142 : : * @return Number of instruction fetch cache misses.
143 : : */
144 : : NRF_STATIC_INLINE uint32_t nrf_cache_instruction_miss_counter_get(NRF_CACHE_Type const * p_reg,
145 : : nrf_cache_region_t region);
146 : :
147 : : /**
148 : : * @brief Function for getting the number of cache hits for data fetch from the specified
149 : : * cache region.
150 : : *
151 : : * @note Separate counters are used for flash region and XIP region.
152 : : * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
153 : : *
154 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
155 : : * @param[in] region Cache region.
156 : : *
157 : : * @return Number of data fetch cache hits.
158 : : */
159 : : NRF_STATIC_INLINE uint32_t nrf_cache_data_hit_counter_get(NRF_CACHE_Type const * p_reg,
160 : : nrf_cache_region_t region);
161 : :
162 : : /**
163 : : * @brief Function for getting the number of cache misses for data fetch from the specified
164 : : * cache region.
165 : : *
166 : : * @note Separate counters are used for flash region and XIP region.
167 : : * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
168 : : *
169 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
170 : : * @param[in] region Cache region.
171 : : *
172 : : * @return Number of data fetch cache misses.
173 : : */
174 : : NRF_STATIC_INLINE uint32_t nrf_cache_data_miss_counter_get(NRF_CACHE_Type const * p_reg,
175 : : nrf_cache_region_t region);
176 : :
177 : : /**
178 : : * @brief Function for setting the cache RAM mode.
179 : : *
180 : : * When configured in the RAM mode, the accesses to internal or external flash will not be cached.
181 : : * In this mode, the cache data contents can be used as the read/write RAM.
182 : : * Only the data content of the cache is available as RAM.
183 : : *
184 : : * @note -Enabling the RAM mode causes the RAM to be cleared.
185 : : * @note -Disabling the RAM mode causes the cache to be invalidated.
186 : : *
187 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
188 : : * @param[in] enable True if the cache RAM mode is to be enabled, false otherwise.
189 : : */
190 : : NRF_STATIC_INLINE void nrf_cache_ram_mode_set(NRF_CACHE_Type * p_reg, bool enable);
191 : :
192 : : /**
193 : : * @brief Function for blocking the cache content access.
194 : : *
195 : : * To unlock the cache content access, a reset has to be performed.
196 : : *
197 : : * @note Blocking is ignored in the RAM mode.
198 : : *
199 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
200 : : */
201 : : NRF_STATIC_INLINE void nrf_cache_read_lock_enable(NRF_CACHE_Type * p_reg);
202 : :
203 : : /**
204 : : * @brief Function for blocking the cache content updates.
205 : : *
206 : : * Blocking of updates prevents updating of cache content on cache misses,
207 : : * but the peripheral will continue to check for instruction/data fetches
208 : : * in the content already present in the cache.
209 : : *
210 : : * @note Blocking is ignored in the RAM mode.
211 : : *
212 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
213 : : * @param[in] enable True if cache content update lock is to be enabled, false otherwise.
214 : : */
215 : : NRF_STATIC_INLINE void nrf_cache_update_lock_set(NRF_CACHE_Type * p_reg, bool enable);
216 : :
217 : : /**
218 : : * @brief Function for getting the cache data word.
219 : : *
220 : : * @note When operating in the RAM mode, the cache data is accessible as a general purpose RAM.
221 : : *
222 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
223 : : * @param[in] set Set that contains the data to get.
224 : : * @param[in] way Way that contains the data to get.
225 : : * @param[in] word Data word index to get.
226 : : *
227 : : * @return 32-bit data word.
228 : : */
229 : : NRF_STATIC_INLINE uint32_t nrf_cache_data_get(NRF_CACHEDATA_Type const * p_reg,
230 : : uint32_t set,
231 : : uint8_t way,
232 : : uint8_t word);
233 : :
234 : : /**
235 : : * @brief Function for getting the tag associated with the specified set and way.
236 : : *
237 : : * The tag is used to check if an entry in the cache matches the address that is being fetched.
238 : : *
239 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
240 : : * @param[in] set Set that contains the tag to get.
241 : : * @param[in] way Way that contains the tag to get.
242 : : *
243 : : * @return Tag value.
244 : : */
245 : : NRF_STATIC_INLINE uint32_t nrf_cache_tag_get(NRF_CACHEINFO_Type const * p_reg,
246 : : uint32_t set,
247 : : uint8_t way);
248 : :
249 : : /**
250 : : * @brief Function for checking the validity of a cache line associated with the specified set and way.
251 : : *
252 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
253 : : * @param[in] set Set that contains the cache line to check.
254 : : * @param[in] way Way that contains the cache line to check.
255 : : *
256 : : * @retval true Cache line is valid.
257 : : * @retval false Cache line is invalid.
258 : : */
259 : : NRF_STATIC_INLINE bool nrf_cache_line_validity_check(NRF_CACHEINFO_Type const * p_reg,
260 : : uint32_t set,
261 : : uint8_t way);
262 : :
263 : : /**
264 : : * @brief Function for getting the most recently used way in the specified set.
265 : : *
266 : : * The most recently used way is updated on each fetch from the cache and is used for the cache replacement policy.
267 : : *
268 : : * @param[in] p_reg Pointer to the structure of registers of the peripheral.
269 : : * @param[in] set Specified set.
270 : : *
271 : : * @return The most recently used way in the specified set.
272 : : */
273 : : NRF_STATIC_INLINE uint8_t nrf_cache_mru_get(NRF_CACHEINFO_Type const * p_reg, uint32_t set);
274 : :
275 : : #ifndef NRF_DECLARE_ONLY
276 : :
277 : 1 : NRF_STATIC_INLINE void nrf_cache_enable(NRF_CACHE_Type * p_reg)
278 : : {
279 : 1 : p_reg->ENABLE = CACHE_ENABLE_ENABLE_Enabled;
280 : 1 : }
281 : :
282 : : NRF_STATIC_INLINE void nrf_cache_disable(NRF_CACHE_Type * p_reg)
283 : : {
284 : : p_reg->ENABLE = CACHE_ENABLE_ENABLE_Disabled;
285 : : }
286 : :
287 : : NRF_STATIC_INLINE void nrf_cache_invalidate(NRF_CACHE_Type * p_reg)
288 : : {
289 : : p_reg->INVALIDATE = CACHE_INVALIDATE_INVALIDATE_Invalidate;
290 : : }
291 : :
292 : : NRF_STATIC_INLINE void nrf_cache_erase(NRF_CACHE_Type * p_reg)
293 : : {
294 : : p_reg->ERASE = CACHE_ERASE_ERASE_Erase;
295 : : }
296 : :
297 : : NRF_STATIC_INLINE bool nrf_cache_erase_status_check(NRF_CACHE_Type const * p_reg)
298 : : {
299 : : return (bool)(p_reg->ERASESTATUS & CACHE_ERASESTATUS_ERASESTATUS_Msk);
300 : : }
301 : :
302 : : NRF_STATIC_INLINE void nrf_cache_erase_status_clear(NRF_CACHE_Type * p_reg)
303 : : {
304 : : p_reg->ERASESTATUS = 0;
305 : : }
306 : :
307 : : NRF_STATIC_INLINE void nrf_cache_profiling_set(NRF_CACHE_Type * p_reg, bool enable)
308 : : {
309 : : p_reg->PROFILINGENABLE =
310 : : (enable ? CACHE_PROFILINGENABLE_ENABLE_Enable : CACHE_PROFILINGENABLE_ENABLE_Disable);
311 : : }
312 : :
313 : : NRF_STATIC_INLINE void nrf_cache_profiling_counters_clear(NRF_CACHE_Type * p_reg)
314 : : {
315 : : p_reg->PROFILINGCLEAR = (CACHE_PROFILINGCLEAR_CLEAR_Clear << CACHE_PROFILINGCLEAR_CLEAR_Pos);
316 : : }
317 : :
318 : : NRF_STATIC_INLINE uint32_t nrf_cache_instruction_hit_counter_get(NRF_CACHE_Type const * p_reg,
319 : : nrf_cache_region_t region)
320 : : {
321 : : return p_reg->PROFILING[region].IHIT;
322 : : }
323 : :
324 : : NRF_STATIC_INLINE uint32_t nrf_cache_instruction_miss_counter_get(NRF_CACHE_Type const * p_reg,
325 : : nrf_cache_region_t region)
326 : : {
327 : : return p_reg->PROFILING[region].IMISS;
328 : : }
329 : :
330 : : NRF_STATIC_INLINE uint32_t nrf_cache_data_hit_counter_get(NRF_CACHE_Type const * p_reg,
331 : : nrf_cache_region_t region)
332 : : {
333 : : return p_reg->PROFILING[region].DHIT;
334 : : }
335 : :
336 : : NRF_STATIC_INLINE uint32_t nrf_cache_data_miss_counter_get(NRF_CACHE_Type const * p_reg,
337 : : nrf_cache_region_t region)
338 : : {
339 : : return p_reg->PROFILING[region].DMISS;
340 : : }
341 : :
342 : : NRF_STATIC_INLINE void nrf_cache_ram_mode_set(NRF_CACHE_Type * p_reg, bool enable)
343 : : {
344 : : p_reg->MODE = (enable ? CACHE_MODE_MODE_Ram : CACHE_MODE_MODE_Cache);
345 : : }
346 : :
347 : : NRF_STATIC_INLINE void nrf_cache_read_lock_enable(NRF_CACHE_Type * p_reg)
348 : : {
349 : : p_reg->DEBUGLOCK = CACHE_DEBUGLOCK_DEBUGLOCK_Locked;
350 : : }
351 : :
352 : : NRF_STATIC_INLINE void nrf_cache_update_lock_set(NRF_CACHE_Type * p_reg, bool enable)
353 : : {
354 : : p_reg->WRITELOCK =
355 : : (enable ? CACHE_WRITELOCK_WRITELOCK_Locked : CACHE_WRITELOCK_WRITELOCK_Unlocked);
356 : : }
357 : :
358 : : NRF_STATIC_INLINE uint32_t nrf_cache_data_get(NRF_CACHEDATA_Type const * p_reg,
359 : : uint32_t set,
360 : : uint8_t way,
361 : : uint8_t word)
362 : : {
363 : : volatile CACHEDATA_SET_WAY_Type const * reg = &p_reg->SET[set].WAY[way];
364 : : switch (word)
365 : : {
366 : : case 0: return reg->DATA0;
367 : : case 1: return reg->DATA1;
368 : : case 2: return reg->DATA2;
369 : : case 3: return reg->DATA3;
370 : : default:
371 : : NRFX_ASSERT(false);
372 : : return 0;
373 : : }
374 : : }
375 : :
376 : : NRF_STATIC_INLINE uint32_t nrf_cache_tag_get(NRF_CACHEINFO_Type const * p_reg,
377 : : uint32_t set,
378 : : uint8_t way)
379 : : {
380 : : return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_TAG_Msk);
381 : : }
382 : :
383 : : NRF_STATIC_INLINE bool nrf_cache_line_validity_check(NRF_CACHEINFO_Type const * p_reg,
384 : : uint32_t set,
385 : : uint8_t way)
386 : : {
387 : : return (bool)(p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_V_Msk);
388 : : }
389 : :
390 : : NRF_STATIC_INLINE uint8_t nrf_cache_mru_get(NRF_CACHEINFO_Type const * p_reg, uint32_t set)
391 : : {
392 : : return ((p_reg->SET[set].WAY[0] & CACHEINFO_SET_WAY_MRU_Msk) >> CACHEINFO_SET_WAY_MRU_Pos);
393 : : }
394 : :
395 : : #endif // NRF_DECLARE_ONLY
396 : :
397 : : /** @} */
398 : :
399 : : #ifdef __cplusplus
400 : : }
401 : : #endif
402 : :
403 : : #endif // NRF_CACHE_H__
|