2007-12-01 05:07:01 +01:00
|
|
|
/*
|
|
|
|
* core/timer.c
|
|
|
|
*
|
|
|
|
* Copyright (C) 2007 Alexey Zaytsev <alexey.zaytsev@gmail.com>
|
|
|
|
*
|
2005-03-08 19:53:11 +01:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
2007-12-01 05:07:01 +01:00
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
2005-03-08 19:53:11 +01:00
|
|
|
*/
|
|
|
|
|
2007-12-01 05:07:01 +01:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <gpxe/init.h>
|
|
|
|
#include <gpxe/timer.h>
|
|
|
|
#include <stdio.h>
|
2005-03-08 19:53:11 +01:00
|
|
|
|
2007-12-01 05:07:01 +01:00
|
|
|
static struct timer ts_table[0]
|
|
|
|
__table_start ( struct timer, timers );
|
|
|
|
static struct timer ts_table_end[0]
|
|
|
|
__table_end ( struct timer, timers );
|
2005-03-08 19:53:11 +01:00
|
|
|
|
2007-12-01 05:07:01 +01:00
|
|
|
|
|
|
|
static struct timer *used_ts = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function may be used in custom timer driver.
|
|
|
|
*
|
|
|
|
* This udelay implementation works well if you've got a
|
|
|
|
* fast currticks().
|
|
|
|
*/
|
|
|
|
void generic_currticks_udelay(unsigned int usecs)
|
2005-03-08 19:53:11 +01:00
|
|
|
{
|
2007-12-01 05:07:01 +01:00
|
|
|
tick_t t;
|
|
|
|
|
|
|
|
t = currticks();
|
|
|
|
while (t + usecs > currticks())
|
|
|
|
; /* xxx: Relax the cpu some way. */
|
2005-03-08 19:53:11 +01:00
|
|
|
}
|
|
|
|
|
2007-12-01 05:07:01 +01:00
|
|
|
|
|
|
|
static void timer_init(void)
|
2005-03-08 19:53:11 +01:00
|
|
|
{
|
2007-12-01 05:07:01 +01:00
|
|
|
struct timer *ts;
|
|
|
|
|
|
|
|
for (ts = ts_table; ts < ts_table_end; ts++) {
|
2008-03-02 02:36:50 +01:00
|
|
|
if (ts->init && ts->init() >= 0) {
|
2007-12-01 05:07:01 +01:00
|
|
|
used_ts = ts;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-02 02:36:50 +01:00
|
|
|
assert(used_ts);
|
2005-03-08 19:53:11 +01:00
|
|
|
}
|
2007-12-01 05:07:01 +01:00
|
|
|
|
|
|
|
struct init_fn ts_init_fn __init_fn ( INIT_NORMAL ) = {
|
|
|
|
.initialise = timer_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Functions for public use. */
|
|
|
|
|
|
|
|
tick_t currticks(void)
|
|
|
|
{
|
|
|
|
tick_t ct;
|
|
|
|
assert(used_ts);
|
|
|
|
|
|
|
|
ct = used_ts->currticks();
|
|
|
|
DBG("currticks: %ld seconds and %06ld microseconds\n", ct/USECS_IN_SEC, ct%USECS_IN_SEC);
|
|
|
|
|
|
|
|
return ct;
|
|
|
|
}
|
|
|
|
|
|
|
|
void udelay(unsigned int usecs)
|
|
|
|
{
|
|
|
|
used_ts->udelay(usecs);
|
|
|
|
}
|
|
|
|
|
|
|
|
void mdelay(unsigned int msecs)
|
|
|
|
{
|
|
|
|
while(msecs--)
|
|
|
|
used_ts->udelay(USECS_IN_MSEC);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int sleep(unsigned int secs)
|
|
|
|
{
|
|
|
|
while (secs--)
|
|
|
|
mdelay(MSECS_IN_SEC);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|