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 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 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