Re: [RFC] TSC patch v2

2008-07-20 Thread Marco Gerards
Colin D Bennett <[EMAIL PROTECTED]> writes:

> Here is an updated version of the TSC patch.
>
> I addressed the issues in your comments with the exception of
> supporting x86 CPUs that don't have a TSC (386 and 486).
>
> I eliminated the grub_time_init() function and the call to it in
> grub_main() in favor of having grub_machine_init() simply call
> grub_tsc_calibrate().  The i386-pc and i386-efi platforms use the TSC.
>
> I also changed the grub_millisleep() generic function to use
> grub_get_time_ms() instead of grub_get_rtc() to achieve better
> precision when a higher resolution time function is available.
>
> Please take a look at it and give me your comments when you have a
> chance.  Thanks!


Great!  Sorry I kept you waiting...

> === modified file 'ChangeLog'
> --- ChangeLog 2008-07-04 02:26:10 +
> +++ ChangeLog 2008-07-04 18:08:36 +
> @@ -1,3 +1,70 @@
> +2008-07-04  Colin D Bennett <[EMAIL PROTECTED]>
> +
> + High resolution timer support.  Implemented for i386 CPU using TSC.
> + Extracted generic grub_millisleep() so it's linked in only as needed.
> + This requires a Pentium compatible CPU; currently the code does not
> + check for this (so it will fail on 386 and 486 machines).

We really need to keep the current machines working.  If you will drop
support for something, please don't do it in a patch but in a separate
discussion so no one will miss it.  But please, I do not think it will
be that hard to keep this.

> + * conf/i386-efi.rmk: Added TSC high resolution time module, link with
> + generic grub_millisleep() function.
> +
> + * conf/i386-pc.rmk: Likewise.
> +
> + * conf/sparc64-ieee1275.rmk: Add kern/generic/millisleep.c and
> + kern/generic/get_time_ms.c to kernel, to use generic time functions.
> +
> + * conf/powerpc-ieee1275.rmk: Add kern/generic/millisleep.c to kernel,
> + to use generic grub_millisleep() function.
> +
> + * conf/i386-linuxbios.rmk: Added kern/generic/get_time_ms.c to the
> + kernel.

Please describe where you change things.  Just have a look at existing
changelog entries how this was done.

> + * kern/generic/get_time_ms.c (grub_get_time_ms): New file.  Platform
> + independent implementation of grub_get_time_ms() using the RTC that
> + can be linked into a platform's kernel when it does not implement its
> + own specialized grub_get_time_ms() function.

"New file." is sufficient.

> + * kern/generic/millisleep.c (grub_millisleep): New file.  Extracted
> + from grub_millisleep_generic() in kern/misc.c and renamed.  Changed it
> + to use grub_get_time_ms() instead of grub_get_rtc() for better
> + precision on when high resolution time is available.

Same here.

> + * kern/misc.c (grub_millisleep_generic): Deleted.  Moved to
> + kern/generic/millisleep.c so that it is only included in the kernel
> + image when a platform does not define a specialized version.

"Deleted." is sufficient.  Or better "Removed.", just because most
people use it :-)

> + * commands/sleep.c (grub_interruptible_millisleep): Uses
> + grub_get_time_ms() instead of grub_get_rtc() to stay in sync with
> + grub_millisleep() from kern/generic/millisleep.c.
> +
> + * include/grub/i386/tsc.h (grub_get_tsc): New file.  Inline function
> + grub_get_tsc() uses x86 RDTSC instruction (available on Pentium+ CPUs)
> + to read the counter value for the TSC.
> + (grub_tsc_calibrate): Declare this function for grub_machine_init().

Same as above.

> + * kern/i386/tsc.c (grub_get_time_ms): x86 TSC support providing a high
> + resolution clock.

I would simply say: "New function."

> + (grub_tsc_calibrate): New function to calibrate the TSC using RTC.

No need to explain what it does.

> + * include/grub/time.h (grub_get_time_ms): Added grub_get_time_ms()
> + function to return the current time in millseconds since the epoch.
> + This supports higher resolution time than grub_get_rtc() on some
> + platforms such as i386-pc, where the RTC has only about 1/18 s
> + precision but a higher precision timer such as the TSC is available.

