]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/cputemp.c
rdmsr/wrmsr become tryrdmsr/trywrmsr, we can should check for trap
[plan9front.git] / sys / src / 9 / pc / cputemp.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7
8 static int
9 intelcputempok(void)
10 {
11         ulong regs[4];
12
13         if(m->cpuiddx & Acpif)
14         if(strcmp(m->cpuidid, "GenuineIntel") == 0){
15                 cpuid(6, regs);
16                 return regs[0] & 1;
17         }
18         return 0;
19 }
20
21 static long
22 cputemprd0(Chan*, void *a, long n, vlong offset)
23 {
24         char buf[32], *s;
25         ulong msr, t, res, d;
26         vlong emsr;
27         ulong regs[4];
28         static ulong tj;
29
30         cpuid(6, regs);
31         if((regs[0] & 1) == 0)
32                 goto unsup;
33         if(tj == 0){
34                 /*
35                  * magic undocumented msr.  tj(max) is 100 or 85.
36                  */
37                 tj = 100;
38                 d = X86MODEL(m->cpuidax);
39                 d |= (m->cpuidax>>12) & 0xf0;
40                 if((d == 0xf && (m->cpuidax & 0xf)>1) || d == 0xe){
41                         if(rdmsr(0xee, &emsr) == 0){
42                                 msr = emsr;
43                                 if(msr & 1<<30)
44                                         tj = 85;
45                         }
46                 }
47         }
48         if(rdmsr(0x19c, &emsr) < 0)
49                 goto unsup;
50         msr = emsr;
51         t = -1;
52         if(msr & 1<<31){
53                 t = (msr>>16) & 127;
54                 t = tj - t;
55         }
56         res = (msr>>27) & 15;
57         s = "";
58         if((msr & 0x30) == 0x30)
59                 s = " alarm";
60         snprint(buf, sizeof buf, "%ld±%uld%s\n", t, res, s);
61         return readstr(offset, a, n, buf);
62 unsup:
63         return readstr(offset, a, n, "-1±-1 unsupported\n");
64 }
65
66 static long
67 intelcputemprd(Chan *c, void *va, long n, vlong offset)
68 {
69         char *a;
70         long i, r, t;
71         Mach *w;
72
73         w = up->wired;
74         a = va;
75         t = 0;
76         for(i = 0; i < conf.nmach; i++){
77                 procwired(up, i);
78                 sched();
79                 r = cputemprd0(c, a, n, offset);
80                 if(r == 0)
81                         break;
82                 offset -= r;
83                 if(offset < 0)
84                         offset = 0;
85                 n -= r;
86                 a = a + r;
87                 t += r;
88         }
89         up->wired = w;
90         sched();
91         return t;
92 }
93
94 static long
95 amd0ftemprd(Chan*, void *a, long n, vlong offset)
96 {
97         char *s, *e, buf[64];
98         long i, t, j, max;
99         Pcidev *p;
100
101         p = pcimatch(0, 0x1022, 0x1103);
102         if(p == nil)
103                 return readstr(offset, a, n, "-1±-1 unsupported\n");
104         max = 2;
105         if(max > conf.nmach)
106                 max = conf.nmach;
107         s = buf;
108         e = buf + sizeof buf;
109         for(j = 0; j < max; j++){
110                 pcicfgw32(p, 0xe4, pcicfgr32(p, 0xe4) & ~4 | j<<2);
111                 i = pcicfgr32(p, 0xe4);
112                 if(X86STEPPING(m->cpuidax) == 2)
113                         t = i>>16 & 0xff;
114                 else{
115                         t = i>>14 & 0x3ff;
116                         t *= 3;
117                         t /= 4;
118                 }
119                 t += -49;
120                 s = seprint(s, e, "%ld±%uld%s\n", t, 1l, "");
121         }
122         return readstr(offset, a, n, buf);
123 }
124
125 static long
126 amd10temprd(Chan*, void *a, long n, vlong offset)
127 {
128         char *s, *e, *r, *buf;
129         long i, t, c, nb, cores[MAXMACH];
130         Pcidev *p;
131
132         nb = 0;
133         for(p = 0; p = pcimatch(p, 0x1022, 0x1203); ){
134                 cores[nb++] = 1 + ((pcicfgr32(p, 0xe8) & 0x3000)>>12);
135                 if(nb == nelem(cores))
136                         break;
137         }
138         if(nb == 0)
139                 return readstr(offset, a, n, "-1±-1 unsupported\n");
140         buf = smalloc(MAXMACH*4*32);
141         s = buf;
142         e = buf + MAXMACH*4*32;
143         nb = 0;
144         c = 0;
145         for(p = 0; p = pcimatch(p, 0x1022, 0x1203); nb++){
146                 i = pcicfgr32(p, 0xa4) & 0x7fffffff;
147                 i >>= 21;
148                 t = i/8;
149                 r = ".0";
150                 if(i % 8 >= 4)
151                         r = "0.5";
152                 /*
153                  * only one value per nb; repeat per core
154                  */
155                 while(c++ < conf.nmach && cores[nb]--)
156                         s = seprint(s, e, "%ld%s±0.5%s\n", t, r, "");
157         }
158         i = readstr(offset, a, n, buf);
159         free(buf);
160         return i;
161 }
162
163 void
164 cputemplink(void)
165 {
166         if(intelcputempok())
167                 addarchfile("cputemp", 0444, intelcputemprd, nil);
168         if(X86FAMILY(m->cpuidax) == 0x0f && !strcmp(m->cpuidid, "AuthenticAMD"))
169                 addarchfile("cputemp", 0444, amd0ftemprd, nil);
170         if(X86FAMILY(m->cpuidax) == 0x10 && !strcmp(m->cpuidid, "AuthenticAMD"))
171                 addarchfile("cputemp", 0444, amd10temprd, nil);
172 }