diff --git a/payloads/libpayload/Kconfig b/payloads/libpayload/Kconfig index ea9189463b..44d656bcac 100644 --- a/payloads/libpayload/Kconfig +++ b/payloads/libpayload/Kconfig @@ -512,6 +512,13 @@ config ARCH_HAS_MEM_FUNCTIONS Architectures must select this when they want to override memset, memcpy and memmove with optimized assembly implementations. +config ARCH_HAS_NDELAY + default n + bool + help + Architectures must select this when they want to override the ndelay() + function with a custom implementation. + source "arch/arm/Kconfig" source "arch/arm64/Kconfig" source "arch/x86/Kconfig" diff --git a/payloads/libpayload/arch/x86/Kconfig b/payloads/libpayload/arch/x86/Kconfig index 00b0ad0e70..1107a3b016 100644 --- a/payloads/libpayload/arch/x86/Kconfig +++ b/payloads/libpayload/arch/x86/Kconfig @@ -32,6 +32,7 @@ config ARCH_X86 select LITTLE_ENDIAN select IO_ADDRESS_SPACE select ARCH_HAS_MEM_FUNCTIONS if GPL + select ARCH_HAS_NDELAY if ARCH_X86 diff --git a/payloads/libpayload/arch/x86/apic.c b/payloads/libpayload/arch/x86/apic.c index e0671064c8..1e70812384 100644 --- a/payloads/libpayload/arch/x86/apic.c +++ b/payloads/libpayload/arch/x86/apic.c @@ -249,7 +249,7 @@ static void apic_init_timer(void) apic_write32(APIC_TIMER_INIT_COUNT, UINT32_MAX); /* This is safe because apic_initialized() returns false so - * arch_ndelay() falls back to a busy loop. */ + * ndelay() falls back to a busy loop. */ mdelay(1); ticks_per_ms = diff --git a/payloads/libpayload/arch/x86/delay.c b/payloads/libpayload/arch/x86/delay.c index 373c8417b3..90592181c7 100644 --- a/payloads/libpayload/arch/x86/delay.c +++ b/payloads/libpayload/arch/x86/delay.c @@ -38,7 +38,7 @@ /* Let's assume APIC interrupts take at least 100us */ #define APIC_INTERRUPT_LATENCY_NS (100 * NSECS_PER_USEC) -void arch_ndelay(uint64_t ns) +void ndelay(uint64_t ns) { uint64_t delta = ns * timer_hz() / NSECS_PER_SEC; uint64_t pause_delta = 0; diff --git a/payloads/libpayload/include/delay.h b/payloads/libpayload/include/delay.h index 126bee66f8..cac759704e 100644 --- a/payloads/libpayload/include/delay.h +++ b/payloads/libpayload/include/delay.h @@ -14,17 +14,12 @@ unsigned int get_cpu_speed(void); -void arch_ndelay(uint64_t n); - /** * Delay for a specified number of nanoseconds. * * @param ns Number of nanoseconds to delay for. */ -static inline void ndelay(unsigned int ns) -{ - arch_ndelay((uint64_t)ns); -} +void ndelay(uint64_t n); /** * Delay for a specified number of microseconds. @@ -33,7 +28,7 @@ static inline void ndelay(unsigned int ns) */ static inline void udelay(unsigned int us) { - arch_ndelay((uint64_t)us * NSECS_PER_USEC); + ndelay((uint64_t)us * NSECS_PER_USEC); } /** @@ -43,7 +38,7 @@ static inline void udelay(unsigned int us) */ static inline void mdelay(unsigned int ms) { - arch_ndelay((uint64_t)ms * NSECS_PER_MSEC); + ndelay((uint64_t)ms * NSECS_PER_MSEC); } /** @@ -53,7 +48,7 @@ static inline void mdelay(unsigned int ms) */ static inline void delay(unsigned int s) { - arch_ndelay((uint64_t)s * NSECS_PER_SEC); + ndelay((uint64_t)s * NSECS_PER_SEC); } #endif /* LIBPAYLOAD_DELAY_H */ diff --git a/payloads/libpayload/libc/time.c b/payloads/libpayload/libc/time.c index 64de80049c..0d599644a7 100644 --- a/payloads/libpayload/libc/time.c +++ b/payloads/libpayload/libc/time.c @@ -161,13 +161,14 @@ int gettimeofday(struct timeval *tv, void *tz) return 0; } -__attribute__((weak)) -void arch_ndelay(uint64_t ns) +#if !CONFIG(LP_ARCH_HAS_NDELAY) +void ndelay(uint64_t ns) { uint64_t delta = ns * timer_hz() / NSECS_PER_SEC; uint64_t start = timer_raw_value(); while (timer_raw_value() - start < delta) ; } +#endif u64 timer_us(u64 base) { diff --git a/payloads/libpayload/tests/drivers/Makefile.mk b/payloads/libpayload/tests/drivers/Makefile.mk index 8d668c2e42..f898278a3a 100644 --- a/payloads/libpayload/tests/drivers/Makefile.mk +++ b/payloads/libpayload/tests/drivers/Makefile.mk @@ -8,4 +8,4 @@ graphics-test-srcs += libc/fpmath.c speaker-test-srcs += tests/drivers/speaker-test.c speaker-test-mocks += inb speaker-test-mocks += outb -speaker-test-mocks += arch_ndelay +speaker-test-mocks += ndelay diff --git a/payloads/libpayload/tests/drivers/speaker-test.c b/payloads/libpayload/tests/drivers/speaker-test.c index a677fa46ca..eb907ce05d 100644 --- a/payloads/libpayload/tests/drivers/speaker-test.c +++ b/payloads/libpayload/tests/drivers/speaker-test.c @@ -104,7 +104,7 @@ static void test_speaker_disable(void **state) speaker_disable(); } -void arch_ndelay(uint64_t ns) +void ndelay(uint64_t ns) { check_expected(ns); } @@ -112,9 +112,9 @@ void arch_ndelay(uint64_t ns) static void setup_speaker_tone_calls(u16 freq, unsigned int duration) { setup_speaker_enable_calls(freq, ~freq & 0xff); - expect_value(arch_ndelay, ns, (uint64_t)duration * NSECS_PER_MSEC); + expect_value(ndelay, ns, (uint64_t)duration * NSECS_PER_MSEC); setup_speaker_disable_calls(0xff); - expect_any(arch_ndelay, ns); + expect_any(ndelay, ns); } static void test_speaker_tone(void **state)