Skip to content

Commit 058516e

Browse files
committed
Avoid 128-bit division in Agilex 5 hal_get_timer_us
1 parent e326052 commit 058516e

1 file changed

Lines changed: 9 additions & 3 deletions

File tree

hal/agilex5.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,20 @@ uint64_t hal_get_timer_us(void)
9797
{
9898
uint64_t frequency = timer_frequency();
9999
uint64_t count = timer_count();
100+
uint64_t whole;
101+
uint64_t rem;
100102

101103
/* BL31 normally programs CNTFRQ_EL0. Keep delay loops live even when a
102-
* non-conforming handoff leaves it clear, and use a wide intermediate so
103-
* long-running counters cannot overflow before conversion to microseconds.
104+
* non-conforming handoff leaves it clear.
104105
*/
105106
if (frequency == 0U)
106107
frequency = 100000000U;
107-
return (uint64_t)(((__uint128_t)count * 1000000ULL) / frequency);
108+
/* Split the conversion so it stays in 64-bit math: a __uint128_t divide
109+
* pulls in libgcc's __udivti3, which the bare-metal link has no runtime
110+
* for. The whole and remainder parts are exact and cannot overflow. */
111+
whole = count / frequency;
112+
rem = count % frequency;
113+
return whole * 1000000ULL + (rem * 1000000ULL) / frequency;
108114
}
109115

110116
void hal_init(void)

0 commit comments

Comments
 (0)