]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/cputemp.c
syscallfmt: use up->syserrstr instead of up->errstr (import from sources)
[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                 return readstr(offset, a, n, "-1±-1 unsupported\n");
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                         rdmsr(0xee, &emsr);
42                         msr = emsr;
43                         if(msr & 1<<30)
44                                 tj = 85;
45                 }
46         }
47         rdmsr(0x19c, &emsr);
48         msr = emsr;
49         t = -1;
50         if(msr & 1<<31){
51                 t = (msr>>16) & 127;
52                 t = tj - t;
53         }
54         res = (msr>>27) & 15;
55         s = "";
56         if((msr & 0x30) == 0x30)
57                 s = " alarm";
58         snprint(buf, sizeof buf, "%ld±%uld%s\n", t, res, s);
59         return readstr(offset, a, n, buf);
60 }
61
62 static long
63 intelcputemprd(Chan *c, void *va, long n, vlong offset)
64 {
65         char *a;
66         long i, r, t;
67         Mach *w;
68
69         w = up->wired;
70         a = va;
71         t = 0;
72         for(i = 0; i < conf.nmach; i++){
73                 procwired(up, i);
74                 sched();
75                 r = cputemprd0(c, a, n, offset);
76                 if(r == 0)
77                         break;
78                 offset -= r;
79                 if(offset < 0)
80                         offset = 0;
81                 n -= r;
82                 a = a + r;
83                 t += r;
84         }
85         up->wired = w;
86         sched();
87         return t;
88 }
89
90 static long
91 amd0ftemprd(Chan*, void *a, long n, vlong offset)
92 {
93         char *s, *e, buf[64];
94         long i, t, j, max;
95         Pcidev *p;
96
97         p = pcimatch(0, 0x1022, 0x1103);
98         if(p == nil)
99                 return readstr(offset, a, n, "-1±-1 unsupported\n");
100         max = 2;
101         if(max > conf.nmach)
102                 max = conf.nmach;
103         s = buf;
104         e = buf + sizeof buf;
105         for(j = 0; j < max; j++){
106                 pcicfgw32(p, 0xe4, pcicfgr32(p, 0xe4) & ~4 | j<<2);
107                 i = pcicfgr32(p, 0xe4);
108                 if(X86STEPPING(m->cpuidax) == 2)
109                         t = i>>16 & 0xff;
110                 else{
111                         t = i>>14 & 0x3ff;
112                         t *= 3;
113                         t /= 4;
114                 }
115                 t += -49;
116                 s = seprint(s, e, "%ld±%uld%s\n", t, 1l, "");
117         }
118         return readstr(offset, a, n, buf);
119 }
120
121 static long
122 amd10temprd(Chan*, void *a, long n, vlong offset)
123 {
124         char *s, *e, *r, *buf;
125         long i, t, c, nb, cores[MAXMACH];
126         Pcidev *p;
127
128         nb = 0;
129         for(p = 0; p = pcimatch(p, 0x1022, 0x1203); ){
130                 cores[nb++] = 1 + ((pcicfgr32(p, 0xe8) & 0x3000)>>12);
131                 if(nb == nelem(cores))
132                         break;
133         }
134         if(nb == 0)
135                 return readstr(offset, a, n, "-1±-1 unsupported\n");
136         buf = smalloc(MAXMACH*4*32);
137         s = buf;
138         e = buf + MAXMACH*4*32;
139         nb = 0;
140         c = 0;
141         for(p = 0; p = pcimatch(p, 0x1022, 0x1203); nb++){
142                 i = pcicfgr32(p, 0xa4) & 0x7fffffff;
143                 i >>= 21;
144                 t = i/8;
145                 r = ".0";
146                 if(i % 8 >= 4)
147                         r = "0.5";
148                 /*
149                  * only one value per nb; repeat per core
150                  */
151                 while(c++ < conf.nmach && cores[nb]--)
152                         s = seprint(s, e, "%ld%s±0.5%s\n", t, r, "");
153         }
154         i = readstr(offset, a, n, buf);
155         free(buf);
156         return i;
157 }
158
159 void
160 cputemplink(void)
161 {
162         if(intelcputempok())
163                 addarchfile("cputemp", 0444, intelcputemprd, nil);
164         if(X86FAMILY(m->cpuidax) == 0x0f && !strcmp(m->cpuidid, "AuthenticAMD"))
165                 addarchfile("cputemp", 0444, amd0ftemprd, nil);
166         if(X86FAMILY(m->cpuidax) == 0x10 && !strcmp(m->cpuidid, "AuthenticAMD"))
167                 addarchfile("cputemp", 0444, amd10temprd, nil);
168 }