From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1KPnPc-0001eM-3Z for mharc-grub-devel@gnu.org; Sun, 03 Aug 2008 19:54:56 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KPnPa-0001e9-Vr for grub-devel@gnu.org; Sun, 03 Aug 2008 19:54:55 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KPnPZ-0001dx-EC for grub-devel@gnu.org; Sun, 03 Aug 2008 19:54:53 -0400 Received: from [199.232.76.173] (port=53442 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KPnPZ-0001du-6R for grub-devel@gnu.org; Sun, 03 Aug 2008 19:54:53 -0400 Received: from aybabtu.com ([69.60.117.155]:38152) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KPnPZ-0005tv-E8 for grub-devel@gnu.org; Sun, 03 Aug 2008 19:54:53 -0400 Received: from [192.168.10.10] (helo=thorin) by aybabtu.com with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1KPnIQ-0003CJ-65 for grub-devel@gnu.org; Mon, 04 Aug 2008 01:47:31 +0200 Received: from rmh by thorin with local (Exim 4.63) (envelope-from ) id 1KPnOW-00068L-EY for grub-devel@gnu.org; Mon, 04 Aug 2008 01:53:48 +0200 Date: Mon, 4 Aug 2008 01:53:48 +0200 From: Robert Millan To: The development of GRUB 2 Message-ID: <20080803235348.GA23220@thorin> References: <20080623075438.5861e6d1@gibibit.com> <878wwi6bqy.fsf@xs4all.nl> <20080704112801.470827ea@gibibit.com> <87tzekiecu.fsf@xs4all.nl> <20080728100533.19118c0b@gibibit.com> <20080803194816.GA13744@thorin> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="GvXjxJ+pjyke8COw" Content-Disposition: inline In-Reply-To: <20080803194816.GA13744@thorin> Organization: free as in freedom X-Message-Flag: Worried about Outlook viruses? Switch to Thunderbird! www.mozilla.com/thunderbird X-Debbugs-No-Ack: true User-Agent: Mutt/1.5.13 (2006-08-11) X-detected-kernel: by monty-python.gnu.org: Genre and OS details not recognized. Subject: TSC on coreboot (Re: [PATCH] High resolution time/TSC patch v3) X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Aug 2008 23:54:55 -0000 --GvXjxJ+pjyke8COw Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sun, Aug 03, 2008 at 09:48:16PM +0200, Robert Millan wrote: > On Mon, Jul 28, 2008 at 10:05:33AM -0700, Colin D Bennett wrote: > > +/* Calibrate the TSC based on the RTC. */ > > +static void > > +calibrate_tsc (void) > > +{ > > + /* First calbrate the TSC rate (relative, not absolute time). */ > > + 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 (); > > Ah, I see the problem. It calls grub_get_rtc() which in grub-coreboot is just > a stub. > > How about using the interval timer for calibration instead? Here. With this patch your code works on coreboot too. Note: AFAICT we can't calculate the epoch without RTC. But then again, this epoch is just as defined by the time BIOS enables RTC interrupts, so why not define it ourselves? I propose that we define epoch as the time in which our TSC code is initialized. If knowing the time in which BIOS was started is really useful, maybe we could #ifdef it instead. Though if it's not I'd prefer the simplicity. -- Robert Millan The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and how) you may access your data; but nobody's threatening your freedom: we still allow you to remove your data and not access it at all." --GvXjxJ+pjyke8COw Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="tsc_coreboot.diff" diff -Nurp -x .svn -x '*.mk' -x '*~' ../grub2.tsc/conf/i386-coreboot.rmk ./conf/i386-coreboot.rmk --- ../grub2.tsc/conf/i386-coreboot.rmk 2008-08-04 00:19:11.000000000 +0200 +++ ./conf/i386-coreboot.rmk 2008-08-04 01:40:37.000000000 +0200 @@ -18,6 +18,9 @@ kernel_elf_SOURCES = kern/i386/linuxbios kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ kern/time.c \ kern/i386/dl.c kern/parser.c kern/partition.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c \ kern/env.c \ term/i386/pc/console.c \ term/i386/pc/at_keyboard.c term/i386/pc/vga_text.c \ diff -Nurp -x .svn -x '*.mk' -x '*~' ../grub2.tsc/conf/i386-pc.rmk ./conf/i386-pc.rmk --- ../grub2.tsc/conf/i386-pc.rmk 2008-08-04 00:19:11.000000000 +0200 +++ ./conf/i386-pc.rmk 2008-08-04 01:21:32.000000000 +0200 @@ -44,7 +44,7 @@ kernel_img_SOURCES = kern/i386/pc/startu kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ kern/time.c \ kern/i386/dl.c kern/i386/pc/init.c kern/parser.c kern/partition.c \ - kern/i386/tsc.c \ + kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ kern/generic/millisleep.c \ kern/env.c \ diff -Nurp -x .svn -x '*.mk' -x '*~' ../grub2.tsc/include/grub/i386/pit.h ./include/grub/i386/pit.h --- ../grub2.tsc/include/grub/i386/pit.h 1970-01-01 01:00:00.000000000 +0100 +++ ./include/grub/i386/pit.h 2008-08-04 01:22:12.000000000 +0200 @@ -0,0 +1,19 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +extern void grub_pit_wait (grub_uint16_t tics); diff -Nurp -x .svn -x '*.mk' -x '*~' ../grub2.tsc/kern/i386/linuxbios/init.c ./kern/i386/linuxbios/init.c --- ../grub2.tsc/kern/i386/linuxbios/init.c 2008-08-04 00:19:11.000000000 +0200 +++ ./kern/i386/linuxbios/init.c 2008-08-04 00:31:45.000000000 +0200 @@ -61,11 +61,6 @@ grub_stop_floppy (void) } void -grub_millisleep (grub_uint32_t ms __attribute__ ((unused))) -{ -} - -void grub_exit (void) { grub_printf ("grub_exit() is not implemented.\n"); @@ -144,7 +139,7 @@ grub_machine_init (void) /* This variable indicates size, not offset. */ grub_upper_mem -= GRUB_MEMORY_MACHINE_UPPER_START; - grub_install_get_time_ms (grub_rtc_get_time_ms); + grub_tsc_init (); } void diff -Nurp -x .svn -x '*.mk' -x '*~' ../grub2.tsc/kern/i386/pit.c ./kern/i386/pit.c --- ../grub2.tsc/kern/i386/pit.c 1970-01-01 01:00:00.000000000 +0100 +++ ./kern/i386/pit.c 2008-08-04 01:27:07.000000000 +0200 @@ -0,0 +1,39 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include + +#define TIMER2_REG_CONTROL 0x42 +#define TIMER_REG_COMMAND 0x43 +#define TIMER2_REG_LATCH 0x61 + +#define TIMER2_SELECT 0x80 +#define TIMER_ENABLE_LSB 0x20 +#define TIMER_ENABLE_MSB 0x10 +#define TIMER2_LATCH 0x20 + +void +grub_pit_wait (grub_uint16_t tics) +{ + grub_outb (TIMER2_SELECT | TIMER_ENABLE_LSB | TIMER_ENABLE_MSB, TIMER_REG_COMMAND); + grub_outb (tics & 0xff, TIMER2_REG_CONTROL); + grub_outb (tics >> 8, TIMER2_REG_CONTROL); + + while ((grub_inb (TIMER2_REG_LATCH) & TIMER2_LATCH) == 0x00); +} diff -Nurp -x .svn -x '*.mk' -x '*~' ../grub2.tsc/kern/i386/tsc.c ./kern/i386/tsc.c --- ../grub2.tsc/kern/i386/tsc.c 2008-08-04 00:19:11.000000000 +0200 +++ ./kern/i386/tsc.c 2008-08-04 01:36:51.000000000 +0200 @@ -25,8 +25,7 @@ #include #include -/* Calibrated reference for TSC=0. This defines the time since the epoch in - milliseconds that TSC=0 refers to. */ +/* This defines the value TSC had at the epoch (that is, when we calibrated it). */ static grub_uint64_t tsc_boot_time; /* Calibrated TSC rate. (In TSC ticks per millisecond.) */ @@ -47,44 +46,15 @@ grub_tsc_get_time_ms (void) static void calibrate_tsc (void) { - /* First calbrate the TSC rate (relative, not absolute time). */ + /* First calibrate the TSC rate (relative, not absolute time). */ 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 = grub_get_tsc (); - /* 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); + start_tsc = grub_get_tsc (); + grub_pit_wait (0xffff); end_tsc = grub_get_tsc (); - tsc_ticks_per_ms = - grub_divmod64 (grub_divmod64 - (end_tsc - start_tsc, end_tick - start_tick, 0) - * GRUB_TICKS_PER_SECOND, 1000, 0); - - /* Reference the TSC zero (boot time) to the epoch to - get an absolute real time reference. */ - grub_uint64_t ms_since_boot = grub_divmod64 (end_tsc, tsc_ticks_per_ms, 0); - grub_uint64_t mstime_now = grub_divmod64 ((grub_uint64_t) 1000 * end_tick, - GRUB_TICKS_PER_SECOND, - 0); - tsc_boot_time = mstime_now - ms_since_boot; + tsc_ticks_per_ms = grub_divmod64 (end_tsc - start_tsc, 55, 0); } void @@ -92,6 +62,7 @@ grub_tsc_init (void) { if (grub_cpu_is_tsc_supported ()) { + tsc_boot_time = grub_get_tsc (); calibrate_tsc (); grub_install_get_time_ms (grub_tsc_get_time_ms); } --GvXjxJ+pjyke8COw--