cvs commit: src/sys/i386/i386 identcpu.c

Bruce Evans bde at zeta.org.au
Fri Apr 11 04:01:52 PDT 2003


On Fri, 11 Apr 2003, Wes Peters wrote:

> On Thursday 10 April 2003 04:20, Bruce Evans wrote:
> > On Thu, 10 Apr 2003, Wes Peters wrote:
> > > wes         2003/04/10 00:05:24 PDT
> > >
> > >   FreeBSD src repository
> > >
> > >   Modified files:
> > >     sys/i386/i386        identcpu.c
> > >   Log:
> > >   Add a sysctl that records and reports the CPU clock rate calculated
> > >   at boot.  Funny how often this trivial piece of information crops
> > > up in embedded boxen.

> > What's wrong with the existing sysctl (machdep.tsc_freq)?  It is
> > machine dependent, but no more than the new sysctl (both only work for
> > certain i386's with TSC's).
>
> This control works across all "i386" processors you can buy today, and

So does machdep.tsc_freq.

> will also work across several other FreeBSD architectures as soon as I
> get my hands on the boxen required.  The sparc64 is on its way; ia64 and
> x86-64 will follow later.  Maybe much later.

If there were an MI sysctl for this, it should not be in the machdep
hierarchy.

> > It doesn't discard up to 6 digits of
> > precision. It reports the current frequency, which should be the actual
> > frequency, which should differ from the frequency determined at boot
> > time since it is difficult to determine the actual frequency at boot
> > time without making the boot too long.
>
> My need, now spanning 3 different companies and product lines, is more to
> determine a few broad classifications of hardware.  If the numbers differ
> by more than 10, that would suffice, but in practice the expected numbers
> are 400, 550, 1130 (or maybe 1260) and 2400.  Those are far enough apart
> to make even imprecise people like me believe I can tell the difference.

This also makes the difference between the value determined at boot time
and the actual value unimportant to you, since the value determined at
boot time needs to be within 500 ppm for ntp to work with the TSC
timecounter at all.

> I am well aware that the boot-time numbers on some hardware might differ
> wildly from the run-time numbers; my laptop boots at 75 MHz and switches
> up to 300 MHz as needed.  That's not an issue in any of the 3
> implementations that have asked for this.

Too much for the TSC to be used as a timecounter.  Does the laptop work
at all without acpi?  The timecounter defaults to the TSC for the !acpi
&& !SMP && !APM && TSC_exists case.

> > Apr  9 20:08:28 besplex kernel: Timecounter "TSC"  frequency 1532823868
> > Hz Apr  9 20:08:28 besplex kernel: CPU: AMD Athlon(TM) XP1600+
> > (1532.82-MHz 686-class CPU)
> >
> > The first line of this is only printed if the TSC is attached to a
> > timecounter, which is in most !SMP && !APM cases.  The second line
> > prints the value that is returned by the new sysctl, except it doesn't
> > return the fractional part and has rounding bugs.
>
> And yet still suffices for the each of the different teams who have asked
> for it.  A more complex, more accurate answer isn't better for their
> need, it's just more complex.

So use the existing sysctl and round it as you need it, and back out the
commit.

Rounding bugs:

% Index: identcpu.c
% ===================================================================
% RCS file: /home/ncvs/src/sys/i386/i386/identcpu.c,v
% retrieving revision 1.120
% retrieving revision 1.121
% diff -u -r1.120 -r1.121
% --- identcpu.c	4 Apr 2003 17:29:54 -0000	1.120
% +++ identcpu.c	10 Apr 2003 07:05:24 -0000	1.121
% ...
% @@ -568,6 +572,7 @@
%  #endif
%  #if defined(I586_CPU)
%  	case CPUCLASS_586:
% +		hw_clockrate = (tsc_freq + 5000) / 1000000;
%  		printf("%jd.%02d-MHz ",
%  		       (intmax_t)(tsc_freq + 4999) / 1000000,
%  		       (u_int)((tsc_freq + 4999) / 10000) % 100);

4999 is for rounding the second place after the decimal point to nearest,
with a fractional part of precisely 0.005 MHz rounded down.  5000 makes
little sense.  4999 would give the same non-fractional part as printed
in the boot messages, but that that would tend to give a value that is
wrong by a full MHz when the precise value is close to an integral
number of MHz but smaller and not that close (5000 or more Hz smaller).

% @@ -576,6 +581,7 @@
%  #endif
%  #if defined(I686_CPU)
%  	case CPUCLASS_686:
% +		hw_clockrate = (tsc_freq + 5000) / 1000000;
%  		printf("%jd.%02d-MHz ",
%  		       (intmax_t)(tsc_freq + 4999) / 1000000,
%  		       (u_int)((tsc_freq + 4999) / 10000) % 100);

Similarly.

Bruce


More information about the cvs-src mailing list