Subject: port-i386/36815: Enhanced SpeedStep fix for Intel A110-800
To: None <port-i386-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: None <fujiwara@f.pyon.org>
List: netbsd-bugs
Date: 08/21/2007 15:45:00
>Number:         36815
>Category:       port-i386
>Synopsis:       enhanced_speedstep panic on Intel A110-800
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-i386-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Aug 21 15:45:00 +0000 2007
>Originator:     Kazunori Fujiwara
>Release:        NetBSD 4.99.29
>Organization:
>Environment:
System: NetBSD looxu2 4.99.29 NetBSD 4.99.29 (LOOXU) #4: Tue Aug 21 22:48:23 JST 2007 fujiwara@f.pyon.org:/home0/NetBSD.crosscompile/obj/i386/home0/NetBSD.crosscompile/src/sys/arch/i386/compile/LOOXU i386
Architecture: i386
Machine: i386

>Description:
  Using "ENHANCED_SPEEDSTEP" option on Intel A110-800 CPU,
  NetBSD kernel panics with division by zero at sys/arch/x86/x86/est.c
>How-To-Repeat:
  If the CPU has ENHANCED_SPEEDSTEP feature
  and the CPU's minvolt == maxvolt and minfreq != maxfreq at est.c,
  voltinc == 0 at line 1201 on est.c rev 1.3
  and division by zero occurs at line 1208.

>Fix:
  Add A110-800 CPU entry(1), or apply est.c patch (2).

(1) A110-800 entry

/* Intel A110 processor 800 800 MHz */ 
static const uint16_t a110_800[] = {
	ID16(800, 812, BUS100),
	ID16(600, 812, BUS100),
}; 

and add "ENTRY(INTEL, BUS100, a110_800)," to est_cpus[].


(2) est.c patch

Index: est.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/est.c,v
retrieving revision 1.3
diff -u -b -r1.3 est.c
--- est.c	6 Aug 2007 03:38:49 -0000	1.3
+++ est.c	21 Aug 2007 14:22:20 -0000
@@ -1204,9 +1204,15 @@
 			voltinc = voltinc * 100 / freqinc - 1;
 			freqinc = 100;
 		} else {
+			if (voltinc > 0) {
 			tablesize = maxvolt - minvolt + 1;
 			freqinc = freqinc * 100 / voltinc - 1;
 			voltinc = 100;
+			} else {
+				freqinc = freqinc * 100;
+				tablesize = 2;
+				voltinc = 0;
+			}
 		}
 
 		fake_table = malloc(tablesize * sizeof(uint16_t), M_DEVBUF,
@@ -1224,7 +1230,7 @@
 			    "MSR*100 mV = %4d freq = %4d\n",
 			    __FUNCTION__, j, MSR2MV(fake_table[j]),
 			    MSR2MHZ(fake_table[j], bus_clock),
-			    freq, volt);
+			    volt, freq);
 #endif /* EST_DEBUG */
 			freq -= freqinc;
 			volt -= voltinc;