libpayload/libc/time: Add an arch_ndelay()

Replace _delay with an arch_ndelay(). This way each arch can setup their
own delay mechanism.

BUG=b:109749762
TEST=Verified delay's still work on grunt.

Change-Id: I552eb30984f9c21e92dffc9d7b36873e9e2e4ac5
Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Reviewed-on: https://review.coreboot.org/28243
Reviewed-by: Martin Roth <martinroth@google.com>
Reviewed-by: Richard Spiegel <richard.spiegel@silverbackltd.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Raul E Rangel 2018-08-20 12:47:19 -06:00 committed by Martin Roth
parent 24ae85c3ff
commit d63627fb84
3 changed files with 47 additions and 45 deletions

View File

@ -464,11 +464,48 @@ unsigned int get_cpu_speed(void);
uint64_t timer_hz(void); uint64_t timer_hz(void);
uint64_t timer_raw_value(void); uint64_t timer_raw_value(void);
uint64_t timer_us(uint64_t base); uint64_t timer_us(uint64_t base);
void arch_ndelay(uint64_t n);
/* Generic. */ /* Generic. */
void ndelay(unsigned int n);
void udelay(unsigned int n); /**
void mdelay(unsigned int n); * Delay for a specified number of nanoseconds.
void delay(unsigned int n); *
* @param ns Number of nanoseconds to delay for.
*/
static inline void ndelay(unsigned int ns)
{
arch_ndelay((uint64_t)ns);
}
/**
* Delay for a specified number of microseconds.
*
* @param us Number of microseconds to delay for.
*/
static inline void udelay(unsigned int us)
{
arch_ndelay((uint64_t)us * NSECS_PER_USEC);
}
/**
* Delay for a specified number of milliseconds.
*
* @param ms Number of milliseconds to delay for.
*/
static inline void mdelay(unsigned int ms)
{
arch_ndelay((uint64_t)ms * NSECS_PER_MSEC);
}
/**
* Delay for a specified number of seconds.
*
* @param s Number of seconds to delay for.
*/
static inline void delay(unsigned int s)
{
arch_ndelay((uint64_t)s * NSECS_PER_SEC);
}
/** /**
* @defgroup readline Readline functions * @defgroup readline Readline functions

View File

@ -29,6 +29,9 @@ typedef __SIZE_TYPE__ ssize_t;
#define MHz (1000*KHz) #define MHz (1000*KHz)
#define GHz (1000*MHz) #define GHz (1000*MHz)
#define NSECS_PER_SEC 1000000000
#define USECS_PER_SEC 1000000 #define USECS_PER_SEC 1000000
#define MSECS_PER_SEC 1000 #define MSECS_PER_SEC 1000
#define NSECS_PER_MSEC (NSECS_PER_SEC / MSECS_PER_SEC)
#define NSECS_PER_USEC (NSECS_PER_SEC / USECS_PER_SEC)
#define USECS_PER_MSEC (USECS_PER_SEC / MSECS_PER_SEC) #define USECS_PER_MSEC (USECS_PER_SEC / MSECS_PER_SEC)

View File

@ -158,52 +158,14 @@ int gettimeofday(struct timeval *tv, void *tz)
return 0; return 0;
} }
static inline void _delay(uint64_t delta) __attribute__((weak))
void arch_ndelay(uint64_t ns)
{ {
uint64_t delta = ns * timer_hz() / NSECS_PER_SEC;
uint64_t start = timer_raw_value(); uint64_t start = timer_raw_value();
while (timer_raw_value() - start < delta) ; while (timer_raw_value() - start < delta) ;
} }
/**
* Delay for a specified number of nanoseconds.
*
* @param n Number of nanoseconds to delay for.
*/
void ndelay(unsigned int n)
{
_delay((uint64_t)n * timer_hz() / 1000000000);
}
/**
* Delay for a specified number of microseconds.
*
* @param n Number of microseconds to delay for.
*/
void udelay(unsigned int n)
{
_delay((uint64_t)n * timer_hz() / 1000000);
}
/**
* Delay for a specified number of milliseconds.
*
* @param m Number of milliseconds to delay for.
*/
void mdelay(unsigned int m)
{
_delay((uint64_t)m * timer_hz() / 1000);
}
/**
* Delay for a specified number of seconds.
*
* @param s Number of seconds to delay for.
*/
void delay(unsigned int s)
{
_delay((uint64_t)s * timer_hz());
}
u64 timer_us(u64 base) u64 timer_us(u64 base)
{ {
static u64 hz; static u64 hz;