diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c --- a/sys/arm/arm/generic_timer.c +++ b/sys/arm/arm/generic_timer.c @@ -102,6 +102,8 @@ struct arm_tmr_softc; +typedef uint64_t (*get_cntxct_cb)(bool); + struct arm_tmr_irq { struct resource *res; void *ihl; @@ -111,7 +113,7 @@ struct arm_tmr_softc { struct arm_tmr_irq irqs[GT_IRQ_COUNT]; - uint64_t (*get_cntxct)(bool); + get_cntxct_cb get_cntxct; uint32_t clkfreq; int irq_count; struct eventtimer et; @@ -801,7 +803,7 @@ #endif static uint64_t -arm_tmr_get_counts(int usec) +arm_tmr_get_counts(int usec, uint32_t freq) { uint64_t counts_per_usec; @@ -809,28 +811,28 @@ return (0); /* Get the number of times to count */ - counts_per_usec = ((arm_tmr_timecount.tc_frequency / 1000000) + 1); + counts_per_usec = (freq / 1000000) + 1; return (usec * counts_per_usec); } static void -arm_tmr_do_delay(int usec, void *arg) +_arm_tmr_do_delay(int usec, uint32_t freq, get_cntxct_cb get_cntxct, + bool physical) { - struct arm_tmr_softc *sc = arg; int64_t counts; uint64_t first; #if defined(__aarch64__) int64_t end; #endif - counts = arm_tmr_get_counts(usec); - first = sc->get_cntxct(sc->physical_sys); + counts = arm_tmr_get_counts(usec, freq); + first = get_cntxct(physical); #if defined(__aarch64__) end = first + counts; #endif - while ((sc->get_cntxct(sc->physical_sys) - first) < counts) { + while ((get_cntxct(physical) - first) < counts) { #if defined(__aarch64__) if (enable_wfxt) wfet(end); @@ -838,12 +840,19 @@ } } +static void +arm_tmr_do_delay(int usec, void *arg) +{ + struct arm_tmr_softc *sc = arg; + + _arm_tmr_do_delay(usec, arm_tmr_timecount.tc_frequency, sc->get_cntxct, + sc->physical_sys); +} + #if defined(__aarch64__) void DELAY(int usec) { - int32_t counts; - TSENTER(); /* * We have two options for a delay: using the timer, or using the wfet @@ -853,10 +862,7 @@ if (arm_tmr_sc != NULL) { arm_tmr_do_delay(usec, arm_tmr_sc); } else { - for (; usec > 0; usec--) - for (counts = 200; counts > 0; counts--) - /* Prevent the compiler from optimizing out the loop */ - cpufunc_nullop(); + _arm_tmr_do_delay(usec, get_freq(), get_cntxct, false); } TSEXIT(); }