1 /*
2  * CDDL HEADER START
3  *
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
7  * with the License.
8  *
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.
13  *
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]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_ENVD_H
28 #define	_ENVD_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include <sys/types.h>
33 #include <libintl.h>
34 
35 #ifdef	__cplusplus
36 extern "C" {
37 #endif
38 
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"
47 
48 /*
49  * Macros to fetch 16 and 32 bit data from unaligned address
50  */
51 #define	GET_UNALIGN16(addr)	\
52 	(((*(uint8_t *)addr) << 8) | *((uint8_t *)addr+1))
53 
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)))
57 
58 
59 /*
60  * SEEPROM section header layout and location
61  */
62 typedef struct {
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 */
68 } section_layout_t;
69 
70 #define	SECTION_HDR_OFFSET	0x1800
71 #define	SECTION_HDR_TAG		0x08
72 #define	SECTION_HDR_VER		0x0001
73 #define	SECTION_HDR_LENGTH	0x06
74 
75 
76 /*
77  * SEEPROM segment header layout
78  */
79 typedef struct {
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 */
84 } segment_layout_t;
85 
86 #define	ENVSEG_NAME		0x4553	/* environmental segment name */
87 #define	ENVSEG_VERSION		1	/* environmental segment version */
88 
89 
90 /*
91  * SEEPROM environmental segment header layout
92  */
93 typedef struct {
94 	uint16_t	sensor_id[2];	/* unique sensor ID (on this FRU) */
95 	uint16_t	offset;		/* sensor data record offset */
96 } envseg_sensor_t;
97 
98 typedef struct {
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) */
102 } envseg_layout_t;
103 
104 
105 /*
106  * SEEPROM environmental segment sensor data layout
107  */
108 #define	MAX_POLICY_ENTRIES	6	/* max # policy data entries */
109 
110 typedef struct {
111 	int8_t		observed;	/* observed (measured) temperature */
112 	int8_t		expected;	/* expected (correct) temperature */
113 } envseg_map_t;
114 
115 typedef struct {
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;
128 
129 /* policy_type */
130 #define	POLICY_TARGET_TEMP	1
131 #define	POLICY_LINEAR		2
132 
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 */
136 
137 
138 /*
139  * FRU envseg list
140  */
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 */
146 } fruenvseg_t;
147 
148 
149 /*
150  * devfs-path and sensor IDs for CPU FRUs
151  */
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"
154 
155 #define	CPU_FRU_AMB_SENSOR	1
156 #define	CPU_FRU_DIE_SENSOR	2
157 
158 /*
159  * devfs-path for various fans and their min/max speeds
160  */
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"
167 
168 /*
169  * devfs-path for xcalwd watchdog
170  */
171 #define	XCALWD_DEVFS	"/devices/pseudo/xcalwd@0:xcalwd"
172 
173 #define	CPU_FAN_SPEED_MIN	12
174 #define	CPU_FAN_SPEED_MAX	63
175 
176 #define	SYSTEM_FAN_SPEED_MIN	12
177 #define	SYSTEM_FAN_SPEED_MAX	63
178 
179 #define	PSUPPLY_FAN_SPEED_MIN	0
180 #define	PSUPPLY_FAN_SPEED_MAX	31
181 
182 
183 /*
184  * devfs-path for various temperature sensors and CPU platform path
185  */
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"
190 
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"
195 
196 /*
197  * Temperature thresholds structure
198  */
199 typedef int16_t tempr_t;
200 
201 typedef struct {
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];
213 } sensor_thresh_t;
214 
215 
216 
217 #define	TEMP_IN_SHUTDOWN_RANGE(val, threshp)	\
218 	((val) > (threshp)->high_shutdown || (val) < (threshp)->low_shutdown)
219 
220 #define	TEMP_IN_WARNING_RANGE(val, threshp)	\
221 	((val) > (threshp)->high_warning || (val) < (threshp)->low_warning)
222 
223 
224 /*
225  * MAX1617 sensor min/max temperature limits
226  */
227 #define	MAX1617_MIN_TEMP	-65
228 #define	MAX1617_MAX_TEMP	127
229 
230 /*
231  * CPU "die" temperature thresholds
232  */
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
241 
242 /*
243  * CPU ambient temperature thresholds
244  */
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
253 
254 
255 /*
256  * Fan names
257  */
258 #define	ENV_SYSTEM_FAN		"system"
259 #define	ENV_CPU_FAN		"cpu"
260 #define	ENV_PSUPPLY_FAN		"power-supply"
261 
262 /*
263  * Sensor ids & names
264  */
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"
271 
272 /*
273  * Temperature correction/map strucutre
274  */
275 typedef struct {
276 	tempr_t		observed;		/* observed temperature */
277 	tempr_t		expected;		/* expected temperature */
278 } tempr_map_t;
279 
280 /*
281  * Temperature sensor related data structure
282  */
283 typedef struct sensor_pmdev sensor_pmdev_t;
284 
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) */
307 } env_sensor_t;
308 
309 /*
310  * Sensor flags
311  */
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 */
315 
316 extern	env_sensor_t *sensor_lookup(char *sensor_name);
317 extern	int get_temperature(env_sensor_t *, tempr_t *);
318 
319 /*
320  * Fan information data structure
321  */
322 #define	SENSORS_PER_FAN	8		/* max sensors per fan */
323 typedef uint8_t fanspeed_t;
324 
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 */
337 } env_fan_t;
338 
339 /*
340  * LPM/Table data structures
341  */
342 #define	LPM_RANGES_PROPERTY	"sunw,lpm-ranges"
343 
344 typedef struct {
345 	int32_t	x;
346 	int32_t	y;
347 } point_t;
348 
349 typedef struct {
350 	int	nentries;
351 	point_t	*xymap;
352 } table_t;
353 
354 struct lpm_dev {
355 	picl_nodehdl_t	nodeh;
356 	table_t		*temp_lpm_tbl;
357 	struct lpm_dev *next;
358 };
359 typedef struct lpm_dev lpm_dev_t;
360 
361 extern	env_fan_t *fan_lookup(char *fan_name);
362 extern	int get_fan_speed(env_fan_t *, fanspeed_t *);
363 
364 extern int env_debug;
365 extern void envd_log(int pri, const char *fmt, ...);
366 
367 /*
368  * Various messages
369  */
370 #define	ENVD_PLUGIN_INIT_FAILED		\
371 	gettext("SUNW_piclenvd: initialization failed!\n")
372 
373 #define	ENVD_PICL_SETUP_FAILED		\
374 	gettext("SUNW_piclenvd: PICL setup failed!\n")
375 
376 #define	PM_THREAD_CREATE_FAILED		\
377 	gettext("SUNW_piclenvd: pmthr thread creation failed!\n")
378 
379 #define	PM_THREAD_EXITING		\
380 	gettext("SUNW_piclenvd: pmthr exiting! errno:%d %s\n")
381 
382 #define	ENV_THREAD_CREATE_FAILED	\
383 	gettext("SUNW_piclenvd: envthr thread creation failed!\n")
384 
385 #define	ENV_SHUTDOWN_MSG		\
386 	gettext("SUNW_piclenvd: '%s' sensor temperature %d outside safe " \
387 	"limits (%d...%d). Shutting down the system.\n")
388 
389 #define	ENV_WARNING_MSG			\
390 	gettext("SUNW_piclenvd: '%s' sensor temperature %d outside safe " \
391 	"operating limits (%d...%d).\n")
392 
393 #define	ENV_WATCHDOG_INIT_FAIL		\
394 	gettext("SUNW_piclenvd: failed to initialize the watchdog timer " \
395 	"errno:%d %s\n")
396 
397 #define	ENV_FAN_OPEN_FAIL		\
398 	gettext("SUNW_piclenvd: can't open '%s' fan path:%s errno:%d %s\n")
399 
400 #define	ENV_SENSOR_OPEN_FAIL		\
401 	gettext("SUNW_piclenvd: can't open '%s' sensor path:%s errno:%d %s\n")
402 
403 #define	ENV_SENSOR_ACCESS_FAIL		\
404 	gettext("SUNW_piclenvd: can't access '%s' sensor errno:%d %s\n")
405 
406 #define	ENV_SENSOR_ACCESS_OK		\
407 	gettext("SUNW_piclenvd: '%s' sensor is accessible now.\n")
408 
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")
412 
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")
416 
417 #define	ENV_CONF_UNSUPPORTED_TYPE	\
418 	gettext("SUNW_piclenvd: file:%s line:%d Unsupported type:%d for " \
419 	"keyword '%s'.\n")
420 
421 #define	ENV_CONF_UNSUPPORTED_KEYWORD	\
422 	gettext("SUNW_piclenvd: file:%s line:%d Unsupported keyword '%s'.\n")
423 
424 #define	ENV_FRU_OPEN_FAIL		\
425 	gettext("SUNW_piclenvd: can't open FRU SEEPROM path:%s errno:%d %s\n")
426 
427 #define	ENV_FRU_BAD_ENVSEG		\
428 	gettext("SUNW_piclenvd: version mismatch or environmental segment " \
429 	"header too short in FRU SEEPROM %s\n")
430 
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")
434 
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")
438 
439 #define	ENV_INVALID_PROPERTY_FORMAT	\
440 	gettext("SUNW_piclenvd: ignoring %s property (invalid format)")
441 
442 #ifdef	__cplusplus
443 }
444 #endif
445 
446 #endif	/* _ENVD_H */
447