Perhaps: "New prototype."

You forgot to mention you included .  Please make sure
you mention all other inclusions of header files you added as well.

> + * kern/i386/efi/init.c (grub_millisleep): Deleted.  Don't define
> + grub_millisleep() -- it just called grub_millisleep_generic() but now
> + it is linked to kern/generic/millisleep.c for the implementation.

Only "Removed." will be sufficient.

> + * kern/sparc64/ieee1275/init.c (grub_millisleep): Deleted.

Hurray! ;-)

> + * kern/i386/pc/init.c (grub_machine_init): Call grub_tsc_calibrate().
> + (grub_millisleep): Deleted.
> +
> + * kern/ieee1275/init.c (grub_millisleep): Deleted.
> + (grub_get_rtc): Now calls grub_get_time_ms(), which does the real
> + work.

As you can see from my comments, you do not have to say what something

Re: [RFC] TSC patch v2

2008-07-04 Thread Vesa Jääskeläinen

Colin D Bennett wrote:

On Fri, 04 Jul 2008 22:49:59 +0300
Vesa Jääskeläinen <[EMAIL PROTECTED]> wrote:


Hi Colin,

Colin D Bennett wrote:

Here is an updated version of the TSC patch.

I addressed the issues in your comments with the exception of
supporting x86 CPUs that don't have a TSC (386 and 486).

I eliminated the grub_time_init() function and the call to it in
grub_main() in favor of having grub_machine_init() simply call
grub_tsc_calibrate().  The i386-pc and i386-efi platforms use the
TSC.

Please still use grub_time_init(). Detect TSC, if it is there
calibrate and adapt for it. If it is not there, use RTC.


Should grub_time_init() be a CPU or machine independent function?
Should it use conditional compilation to be usable on different CPUs?
Or should grub_time_init() be specific to i386 kernels at this point?
(Since we don't have anything to initialize for non-TSC-supporting
platforms.)


In your patch you just change call of grub_tsc_calibrate() to 
grub_time_init(). And in grub_time_init() you check cpuflags if tsc is 
available or not. If tsc is available you call grub_tsc_calibrate(). And 
if you are planning to use function pointers then you set proper 
function pointers accordingly.



If grub_time_init() is specific to the i386 CPU, then grub_time_init()
should check whether the CPU has TSC support, and if so,
grub_tsc_calibrate() should be called, and calls to grub_get_time_ms()
should be directed to the TSC implementation.  If no TSC support is
available, then no calibration is done, and calls to grub_get_time_ms()
should be directed to the generic get_time_ms() implementation that
uses grub_get_rtc() to do its job.


You can even make it something like:

- check for cpu flags (eg. detect method)
- if tsc, set function pointers rtc (init=tsc, getters=tsc)
- if no tsc set function pointers to rtc (init=rtc, getters=rtc)
- call function pointer init


I want to make sure that I clearly understand what you want, since I
have made major re-designs of the TSC support in GRUB in an attempt to
do what you want.  Just in the past couple of days I have spent about 8
hours getting the TSC patch where it is now. (I know that seems
like a lot since it's not that much code, but I am just beginning to get
familiar with the GRUB kernel organization, so simple changes have been
taking me a long time.)


Sure... This is why it is good to discuss and design these things on 
mailing list :)




___
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel


Re: [RFC] TSC patch v2

2008-07-04 Thread Colin D Bennett
On Fri, 04 Jul 2008 22:49:59 +0300
Vesa Jääskeläinen <[EMAIL PROTECTED]> wrote:

> Hi Colin,
> 
> Colin D Bennett wrote:
> > Here is an updated version of the TSC patch.
> > 
> > I addressed the issues in your comments with the exception of
> > supporting x86 CPUs that don't have a TSC (386 and 486).
> > 
> > I eliminated the grub_time_init() function and the call to it in
> > grub_main() in favor of having grub_machine_init() simply call
> > grub_tsc_calibrate().  The i386-pc and i386-efi platforms use the
> > TSC.
> 
> Please still use grub_time_init(). Detect TSC, if it is there
> calibrate and adapt for it. If it is not there, use RTC.

