coretemp: Register sensor task for each core instead each HT
[dragonfly.git] / sys / dev / powermng / coretemp / coretemp.c
1 /*
2  * Copyright (c) 2007, 2008 Rui Paulo <rpaulo@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
18  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
22  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
23  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  *
26  * $FreeBSD: src/sys/dev/coretemp/coretemp.c,v 1.14 2011/05/05 19:15:15 delphij Exp $
27  */
28
29 /*
30  * Device driver for Intel's On Die thermal sensor via MSR.
31  * First introduced in Intel's Core line of processors.
32  */
33
34 #include <sys/param.h>
35 #include <sys/bus.h>
36 #include <sys/systm.h>
37 #include <sys/module.h>
38 #include <sys/conf.h>
39 #include <sys/cpu_topology.h>
40 #include <sys/kernel.h>
41 #include <sys/sensors.h>
42 #include <sys/proc.h>   /* for curthread */
43 #include <sys/sched.h>
44 #include <sys/thread2.h>
45
46 #include <machine/specialreg.h>
47 #include <machine/cpufunc.h>
48 #include <machine/cputypes.h>
49 #include <machine/md_var.h>
50
51 struct coretemp_sensor {
52         struct ksensordev       c_sensdev;
53         struct ksensor          c_sens;
54 };
55
56 struct coretemp_softc {
57         device_t                sc_dev;
58         int                     sc_tjmax;
59
60         int                     sc_nsens;
61         struct coretemp_sensor  *sc_sens;
62
63         struct globaldata       *sc_gd;
64         int                     sc_cpu;
65         volatile uint32_t       sc_flags;       /* CORETEMP_FLAG_ */
66         volatile uint64_t       sc_msr;
67 };
68
69 #define CORETEMP_FLAG_INITED    0x1
70 #define CORETEMP_FLAG_PENDING   0x2
71 #define CORETEMP_FLAG_CRIT      0x4
72
73 /*
74  * Device methods.
75  */
76 static void     coretemp_identify(driver_t *driver, device_t parent);
77 static int      coretemp_probe(device_t dev);
78 static int      coretemp_attach(device_t dev);
79 static int      coretemp_detach(device_t dev);
80
81 static int      coretemp_get_temp(device_t dev);
82 static void     coretemp_refresh(void *arg);
83
84 static device_method_t coretemp_methods[] = {
85         /* Device interface */
86         DEVMETHOD(device_identify,      coretemp_identify),
87         DEVMETHOD(device_probe,         coretemp_probe),
88         DEVMETHOD(device_attach,        coretemp_attach),
89         DEVMETHOD(device_detach,        coretemp_detach),
90
91         DEVMETHOD_END
92 };
93
94 static driver_t coretemp_driver = {
95         "coretemp",
96         coretemp_methods,
97         sizeof(struct coretemp_softc),
98 };
99
100 static devclass_t coretemp_devclass;
101 DRIVER_MODULE(coretemp, cpu, coretemp_driver, coretemp_devclass, NULL, NULL);
102 MODULE_VERSION(coretemp, 1);
103
104 static void
105 coretemp_identify(driver_t *driver, device_t parent)
106 {
107         device_t child;
108
109         /* Make sure we're not being doubly invoked. */
110         if (device_find_child(parent, "coretemp", -1) != NULL)
111                 return;
112
113         /* Check that the vendor is Intel. */
114         if (cpu_vendor_id != CPU_VENDOR_INTEL)
115                 return;
116
117         /*
118          * Some Intel CPUs, namely the PIII, don't have thermal sensors,
119          * but report them in cpu_thermal_feature.  This leads to a later
120          * GPF when the sensor is queried via a MSR, so we stop here.
121          */
122         if (CPUID_TO_MODEL(cpu_id) < 0xe)
123                 return;
124
125         if ((cpu_thermal_feature & CPUID_THERMAL_SENSOR) == 0)
126                 return;
127
128         /*
129          * We add a child for each CPU since settings must be performed
130          * on each CPU in the SMP case.
131          */
132         child = device_add_child(parent, "coretemp", -1);
133         if (child == NULL)
134                 device_printf(parent, "add coretemp child failed\n");
135 }
136
137 static int
138 coretemp_probe(device_t dev)
139 {
140         if (resource_disabled("coretemp", 0))
141                 return (ENXIO);
142
143         device_set_desc(dev, "CPU On-Die Thermal Sensors");
144
145         return (BUS_PROBE_GENERIC);
146 }
147
148 static int
149 coretemp_attach(device_t dev)
150 {
151         struct coretemp_softc *sc = device_get_softc(dev);
152         const struct cpu_node *node, *start_node;
153         cpumask_t cpu_mask;
154         device_t pdev;
155         uint64_t msr;
156         int cpu_model, cpu_stepping;
157         int ret, tjtarget, cpu, sens_idx;
158
159         sc->sc_dev = dev;
160         pdev = device_get_parent(dev);
161         cpu_model = CPUID_TO_MODEL(cpu_id);
162         cpu_stepping = cpu_id & CPUID_STEPPING;
163
164 #if 0 /*
165        * XXXrpaulo: I have this CPU model and when it returns from C3
166        * coretemp continues to function properly.
167        */
168
169         /*
170          * Check for errata AE18.
171          * "Processor Digital Thermal Sensor (DTS) Readout stops
172          *  updating upon returning from C3/C4 state."
173          *
174          * Adapted from the Linux coretemp driver.
175          */
176         if (cpu_model == 0xe && cpu_stepping < 0xc) {
177                 msr = rdmsr(MSR_BIOS_SIGN);
178                 msr = msr >> 32;
179                 if (msr < 0x39) {
180                         device_printf(dev, "not supported (Intel errata "
181                             "AE18), try updating your BIOS\n");
182                         return (ENXIO);
183                 }
184         }
185 #endif
186
187         /*
188          * Use 100C as the initial value.
189          */
190         sc->sc_tjmax = 100;
191
192         if ((cpu_model == 0xf && cpu_stepping >= 2) || cpu_model == 0xe) {
193                 /*
194                  * On some Core 2 CPUs, there's an undocumented MSR that
195                  * can tell us if Tj(max) is 100 or 85.
196                  *
197                  * The if-clause for CPUs having the MSR_IA32_EXT_CONFIG
198                  * was adapted from the Linux coretemp driver.
199                  */
200                 msr = rdmsr(MSR_IA32_EXT_CONFIG);
201                 if (msr & (1 << 30))
202                         sc->sc_tjmax = 85;
203         } else if (cpu_model == 0x17) {
204                 switch (cpu_stepping) {
205                 case 0x6:       /* Mobile Core 2 Duo */
206                         sc->sc_tjmax = 105;
207                         break;
208                 default:        /* Unknown stepping */
209                         break;
210                 }
211         } else if (cpu_model == 0x1c) {
212                 switch (cpu_stepping) {
213                 case 0xa:       /* 45nm Atom D400, N400 and D500 series */
214                         sc->sc_tjmax = 100;
215                         break;
216                 default:
217                         sc->sc_tjmax = 90;
218                         break;
219                 }
220         } else {
221                 /*
222                  * Attempt to get Tj(max) from MSR IA32_TEMPERATURE_TARGET.
223                  *
224                  * This method is described in Intel white paper "CPU
225                  * Monitoring With DTS/PECI". (#322683)
226                  */
227                 ret = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &msr);
228                 if (ret == 0) {
229                         tjtarget = (msr >> 16) & 0xff;
230
231                         /*
232                          * On earlier generation of processors, the value
233                          * obtained from IA32_TEMPERATURE_TARGET register is
234                          * an offset that needs to be summed with a model
235                          * specific base.  It is however not clear what
236                          * these numbers are, with the publicly available
237                          * documents from Intel.
238                          *
239                          * For now, we consider [70, 110]C range, as
240                          * described in #322683, as "reasonable" and accept
241                          * these values whenever the MSR is available for
242                          * read, regardless the CPU model.
243                          */
244                         if (tjtarget >= 70 && tjtarget <= 110)
245                                 sc->sc_tjmax = tjtarget;
246                         else
247                                 device_printf(dev, "Tj(target) value %d "
248                                     "does not seem right.\n", tjtarget);
249                 } else
250                         device_printf(dev, "Can not get Tj(target) "
251                             "from your CPU, using 100C.\n");
252         }
253
254         if (bootverbose)
255                 device_printf(dev, "Setting TjMax=%d\n", sc->sc_tjmax);
256
257         sc->sc_cpu = device_get_unit(device_get_parent(dev));
258         sc->sc_gd = globaldata_find(sc->sc_cpu);
259
260         start_node = get_cpu_node_by_cpuid(sc->sc_cpu);
261
262         node = start_node;
263         while (node != NULL) {
264                 if (node->type == CORE_LEVEL)
265                         break;
266                 node = node->parent_node;
267         }
268         if (node != NULL) {
269                 int master_cpu = BSRCPUMASK(node->members);
270
271                 if (bootverbose) {
272                         device_printf(dev, "master cpu%d, count %u\n",
273                             master_cpu, node->child_no);
274                 }
275
276                 if (sc->sc_cpu != master_cpu)
277                         return (0);
278
279                 KKASSERT(node->child_no > 0);
280                 sc->sc_nsens = node->child_no;
281                 cpu_mask = node->members;
282         } else {
283                 sc->sc_nsens = 1;
284                 CPUMASK_ASSBIT(cpu_mask, sc->sc_cpu);
285         }
286         sc->sc_sens = kmalloc(sizeof(struct coretemp_sensor) * sc->sc_nsens,
287             M_DEVBUF, M_WAITOK | M_ZERO);
288
289         sens_idx = 0;
290         CPUSET_FOREACH(cpu, cpu_mask) {
291                 struct coretemp_sensor *csens;
292
293                 KKASSERT(sens_idx < sc->sc_nsens);
294                 csens = &sc->sc_sens[sens_idx];
295
296                 /*
297                  * Add hw.sensors.cpuN.temp0 MIB.
298                  */
299                 ksnprintf(csens->c_sensdev.xname,
300                     sizeof(csens->c_sensdev.xname), "cpu%d", cpu);
301                 ksnprintf(csens->c_sens.desc, sizeof(csens->c_sens.desc),
302                     "node%d core%d", get_chip_ID(cpu),
303                     get_core_number_within_chip(cpu));
304                 csens->c_sens.type = SENSOR_TEMP;
305                 csens->c_sens.status = SENSOR_S_UNSPEC;
306                 csens->c_sens.flags |= SENSOR_FINVALID;
307                 csens->c_sens.value = 0;
308                 sensor_attach(&csens->c_sensdev, &csens->c_sens);
309                 sensordev_install(&csens->c_sensdev);
310
311                 ++sens_idx;
312         }
313         sensor_task_register(sc, coretemp_refresh, 2);
314
315         return (0);
316 }
317
318 static int
319 coretemp_detach(device_t dev)
320 {
321         struct coretemp_softc *sc = device_get_softc(dev);
322
323         if (sc->sc_nsens > 0) {
324                 int i;
325
326                 sensor_task_unregister(sc);
327                 lwkt_synchronize_ipiqs("coretemp");
328
329                 for (i = 0; i < sc->sc_nsens; ++i)
330                         sensordev_deinstall(&sc->sc_sens[i].c_sensdev);
331                 kfree(sc->sc_sens, M_DEVBUF);
332         }
333         return (0);
334 }
335
336 static void
337 coretemp_ipifunc(void *xsc)
338 {
339         struct coretemp_softc *sc = xsc; 
340
341         sc->sc_msr = rdmsr(MSR_THERM_STATUS);
342         cpu_sfence();
343         atomic_clear_int(&sc->sc_flags, CORETEMP_FLAG_PENDING);
344 }
345
346 static int
347 coretemp_get_temp(device_t dev)
348 {
349         uint64_t msr;
350         int temp, cpu;
351         struct coretemp_softc *sc = device_get_softc(dev);
352
353         cpu = sc->sc_cpu;
354
355         /*
356          * Send IPI to the specific CPU to read the correct
357          * temperature.  If the IPI does not complete yet,
358          * i.e. CORETEMP_FLAG_PENDING is set, return -1.
359          */
360         if (cpu != mycpuid) {
361                 if ((sc->sc_flags & CORETEMP_FLAG_INITED) == 0) {
362                         /* The first time we are called */
363                         KASSERT((sc->sc_flags & CORETEMP_FLAG_PENDING) == 0,
364                             ("has pending bit set"));
365                         atomic_set_int(&sc->sc_flags,
366                             CORETEMP_FLAG_INITED | CORETEMP_FLAG_PENDING);
367                         cpu_mfence();
368                         lwkt_send_ipiq_passive(sc->sc_gd, coretemp_ipifunc, sc);
369                         return (-2);
370                 } else {
371                         if (sc->sc_flags & CORETEMP_FLAG_PENDING) {
372                                 /* IPI does not complete yet */
373                                 return (-2);
374                         }
375                         atomic_set_int(&sc->sc_flags, CORETEMP_FLAG_PENDING);
376                         msr = sc->sc_msr;
377                 }
378         } else {
379                 msr = rdmsr(MSR_THERM_STATUS);
380         }
381
382         /*
383          * Check for Thermal Status and Thermal Status Log.
384          */
385         if ((msr & 0x3) == 0x3)
386                 device_printf(dev, "PROCHOT asserted\n");
387
388         /*
389          * Bit 31 contains "Reading valid"
390          */
391         if (((msr >> 31) & 0x1) == 1) {
392                 /*
393                  * Starting on bit 16 and ending on bit 22.
394                  */
395                 temp = sc->sc_tjmax - ((msr >> 16) & 0x7f);
396         } else
397                 temp = -1;
398
399         /*
400          * Check for Critical Temperature Status and Critical
401          * Temperature Log.
402          * It doesn't really matter if the current temperature is
403          * invalid because the "Critical Temperature Log" bit will
404          * tell us if the Critical Temperature has been reached in
405          * past. It's not directly related to the current temperature.
406          *
407          * If we reach a critical level, allow devctl(4) to catch this
408          * and shutdown the system.
409          */
410         if (((msr >> 4) & 0x3) == 0x3) {
411                 if ((sc->sc_flags & CORETEMP_FLAG_CRIT) == 0) {
412                         char stemp[16];
413
414                         device_printf(dev, "critical temperature detected, "
415                             "suggest system shutdown\n");
416                         ksnprintf(stemp, sizeof(stemp), "%d", temp);
417                         devctl_notify("coretemp", "Thermal", stemp,
418                             "notify=0xcc");
419                         atomic_set_int(&sc->sc_flags, CORETEMP_FLAG_CRIT);
420                 }
421         } else if (sc->sc_flags & CORETEMP_FLAG_CRIT) {
422                 atomic_clear_int(&sc->sc_flags, CORETEMP_FLAG_CRIT);
423         }
424
425         if (sc->sc_flags & CORETEMP_FLAG_PENDING) {
426                 cpu_mfence();
427                 lwkt_send_ipiq_passive(sc->sc_gd, coretemp_ipifunc, sc);
428         }
429
430         return (temp);
431 }
432
433 static void
434 coretemp_refresh(void *arg)
435 {
436         struct coretemp_softc *sc = arg;
437         device_t dev = sc->sc_dev;
438         struct ksensor *sens;
439         int temp, i;
440
441         temp = coretemp_get_temp(dev);
442
443         if (temp == -2) {
444                 /* No updates; keep the previous value */
445         } else if (temp == -1) {
446                 for (i = 0; i < sc->sc_nsens; ++i) {
447                         sens = &sc->sc_sens[i].c_sens;
448
449                         sens->status = SENSOR_S_UNSPEC;
450                         sens->flags |= SENSOR_FINVALID;
451                         sens->value = 0;
452                 }
453         } else {
454                 for (i = 0; i < sc->sc_nsens; ++i) {
455                         sens = &sc->sc_sens[i].c_sens;
456                         if (sc->sc_flags & CORETEMP_FLAG_CRIT)
457                                 sens->status = SENSOR_S_CRIT;
458                         else
459                                 sens->status = SENSOR_S_OK;
460                         sens->flags &= ~SENSOR_FINVALID;
461                         sens->value = temp * 1000000 + 273150000;
462                 }
463         }
464 }