4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
30 #pragma ident "%Z%%M% %I% %E% SMI"
32 #include <sys/types.h>
39 #define SENSOR_POLL_INTERVAL 4 /* in seconds */
40 #define WARNING_INTERVAL 30 /* in seconds */
41 #define WARNING_DURATION 28 /* in seconds */
42 #define SHUTDOWN_INTERVAL 60 /* in seconds */
43 #define ENV_CONF_FILE "piclenvd.conf"
44 #define PM_DEVICE "/dev/pm"
45 #define SHUTDOWN_CMD "/usr/sbin/shutdown -y -g 60 -i 5"
46 #define ENVMODEL_CONF_FILE "envmodel.conf"
49 * Macros to fetch 16 and 32 bit data from unaligned address
51 #define GET_UNALIGN16(addr) \
52 (((*(uint8_t *)addr) << 8) | *((uint8_t *)addr+1))
54 #define GET_UNALIGN32(addr) \
55 (((*(uint8_t *)addr) << 24) | (*((uint8_t *)addr+1) << 16) | \
56 ((*((uint8_t *)addr+2)) << 8) | (*((uint8_t *)addr+3)))
60 * SEEPROM section header layout and location
63 uint8_t header_tag
; /* section header tag */
64 uint8_t header_version
[2]; /* header version (msb) */
65 uint8_t header_length
; /* header length */
66 uint8_t header_crc8
; /* crc8 */
67 uint8_t segment_count
; /* total number of segments */
70 #define SECTION_HDR_OFFSET 0x1800
71 #define SECTION_HDR_TAG 0x08
72 #define SECTION_HDR_VER 0x0001
73 #define SECTION_HDR_LENGTH 0x06
77 * SEEPROM segment header layout
80 uint16_t name
; /* segment name */
81 uint16_t descriptor
[2]; /* descriptor (msb) */
82 uint16_t offset
; /* segment data offset */
83 uint16_t length
; /* segment length */
86 #define ENVSEG_NAME 0x4553 /* environmental segment name */
87 #define ENVSEG_VERSION 1 /* environmental segment version */
91 * SEEPROM environmental segment header layout
94 uint16_t sensor_id
[2]; /* unique sensor ID (on this FRU) */
95 uint16_t offset
; /* sensor data record offset */
99 uint8_t version
; /* envseg version */
100 uint8_t sensor_count
; /* total number of sensor records */
101 envseg_sensor_t sensors
[1]; /* sensor table (variable length) */
106 * SEEPROM environmental segment sensor data layout
108 #define MAX_POLICY_ENTRIES 6 /* max # policy data entries */
111 int8_t observed
; /* observed (measured) temperature */
112 int8_t expected
; /* expected (correct) temperature */
116 int8_t high_power_off
; /* high power off threshold */
117 int8_t high_shutdown
; /* high shutdown threshold */
118 int8_t high_warning
; /* high warning threshold */
119 int8_t low_warning
; /* low warning threshold */
120 int8_t low_shutdown
; /* low shutdown threshold */
121 int8_t low_power_off
; /* low power off threshold */
122 int8_t policy_type
; /* policy type */
123 int8_t policy_entries
; /* #valid entries in policy_data[] */
124 int8_t policy_data
[MAX_POLICY_ENTRIES
];
125 uint16_t obs2exp_cnt
; /* map entries count */
126 envseg_map_t obs2exp_map
[1]; /* variable length map table */
127 } envseg_sensor_data_t
;
130 #define POLICY_TARGET_TEMP 1
131 #define POLICY_LINEAR 2
133 /* linear policy data indices */
134 #define LOW_NOMINAL_LOC 0 /* linear policy: lower temp index */
135 #define HIGH_NOMINAL_LOC 1 /* linear policy: higher temp index */
141 typedef struct fruenvseg
{
142 struct fruenvseg
*next
; /* next entry */
143 char *fru
; /* FRU SEEPROM path */
144 void *envsegbufp
; /* envseg data buffer */
145 int envseglen
; /* envseg length */
150 * devfs-path and sensor IDs for CPU FRUs
152 #define CPU0_FRU_DEVFS "/pci@8,700000/ebus@5/i2c@1,30/cpu-fru@0,a0:cpu-fru"
153 #define CPU1_FRU_DEVFS "/pci@8,700000/ebus@5/i2c@1,30/cpu-fru@0,a2:cpu-fru"
155 #define CPU_FRU_AMB_SENSOR 1
156 #define CPU_FRU_DIE_SENSOR 2
159 * devfs-path for various fans and their min/max speeds
161 #define ENV_CPU_FAN_DEVFS \
162 "/pci@8,700000/ebus@5/i2c@1,30/fan-control@0,48:2"
163 #define ENV_SYSTEM_FAN_DEVFS \
164 "/pci@8,700000/ebus@5/i2c@1,30/fan-control@0,48:0"
165 #define ENV_PSUPPLY_FAN_DEVFS \
166 "/pci@8,700000/ebus@5/i2c@1,30/fan-control@0,48:4"
169 * devfs-path for xcalwd watchdog
171 #define XCALWD_DEVFS "/devices/pseudo/xcalwd@0:xcalwd"
173 #define CPU_FAN_SPEED_MIN 12
174 #define CPU_FAN_SPEED_MAX 63
176 #define SYSTEM_FAN_SPEED_MIN 12
177 #define SYSTEM_FAN_SPEED_MAX 63
179 #define PSUPPLY_FAN_SPEED_MIN 0
180 #define PSUPPLY_FAN_SPEED_MAX 31
184 * devfs-path for various temperature sensors and CPU platform path
186 #define CPU0_DIE_SENSOR_DEVFS \
187 "/pci@8,700000/ebus@5/i2c@1,30/temperature@0,30:die_temp"
188 #define CPU0_AMB_SENSOR_DEVFS \
189 "/pci@8,700000/ebus@5/i2c@1,30/temperature@0,30:amb_temp"
191 #define CPU1_DIE_SENSOR_DEVFS \
192 "/pci@8,700000/ebus@5/i2c@1,30/temperature@0,98:die_temp"
193 #define CPU1_AMB_SENSOR_DEVFS \
194 "/pci@8,700000/ebus@5/i2c@1,30/temperature@0,98:amb_temp"
197 * Temperature thresholds structure
199 typedef int16_t tempr_t
;
202 tempr_t low_power_off
; /* low power-off temperature */
203 tempr_t high_power_off
; /* high power-off temperature */
204 tempr_t low_shutdown
; /* low shutdown temperature */
205 tempr_t high_shutdown
; /* high shutdown temperature */
206 tempr_t low_warning
; /* low warning temperature */
207 tempr_t high_warning
; /* high warning temperature */
208 tempr_t min_limit
; /* sensor minimum temperature limit */
209 tempr_t max_limit
; /* sensor maximum temperature limit */
210 short policy_type
; /* temperature policy */
211 short policy_entries
; /* # entries in policy_data */
212 tempr_t policy_data
[MAX_POLICY_ENTRIES
];
217 #define TEMP_IN_SHUTDOWN_RANGE(val, threshp) \
218 ((val) > (threshp)->high_shutdown || (val) < (threshp)->low_shutdown)
220 #define TEMP_IN_WARNING_RANGE(val, threshp) \
221 ((val) > (threshp)->high_warning || (val) < (threshp)->low_warning)
225 * MAX1617 sensor min/max temperature limits
227 #define MAX1617_MIN_TEMP -65
228 #define MAX1617_MAX_TEMP 127
231 * CPU "die" temperature thresholds
233 #define CPU_DIE_HIGH_POWER_OFF 110
234 #define CPU_DIE_HIGH_SHUTDOWN 90
235 #define CPU_DIE_HIGH_WARNING 88
236 #define CPU_DIE_NORMAL_TARGET 80
237 #define CPU_DIE_OTHER_TARGET 65
238 #define CPU_DIE_LOW_WARNING 0
239 #define CPU_DIE_LOW_SHUTDOWN -10
240 #define CPU_DIE_LOW_POWER_OFF -20
243 * CPU ambient temperature thresholds
245 #define CPU_AMB_HIGH_POWER_OFF 70
246 #define CPU_AMB_HIGH_SHUTDOWN 60
247 #define CPU_AMB_HIGH_WARNING 40
248 #define CPU_AMB_HIGH_NOMINAL 40
249 #define CPU_AMB_LOW_NOMINAL 25
250 #define CPU_AMB_LOW_WARNING 0
251 #define CPU_AMB_LOW_SHUTDOWN -10
252 #define CPU_AMB_LOW_POWER_OFF -20
258 #define ENV_SYSTEM_FAN "system"
259 #define ENV_CPU_FAN "cpu"
260 #define ENV_PSUPPLY_FAN "power-supply"
265 #define SENSOR_CPU0_ID 0
266 #define SENSOR_CPU0_DIE "cpu0"
267 #define SENSOR_CPU0_AMB "cpu0-ambient"
268 #define SENSOR_CPU1_ID 1
269 #define SENSOR_CPU1_DIE "cpu1"
270 #define SENSOR_CPU1_AMB "cpu1-ambient"
273 * Temperature correction/map strucutre
276 tempr_t observed
; /* observed temperature */
277 tempr_t expected
; /* expected temperature */
281 * Temperature sensor related data structure
283 typedef struct sensor_pmdev sensor_pmdev_t
;
285 typedef struct env_sensor
{
286 char *name
; /* sensor name */
287 char *devfs_path
; /* sensor device devfs path */
288 sensor_thresh_t
*temp_thresh
; /* sensor temp threshold */
289 char *fru
; /* FRU seeprom pathname */
290 int fru_sensor
; /* FRU sensor ID */
291 int flags
; /* flags (see below) */
292 int fd
; /* device file descriptor */
293 int error
; /* error flag */
294 boolean_t present
; /* sensor present */
295 tempr_t cur_temp
; /* current temperature */
296 tempr_t target_temp
; /* target temperature */
297 float avg_temp
; /* average temperature */
298 float prev_avg_temp
; /* prev average temperature */
299 time_t warning_tstamp
; /* last warning time (secs) */
300 time_t shutdown_tstamp
; /* shutdown temp time (secs) */
301 boolean_t shutdown_initiated
; /* shutdown initated */
302 sensor_pmdev_t
*pmdevp
; /* power managed device info */
303 float fan_adjustment_rate
; /* fan adjustment rate */
304 uint_t obs2exp_cnt
; /* # mapping entries */
305 tempr_map_t
*obs2exp_map
; /* temperature map entries */
306 time_t warning_start
; /* warning start time (secs) */
312 #define SFLAG_TARGET_TEMP 0x01 /* track target temperature */
313 #define SFLAG_CPU_AMB_SENSOR 0x10 /* CPU ambient sensor */
314 #define SFLAG_CPU_DIE_SENSOR 0x20 /* CPU die snesor */
316 extern env_sensor_t
*sensor_lookup(char *sensor_name
);
317 extern int get_temperature(env_sensor_t
*, tempr_t
*);
320 * Fan information data structure
322 #define SENSORS_PER_FAN 8 /* max sensors per fan */
323 typedef uint8_t fanspeed_t
;
325 typedef struct env_fan
{
326 char *name
; /* fan name */
327 char *devfs_path
; /* fan device devfs path */
328 fanspeed_t speed_min
; /* minimum speed */
329 fanspeed_t speed_max
; /* maximum speed */
330 int forced_speed
; /* forced (fixed) speed */
331 int fd
; /* device file descriptor */
332 boolean_t present
; /* fan present */
333 float cur_speed
; /* current fan speed */
334 float prev_speed
; /* previous fan speed */
335 int sensor_cnt
; /* #sensors in sensors[] */
336 env_sensor_t
*sensors
[SENSORS_PER_FAN
]; /* array of sensors */
340 * LPM/Table data structures
342 #define LPM_RANGES_PROPERTY "sunw,lpm-ranges"
355 picl_nodehdl_t nodeh
;
356 table_t
*temp_lpm_tbl
;
357 struct lpm_dev
*next
;
359 typedef struct lpm_dev lpm_dev_t
;
361 extern env_fan_t
*fan_lookup(char *fan_name
);
362 extern int get_fan_speed(env_fan_t
*, fanspeed_t
*);
364 extern int env_debug
;
365 extern void envd_log(int pri
, const char *fmt
, ...);
370 #define ENVD_PLUGIN_INIT_FAILED \
371 gettext("SUNW_piclenvd: initialization failed!\n")
373 #define ENVD_PICL_SETUP_FAILED \
374 gettext("SUNW_piclenvd: PICL setup failed!\n")
376 #define PM_THREAD_CREATE_FAILED \
377 gettext("SUNW_piclenvd: pmthr thread creation failed!\n")
379 #define PM_THREAD_EXITING \
380 gettext("SUNW_piclenvd: pmthr exiting! errno:%d %s\n")
382 #define ENV_THREAD_CREATE_FAILED \
383 gettext("SUNW_piclenvd: envthr thread creation failed!\n")
385 #define ENV_SHUTDOWN_MSG \
386 gettext("SUNW_piclenvd: '%s' sensor temperature %d outside safe " \
387 "limits (%d...%d). Shutting down the system.\n")
389 #define ENV_WARNING_MSG \
390 gettext("SUNW_piclenvd: '%s' sensor temperature %d outside safe " \
391 "operating limits (%d...%d).\n")
393 #define ENV_WATCHDOG_INIT_FAIL \
394 gettext("SUNW_piclenvd: failed to initialize the watchdog timer " \
397 #define ENV_FAN_OPEN_FAIL \
398 gettext("SUNW_piclenvd: can't open '%s' fan path:%s errno:%d %s\n")
400 #define ENV_SENSOR_OPEN_FAIL \
401 gettext("SUNW_piclenvd: can't open '%s' sensor path:%s errno:%d %s\n")
403 #define ENV_SENSOR_ACCESS_FAIL \
404 gettext("SUNW_piclenvd: can't access '%s' sensor errno:%d %s\n")
406 #define ENV_SENSOR_ACCESS_OK \
407 gettext("SUNW_piclenvd: '%s' sensor is accessible now.\n")
409 #define ENV_CONF_INT_EXPECTED \
410 gettext("SUNW_piclenvd: file:%s line:%d Invalid syntax or integer " \
411 "value outside range for keyword '%s'.\n")
413 #define ENV_CONF_STRING_EXPECTED \
414 gettext("SUNW_piclenvd: file:%s line:%d Invalid syntax for keyword " \
415 "'%s'. Expecting string in double quotes (length < %d).\n")
417 #define ENV_CONF_UNSUPPORTED_TYPE \
418 gettext("SUNW_piclenvd: file:%s line:%d Unsupported type:%d for " \
421 #define ENV_CONF_UNSUPPORTED_KEYWORD \
422 gettext("SUNW_piclenvd: file:%s line:%d Unsupported keyword '%s'.\n")
424 #define ENV_FRU_OPEN_FAIL \
425 gettext("SUNW_piclenvd: can't open FRU SEEPROM path:%s errno:%d %s\n")
427 #define ENV_FRU_BAD_ENVSEG \
428 gettext("SUNW_piclenvd: version mismatch or environmental segment " \
429 "header too short in FRU SEEPROM %s\n")
431 #define ENV_FRU_BAD_SENSOR_ENTRY \
432 gettext("SUNW_piclenvd: discarding bad sensor entry (sensor_id " \
433 "%x sensor '%s') in FRU SEEPROM %s\n")
435 #define ENV_FRU_SENSOR_MAP_NOMEM \
436 gettext("SUNW_piclenvd: out of memory, discarding sensor map for " \
437 "sensor_id %x (sensor '%s') in FRU SEEPROM %s\n")
439 #define ENV_INVALID_PROPERTY_FORMAT \
440 gettext("SUNW_piclenvd: ignoring %s property (invalid format)")