Plan 9 from Bell Labs’s /usr/web/sources/contrib/yk/dist/9legacy/applied/pc-devarch-cputemp.diff

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


--- /n/sources/plan9/sys/man/3/arch	Tue Sep 18 22:24:42 2012
+++ /sys/man/3/arch	Sat Jan  5 00:00:00 2013
@@ -7,6 +7,7 @@
 .sp 0.3v
 .B /dev/archctl
 .B /dev/cputype
+.B /dev/cputemp
 .B /dev/ioalloc
 .B /dev/iob
 .B /dev/iol
@@ -19,6 +20,11 @@
 Reads from
 .I cputype
 recover the processor type and clock rate in MHz.
+Reads from
+.I cputemp
+recover one line containing per processor containing
+two fields: the processor temperature and precision
+in degrees Celsius.
 Reads from
 .I archctl
 yield at least data of this form:
--- /n/sources/plan9/sys/src/9/pcboot/dat.h	Fri Aug 17 20:11:39 2012
+++ /sys/src/9/pcboot/dat.h	Sat Jan  5 00:00:00 2013
@@ -324,6 +324,7 @@
 	Pge	= 1<<13,	/* page global extension */
 	Pse2	= 1<<17,	/* more page size extensions */
 	Clflush = 1<<19,
+	Acpif	= 1<<22,
 	Mmx	= 1<<23,
 	Fxsr	= 1<<24,	/* have SSE FXSAVE/FXRSTOR */
 	Sse	= 1<<25,	/* thus sfence instr. */
--- /n/sources/plan9/sys/src/9/pc/dat.h	Wed Aug 15 19:06:06 2012
+++ /sys/src/9/pc/dat.h	Sat Jan  5 00:00:00 2013
@@ -323,6 +323,7 @@
 	Pge	= 1<<13,	/* page global extension */
 	Pse2	= 1<<17,	/* more page size extensions */
 	Clflush = 1<<19,
+	Acpif	= 1<<22,
 	Mmx	= 1<<23,
 	Fxsr	= 1<<24,	/* have SSE FXSAVE/FXRSTOR */
 	Sse	= 1<<25,	/* thus sfence instr. */
--- /n/sources/plan9/sys/src/9/pc/devarch.c	Wed Aug 15 19:12:39 2012
+++ /sys/src/9/pc/devarch.c	Sat Jan  5 00:00:00 2013
@@ -869,6 +869,159 @@
 	return readstr(offset, a, n, str);
 }
 
+static int
+intelcputempok(void)
+{
+	ulong regs[4];
+
+	if(m->cpuiddx & Acpif)
+	if(strcmp(m->cpuidid, "GenuineIntel") == 0){
+		cpuid(6, regs);
+		return regs[0] & 1;
+	}
+	return 0;
+}
+
+static char Notemp[] = "-1 -1 unsupported\n";
+
+static long
+cputemprd0(Chan*, void *a, long n, vlong offset)
+{
+	char buf[32], *s;
+	ulong msr, t, res, d;
+	vlong emsr;
+	ulong regs[4];
+	static ulong tj;
+
+	cpuid(6, regs);
+	if((regs[0] & 1) == 0)
+		return readstr(offset, a, n, Notemp);
+	if(tj == 0){
+		/*
+		 * magic undocumented msr.  tj(max) is 100 or 85.
+		 */
+		tj = 100;
+		d = X86MODEL(m->cpuidax);
+		d |= (m->cpuidax>>12) & 0xf0;
+		if((d == 0xf && (m->cpuidax & 0xf)>1) || d == 0xe){
+			rdmsr(0xee, &emsr);
+			msr = emsr;
+			if(msr & 1<<30)
+				tj = 85;
+		}
+	}
+	rdmsr(0x19c, &emsr);
+	msr = emsr;
+	t = -1;
+	if(msr & 1<<31){
+		t = (msr>>16) & 127;
+		t = tj - t;
+	}
+	res = (msr>>27) & 15;
+	s = "";
+	if((msr & 0x30) == 0x30)
+		s = " alarm";
+	snprint(buf, sizeof buf, "%ld %lud%s\n", t, res, s);
+	return readstr(offset, a, n, buf);
+}
+
+static long
+intelcputemprd(Chan *c, void *va, long n, vlong offset)
+{
+	char *a;
+	long i, r, t;
+	Mach *w;
+
+	w = up->wired;
+	a = va;
+	t = 0;
+	for(i = 0; i < conf.nmach; i++){
+		procwired(up, i);
+		sched();
+		r = cputemprd0(c, a, n, offset);
+		if(r == 0)
+			break;
+		offset -= r;
+		if(offset < 0)
+			offset = 0;
+		n -= r;
+		a = a + r;
+		t += r;
+	}
+	up->wired = w;
+	sched();
+	return t;
+}
+
+static long
+amd0ftemprd(Chan*, void *a, long n, vlong offset)
+{
+	char *s, *e, buf[64];
+	long i, t, j, max;
+	Pcidev *p;
+
+	p = pcimatch(0, 0x1022, 0x1103);
+	if(p == nil)
+		return readstr(offset, a, n, Notemp);
+	max = 2;
+	if(max > conf.nmach)
+		max = conf.nmach;
+	s = buf;
+	e = buf + sizeof buf;
+	for(j = 0; j < max; j++){
+		pcicfgw32(p, 0xe4, pcicfgr32(p, 0xe4) & ~4 | j<<2);
+		i = pcicfgr32(p, 0xe4);
+		if(X86STEPPING(m->cpuidax) == 2)
+			t = i>>16 & 0xff;
+		else{
+			t = i>>14 & 0x3ff;
+			t *= 3;
+			t /= 4;
+		}
+		t += -49;
+		s = seprint(s, e, "%ld %lud%s\n", t, 1l, "");
+	}
+	return readstr(offset, a, n, buf);
+}
+
+static long
+amd10temprd(Chan*, void *a, long n, vlong offset)
+{
+	char *s, *e, *r, *buf;
+	long i, t, c, nb, cores[MAXMACH];
+	Pcidev *p;
+
+	nb = 0;
+	for(p = 0; p = pcimatch(p, 0x1022, 0x1203); ){
+		cores[nb++] = 1 + ((pcicfgr32(p, 0xe8) & 0x3000)>>12);
+		if(nb == nelem(cores))
+			break;
+	}
+	if(nb == 0)
+		return readstr(offset, a, n, Notemp);
+	buf = smalloc(MAXMACH*4*32);
+	s = buf;
+	e = buf + MAXMACH*4*32;
+	nb = 0;
+	c = 0;
+	for(p = 0; p = pcimatch(p, 0x1022, 0x1203); nb++){
+		i = pcicfgr32(p, 0xa4) & 0x7fffffff;
+		i >>= 21;
+		t = i/8;
+		r = ".0";
+		if(i % 8 >= 4)
+			r = "0.5";
+		/*
+		 * only one value per nb; repeat per core
+		 */
+		while(c++ < conf.nmach && cores[nb]--)
+			s = seprint(s, e, "%ld%s 0.5%s\n", t, r, "");
+	}
+	i = readstr(offset, a, n, buf);
+	free(buf);
+	return i;
+}
+
 static long
 archctlread(Chan*, void *a, long nn, vlong offset)
 {
@@ -1041,6 +1194,18 @@
 	if(m->cpuiddx & Sse2)
 		coherence = mfence;
 
+	if(intelcputempok())
+		addarchfile("cputemp", 0444, intelcputemprd, nil);
+	if(strcmp(m->cpuidid, "AuthenticAMD") == 0)
+		switch(X86FAMILY(m->cpuidax)){
+		case 0xf:
+			addarchfile("cputemp", 0444, amd0ftemprd, nil);
+			break;
+		case 0x10:
+		case 0x1f:
+			addarchfile("cputemp", 0444, amd10temprd, nil);
+			break;
+		}
 	addarchfile("cputype", 0444, cputyperead, nil);
 	addarchfile("archctl", 0664, archctlread, archctlwrite);
 }

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].