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); }