[U-Boot] [RFC] Timer API (again!)

Simon Glass sjg at chromium.org
Wed Sep 28 06:33:54 CEST 2011


Hi Graeme,

On Fri, Sep 16, 2011 at 4:53 AM, Graeme Russ <graeme.russ at gmail.com> wrote:
> Hi All,
>
> Well, here we are again, a Timer API discussion :)
>
> All things considered, I don't think the Linux approach is right for U-Boot
> - It is designed to cater for way more use-cases than U-Boot will ever need
> to deal with (time queues and call-backs in particular)

Yes it is extremely complex.

>
> To summarise, in a nutshell, what _I_ think U-Boot need from a Timer API
>
>  1. A reliable udelay() available as early as possible that is OK to delay
>    longer than requested, but not shorter - Accuracy is not implied or
>    assumed

Yes. Can you be specific about 'early'? Do you mean in start.S, before
board_init_f(), or before arch_cpu_init() or something else?

My feeling is that callers prior to, say, the first few init functions
called by board_init_f() could probably call their own implementation
directly if needed.

>  2. A method of obtaining a number of 'time intervals' which have elapsed
>    since some random epoch (more info below)
>  3. A nice way of making A->B time checks simple within the code
>
> OK, some details:
>
> 1. I'm starting to thing this should be a function pointer or a flag in gd.
> Why oh why would you do such a thing I hear you ask... udelay() is needed
> _EARLY_ - It may well be needed for SDRAM or other hardware initialisation
> prior to any reliable timer sub-system being available. But early udelay()
> is often inaccurate and when the timer sub-system gets fully initialised,
> it can be used for an accurate udelay(). x86 used to have an global data
> flag that got set when the timer-subsystem got initialised. If the flag was
> not set, udelay() would use one implementation, but if it was set, udelay()
> would use a more accurate implementation. In the case of the eNET board, it
> had an FPGA implementation of a microsecond timer which was even more
> accurate that the CPU, so it had it's own implementation that should have
> duplicated the 'if (gd->flags & TIMER_INIT)' but never did (this was OK
> because udelay() was never needed before then)
>
> I think a function pointer in gd would be a much neater way of handling the
> fact that more accurate (and efficient) implementations of udelay() may
> present themselves throughout the boot process
>
> An other option would be to have the gd flag and make udelay() a lib
> function which performs the test - If the arch timer has better than 1us
> resolution it can set the flag and udelay() will use the timer API

Is this a general need or something architecture specific? Perhaps we
should allow boards to override the raw timer function and deal with
this feature that way? Am I right in saying that most boards will not
need this feature?

>
> 2a (random epoch) - The timer sub-system should not rely on a particular
> epoch (1970, 1901, 0, 1, since boot, since timer init, etc...) - By using
> the full range of an unsigned variable, the epoch does not matter
>

Yes, the way I see it this is monotonic timer of no fixed base. The
base could well be the time reset was removed from the board...

> 2b (time interval) - We need to pick a base resolution for the timer API -
> Linux uses nano-seconds and I believe this is a good choice. Big Fat Note:
> The underlying hardware DOES NOT need to have nano-second resolution. The
> only issue with nano-seconds is that it mandates a 64-bit timer - A few
> people are against this idea - lets discuss. A 32-bit microsecond timer
> provides ~4300 seconds (~1.2 hours) which _might_ be long enough, but
> stand-alone applications doing burn-in tests may need longer. Going
> milli-seconds means we cannot piggy-back udelay() on the timer API.

Re burn-in tests this sounds like an unusual case, and anyway it is
unlikely to matter that the timer wraps. The tests can be written to
deal with this quite easily, right?

>
> My preference is a 64-bit nano-second timer with udelay() piggy-backed on
> the timer API (unless, like NIOS, the timer sub-system cannot provide
> micro-second resolution, in which case the gd flag or function pointer does
> not get set to use the timer API for udelay())

Well clearly nanoseconds fits better with the kernel, but it does
mandate a 64-bit counter. No comments on this so far from anyone else.
My feeling is that microsecond is enough for most purposes. Perhaps to
placate the efficiency / code size people we could split the API into
a mandatory nanosecond 64-bit value and an optional microsecond value
which is 32-bit only. The default udelay() and get_timer_us (or
whatever it is called) can rely on the 64-bit ns counter divided by
1000, but archs are free to provide their own implementation which is
32-bits. I suppose the main thing is to get the API clear and
consistent even if implementations differ.

While I can see a ns in our future I also feel that CPU speeds have
hit a limit of a few GHz and most things that U-Boot cares about re
measured in us.

>
> I really want to get the Timer API sorted this time around

Yes. I'm looking forward to getting my microsecond timer!

Regards,
Simon

>
> Regards,
>
> Graeme
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>


More information about the U-Boot mailing list