[U-Boot] [RFC] Review of U-Boot timer API

J. William Campbell
2011-05-22T00:43:56Z

On 5/21/2011 5:06 PM, Graeme Russ wrote:
> On 22/05/11 01:33, J. William Campbell wrote:
>> On 5/21/2011 5:38 AM, Graeme Russ wrote:
>>> Hi All,
>>> 4. Implement microsecond API - get_usec_timer()
>>> -----------------------------------------------
>>> - Useful for profiling
>>> - A 32-bit microsecond counter wraps in 71 minutes - Probably OK for most
>>> U-Boot usage scenarios
>>> - By default could return get_timer() * 1000 if hardware does not support
>>> microsecond accuracy - Beware of results> 32 bits!
>> Hi All,
>> I think the multiply overflowing an unsigned long is ok here as long
>> as the timeout value you desire is less than 71 seconds. This assumes that
>> the CPU returns the correct lower 32 bits when overflow occurs, but I think
>> this is the "normal" behavior(?)
> I think you mean 71 minutes - 2^32 = 4294967296 (usec) = 4294967.296 (msec)
> = 4294.967296 s = 71.582788267 minutes
>
> So provided any millisecond timer using a 32-bit microsecond timer as a
> time base is called every 71 minutes, a 32-bit microsecond timer should
> suffice to keep the msb's accurately maintained by software
>
Hi Graeme,
Yes, you are certainly correct, it is minutes, not seconds.
>>> - If hardware supports microsecond resolution counters, get_timer() could
>>> simply use get_usec_timer() / 1000
>> I think this actually is NOT equivalent to the "current" API in
>> that the full 32 bits of the timer is not available and as a result the
>> "wrapping" properties of a 32 bit subtract for delta times will not work
>> properly. If a "larger" counter is available in hardware, then it is
>> certainly possible to do a 64 by 32 bit divide in get_timer, but probably
>> you don't want to do that either. As previously discussed, it is possible
>> to extract a 32 bit monotonic counter of given resolution (microsecond or
>> millisecond resolution) from a higher resolution counter using a shift to
>> "approximately" the desired resolution followed by a couple of multiply/add
>> functions of 32 bit resolution. To do this with a microsecond resolution,
>> a 42 bit or larger timer is required. The "extra" bits can be provided in
> Of course, how silly of me - To downscale the microsecond timer down to
> milliseconds you need to have at least 1000 times more resolution
> (9.965784285 bits) - It was late ;)
>
>> software as long as the get_timer/get_usec_timer routines are called more
>> often than every 71/2 sec, so that a correct delta in microseconds can be
>> obtained. Note that when the timer is not actively in use (not called
>> often enough), the millisecond timer msb would stop updating, but that
>> wouldn't matter.
> Minutes - see above
Correct.
>> If the hardware supports sub-microsecond accuracy in a "longer"
>> register, say 64 bits, you can just convert the 64 bit hardware timer to 32
>> bit microseconds or milliseconds by a shift and 32 bit multiplies
> Yes
>
>> Good luck with this effort. I think getting the timer API and also
>> the method of implementation of the interface to the hardware to be the
>> same across all u-boot architectures is a very good idea, and it is
>> possible. However, it is a quite a bit of work and I am glad you are brave
>> enough to try!
> It's all there already - it just needs a little bit of housekeeping :)
Correct, if we do not worry too much about the "low level" details of
get_timer. It looks to me like there is a lot of cruft there, depending
on which architecture one looks at. Many implementations create a
parallel universe of get_ticks or some similar timing system that is
then used to support get_timer. However, the get_ticks routines are also
used in timeouts elsewhere in the code. Searching on "get_timer" doesn't
find these non-standard usages. It would be nice to fix these also, but
every bit does help!

Best Regards,
Bill Campbell
> Regards,
>
> Graeme
>
>