Colin D Bennett <[EMAIL PROTECTED]> writes: > Another updated TSC patch. Now it detects TSC support for x86 CPUs at > runtime and selects either the TSC or RTC time source. This way 386 > and 486 CPUs without RDTSC instruction support are supported. > > Robert Millan was interested in getting this patch merged for the > Coreboot port, so I decided to take another crack at it. > > Comments are welcome!
Great! Did you have a look at Roberts comment that it does not work in Qemu? This is the most important testing ground for many of us... > === modified file 'ChangeLog' > --- ChangeLog 2008-07-27 19:57:43 +0000 > +++ ChangeLog 2008-07-28 16:51:30 +0000 > @@ -1,3 +1,68 @@ > +2008-07-28 Colin D Bennett <[EMAIL PROTECTED]> > + > + High resolution timer support. Implemented for x86 CPUs using TSC. > + Extracted generic grub_millisleep() so it's linked in only as needed. > + This requires a Pentium compatible CPU; if the RDTSC instruction is > + not supported, then it falls back on the generic grub_get_time_ms() > + implementation that uses the machine's RTC. > + > + * conf/i386-efi.rmk: Added new source files to kernel_elf_SOURCES. Do you mean: * conf/i386-efi.rmk (kernel_elf_SOURCES): Add <...>. Please replace <...> by your source files :-) > + * conf/i386-pc.rmk: Likewise. > + > + * conf/sparc64-ieee1275.rmk: Likewise. > + > + * conf/powerpc-ieee1275.rmk: Likewise. > + > + * conf/i386-coreboot.rmk: Likewise. > + > + * kern/generic/rtc_get_time_ms.c: New file. > + > + * kern/generic/millisleep.c: New file. > + > + * kern/misc.c (grub_millisleep_generic): Removed. > + > + * 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. New inline > + function. Huh? * include/grub/i386/tsc.h: New file. Would be correct, right? > + (grub_cpu_is_cpuid_supported): New inline function. > + (grub_cpu_is_tsc_supported): New inline function. > + (grub_tsc_init): New function prototype. > + (grub_tsc_get_time_ms): New function prototype. No need to describe the contents of a new file, simply stating the file is new is sufficient. > + * kern/i386/tsc.c (grub_get_time_ms): New file. New function. > + (calibrate_tsc): New static function. > + (grub_tsc_init): New function. Same here. > + * include/grub/time.h (grub_millisleep_generic): Removed. > + (grub_get_time_ms): New function. > + (grub_install_get_time_ms): New function. > + > + * kern/time.c (grub_get_time_ms): New function. > + (grub_install_get_time_ms): New function. > + > + * kern/i386/efi/init.c (grub_millisleep): Removed. > + (grub_machine_init): Call grub_tsc_init. > + > + * kern/i386/linuxbios/init.c (grub_machine_init): Install the RTC > + get_time_ms() implementation. > + > + * kern/sparc64/ieee1275/init.c (grub_millisleep): Removed. > + (ieee1275_get_time_ms): New function. > + (grub_machine_init): Install get_time_ms() implementation. > + > + * kern/i386/pc/init.c (grub_machine_init): Call grub_tsc_init(). > + (grub_millisleep): Removed. > + > + * kern/ieee1275/init.c (grub_millisleep): Removed. > + (grub_machine_init): Install ieee1275_get_time_ms() implementation. > + (ieee1275_get_time_ms): New static function. > + (grub_get_rtc): Now calls ieee1275_get_time_ms(), which does the real > + work. > + > 2008-07-27 Robert Millan <[EMAIL PROTECTED]> > > * disk/ata.c (grub_ata_dumpinfo): Use grub_dprintf() for debugging > > === modified file 'commands/sleep.c' > --- commands/sleep.c 2008-05-16 20:55:29 +0000 > +++ commands/sleep.c 2008-07-04 16:55:48 +0000 > @@ -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-coreboot.rmk' > --- conf/i386-coreboot.rmk 2008-07-27 12:51:30 +0000 > +++ conf/i386-coreboot.rmk 2008-07-28 16:23:46 +0000 > @@ -16,6 +16,7 @@ > kern/main.c kern/device.c \ > kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ > 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/env.c \ > term/i386/pc/console.c \ > > === modified file 'conf/i386-efi.rmk' > --- conf/i386-efi.rmk 2008-07-27 12:51:30 +0000 > +++ conf/i386-efi.rmk 2008-07-28 16:23:46 +0000 > @@ -84,7 +84,10 @@ > 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 disk/efi/efidisk.c > + term/efi/console.c disk/efi/efidisk.c \ > + kern/i386/tsc.c \ > + kern/generic/rtc_get_time_ms.c \ > + kern/generic/millisleep.c > kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h > elfload.h \ > env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ > partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \ > > === modified file 'conf/i386-ieee1275.rmk' > --- conf/i386-ieee1275.rmk 2008-07-27 12:51:30 +0000 > +++ conf/i386-ieee1275.rmk 2008-07-28 16:23:46 +0000 > @@ -19,6 +19,7 @@ > kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ > kern/i386/dl.c kern/parser.c kern/partition.c \ > kern/env.c \ > + kern/generic/millisleep.c \ > kern/ieee1275/ieee1275.c \ > term/ieee1275/ofconsole.c term/i386/pc/at_keyboard.c \ > disk/ieee1275/ofdisk.c \ > > === modified file 'conf/i386-pc.rmk' > --- conf/i386-pc.rmk 2008-07-27 12:51:30 +0000 > +++ conf/i386-pc.rmk 2008-07-28 16:23:46 +0000 > @@ -42,7 +42,11 @@ > kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \ > kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ > 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/generic/rtc_get_time_ms.c \ > + kern/generic/millisleep.c \ > kern/env.c \ > term/i386/pc/console.c \ > symlist.c > > === modified file 'conf/powerpc-ieee1275.rmk' > --- conf/powerpc-ieee1275.rmk 2008-07-27 12:51:30 +0000 > +++ conf/powerpc-ieee1275.rmk 2008-07-28 13:59:50 +0000 > @@ -85,6 +85,7 @@ > kern/ieee1275/init.c term/ieee1275/ofconsole.c \ > kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ > kern/parser.c kern/partition.c kern/env.c kern/powerpc/dl.c \ > + kern/generic/millisleep.c \ > symlist.c kern/powerpc/cache.S > kernel_elf_HEADERS = grub/powerpc/ieee1275/ieee1275.h > kernel_elf_CFLAGS = $(COMMON_CFLAGS) > > === modified file 'conf/sparc64-ieee1275.rmk' > --- conf/sparc64-ieee1275.rmk 2008-06-19 00:04:59 +0000 > +++ conf/sparc64-ieee1275.rmk 2008-07-03 04:19:16 +0000 > @@ -73,6 +73,7 @@ > kern/rescue.c kern/term.c term/ieee1275/ofconsole.c \ > kern/sparc64/ieee1275/openfw.c disk/ieee1275/ofdisk.c \ > kern/partition.c kern/env.c kern/sparc64/dl.c symlist.c \ > + kern/generic/millisleep.c kern/generic/get_time_ms.c \ > kern/sparc64/cache.S kern/parser.c > kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h > kernel_elf_CFLAGS = $(COMMON_CFLAGS) > > === modified file 'conf/x86_64-efi.rmk' > --- conf/x86_64-efi.rmk 2008-07-27 12:51:30 +0000 > +++ conf/x86_64-efi.rmk 2008-07-28 16:23:46 +0000 > @@ -87,6 +87,7 @@ > kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \ > kern/x86_64/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 \ > + kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \ > term/efi/console.c disk/efi/efidisk.c > kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h > elfload.h \ > env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ > > === added file 'include/grub/i386/tsc.h' > --- include/grub/i386/tsc.h 1970-01-01 00:00:00 +0000 > +++ include/grub/i386/tsc.h 2008-07-28 16:23:46 +0000 > @@ -0,0 +1,80 @@ > +/* > + * 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 <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef KERNEL_CPU_TSC_HEADER > +#define KERNEL_CPU_TSC_HEADER 1 > + > +#include <grub/types.h> > + > +/* Read the TSC value, which increments with each CPU clock cycle. */ > +static __inline grub_uint64_t > +grub_get_tsc (void) > +{ > + grub_uint32_t lo, hi; > + > + /* The CPUID instruction is a 'serializing' instruction, and > + avoids out-of-order execution of the RDTSC instruction. */ > + __asm__ __volatile__ ("xorl %%eax, %%eax\n\t" > + "cpuid":::"%rax", "%rbx", "%rcx", "%rdx"); > + /* Read TSC value. We cannot use "=A", since this would use > + %rax on x86_64. */ > + __asm__ __volatile__ ("rdtsc":"=a" (lo), "=d" (hi)); > + > + return (((grub_uint64_t) hi) << 32) | lo; > +} > + > +static __inline int > +grub_cpu_is_cpuid_supported (void) > +{ > + grub_uint32_t id_supported; > + > + __asm__ ("pushfl\n\t" > + "popl %%eax /* Get EFLAGS into EAX */\n\t" > + "movl %%eax, %%ecx /* Save original flags in ECX */\n\t" > + "xorl $0x200000, %%eax /* Flip ID bit in EFLAGS */\n\t" > + "pushl %%eax /* Store modified EFLAGS on stack */\n\t" > + "popfl /* Replace current EFLAGS */\n\t" > + "pushfl /* Read back the EFLAGS */\n\t" > + "popl %%eax /* Get EFLAGS into EAX */\n\t" > + "xorl %%ecx, %%eax /* Check if flag could be modified */\n\t" > + : "=a" (id_supported) > + : /* No inputs. */ > + : /* Clobbered: */ "%rcx"); > + > + return id_supported != 0; > +} > + > +static __inline int > +grub_cpu_is_tsc_supported (void) > +{ > + if (! grub_cpu_is_cpuid_supported ()) > + return 0; > + > + grub_uint32_t features; > + __asm__ ("movl $1, %%eax\n\t" > + "cpuid" > + : "=d" (features) > + : /* No inputs. */ > + : /* Clobbered: */ "%rax", "%rbx", "%rcx"); > + return (features & (1 << 4)) != 0; > +} > + > +void grub_tsc_init (void); > +grub_uint64_t grub_tsc_get_time_ms (void); > + > +#endif /* ! KERNEL_CPU_TSC_HEADER */ > > === modified file 'include/grub/time.h' > --- include/grub/time.h 2007-10-22 19:02:16 +0000 > +++ include/grub/time.h 2008-07-28 16:51:30 +0000 > @@ -1,6 +1,6 @@ > /* > * GRUB -- GRand Unified Bootloader > - * Copyright (C) 2007 Free Software Foundation, Inc. > + * Copyright (C) 2007, 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 > @@ -19,12 +19,15 @@ > #ifndef KERNEL_TIME_HEADER > #define KERNEL_TIME_HEADER 1 > > +#include <grub/types.h> This include is not mentioned in the changelog entry. > #include <grub/symbol.h> > #include <grub/machine/time.h> > #include <grub/cpu/time.h> > > void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms); > -void EXPORT_FUNC(grub_millisleep_generic) (grub_uint32_t ms); > +grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void); > + > +grub_uint64_t grub_rtc_get_time_ms (void); > > static __inline void > grub_sleep (grub_uint32_t s) > @@ -32,4 +35,6 @@ > grub_millisleep (1000 * s); > } > > +void grub_install_get_time_ms (grub_uint64_t (*get_time_ms_func) (void)); > + > #endif /* ! KERNEL_TIME_HEADER */ > > === added directory 'kern/generic' > === added file 'kern/generic/millisleep.c' > --- kern/generic/millisleep.c 1970-01-01 00:00:00 +0000 > +++ kern/generic/millisleep.c 2008-07-28 16:51:30 +0000 > @@ -0,0 +1,39 @@ > +/* millisleep.c - generic millisleep function. > + * The generic implementation of these functions can be used for > architectures > + * or platforms that do not have a more specialized implementation. */ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,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 <http://www.gnu.org/licenses/>. > + */ > + > +#include <grub/misc.h> > +#include <grub/time.h> > + > +void > +grub_millisleep (grub_uint32_t ms) > +{ > + grub_uint64_t start; > + > + start = grub_get_time_ms (); > + > + /* Instead of setting an end time and looping while the current time is > + less than that, comparing the elapsed sleep time with the desired sleep > + time handles the (unlikely!) case that the timer would wrap around > + during the sleep. */ > + > + while (grub_get_time_ms () - start < ms) > + grub_cpu_idle (); > +} > > === added file 'kern/generic/rtc_get_time_ms.c' > --- kern/generic/rtc_get_time_ms.c 1970-01-01 00:00:00 +0000 > +++ kern/generic/rtc_get_time_ms.c 2008-07-28 16:51:30 +0000 > @@ -0,0 +1,37 @@ > +/* rtc_get_time_ms.c - get_time_ms implementation using platform RTC. > + * The generic implementation of these functions can be used for > architectures > + * or platforms that do not have a more specialized implementation. */ > +/* > + * 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 <http://www.gnu.org/licenses/>. > + */ > + > +#include <grub/time.h> > +#include <grub/misc.h> > + > +/* Calculate the time in milliseconds since the epoch based on the RTC. */ > +grub_uint64_t > +grub_rtc_get_time_ms (void) > +{ > + /* By dimensional analysis: > + > + 1000 ms N rtc ticks 1 s > + ------- * ----------- * ----------- = 1000*N/T ms > + 1 s 1 T rtc ticks > + */ > + grub_uint64_t ticks_ms_per_sec = ((grub_uint64_t) 1000) * grub_get_rtc (); > + return grub_divmod64 (ticks_ms_per_sec, GRUB_TICKS_PER_SECOND, 0); > +} > > === modified file 'kern/i386/efi/init.c' > --- kern/i386/efi/init.c 2007-10-22 18:59:33 +0000 > +++ kern/i386/efi/init.c 2008-07-28 16:23:46 +0000 > @@ -25,18 +25,13 @@ > #include <grub/cache.h> > #include <grub/kernel.h> > #include <grub/efi/efi.h> > -#include <grub/time.h> > - > -void > -grub_millisleep (grub_uint32_t ms) > -{ > - grub_millisleep_generic (ms); > -} > +#include <grub/cpu/tsc.h> > > void > grub_machine_init (void) > { > grub_efi_init (); > + grub_tsc_init (); > } > > void > > === modified file 'kern/i386/linuxbios/init.c' > --- kern/i386/linuxbios/init.c 2008-07-04 02:26:10 +0000 > +++ kern/i386/linuxbios/init.c 2008-07-28 16:23:46 +0000 > @@ -149,6 +149,8 @@ > > /* This variable indicates size, not offset. */ > grub_upper_mem -= GRUB_MEMORY_MACHINE_UPPER_START; > + > + grub_install_get_time_ms (grub_rtc_get_time_ms); > } > > void > > === modified file 'kern/i386/pc/init.c' > --- kern/i386/pc/init.c 2008-06-15 17:21:16 +0000 > +++ kern/i386/pc/init.c 2008-07-28 16:23:46 +0000 > @@ -30,6 +30,7 @@ > #include <grub/env.h> > #include <grub/cache.h> > #include <grub/time.h> > +#include <grub/cpu/tsc.h> > > struct mem_region > { > @@ -46,12 +47,6 @@ > grub_size_t grub_os_area_size; > grub_size_t grub_lower_mem, grub_upper_mem; > > -void > -grub_millisleep (grub_uint32_t ms) > -{ > - grub_millisleep_generic (ms); > -} > - > void > grub_arch_sync_caches (void *address __attribute__ ((unused)), > grub_size_t len __attribute__ ((unused))) > @@ -231,6 +226,8 @@ > > if (! grub_os_area_addr) > grub_fatal ("no upper memory"); > + > + grub_tsc_init (); > } > > void > > === added file 'kern/i386/tsc.c' > --- kern/i386/tsc.c 1970-01-01 00:00:00 +0000 > +++ kern/i386/tsc.c 2008-07-28 16:51:30 +0000 > @@ -0,0 +1,102 @@ > +/* kern/i386/tsc.c - x86 TSC time source implementation > + * Requires Pentium or better x86 CPU that supports the RDTSC instruction. > + * This module uses the RTC (via grub_get_rtc()) to calibrate the TSC to > + * real time. > + * > + * 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 <http://www.gnu.org/licenses/>. > + */ > + > +#include <grub/types.h> > +#include <grub/time.h> > +#include <grub/misc.h> > +#include <grub/i386/tsc.h> > + > +/* Calibrated reference for TSC=0. This defines the time since the epoch in > + milliseconds that TSC=0 refers to. */ > +static grub_uint64_t tsc_boot_time; > + > +/* Calibrated TSC rate. (In TSC ticks per millisecond.) */ > +static grub_uint64_t tsc_ticks_per_ms; > + > + > +grub_uint64_t > +grub_tsc_get_time_ms (void) > +{ > + return tsc_boot_time + grub_divmod64 (grub_get_tsc (), tsc_ticks_per_ms, > 0); > +} > + > + > +/* How many RTC ticks to use for calibration loop. (>= 1) */ > +#define CALIBRATION_TICKS 2 > + > +/* 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 (); > + 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); > + 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; > +} > + > +void > +grub_tsc_init (void) > +{ > + if (grub_cpu_is_tsc_supported ()) > + { > + calibrate_tsc (); > + grub_install_get_time_ms (grub_tsc_get_time_ms); > + } > + else > + { > + grub_install_get_time_ms (grub_rtc_get_time_ms); > + } > +} > > === modified file 'kern/ieee1275/init.c' > --- kern/ieee1275/init.c 2008-07-04 02:01:55 +0000 > +++ kern/ieee1275/init.c 2008-07-28 16:23:46 +0000 > @@ -47,12 +47,6 @@ > extern char _end[]; > > void > -grub_millisleep (grub_uint32_t ms) > -{ > - grub_millisleep_generic (ms); > -} > - > -void > grub_exit (void) > { > grub_ieee1275_exit (); > @@ -202,6 +196,8 @@ > > #endif > > +static grub_uint64_t ieee1275_get_time_ms (void); > + > void > grub_machine_init (void) > { > @@ -251,6 +247,8 @@ > } > } > } > + > + grub_install_get_time_ms (ieee1275_get_time_ms); > } > > void > @@ -260,8 +258,8 @@ > grub_console_fini (); > } > > -grub_uint32_t > -grub_get_rtc (void) > +static grub_uint64_t > +ieee1275_get_time_ms (void) > { > grub_uint32_t msecs = 0; > > @@ -270,6 +268,12 @@ > return msecs; > } > > +grub_uint32_t > +grub_get_rtc (void) > +{ > + return ieee1275_get_time_ms (); > +} > + > grub_addr_t > grub_arch_modules_addr (void) > { > > === modified file 'kern/misc.c' > --- kern/misc.c 2008-06-15 23:42:48 +0000 > +++ kern/misc.c 2008-07-04 18:03:26 +0000 > @@ -23,7 +23,6 @@ > #include <stdarg.h> > #include <grub/term.h> > #include <grub/env.h> > -#include <grub/time.h> > > void * > grub_memmove (void *dest, const void *src, grub_size_t n) > @@ -1018,17 +1017,6 @@ > return p - dest; > } > > -void > -grub_millisleep_generic (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_cpu_idle (); > -} > - > /* Abort GRUB. This function does not return. */ > void > grub_abort (void) > > === modified file 'kern/sparc64/ieee1275/init.c' > --- kern/sparc64/ieee1275/init.c 2007-10-22 18:59:33 +0000 > +++ kern/sparc64/ieee1275/init.c 2008-07-28 16:23:46 +0000 > @@ -66,12 +66,6 @@ > /* Never reached. */ > } > > -void > -grub_millisleep (grub_uint32_t ms) > -{ > - grub_millisleep_generic (ms); > -} > - > int > grub_ieee1275_test_flag (enum grub_ieee1275_flag flag) > { > @@ -145,6 +139,8 @@ > grub_free (prefix); > } > > +grub_uint64_t ieee1275_get_time_ms (void); > + > void > grub_machine_init (void) > { > @@ -201,6 +197,7 @@ > } > } > > + grub_install_get_time_ms (ieee1275_get_time_ms); > } > > void > @@ -216,6 +213,12 @@ > grub_ieee1275_enter (); > } > > +grub_uint64_t > +ieee1275_get_time_ms (void) > +{ > + return grub_get_rtc (); > +} > + > grub_uint32_t > grub_get_rtc (void) > { > > === added file 'kern/time.c' > --- kern/time.c 1970-01-01 00:00:00 +0000 > +++ kern/time.c 2008-07-28 16:23:46 +0000 > @@ -0,0 +1,37 @@ > +/* time.c - kernel time functions */ > +/* > + * 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 <http://www.gnu.org/licenses/>. > + */ > + > +#include <grub/time.h> > + > +typedef grub_uint64_t (*get_time_ms_func_t) (void); > + > +/* Function pointer to the implementation in use. */ > +static get_time_ms_func_t get_time_ms_func; > + > +grub_uint64_t > +grub_get_time_ms (void) > +{ > + return get_time_ms_func (); > +} > + > +void > +grub_install_get_time_ms (get_time_ms_func_t func) > +{ > + get_time_ms_func = func; > +} _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel