1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2019, Joyent, Inc.
14 */
15
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <libnvpair.h>
23 #include <sys/sensors.h>
24 #include <sys/fm/protocol.h>
25 #include <fm/topo_mod.h>
26 #include <topo_sensor.h>
27
28 #include "chip.h"
29
30 static const char *chip_sensor_base = "/dev/sensors/temperature/cpu";
31
32 int
chip_create_core_temp_sensor(topo_mod_t * mod,tnode_t * pnode)33 chip_create_core_temp_sensor(topo_mod_t *mod, tnode_t *pnode)
34 {
35 int err;
36 int32_t chip, core;
37 char buf[PATH_MAX];
38 struct stat st;
39
40 core = topo_node_instance(pnode);
41 if (topo_prop_get_int32(pnode, PGNAME(CORE), CORE_CHIP_ID, &chip,
42 &err) != 0) {
43 return (topo_mod_seterrno(mod, err));
44 }
45
46 if (snprintf(buf, sizeof (buf), "%s/chip%d.core%d", chip_sensor_base,
47 chip, core) >= sizeof (buf)) {
48 return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
49 }
50
51 /*
52 * Some systems have per-core sensors. Others have it on a per-die aka
53 * procnode basis. Check to see if the file exists before we attempt to
54 * do something.
55 */
56 if (stat(buf, &st) != 0) {
57 int32_t procnode;
58
59 if (errno != ENOENT) {
60 return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
61 }
62
63 if (topo_prop_get_int32(pnode, PGNAME(CORE), CORE_PROCNODE_ID,
64 &procnode, &err) != 0) {
65 return (topo_mod_seterrno(mod, err));
66 }
67
68 if (snprintf(buf, sizeof (buf), "%s/procnode.%d",
69 chip_sensor_base, procnode) >= sizeof (buf)) {
70 return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
71 }
72 }
73
74 return (topo_sensor_create_scalar_sensor(mod, pnode, buf, "temp"));
75 }
76
77 int
chip_create_chip_temp_sensor(topo_mod_t * mod,tnode_t * pnode)78 chip_create_chip_temp_sensor(topo_mod_t *mod, tnode_t *pnode)
79 {
80 int32_t chip;
81 char buf[PATH_MAX];
82
83 chip = topo_node_instance(pnode);
84
85 if (snprintf(buf, sizeof (buf), "%s/chip%d", chip_sensor_base,
86 chip) >= sizeof (buf)) {
87 return (topo_mod_seterrno(mod, EMOD_UNKNOWN));
88 }
89
90 return (topo_sensor_create_scalar_sensor(mod, pnode, buf, "temp"));
91 }
92