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:
parent
d6cbdace78
commit
43f0726985
1 changed files with 19 additions and 15 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue