Skip to content

Commit 4d7dca7

Browse files
committed
imx95_m7: do not issue D-cache clean by address while the cache is disabled
1 parent e10160d commit 4d7dca7

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

‎hal/imx95_m7.c‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,17 @@ void hal_init(void)
303303
hal_status(HAL_STATUS_INIT);
304304
}
305305

306+
#if defined(WOLFBOOT_UPDATE_DISK) || defined(BOOT_BENCHMARK)
307+
/* Microseconds from the DWT cycle counter hal_init() starts. The counter is
308+
* 32-bit and wraps about every 5.4 s at 800 MHz, which bounds any single
309+
* measurement rather than the boot as a whole - each BENCHMARK_END subtracts
310+
* two reads, so a wrap only matters for an interval longer than that. */
311+
uint64_t hal_get_timer_us(void)
312+
{
313+
return (uint64_t)DWT_CYCCNT / (IMX95_M7_CORE_HZ / 1000000UL);
314+
}
315+
#endif
316+
306317
void hal_prepare_boot(void)
307318
{
308319
hal_status(HAL_STATUS_PREBOOT);

‎hal/imx95_m7.h‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ static inline void imx95_dcache_clean(const void *addr, uint32_t len)
115115

116116
if (len == 0)
117117
return;
118+
/* Nothing to clean while the cache is off - every store already reached
119+
* memory. It is also unsafe: the M7 does maintenance by address even with
120+
* the cache disabled, and out of a cold reset the cache RAMs hold random
121+
* tags and dirty bits until hal_cache_enable() invalidates them, so a hit
122+
* writes garbage to a random address and the bus error comes back as an
123+
* imprecise BusFault. */
124+
if ((SCB_CCR & CCR_DC) == 0UL)
125+
return;
118126
line = ((uint32_t)(uintptr_t)addr) & ~(IMX95_CACHE_LINE - 1UL);
119127
end = (uint32_t)(uintptr_t)addr + len;
120128
for (; line < end; line += IMX95_CACHE_LINE) {
@@ -147,6 +155,12 @@ static inline void imx95_dwt_init(void)
147155
DWT_CTRL |= DWT_CYCCNTENA;
148156
}
149157

158+
/* The M7 core clock on this part. Only used to turn cycle counts into
159+
* microseconds for the boot benchmark; override for a different clock. */
160+
#ifndef IMX95_M7_CORE_HZ
161+
#define IMX95_M7_CORE_HZ 800000000UL
162+
#endif
163+
150164
/* Bounded spin. Wrap-safe for any delay shorter than a full 32-bit period
151165
* (~5.4 s at 800 MHz) because the comparison is done on the difference. */
152166
static inline void imx95_delay_cycles(uint32_t cycles)

0 commit comments

Comments
 (0)