arm: aarch32: timing: fix potential divide by zero if DWT

There is a possibility that the DWT frequency calculation
is divided by zero. So this fixes the issue by repeatedly
trying to get the delta clock cycles and delta DWT cycles
until they both are not zero.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2021-04-27 10:19:42 -07:00 committed by Anas Nashif
commit 43f0726985

View file

@ -43,31 +43,35 @@ static inline uint64_t z_arm_dwt_freq_get(void)
return CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
#else
static uint64_t dwt_frequency;
uint32_t cyc_start, cyc_end;
uint64_t dwt_start, dwt_end;
uint64_t cyc_freq = sys_clock_hw_cycles_per_sec();
uint64_t dcyc, ddwt;
if (!dwt_frequency) {
z_arm_dwt_init();
uint32_t cyc_start = k_cycle_get_32();
uint64_t dwt_start = z_arm_dwt_get_cycles();
do {
cyc_start = k_cycle_get_32();
dwt_start = z_arm_dwt_get_cycles();
k_busy_wait(10 * USEC_PER_MSEC);
k_busy_wait(10 * USEC_PER_MSEC);
uint32_t cyc_end = k_cycle_get_32();
uint64_t dwt_end = z_arm_dwt_get_cycles();
cyc_end = k_cycle_get_32();
dwt_end = z_arm_dwt_get_cycles();
uint64_t cyc_freq = sys_clock_hw_cycles_per_sec();
/*
* cycles are in 32-bit, and delta must be
* calculated in 32-bit percision. Or it would
* wrapping around in 64-bit.
*/
dcyc = (uint32_t)cyc_end - (uint32_t)cyc_start;
/*
* cycles are in 32-bit, and delta must be
* calculated in 32-bit percision. Or it would
* wrapping around in 64-bit.
*/
uint64_t dcyc = (uint32_t)cyc_end - (uint32_t)cyc_start;
ddwt = dwt_end - dwt_start;
} while ((dcyc == 0) || (ddwt == 0));
uint64_t dtsc = dwt_end - dwt_start;
dwt_frequency = (cyc_freq * dtsc) / dcyc;
dwt_frequency = (cyc_freq * ddwt) / dcyc;
}
return dwt_frequency;