From Andre.Albsmeier@siemens.com  Thu Apr 15 08:33:49 2010
Return-Path: <Andre.Albsmeier@siemens.com>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id BF5AA1065676
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 15 Apr 2010 08:33:49 +0000 (UTC)
	(envelope-from Andre.Albsmeier@siemens.com)
Received: from david.siemens.de (david.siemens.de [192.35.17.14])
	by mx1.freebsd.org (Postfix) with ESMTP id 57F088FC16
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 15 Apr 2010 08:33:48 +0000 (UTC)
Received: from mail2.siemens.de (localhost [127.0.0.1])
	by david.siemens.de (8.12.11.20060308/8.12.11) with ESMTP id o3F8XmNq012173
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 15 Apr 2010 10:33:48 +0200
Received: from curry.mchp.siemens.de (curry.mchp.siemens.de [139.25.40.130])
	by mail2.siemens.de (8.12.11.20060308/8.12.11) with ESMTP id o3F8XmvF014952
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 15 Apr 2010 10:33:48 +0200
Received: (from localhost)
	by curry.mchp.siemens.de (8.14.4/8.14.4) id o3F8XlUH017158
	for FreeBSD-gnats-submit@freebsd.org; Thu, 15 Apr 2010 10:33:48 +0200 (CEST)
Message-Id: <201004150833.o3F8XliI017683@curry.mchp.siemens.de>
Date: Thu, 15 Apr 2010 10:33:47 +0200 (CEST)
From: Andre Albsmeier <Andre.Albsmeier@siemens.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [PATCH] fix freq calculation from MSR for CPUs with fractional multipliers
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         145718
>Category:       i386
>Synopsis:       [est] [patch] fix freq calculation from MSR for CPUs with fractional multipliers
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-i386
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 15 08:40:00 UTC 2010
>Closed-Date:    
>Last-Modified:  Fri Apr 26 16:50:01 UTC 2013
>Originator:     Andre Albsmeier
>Release:        FreeBSD 7.3-STABLE i386
>Organization:
>Environment:

System: FreeBSD 7.3-STABLE #6: Thu Apr 15 09:42:06 CEST 2010

using a Q9550 cpu

>Description:

When calculating the simple rate table in est_msr_info()
we have to observe bit 6 (0x40) of the multiplier which
denotes an additional 0.5 for the value. Examples:

FID	Multiplier
--------------------
0x06	6
0x07	7
0x08	8
0x46	6.5
0x47	7.5
0x48	8.5

>How-To-Repeat:

Enable cpufreq on a cpu with a fractional multiplier (in
my case a Q9550 which uses 8.5), set hw.est.msr_info=1,
and watch dmesg spitting out insane low/high values for
the bus clock.

>Fix:

--- est.c.ORI	2009-07-14 08:57:29.000000000 +0200
+++ est.c	2010-04-15 10:29:11.000000000 +0200
@@ -1207,11 +1207,15 @@
 	freq = tsc_freq / 1000000;
 	id = msr >> 32;
 	bus = freq / (id >> 8);
+	if( id & 0x4000 )
+	  bus = 2 * freq / ( (id >> 7 & 0x7e) + 1 );
 	device_printf(dev, "Guessed bus clock (high) of %d MHz\n", bus);
 	if (!bus_speed_ok(bus)) {
 		/* We may be running on the low frequency. */
 		id = msr >> 48;
 		bus = freq / (id >> 8);
+		if( id & 0x4000 )
+		  bus = 2 * freq / ( (id >> 7 & 0x7e) + 1 );
 		device_printf(dev, "Guessed bus clock (low) of %d MHz\n", bus);
 		if (!bus_speed_ok(bus))
 			return (EOPNOTSUPP);
@@ -1219,6 +1223,8 @@
 		/* Calculate high frequency. */
 		id = msr >> 32;
 		freq = ((id >> 8) & 0xff) * bus;
+		if( id & 0x4000 )
+		  freq =( (id >> 7 & 0x7e) + 1 ) * bus / 2;
 	}
 
 	/* Fill out a new freq table containing just the high and low freqs. */
@@ -1241,6 +1247,8 @@
 	/* Second, the low frequency. */
 	id = msr >> 48;
 	freq = ((id >> 8) & 0xff) * bus;
+	if( id & 0x4000 )
+	  freq =( (id >> 7 & 0x7e) + 1 ) * bus / 2;
 	volts = id & 0xff;
 	if (volts != 0) {
 		volts <<= 4;
>Release-Note:
>Audit-Trail:

From: Andre Albsmeier <Andre.Albsmeier@siemens.com>
To: bug-followup@FreeBSD.org, Andre.Albsmeier@siemens.com
Cc:  
Subject: Re: i386/145718: [est] [patch] fix freq calculation from MSR for
 CPUs with fractional multipliers
Date: Fri, 26 Apr 2013 18:34:30 +0200

 And another additional patch to make this work with an E6600 CPU
 (266 MHz clock). While we are here, fix the unit of the voltage
 as well (Mv -> mV).
 
 --- est.c.ORI	2013-04-26 18:30:02.000000000 +0200
 +++ est.c	2013-04-26 18:30:02.000000000 +0200
 @@ -1192,6 +1192,7 @@
  	switch (bus) {
  	case 100:
  	case 133:
 +	case 267:
  	case 333:
  		return (1);
  	default:
 @@ -1252,7 +1253,7 @@
  	fp[0].volts = volts;
  	fp[0].id16 = id;
  	fp[0].power = CPUFREQ_VAL_UNKNOWN;
 -	device_printf(dev, "Guessed high setting of %d MHz @ %d Mv\n", freq,
 +	device_printf(dev, "Guessed high setting of %d MHz @ %d mV\n", freq,
  	    volts);
  
  	/* Second, the low frequency. */
 @@ -1269,7 +1270,7 @@
  	fp[1].volts = volts;
  	fp[1].id16 = id;
  	fp[1].power = CPUFREQ_VAL_UNKNOWN;
 -	device_printf(dev, "Guessed low setting of %d MHz @ %d Mv\n", freq,
 +	device_printf(dev, "Guessed low setting of %d MHz @ %d mV\n", freq,
  	    volts);
  
  	/* Table is already terminated due to M_ZERO. */
>Unformatted:
