* Higher resolution timers
@ 2008-05-12 16:33 Colin D Bennett
2008-05-14 16:26 ` Vesa Jääskeläinen
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Colin D Bennett @ 2008-05-12 16:33 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 635 bytes --]
To implement a nice GUI with some animations, it will be important to
have a timer with a better resolution than 1/18 second (which appears
to be the current GRUB timer resolution on the PC).
What would be the best way to do this? Possibilities that I am aware of
are:
* RDTSC instruction (must calibrate with RTC at startup?)
* HPET (complex to use?)
* RTC (can we set the timer interrupt rate to >18 Hz?)
Does anyone have any thoughts on these options?
I think that using the TSC (w/ RDTSC instruction) and calibrating it
with a quick 2-3 RTC tick loop at startup might be the easiest option.
Regards,
Colin
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: Higher resolution timers
2008-05-12 16:33 Higher resolution timers Colin D Bennett
@ 2008-05-14 16:26 ` Vesa Jääskeläinen
2008-05-18 16:27 ` Vesa Jääskeläinen
` (2 subsequent siblings)
3 siblings, 0 replies; 11+ messages in thread
From: Vesa Jääskeläinen @ 2008-05-14 16:26 UTC (permalink / raw)
To: The development of GRUB 2
Hi All,
Colin D Bennett wrote:
> To implement a nice GUI with some animations, it will be important to
> have a timer with a better resolution than 1/18 second (which appears
> to be the current GRUB timer resolution on the PC).
>
> What would be the best way to do this? Possibilities that I am aware of
> are:
> * RDTSC instruction (must calibrate with RTC at startup?)
> * HPET (complex to use?)
> * RTC (can we set the timer interrupt rate to >18 Hz?)
>
> Does anyone have any thoughts on these options?
>
> I think that using the TSC (w/ RDTSC instruction) and calibrating it
> with a quick 2-3 RTC tick loop at startup might be the easiest option.
Perhaps non-x86 BIOS people could provide feedback how to get more
detailed timer information on other platforms? So we could produce an
API that would be portable.
At least RDTSC do not work on pre-pentium machines so at least some
detection for this OP code would be required to determine best possible
way to use timer service. I think we have cpuid module already, perhaps
this could be used for that too...
Thanks,
Vesa Jääskeläinen
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: Higher resolution timers
2008-05-12 16:33 Higher resolution timers Colin D Bennett
2008-05-14 16:26 ` Vesa Jääskeläinen
@ 2008-05-18 16:27 ` Vesa Jääskeläinen
2008-05-20 17:20 ` Colin D Bennett
2008-05-20 17:46 ` Colin D Bennett
2008-05-23 11:48 ` Marco Gerards
3 siblings, 1 reply; 11+ messages in thread
From: Vesa Jääskeläinen @ 2008-05-18 16:27 UTC (permalink / raw)
To: The development of GRUB 2
Colin D Bennett wrote:
> To implement a nice GUI with some animations, it will be important to
> have a timer with a better resolution than 1/18 second (which appears
> to be the current GRUB timer resolution on the PC).
>
> What would be the best way to do this? Possibilities that I am aware of
> are:
> * RDTSC instruction (must calibrate with RTC at startup?)
> * HPET (complex to use?)
> * RTC (can we set the timer interrupt rate to >18 Hz?)
>
> Does anyone have any thoughts on these options?
>
> I think that using the TSC (w/ RDTSC instruction) and calibrating it
> with a quick 2-3 RTC tick loop at startup might be the easiest option.
Hi Colin,
What kind of accuracy would you need?
I am just wondering if you just define function like:
grub_uint64_t
grub_timer_[nu]time(void);
This could return time in nanoseconds, or microseconds from epoch.
Then during grub init you would call some platform function to
initialize time (calibrate when using rdtsc), and set proper offset
value so you get correct time when asking for time. On every system it
would return time in this format, but granularity would be different.
This could be:
void
grub_timer_init(void)
What do you think?
Thanks,
Vesa Jääskeläinen
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Higher resolution timers
2008-05-18 16:27 ` Vesa Jääskeläinen
@ 2008-05-20 17:20 ` Colin D Bennett
0 siblings, 0 replies; 11+ messages in thread
From: Colin D Bennett @ 2008-05-20 17:20 UTC (permalink / raw)
To: grub-devel
On Sun, 18 May 2008 19:27:05 +0300
Vesa Jääskeläinen <chaac@nic.fi> wrote:
> Colin D Bennett wrote:
> > I think that using the TSC (w/ RDTSC instruction) and calibrating it
> > with a quick 2-3 RTC tick loop at startup might be the easiest
> > option.
>
> Hi Colin,
>
> What kind of accuracy would you need?
>
> I am just wondering if you just define function like:
>
> grub_uint64_t
> grub_timer_[nu]time(void);
>
> This could return time in nanoseconds, or microseconds from epoch.
>
> Then during grub init you would call some platform function to
> initialize time (calibrate when using rdtsc), and set proper offset
> value so you get correct time when asking for time. On every system
> it would return time in this format, but granularity would be
> different.
>
> This could be:
>
> void
> grub_timer_init(void)
>
> What do you think?
Vesa,
It sounds good. Actually, for the kind of the situations I am
thinking of, high resolution timing is not required to be based on any
absolute real time, so we would not necessarily need to base it on RTC
time. Synchronizing it to RTC time would probably not be difficult, but
I thought I would mention what my requirements will be.
Here is the kind of situation I envision, in an event loop that handles
accepting user input and updating the screen at regular intervals
(possibly at 30 to 60 frames/sec, hence the need for higher resolution
timers) to support the user interface:
/* Event loop */
grub_uint32_t nextframe_time = 0;
grub_uint32_t now;
while (1)
{
now = grub_timer_utime();
if (now >= nextframe_time)
{
/* Schedule the next frame. */
nextframe_time = now + 1000000 / FRAMES_PER_SEC;
do_animation_step();
}
if (key_is_pressed())
{
/* Handle key presses... */
}
}
So all I care about is the value relative to other calls to
grub_timer_utime() during a particular runtime of grub. It could start
at 0 if that is easier, but either way is fine.
Colin
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Higher resolution timers
2008-05-12 16:33 Higher resolution timers Colin D Bennett
2008-05-14 16:26 ` Vesa Jääskeläinen
2008-05-18 16:27 ` Vesa Jääskeläinen
@ 2008-05-20 17:46 ` Colin D Bennett
2008-05-23 11:55 ` Marco Gerards
2008-05-23 11:48 ` Marco Gerards
3 siblings, 1 reply; 11+ messages in thread
From: Colin D Bennett @ 2008-05-20 17:46 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 1417 bytes --]
On Mon, 12 May 2008 09:33:54 -0700
Colin D Bennett <colin@gibibit.com> wrote:
> I think that using the TSC (w/ RDTSC instruction) and calibrating it
> with a quick 2-3 RTC tick loop at startup might be the easiest option.
Just wondered if something like this would be a practical way to go:
/*******************************************************************/
/* How many ticks to use for calibration loop. (>= 1) */
#define CALIBRATION_TICKS 2
/* Output: Number of TSC cycles per second. */
grub_uint64_t tsc_cycles_per_second;
void grub_timer_tsc_calibrate(void)
{
/* Calibrate to real time (relative, not absolute). */
grub_uint64_t start_tsc;
grub_uint64_t end_tsc;
grub_uint32_t initial_tick;
grub_uint32_t start_tick;
grub_uint32_t end_tick;
/* Wait for the start of the next tick;
we'll base out timing off this edge. */
initial_tick = grub_get_rtc();
do
{
start_tick = grub_get_rtc();
}
while (start_tick == initial_tick);
start_tsc = rdtsc();
/* Wait for the start of the next tick. This will
be the end of the 1-tick period. */
do
{
end_tick = grub_get_rtc();
}
while (end_tick - start_tick < CALIBRATION_TICKS);
end_tsc = rdtsc();
tsc_cycles_per_second =
(end_tsc - start_tsc) / (end_tick - start_tick)
* GRUB_TICKS_PER_SEC;
}
/*******************************************************************/
Colin
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: Higher resolution timers
2008-05-20 17:46 ` Colin D Bennett
@ 2008-05-23 11:55 ` Marco Gerards
2008-05-23 14:28 ` Colin D Bennett
0 siblings, 1 reply; 11+ messages in thread
From: Marco Gerards @ 2008-05-23 11:55 UTC (permalink / raw)
To: The development of GRUB 2
Colin D Bennett <colin@gibibit.com> writes:
> On Mon, 12 May 2008 09:33:54 -0700
> Colin D Bennett <colin@gibibit.com> wrote:
>
>> I think that using the TSC (w/ RDTSC instruction) and calibrating it
>> with a quick 2-3 RTC tick loop at startup might be the easiest option.
>
> Just wondered if something like this would be a practical way to go:
Well, I only had a quick look and this might be a good way to measure
the clock speed. BTW, can you please make sure you use our coding
style? Are the 2-3 loops based on some calculations or only a guess?
There might be a problem with using this instruction. Are clock
cycles actually measured after using the "halt" instruction? If not,
the use of such instruction might not generally used in GRUB :-/
--
Marco
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Higher resolution timers
2008-05-23 11:55 ` Marco Gerards
@ 2008-05-23 14:28 ` Colin D Bennett
2008-05-24 9:23 ` Marco Gerards
0 siblings, 1 reply; 11+ messages in thread
From: Colin D Bennett @ 2008-05-23 14:28 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 2404 bytes --]
On Fri, 23 May 2008 13:55:21 +0200
Marco Gerards <mgerards@xs4all.nl> wrote:
> Colin D Bennett <colin@gibibit.com> writes:
>
> > On Mon, 12 May 2008 09:33:54 -0700
> > Colin D Bennett <colin@gibibit.com> wrote:
> >
> >> I think that using the TSC (w/ RDTSC instruction) and calibrating
> >> it with a quick 2-3 RTC tick loop at startup might be the easiest
> >> option.
> >
> > Just wondered if something like this would be a practical way to go:
>
> Well, I only had a quick look and this might be a good way to measure
> the clock speed. BTW, can you please make sure you use our coding
> style? Are the 2-3 loops based on some calculations or only a guess?
Of course I will adhere to the GRUB coding style. The snippet I posted
was just basically just quick pseudocode (not actually compiled) based
on 10 minutes of thought. I did not take time to format the code style
but surely I would before submitting an actual patch.
I think we only need 1 full RTC timer tick (i.e. 1/18 of a
second) to figure out how many TSC cycles correspond to one second of
real time. The code has to first synchronize to the starting edge of
an RTC tick, so that is the loop:
do { ... } while (start_tick == initial_tick);
Then the number of elapsed TSC cycles until the next RTC tick is
calculated and the TSC cycles per second is calculated.
(As I said, this is untested and incomplete scratch work as a starting
point for a discussion, and it might not even compile.)
> There might be a problem with using this instruction. Are clock
> cycles actually measured after using the "halt" instruction? If not,
> the use of such instruction might not generally used in GRUB :-/
Thanks for thinking of that. According to
<http://www.scl.ameslab.gov/Projects/Rabbit/menu4.html>, the TSC
continues counting even when the CPU executes the HLT instruction:
The TSC is set to 0 at system reset. It presently increments once per
processor cycle, and is 64 bits wide. Only CPL = 0 can modify TSC,
and then only the lower 32 bits can be set, while the upper 32 bits
are cleared. We do not recommend changing TSC, and the library does
not permit it. The TSC will continue to increment in the halt state
(HLT instruction).
Therefore, I think that that the HLT instruction in GRUB will not
negatively impact the use of RDTSC.
Regards,
Colin
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: Higher resolution timers
2008-05-23 14:28 ` Colin D Bennett
@ 2008-05-24 9:23 ` Marco Gerards
2008-05-28 13:43 ` Robert Millan
0 siblings, 1 reply; 11+ messages in thread
From: Marco Gerards @ 2008-05-24 9:23 UTC (permalink / raw)
To: The development of GRUB 2
Colin D Bennett <colin@gibibit.com> writes:
> On Fri, 23 May 2008 13:55:21 +0200
> Marco Gerards <mgerards@xs4all.nl> wrote:
>
>> Colin D Bennett <colin@gibibit.com> writes:
>>
>> > On Mon, 12 May 2008 09:33:54 -0700
>> > Colin D Bennett <colin@gibibit.com> wrote:
>> >
>> >> I think that using the TSC (w/ RDTSC instruction) and calibrating
>> >> it with a quick 2-3 RTC tick loop at startup might be the easiest
>> >> option.
>> >
>> > Just wondered if something like this would be a practical way to go:
>>
>> Well, I only had a quick look and this might be a good way to measure
>> the clock speed. BTW, can you please make sure you use our coding
>> style? Are the 2-3 loops based on some calculations or only a guess?
>
> Of course I will adhere to the GRUB coding style. The snippet I posted
> was just basically just quick pseudocode (not actually compiled) based
> on 10 minutes of thought. I did not take time to format the code style
> but surely I would before submitting an actual patch.
Great. I hope you didn't mind that I asked. I always feel evil after
asking this question when someone sends in a great amount of code, so
I rather ask it now :-)
> I think we only need 1 full RTC timer tick (i.e. 1/18 of a
> second) to figure out how many TSC cycles correspond to one second of
> real time. The code has to first synchronize to the starting edge of
> an RTC tick, so that is the loop:
> do { ... } while (start_tick == initial_tick);
> Then the number of elapsed TSC cycles until the next RTC tick is
> calculated and the TSC cycles per second is calculated.
I agree! :-)
> (As I said, this is untested and incomplete scratch work as a starting
> point for a discussion, and it might not even compile.)
It's perfectly clear for discussion.
>> There might be a problem with using this instruction. Are clock
>> cycles actually measured after using the "halt" instruction? If not,
>> the use of such instruction might not generally used in GRUB :-/
>
> Thanks for thinking of that. According to
> <http://www.scl.ameslab.gov/Projects/Rabbit/menu4.html>, the TSC
> continues counting even when the CPU executes the HLT instruction:
>
> The TSC is set to 0 at system reset. It presently increments once per
> processor cycle, and is 64 bits wide. Only CPL = 0 can modify TSC,
> and then only the lower 32 bits can be set, while the upper 32 bits
> are cleared. We do not recommend changing TSC, and the library does
> not permit it. The TSC will continue to increment in the halt state
> (HLT instruction).
>
> Therefore, I think that that the HLT instruction in GRUB will not
> negatively impact the use of RDTSC.
Great!
Will you keep in mind that we have to switch back the RTC in case this
instruction is not available? In that case this patch will not work
perfectly on older hardware, but it will at least not crash the
computer.
--
Marco
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: Higher resolution timers
2008-05-24 9:23 ` Marco Gerards
@ 2008-05-28 13:43 ` Robert Millan
0 siblings, 0 replies; 11+ messages in thread
From: Robert Millan @ 2008-05-28 13:43 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, May 24, 2008 at 11:23:14AM +0200, Marco Gerards wrote:
> > Of course I will adhere to the GRUB coding style. The snippet I posted
> > was just basically just quick pseudocode (not actually compiled) based
> > on 10 minutes of thought. I did not take time to format the code style
> > but surely I would before submitting an actual patch.
>
> Great. I hope you didn't mind that I asked. I always feel evil after
> asking this question when someone sends in a great amount of code, so
> I rather ask it now :-)
But they could use indent... ;-)
--
Robert Millan
<GPLv2> I know my rights; I want my phone call!
<DRM> What good is a phone call… if you are unable to speak?
(as seen on /.)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Higher resolution timers
2008-05-12 16:33 Higher resolution timers Colin D Bennett
` (2 preceding siblings ...)
2008-05-20 17:46 ` Colin D Bennett
@ 2008-05-23 11:48 ` Marco Gerards
2008-05-24 15:25 ` Vesa Jääskeläinen
3 siblings, 1 reply; 11+ messages in thread
From: Marco Gerards @ 2008-05-23 11:48 UTC (permalink / raw)
To: The development of GRUB 2
Hi Colin,
Colin D Bennett <colin@gibibit.com> writes:
> To implement a nice GUI with some animations, it will be important to
> have a timer with a better resolution than 1/18 second (which appears
> to be the current GRUB timer resolution on the PC).
Such patch will me more than welcome. We actually need this to get
the ATA driver working on Coreboot. Furthermore, there are many other
things we will need this for. I hope you can, when you have such a
thing, can send in a patch for this? This will avoid duplicate work
because we really need this soon.
I expect I will need this for USB as well.
> What would be the best way to do this? Possibilities that I am aware of
> are:
> * RDTSC instruction (must calibrate with RTC at startup?)
> * HPET (complex to use?)
> * RTC (can we set the timer interrupt rate to >18 Hz?)
>
> Does anyone have any thoughts on these options?
>
> I think that using the TSC (w/ RDTSC instruction) and calibrating it
> with a quick 2-3 RTC tick loop at startup might be the easiest option.
Only something that really returns a time seems like a good choise to
me. AFAIK RDTSC returns clock cycles that passed since the system was
switched on. This means that code will run faster on a processor with
a higher clock speed. Am I mistaken?
So I prefer something that can be used to wait a microsecond and not a
certain amount of clock cycles. Using the RTC seems a good choice,
but we have to keep in mind the BIOS uses it as well.
Isn't HPET only available on newer processors?
--
Marco
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: Higher resolution timers
2008-05-23 11:48 ` Marco Gerards
@ 2008-05-24 15:25 ` Vesa Jääskeläinen
0 siblings, 0 replies; 11+ messages in thread
From: Vesa Jääskeläinen @ 2008-05-24 15:25 UTC (permalink / raw)
To: The development of GRUB 2
Marco Gerards wrote:
> Hi Colin,
>
> Colin D Bennett <colin@gibibit.com> writes:
>> What would be the best way to do this? Possibilities that I am aware of
>> are:
>> * RDTSC instruction (must calibrate with RTC at startup?)
>> * HPET (complex to use?)
>> * RTC (can we set the timer interrupt rate to >18 Hz?)
>>
>> Does anyone have any thoughts on these options?
>>
>> I think that using the TSC (w/ RDTSC instruction) and calibrating it
>> with a quick 2-3 RTC tick loop at startup might be the easiest option.
>
> Only something that really returns a time seems like a good choise to
> me. AFAIK RDTSC returns clock cycles that passed since the system was
> switched on. This means that code will run faster on a processor with
> a higher clock speed. Am I mistaken?
That's way you calibrate it :) Then you can get pretty good accuracy :)
> So I prefer something that can be used to wait a microsecond and not a
> certain amount of clock cycles. Using the RTC seems a good choice,
> but we have to keep in mind the BIOS uses it as well.
Default rate for RTC is bad for any accuracy. At least in this case.
>
> Isn't HPET only available on newer processors?
Yes.
But the idea is to use best possible resolution available. So if choice
A is not there then fallback for choice B. Of course in some cases
animation will not be so smooth. But at least it will work.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-05-28 13:44 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-12 16:33 Higher resolution timers Colin D Bennett
2008-05-14 16:26 ` Vesa Jääskeläinen
2008-05-18 16:27 ` Vesa Jääskeläinen
2008-05-20 17:20 ` Colin D Bennett
2008-05-20 17:46 ` Colin D Bennett
2008-05-23 11:55 ` Marco Gerards
2008-05-23 14:28 ` Colin D Bennett
2008-05-24 9:23 ` Marco Gerards
2008-05-28 13:43 ` Robert Millan
2008-05-23 11:48 ` Marco Gerards
2008-05-24 15:25 ` Vesa Jääskeläinen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.