Should grub_time_init() be a CPU or machine independent function?
Should it use conditional compilation to be usable on different CPUs?
Or should grub_time_init() be specific to i386 kernels at this point?
(Since we don't have anything to initialize for non-TSC-supporting
platforms.)

If grub_time_init() is specific to the i386 CPU, then grub_time_init()
should check whether the CPU has TSC support, and if so,
grub_tsc_calibrate() should be called, and calls to grub_get_time_ms()
should be directed to the TSC implementation.  If no TSC support is
available, then no calibration is done, and calls to grub_get_time_ms()
should be directed to the generic get_time_ms() implementation that
uses grub_get_rtc() to do its job.

I want to make sure that I clearly understand what you want, since I
have made major re-designs of the TSC support in GRUB in an attempt to
do what you want.  Just in the past couple of days I have spent about 8
hours getting the TSC patch where it is now. (I know that seems
like a lot since it's not that much code, but I am just beginning to get
familiar with the GRUB kernel organization, so simple changes have been
taking me a long time.)

> grub_time_init() is just more clearer term than tsc. At least for
> people that are not familiar with it. in grub_time_init() you can
> have anything then. And people that are not interested on time stuff
> do not need to bother their heads about it. Also modifying logic
> afterwards do not change other parts and it will be less error prone.

OK.

Regards,
Colin


signature.asc
Description: PGP signature
___
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel


Re: [RFC] TSC patch v2

2008-07-04 Thread Vesa Jääskeläinen

Hi Colin,

Colin D Bennett wrote:

Here is an updated version of the TSC patch.

I addressed the issues in your comments with the exception of
supporting x86 CPUs that don't have a TSC (386 and 486).

I eliminated the grub_time_init() function and the call to it in
grub_main() in favor of having grub_machine_init() simply call
grub_tsc_calibrate().  The i386-pc and i386-efi platforms use the TSC.


Please still use grub_time_init(). Detect TSC, if it is there calibrate 
and adapt for it. If it is not there, use RTC.


grub_time_init() is just more clearer term than tsc. At least for people 
that are not familiar with it. in grub_time_init() you can have anything 
then. And people that are not interested on time stuff do not need to 
bother their heads about it. Also modifying logic afterwards do not 
change other parts and it will be less error prone.


Thanks,
Vesa Jääskeläinen


___
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel


Re: [RFC] TSC patch v2

2008-07-04 Thread Colin D Bennett
Here is an updated version of the TSC patch.

I addressed the issues in your comments with the exception of
supporting x86 CPUs that don't have a TSC (386 and 486).

I eliminated the grub_time_init() function and the call to it in
grub_main() in favor of having grub_machine_init() simply call
grub_tsc_calibrate().  The i386-pc and i386-efi platforms use the TSC.

I also changed the grub_millisleep() generic function to use
grub_get_time_ms() instead of grub_get_rtc() to achieve better
precision when a higher resolution time function is available.

Please take a look at it and give me your comments when you have a
chance.  Thanks!

Regards,
Colin
=== modified file 'ChangeLog'
--- ChangeLog	2008-07-04 02:26:10 +
+++ ChangeLog	2008-07-04 18:08:36 +
@@ -1,3 +1,70 @@
+2008-07-04  Colin D Bennett <[EMAIL PROTECTED]>
+
+	High resolution timer support.  Implemented for i386 CPU using TSC.
+	Extracted generic grub_millisleep() so it's linked in only as needed.
+	This requires a Pentium compatible CPU; currently the code does not
+	check for this (so it will fail on 386 and 486 machines).
+
+	* conf/i386-efi.rmk: Added TSC high resolution time module, link with
+	generic grub_millisleep() function.
+
+	* conf/i386-pc.rmk: Likewise.
+
+	* conf/sparc64-ieee1275.rmk: Add kern/generic/millisleep.c and
+	kern/generic/get_time_ms.c to kernel, to use generic time functions.
+
+	* conf/powerpc-ieee1275.rmk: Add kern/generic/millisleep.c to kernel,
+	to use generic grub_millisleep() function.
+
+	* conf/i386-linuxbios.rmk: Added kern/generic/get_time_ms.c to the
+	kernel.
+
+	* kern/generic/get_time_ms.c (grub_get_time_ms): New file.  Platform
+	independent implementation of grub_get_time_ms() using the RTC that
+	can be linked into a platform's kernel when it does not implement its
+	own specialized grub_get_time_ms() function.
+
+	* kern/generic/millisleep.c (grub_millisleep): New file.  Extracted
+	from grub_millisleep_generic() in kern/misc.c and renamed.  Changed it
+	to use grub_get_time_ms() instead of grub_get_rtc() for better
+	precision on when high resolution time is available.
+
+	* kern/misc.c (grub_millisleep_generic): Deleted.  Moved to
+	kern/generic/millisleep.c so that it is only included in the kernel
+	image when a platform does not define a specialized version.
+
+	* commands/sleep.c (grub_interruptible_millisleep): Uses
+	grub_get_time_ms() instead of grub_get_rtc() to stay in sync with
+	grub_millisleep() from kern/generic/millisleep.c.
+
+	* include/grub/i386/tsc.h (grub_get_tsc): New file.  Inline function
+	grub_get_tsc() uses x86 RDTSC instruction (available on Pentium+ CPUs)
+	to read the counter value for the TSC.
+	(grub_tsc_calibrate): Declare this function for grub_machine_init().
+
+	* kern/i386/tsc.c (grub_get_time_ms): x86 TSC support providing a high
+	resolution clock.
+	(grub_tsc_calibrate): New function to calibrate the TSC using RTC.
+
+	* include/grub/time.h (grub_get_time_ms): Added grub_get_time_ms()
+	function to return the current time in millseconds since the epoch.
+	This supports higher resolution time than grub_get_rtc() on some
+	platforms such as i386-pc, where the RTC has only about 1/18 s
+	precision but a higher precision timer such as the TSC is available.
+
+	* kern/i386/efi/init.c (grub_millisleep): Deleted.  Don't define
+	grub_millisleep() -- it just called grub_millisleep_generic() but now
+	it is linked to kern/generic/millisleep.c for the implementation.
+
+	* kern/sparc64/ieee1275/init.c (grub_millisleep): Deleted.
+
+	* kern/i386/pc/init.c (grub_machine_init): Call grub_tsc_calibrate().
+	(grub_millisleep): Deleted.
+
+	* kern/ieee1275/init.c (grub_millisleep): Deleted.
+	(grub_get_rtc): Now calls grub_get_time_ms(), which does the real
+	work.
+
 2008-07-04  Pavel Roskin  <[EMAIL PROTECTED]>
 
 	* kern/i386/linuxbios/init.c (grub_machine_init): Cast addr to

=== modified file 'commands/sleep.c'
--- commands/sleep.c	2008-05-16 20:55:29 +
+++ commands/sleep.c	2008-07-04 16:55:48 +
@@ -43,15 +43,15 @@
   grub_printf ("%d", n);
 }
 
-/* Based on grub_millisleep() from kern/misc.c.  */
+/* Based on grub_millisleep() from kern/generic/millisleep.c.  */
 static int
 grub_interruptible_millisleep (grub_uint32_t ms)
 {
-  grub_uint32_t end_at;
-  
-  end_at = grub_get_rtc () + grub_div_roundup (ms * GRUB_TICKS_PER_SECOND, 1000);
-  
-  while (grub_get_rtc () < end_at)
+  grub_uint64_t start;
+
+  start = grub_get_time_ms ();
+
+  while (grub_get_time_ms () - start < ms)
 if (grub_checkkey () >= 0 &&
 	GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC)
   return 1;

=== modified file 'conf/i386-efi.rmk'
--- conf/i386-efi.rmk	2008-06-19 04:14:16 +
+++ conf/i386-efi.rmk	2008-07-03 04:19:16 +
@@ -84,7 +84,9 @@
 	kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
 	kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
 	kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
-	term/efi/console.c