shithub: riscv

Download patch

ref: 68c77bf4a6aa932a7f31d8d84a378656542c80c2
parent: 70aab46761fe0a9810323bf1664a890c4af3ae5d
author: cinap_lenrek <[email protected]>
date: Sat May 5 06:44:29 EDT 2012

kernel: add eriks #P/cputemp

--- /dev/null
+++ b/sys/src/9/pc/cputemp.c
@@ -1,0 +1,168 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+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 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, "-1±-1 unsupported\n");
+	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±%uld%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, "-1±-1 unsupported\n");
+	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±%uld%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, "-1±-1 unsupported\n");
+	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;
+}
+
+void
+cputemplink(void)
+{
+	if(intelcputempok())
+		addarchfile("cputemp", 0444, intelcputemprd, nil);
+	if(X86FAMILY(m->cpuidax) == 0x0f && !strcmp(m->cpuidid, "AuthenticAMD"))
+		addarchfile("cputemp", 0444, amd0ftemprd, nil);
+	if(X86FAMILY(m->cpuidax) == 0x10 && !strcmp(m->cpuidid, "AuthenticAMD"))
+		addarchfile("cputemp", 0444, amd10temprd, nil);
+}
--- a/sys/src/9/pc/dat.h
+++ b/sys/src/9/pc/dat.h
@@ -294,6 +294,7 @@
 	Pge	= 1<<13,	/* page global extension */
 //	Pse2	= 1<<17,	/* more page size extensions */
 	Clflush = 1<<19,
+	Acpif	= 1<<22,	/* therm control msr */
 	Mmx	= 1<<23,
 	Sse	= 1<<25,	/* thus sfence instr. */
 	Sse2	= 1<<26,	/* thus mfence & lfence instr.s */
--- a/sys/src/9/pc/pccpuf
+++ b/sys/src/9/pc/pccpuf
@@ -40,6 +40,7 @@
 	segdesc
 	devpccard
 	devi82365
+	cputemp
 	apm		apmjump
 	ether2000	ether8390
 	ether2114x	pci
--- a/sys/src/9/pc/pcf
+++ b/sys/src/9/pc/pcf
@@ -41,6 +41,7 @@
 	segdesc
 	devpccard
 	devi82365
+	cputemp
 	apm		apmjump
 	ether2000	ether8390
 	ether2114x	pci