Re: Sandy Bridge support?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 18 Jan 2011 17:32:46 +0100, Jean Delvare wrote:
> On Tue, 18 Jan 2011 10:03:23 -0600, Nick Hall wrote:
> > And regarding the sensors-detect script, I understand now. If anyone is
> > interested, my Sandy Bridge processor would be model "0x2A" according to how
> > that script does things.
> 
> This is an option, yes, but it would be better if we could implement
> the same detection logic as the coretemp driver has. For one thing, this
> would guarantee that the two are always in sync. For another, it would
> lower the maintenance effort from our side, as the new detection logic
> is universal and doesn't need to be updated with every new CPU model.
> I'm looking into it but this is non-trivial.

I have come up with the following patch:

Index: prog/detect/sensors-detect
===================================================================
--- prog/detect/sensors-detect	(révision 5904)
+++ prog/detect/sensors-detect	(copie de travail)
@@ -23,7 +23,7 @@
 require 5.004;
 
 use strict;
-use Fcntl;
+use Fcntl qw(:DEFAULT :seek);
 use File::Basename;
 
 # We will call modprobe, which typically lives in either /sbin,
@@ -2046,14 +2046,10 @@
 		driver => "k10temp",
 		detect => \&fam11h_pci_detect,
 	}, {
-		name => "Intel Core family thermal sensor",
+		name => "Intel digital thermal sensor",
 		driver => "coretemp",
-		detect => sub { coretemp_detect(0); },
+		detect => \&coretemp_detect,
 	}, {
-		name => "Intel Atom thermal sensor",
-		driver => "coretemp",
-		detect => sub { coretemp_detect(1); },
-	}, {
 		name => "Intel AMB FB-DIMM thermal sensor",
 		driver => "i5k_amb",
 		detect => \&intel_amb_detect,
@@ -2314,10 +2310,10 @@
 	while (<INPUTFILE>) {
 		if (m/^processor\s*:\s*(\d+)/) {
 			push @cpu, $entry if scalar keys(%{$entry}); # Previous entry
-			$entry = {}; # New entry
+			$entry = { nr => $1 }; # New entry
 			next;
 		}
-		if (m/^(vendor_id|cpu family|model|model name|stepping)\s*:\s*(.+)$/) {
+		if (m/^(vendor_id|cpu family|model|model name|stepping|cpuid level)\s*:\s*(.+)$/) {
 			my $k = $1;
 			my $v = $2;
 			$v =~ s/\s+/ /g;	# Merge multiple spaces
@@ -2486,6 +2482,15 @@
 	$modules_list{$normalized} = 1;
 }
 
+# udev may take some time to create device nodes when loading modules
+sub udev_settle
+{
+	if (!(-x "/sbin/udevadm" && system("/sbin/udevadm settle") == 0)
+	 && !(-x "/sbin/udevsettle" && system("/sbin/udevsettle") == 0)) {
+		sleep(1);
+	}
+}
+
 sub initialize_modules_supported
 {
 	foreach my $chip (@chip_ids) {
@@ -5833,23 +5838,33 @@
 	return;
 }
 
+sub cpuid
+{
+	my ($cpu_nr, $eax) = @_;
+
+	sysopen(CPUID, "/dev/cpu/$cpu_nr/cpuid", O_RDONLY) or return;
+	binmode CPUID;
+	sysseek(CPUID, $eax, SEEK_SET)
+		or die "Cannot seek /dev/cpu/$cpu_nr/cpuid";
+	sysread(CPUID, my $data, 16)
+		or die "Cannot read /dev/cpu/$cpu_nr/cpuid";
+	close CPUID;
+
+	return unpack("L4", $data);
+}
+
 sub coretemp_detect
 {
-	my $chip = shift;
 	my $probecpu;
 
 	foreach $probecpu (@cpu) {
 		next unless $probecpu->{vendor_id} eq 'GenuineIntel' &&
-			    $probecpu->{'cpu family'} == 6;
-		return 9 if $chip == 0 &&
-			($probecpu->{model} == 14 ||	# Pentium M DC
-			 $probecpu->{model} == 15 ||	# Core 2 DC 65nm
-			 $probecpu->{model} == 0x16 ||	# Core 2 SC 65nm
-			 $probecpu->{model} == 0x17 ||	# Penryn 45nm
-			 $probecpu->{model} == 0x1a ||	# Nehalem
-			 $probecpu->{model} == 0x1e);	# Lynnfield
-		return 9 if $chip == 1 &&
-			($probecpu->{model} == 0x1c);	# Atom
+			    $probecpu->{'cpuid level'} >= 6;
+
+		# Now we check for the DTS flag
+		my @regs = cpuid($probecpu->{nr}, 0x06);
+		return unless @regs == 4;
+		return 9 if ($regs[0] & (1 << 0));	# eax, bit 0
 	}
 	return;
 }
@@ -6203,6 +6218,12 @@
 	print "Some south bridges, CPUs or memory controllers contain embedded sensors.\n".
 	      "Do you want to scan for them? This is totally safe. (YES/no): ";
 	unless (<STDIN> =~ /^\s*n/i) {
+		# Load the cpuid driver if needed
+		if (@cpu >= 1 && ! -e "/dev/cpu/$cpu[0]->{nr}/cpuid") {
+			load_module("cpuid");
+			udev_settle();
+		}
+
 		$| = 1;
 		foreach my $entry (@cpu_ids) {
 			scan_cpu($entry);
@@ -6278,12 +6299,7 @@
 		$by_default = 1 if dmi_match('board_vendor', 'asustek', 'tyan',
 					     'supermicro');
 
-		# udev may take some time to create the device node
-		if (!(-x "/sbin/udevadm" && system("/sbin/udevadm settle") == 0)
-		 && !(-x "/sbin/udevsettle" && system("/sbin/udevsettle") == 0)) {
-			sleep(1);
-		}
-
+		udev_settle();
 		for (my $dev_nr = 0; $dev_nr < @i2c_adapters; $dev_nr++) {
 			next unless exists $i2c_adapters[$dev_nr];
 			scan_i2c_adapter($dev_nr, $by_default);

This seems to do the trick for me. Obviously it assumes that the cpuid
kernel driver is available. All my systems have it available as a
module, but I don't know if we can reasonably assume that it will be
available on all x86 systems where sensors-detect is used.

I would like this change to get as wide a test coverage as possible.
To make testing easier, I've made the full script available for
download at:
  http://khali.linux-fr.org/devel/misc/sensors-detect
(It's exactly equivalent to sensors-detect SVN + the patch above.) In
particular, this needs testing on Intel CPUs with cpuid level >= 6 but
without DTS support... if such systems exist (I don't have any here,
for sure.)

If this appears to work for everyone and nobody comes up with a major
objection, then we have our fix.

Thanks,
-- 
Jean Delvare

_______________________________________________
lm-sensors mailing list
lm-sensors@xxxxxxxxxxxxxx
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors



[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux