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 #include <sys/types.h>
31 #include <libintl.h>
32 
33 #ifdef	__cplusplus
34 extern "C" {
35 #endif
36 
37 #define	SENSOR_POLL_INTERVAL 	4			/* in seconds */
38 #define	WARNING_INTERVAL	30			/* in seconds */
39 #define	WARNING_DURATION	28			/* in seconds */
40 #define	SHUTDOWN_INTERVAL	60			/* in seconds */
41 #define	ENV_CONF_FILE		"piclenvd.conf"
42 #define	PM_DEVICE		"/dev/pm"
43 #define	SHUTDOWN_CMD		"/usr/sbin/shutdown -y -g 60 -i 5"
44 #define	ENVMODEL_CONF_FILE	"envmodel.conf"
45 
46 /*
47  * Macros to fetch 16 and 32 bit data from unaligned address
48  */
49 #define	GET_UNALIGN16(addr)	\
50 	(((*(uint8_t *)addr) << 8) | *((uint8_t *)addr+1))
51 
52 #define	GET_UNALIGN32(addr)	\
53 	(((*(uint8_t *)addr) << 24) | (*((uint8_t *)addr+1) << 16) | \
54 	((*((uint8_t *)addr+2)) << 8) | (*((uint8_t *)addr+3)))
55 
56 
57 /*
58  * SEEPROM section header layout and location
59  */
60 typedef struct {
61 	uint8_t		header_tag;		/* section header tag */
62 	uint8_t		header_version[2];	/* header version (msb) */
63 	uint8_t		header_length;		/* header length */
64 	uint8_t		header_crc8;		/* crc8 */
65 	uint8_t		segment_count;		/* total number of segments */
66 } section_layout_t;
67 
68 #define	SECTION_HDR_OFFSET	0x1800
69 #define	SECTION_HDR_TAG		0x08
70 #define	SECTION_HDR_VER		0x0001
71 #define	SECTION_HDR_LENGTH	0x06
72 
73 
74 /*
75  * SEEPROM segment header layout
76  */
77 typedef struct {
78 	uint16_t	name;		/* segment name */
79 	uint16_t	descriptor[2];	/* descriptor (msb) */
80 	uint16_t	offset;		/* segment data offset */
81 	uint16_t	length;		/* segment length */
82 } segment_layout_t;
83 
84 #define	ENVSEG_NAME		0x4553	/* environmental segment name */
85 #define	ENVSEG_VERSION		1	/* environmental segment version */
86 
87 
88 /*
89  * SEEPROM environmental segment header layout
90  */
91 typedef struct {
92 	uint16_t	sensor_id[2];	/* unique sensor ID (on this FRU) */
93 	uint16_t	offset;		/* sensor data record offset */
94 } envseg_sensor_t;
95 
96 typedef struct {
97 	uint8_t		version;	/* envseg version */
98 	uint8_t		sensor_count;	/* total number of sensor records */
99 	envseg_sensor_t	sensors[1];	/* sensor table (variable length) */
100 } envseg_layout_t;
101 
102 
103 /*
104  * SEEPROM environmental segment sensor data layout
105  */
106 #define	MAX_POLICY_ENTRIES	6	/* max # policy data entries */
107 
108 typedef struct {
109 	int8_t		observed;	/* observed (measured) temperature */
110 	int8_t		expected;	/* expected (correct) temperature */
111 } envseg_map_t;
112 
113 typedef struct {
114 	int8_t		high_power_off;	/* high power off threshold */
115 	int8_t		high_shutdown;	/* high shutdown threshold */
116 	int8_t		high_warning;	/* high warning threshold */
117 	int8_t		low_warning;	/* low warning threshold */
118 	int8_t		low_shutdown;	/* low shutdown threshold */
119 	int8_t		low_power_off;	/* low power off threshold */
120 	int8_t		policy_type;	/* policy type */
121 	int8_t		policy_entries;	/* #valid entries in policy_data[] */
122 	int8_t		policy_data[MAX_POLICY_ENTRIES];
123 	uint16_t	obs2exp_cnt;	/* map entries count */
124 	envseg_map_t	obs2exp_map[1];	/* variable length map table */
125 } envseg_sensor_data_t;
126 
127 /* policy_type */
128 #define	POLICY_TARGET_TEMP	1
129 #define	POLICY_LINEAR		2
130 
131 /* linear policy data indices */
132 #define	LOW_NOMINAL_LOC		0	/* linear policy: lower temp index */
133 #define	HIGH_NOMINAL_LOC	1	/* linear policy: higher temp index */
134 
135 
136 /*
137  * FRU envseg list
138  */
139 typedef struct fruenvseg {
140 	struct fruenvseg	*next;		/* next entry */
141 	char			*fru;		/* FRU SEEPROM path */
142 	void			*envsegbufp;	/* envseg data buffer */
143 	int			envseglen;	/* envseg length */
144 } fruenvseg_t;
145 
146 
147 /*
148  * devfs-path and sensor IDs for CPU FRUs
149  */
150 #define	CPU0_FRU_DEVFS	"/pci@8,700000/ebus@5/i2c@1,30/cpu-fru@0,a0:cpu-fru"
151 #define	CPU1_FRU_DEVFS	"/pci@8,700000/ebus@5/i2c@1,30/cpu-fru@0,a2:cpu-fru"
152 
153 #define	CPU_FRU_AMB_SENSOR	1
154 #define	CPU_FRU_DIE_SENSOR	2
155 
156 /*
157  * devfs-path for various fans and their min/max speeds
158  */
159 #define	ENV_CPU_FAN_DEVFS	\
160 	"/pci@8,700000/ebus@5/i2c@1,30/fan-control@0,48:2"
161 #define	ENV_SYSTEM_FAN_DEVFS	\
162 	"/pci@8,700000/ebus@5/i2c@1,30/fan-control@0,48:0"
163 #define	ENV_PSUPPLY_FAN_DEVFS	\
164 	"/pci@8,700000/ebus@5/i2c@1,30/fan-control@0,48:4"
165 
166 /*
167  * devfs-path for xcalwd watchdog
168  */
169 #define	XCALWD_DEVFS	"/devices/pseudo/xcalwd@0:xcalwd"
170 
171 #define	CPU_FAN_SPEED_MIN	12
172 #define	CPU_FAN_SPEED_MAX	63
173 
174 #define	SYSTEM_FAN_SPEED_MIN	12
175 #define	SYSTEM_FAN_SPEED_MAX	63
176 
177 #define	PSUPPLY_FAN_SPEED_MIN	0
178 #define	PSUPPLY_FAN_SPEED_MAX	31
179 
180 
181 /*
182  * devfs-path for various temperature sensors and CPU platform path
183  */
184 #define	CPU0_DIE_SENSOR_DEVFS	\
185 	"/pci@8,700000/ebus@5/i2c@1,30/temperature@0,30:die_temp"
186 #define	CPU0_AMB_SENSOR_DEVFS	\
187 	"/pci@8,700000/ebus@5/i2c@1,30/temperature@0,30:amb_temp"
188 
189 #define	CPU1_DIE_SENSOR_DEVFS	\
190 	"/pci@8,700000/ebus@5/i2c@1,30/temperature@0,98:die_temp"
191 #define	CPU1_AMB_SENSOR_DEVFS	\
192 	"/pci@8,700000/ebus@5/i2c@1,30/temperature@0,98:amb_temp"
193 
194 /*
195  * Temperature thresholds structure
196  */
197 typedef int16_t tempr_t;
198 
199 typedef struct {
200 	tempr_t	low_power_off;		/* low power-off temperature */
201 	tempr_t	high_power_off;		/* high power-off temperature */
202 	tempr_t	low_shutdown;		/* low shutdown temperature */
203 	tempr_t	high_shutdown;		/* high shutdown temperature */
204 	tempr_t	low_warning;		/* low warning temperature */
205 	tempr_t	high_warning;		/* high warning temperature */
206 	tempr_t	min_limit;		/* sensor minimum temperature limit */
207 	tempr_t	max_limit;		/* sensor maximum temperature limit */
208 	short	policy_type;		/* temperature policy */
209 	short	policy_entries;		/* # entries in policy_data */
210 	tempr_t	policy_data[MAX_POLICY_ENTRIES];
211 } sensor_thresh_t;
212 
213 
214 
215 #define	TEMP_IN_SHUTDOWN_RANGE(val, threshp)	\
216 	((val) > (threshp)->high_shutdown || (val) < (threshp)->low_shutdown)
217 
218 #define	TEMP_IN_WARNING_RANGE(val, threshp)	\
219 	((val) > (threshp)->high_warning || (val) < (threshp)->low_warning)
220 
221 
222 /*
223  * MAX1617 sensor min/max temperature limits
224  */
225 #define	MAX1617_MIN_TEMP	-65
226 #define	MAX1617_MAX_TEMP	127
227 
228 /*
229  * CPU "die" temperature thresholds
230  */
231 #define	CPU_DIE_HIGH_POWER_OFF	110
232 #define	CPU_DIE_HIGH_SHUTDOWN	90
233 #define	CPU_DIE_HIGH_WARNING	88
234 #define	CPU_DIE_NORMAL_TARGET	80
235 #define	CPU_DIE_OTHER_TARGET	65
236 #define	CPU_DIE_LOW_WARNING	0
237 #define	CPU_DIE_LOW_SHUTDOWN	-10
238 #define	CPU_DIE_LOW_POWER_OFF	-20
239 
240 /*
241  * CPU ambient temperature thresholds
242  */
243 #define	CPU_AMB_HIGH_POWER_OFF	70
244 #define	CPU_AMB_HIGH_SHUTDOWN	60
245 #define	CPU_AMB_HIGH_WARNING	40
246 #define	CPU_AMB_HIGH_NOMINAL	40
247 #define	CPU_AMB_LOW_NOMINAL	25
248 #define	CPU_AMB_LOW_WARNING	0
249 #define	CPU_AMB_LOW_SHUTDOWN	-10
250 #define	CPU_AMB_LOW_POWER_OFF	-20
251 
252 
253 /*
254  * Fan names
255  */
256 #define	ENV_SYSTEM_FAN		"system"
257 #define	ENV_CPU_FAN		"cpu"
258 #define	ENV_PSUPPLY_FAN		"power-supply"
259 
260 /*
261  * Sensor ids & names
262  */
263 #define	SENSOR_CPU0_ID		0
264 #define	SENSOR_CPU0_DIE		"cpu0"
265 #define	SENSOR_CPU0_AMB		"cpu0-ambient"
266 #define	SENSOR_CPU1_ID		1
267 #define	SENSOR_CPU1_DIE		"cpu1"
268 #define	SENSOR_CPU1_AMB		"cpu1-ambient"
269 
270 /*
271  * Temperature correction/map strucutre
272  */
273 typedef struct {
274 	tempr_t		observed;		/* observed temperature */
275 	tempr_t		expected;		/* expected temperature */
276 } tempr_map_t;
277 
278 /*
279  * Temperature sensor related data structure
280  */
281 typedef struct sensor_pmdev sensor_pmdev_t;
282 
283 typedef struct env_sensor {
284 	char		*name;			/* sensor name */
285 	char		*devfs_path;		/* sensor device devfs path */
286 	sensor_thresh_t	*temp_thresh;		/* sensor temp threshold */
287 	char		*fru;			/* FRU seeprom pathname */
288 	int		fru_sensor;		/* FRU sensor ID */
289 	int		flags;			/* flags (see below) */
290 	int		fd;			/* device file descriptor */
291 	int		error;			/* error flag */
292 	boolean_t 	present;		/* sensor present */
293 	tempr_t		cur_temp;		/* current temperature */
294 	tempr_t		target_temp;		/* target temperature */
295 	float		avg_temp;		/* average temperature */
296 	float		prev_avg_temp;		/* prev average temperature */
297 	time_t		warning_tstamp;		/* last warning time (secs) */
298 	time_t		shutdown_tstamp;	/* shutdown temp time (secs) */
299 	boolean_t 	shutdown_initiated;	/* shutdown initated */
300 	sensor_pmdev_t	*pmdevp;		/* power managed device info */
301 	float		fan_adjustment_rate;	/* fan adjustment rate */
302 	uint_t		obs2exp_cnt;		/* # mapping entries */
303 	tempr_map_t	*obs2exp_map;		/* temperature map entries */
304 	time_t		warning_start;		/* warning start time (secs) */
305 } env_sensor_t;
306 
307 /*
308  * Sensor flags
309  */
310 #define	SFLAG_TARGET_TEMP	0x01		/* track target temperature */
311 #define	SFLAG_CPU_AMB_SENSOR	0x10		/* CPU ambient sensor */
312 #define	SFLAG_CPU_DIE_SENSOR	0x20		/* CPU die snesor */
313 
314 extern	env_sensor_t *sensor_lookup(char *sensor_name);
315 extern	int get_temperature(env_sensor_t *, tempr_t *);
316 
317 /*
318  * Fan information data structure
319  */
320 #define	SENSORS_PER_FAN	8		/* max sensors per fan */
321 typedef uint8_t fanspeed_t;
322 
323 typedef struct env_fan {
324 	char		*name;			/* fan name */
325 	char		*devfs_path;		/* fan device devfs path */
326 	fanspeed_t	speed_min;		/* minimum speed */
327 	fanspeed_t	speed_max;		/* maximum speed */
328 	int		forced_speed;		/* forced (fixed) speed */
329 	int		fd;			/* device file descriptor */
330 	boolean_t	present;		/* fan present */
331 	float		cur_speed;		/* current fan speed */
332 	float		prev_speed;		/* previous fan speed */
333 	int		sensor_cnt;		/* #sensors in sensors[] */
334 	env_sensor_t	*sensors[SENSORS_PER_FAN]; /* array of sensors */
335 } env_fan_t;
336 
337 /*
338  * LPM/Table data structures
339  */
340 #define	LPM_RANGES_PROPERTY	"sunw,lpm-ranges"
341 
342 typedef struct {
343 	int32_t	x;
344 	int32_t	y;
345 } point_t;
346 
347 typedef struct {
348 	int	nentries;
349 	point_t	*xymap;
350 } table_t;
351 
352 struct lpm_dev {
353 	picl_nodehdl_t	nodeh;
354 	table_t		*temp_lpm_tbl;
355 	struct lpm_dev *next;
356 };
357 typedef struct lpm_dev lpm_dev_t;
358 
359 extern	env_fan_t *fan_lookup(char *fan_name);
360 extern	int get_fan_speed(env_fan_t *, fanspeed_t *);
361 
362 extern int env_debug;
363 extern void envd_log(int pri, const char *fmt, ...);
364 
365 /*
366  * Various messages
367  */
368 #define	ENVD_PLUGIN_INIT_FAILED		\
369 	gettext("SUNW_piclenvd: initialization failed!\n")
370 
371 #define	ENVD_PICL_SETUP_FAILED		\
372 	gettext("SUNW_piclenvd: PICL setup failed!\n")
373 
374 #define	PM_THREAD_CREATE_FAILED		\
375 	gettext("SUNW_piclenvd: pmthr thread creation failed!\n")
376 
377 #define	PM_THREAD_EXITING		\
378 	gettext("SUNW_piclenvd: pmthr exiting! errno:%d %s\n")
379 
380 #define	ENV_THREAD_CREATE_FAILED	\
381 	gettext("SUNW_piclenvd: envthr thread creation failed!\n")
382 
383 #define	ENV_SHUTDOWN_MSG		\
384 	gettext("SUNW_piclenvd: '%s' sensor temperature %d outside safe " \
385 	"limits (%d...%d). Shutting down the system.\n")
386 
387 #define	ENV_WARNING_MSG			\
388 	gettext("SUNW_piclenvd: '%s' sensor temperature %d outside safe " \
389 	"operating limits (%d...%d).\n")
390 
391 #define	ENV_WATCHDOG_INIT_FAIL		\
392 	gettext("SUNW_piclenvd: failed to initialize the watchdog timer " \
393 	"errno:%d %s\n")
394 
395 #define	ENV_FAN_OPEN_FAIL		\
396 	gettext("SUNW_piclenvd: can't open '%s' fan path:%s errno:%d %s\n")
397 
398 #define	ENV_SENSOR_OPEN_FAIL		\
399 	gettext("SUNW_piclenvd: can't open '%s' sensor path:%s errno:%d %s\n")
400 
401 #define	ENV_SENSOR_ACCESS_FAIL		\
402 	gettext("SUNW_piclenvd: can't access '%s' sensor errno:%d %s\n")
403 
404 #define	ENV_SENSOR_ACCESS_OK		\
405 	gettext("SUNW_piclenvd: '%s' sensor is accessible now.\n")
406 
407 #define	ENV_CONF_INT_EXPECTED		\
408 	gettext("SUNW_piclenvd: file:%s line:%d Invalid syntax or integer " \
409 	"value outside range for keyword '%s'.\n")
410 
411 #define	ENV_CONF_STRING_EXPECTED	\
412 	gettext("SUNW_piclenvd: file:%s line:%d Invalid syntax for keyword " \
413 	"'%s'. Expecting string in double quotes (length < %d).\n")
414 
415 #define	ENV_CONF_UNSUPPORTED_TYPE	\
416 	gettext("SUNW_piclenvd: file:%s line:%d Unsupported type:%d for " \
417 	"keyword '%s'.\n")
418 
419 #define	ENV_CONF_UNSUPPORTED_KEYWORD	\
420 	gettext("SUNW_piclenvd: file:%s line:%d Unsupported keyword '%s'.\n")
421 
422 #define	ENV_FRU_OPEN_FAIL		\
423 	gettext("SUNW_piclenvd: can't open FRU SEEPROM path:%s errno:%d %s\n")
424 
425 #define	ENV_FRU_BAD_ENVSEG		\
426 	gettext("SUNW_piclenvd: version mismatch or environmental segment " \
427 	"header too short in FRU SEEPROM %s\n")
428 
429 #define	ENV_FRU_BAD_SENSOR_ENTRY	\
430 	gettext("SUNW_piclenvd: discarding bad sensor entry (sensor_id " \
431 	"%x sensor '%s') in FRU SEEPROM %s\n")
432 
433 #define	ENV_FRU_SENSOR_MAP_NOMEM	\
434 	gettext("SUNW_piclenvd: out of memory, discarding sensor map for " \
435 	"sensor_id %x (sensor '%s') in FRU SEEPROM %s\n")
436 
437 #define	ENV_INVALID_PROPERTY_FORMAT	\
438 	gettext("SUNW_piclenvd: ignoring %s property (invalid format)")
439 
440 #ifdef	__cplusplus
441 }
442 #endif
443 
444 #endif	/* _ENVD_H */
445