xref: /netbsd/sys/arch/x86/include/ipmivar.h (revision 6550d01e)
1 /* $NetBSD: ipmivar.h,v 1.11 2010/08/01 08:16:14 mlelstv Exp $ */
2 
3 /*
4  * Copyright (c) 2005 Jordan Hargrave
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  */
29 
30 #include <sys/mutex.h>
31 #include <sys/condvar.h>
32 
33 #include <dev/sysmon/sysmonvar.h>
34 
35 #ifndef _IPMIVAR_H_
36 #define _IPMIVAR_H_
37 
38 #define IPMI_IF_KCS		1
39 #define IPMI_IF_SMIC		2
40 #define IPMI_IF_BT		3
41 
42 #define IPMI_IF_KCS_NREGS	2
43 #define IPMI_IF_SMIC_NREGS	3
44 #define IPMI_IF_BT_NREGS	3
45 
46 struct ipmi_thread;
47 struct ipmi_softc;
48 
49 struct ipmi_attach_args {
50 	bus_space_tag_t	iaa_iot;
51 	bus_space_tag_t	iaa_memt;
52 
53 	int		iaa_if_type;
54 	int		iaa_if_rev;
55 	int		iaa_if_iotype;
56 	int		iaa_if_iobase;
57 	int		iaa_if_iospacing;
58 	int		iaa_if_irq;
59 	int		iaa_if_irqlvl;
60 };
61 
62 struct ipmi_if {
63 	const char	*name;
64 	int		nregs;
65 	void		*(*buildmsg)(struct ipmi_softc *, int, int, int,
66 			    const void *, int *);
67 	int		(*sendmsg)(struct ipmi_softc *, int, const uint8_t *);
68 	int		(*recvmsg)(struct ipmi_softc *, int, int *, uint8_t *);
69 	int		(*reset)(struct ipmi_softc *);
70 	int		(*probe)(struct ipmi_softc *);
71 };
72 
73 struct ipmi_softc {
74 	device_t		sc_dev;
75 
76 	struct ipmi_if		*sc_if;		/* Interface layer */
77 	int			sc_if_iospacing; /* Spacing of I/O ports */
78 	int			sc_if_rev;	/* IPMI Revision */
79 	struct ipmi_attach_args	sc_ia;
80 
81 	void			*sc_ih;		/* Interrupt/IO handles */
82 	bus_space_tag_t		sc_iot;
83 	bus_space_handle_t	sc_ioh;
84 
85 	int			sc_btseq;
86 
87 	struct lwp		*sc_kthread;
88 
89 	int			sc_max_retries;
90 
91 	kmutex_t		sc_poll_mtx;
92 	kcondvar_t		sc_poll_cv;
93 
94 	kmutex_t		sc_cmd_mtx;
95 	kmutex_t		sc_sleep_mtx;
96 	kcondvar_t		sc_cmd_sleep;
97 
98 	struct ipmi_bmc_args	*sc_iowait_args;
99 
100 	struct ipmi_sensor	*current_sensor;
101 	volatile bool		sc_thread_running;
102 	volatile bool		sc_tickle_due;
103 	struct sysmon_wdog	sc_wdog;
104 	struct sysmon_envsys	*sc_envsys;
105 	envsys_data_t		*sc_sensor;
106 	int 		sc_nsensors; /* total number of sensors */
107 
108 	char		sc_buf[64];
109 	bool		sc_buf_rsvd;
110 };
111 
112 struct ipmi_thread {
113 	struct ipmi_softc   *sc;
114 	volatile int	    running;
115 };
116 
117 #define IPMI_WDOG_USE_NOLOG		__BIT(7)
118 #define IPMI_WDOG_USE_NOSTOP		__BIT(6)
119 #define IPMI_WDOG_USE_RSVD1		__BITS(5, 3)
120 #define IPMI_WDOG_USE_USE_MASK		__BITS(2, 0)
121 #define IPMI_WDOG_USE_USE_RSVD		__SHIFTIN(0, IPMI_WDOG_USE_USE_MASK);
122 #define IPMI_WDOG_USE_USE_FRB2		__SHIFTIN(1, IPMI_WDOG_USE_USE_MASK);
123 #define IPMI_WDOG_USE_USE_POST		__SHIFTIN(2, IPMI_WDOG_USE_USE_MASK);
124 #define IPMI_WDOG_USE_USE_OSLOAD	__SHIFTIN(3, IPMI_WDOG_USE_USE_MASK);
125 #define IPMI_WDOG_USE_USE_OS		__SHIFTIN(4, IPMI_WDOG_USE_USE_MASK);
126 #define IPMI_WDOG_USE_USE_OEM		__SHIFTIN(5, IPMI_WDOG_USE_USE_MASK);
127 
128 #define IPMI_WDOG_ACT_PRE_RSVD1		__BIT(7)
129 #define IPMI_WDOG_ACT_PRE_MASK		__BITS(6, 4)
130 #define IPMI_WDOG_ACT_PRE_DISABLED	__SHIFTIN(0, IPMI_WDOG_ACT_MASK)
131 #define IPMI_WDOG_ACT_PRE_SMI		__SHIFTIN(1, IPMI_WDOG_ACT_MASK)
132 #define IPMI_WDOG_ACT_PRE_NMI		__SHIFTIN(2, IPMI_WDOG_ACT_MASK)
133 #define IPMI_WDOG_ACT_PRE_INTERRUPT	__SHIFTIN(3, IPMI_WDOG_ACT_MASK)
134 #define IPMI_WDOG_ACT_PRE_RSVD0		__BIT(3)
135 #define IPMI_WDOG_ACT_MASK		__BITS(2, 0)
136 #define IPMI_WDOG_ACT_DISABLED		__SHIFTIN(0, IPMI_WDOG_ACT_MASK)
137 #define IPMI_WDOG_ACT_RESET		__SHIFTIN(1, IPMI_WDOG_ACT_MASK)
138 #define IPMI_WDOG_ACT_PWROFF		__SHIFTIN(2, IPMI_WDOG_ACT_MASK)
139 #define IPMI_WDOG_ACT_PWRCYCLE		__SHIFTIN(3, IPMI_WDOG_ACT_MASK)
140 
141 #define IPMI_WDOG_FLAGS_RSVD1		__BITS(7, 6)
142 #define IPMI_WDOG_FLAGS_OEM		__BIT(5)
143 #define IPMI_WDOG_FLAGS_OS		__BIT(4)
144 #define IPMI_WDOG_FLAGS_OSLOAD		__BIT(3)
145 #define IPMI_WDOG_FLAGS_POST		__BIT(2)
146 #define IPMI_WDOG_FLAGS_FRB2		__BIT(1)
147 #define IPMI_WDOG_FLAGS_RSVD0		__BIT(0)
148 
149 struct ipmi_set_watchdog {
150 	uint8_t		wdog_use;
151 	uint8_t		wdog_action;
152 	uint8_t		wdog_pretimeout;
153 	uint8_t		wdog_flags;
154 	uint16_t		wdog_timeout;
155 } __packed;
156 
157 struct ipmi_get_watchdog {
158 	uint8_t		wdog_use;
159 	uint8_t		wdog_action;
160 	uint8_t		wdog_pretimeout;
161 	uint8_t		wdog_flags;
162 	uint16_t		wdog_timeout;
163 	uint16_t		wdog_countdown;
164 } __packed;
165 
166 void	ipmi_poll_thread(void *);
167 
168 int	kcs_probe(struct ipmi_softc *);
169 int	kcs_reset(struct ipmi_softc *);
170 int	kcs_sendmsg(struct ipmi_softc *, int, const uint8_t *);
171 int	kcs_recvmsg(struct ipmi_softc *, int, int *len, uint8_t *);
172 
173 int	bt_probe(struct ipmi_softc *);
174 int	bt_reset(struct ipmi_softc *);
175 int	bt_sendmsg(struct ipmi_softc *, int, const uint8_t *);
176 int	bt_recvmsg(struct ipmi_softc *, int, int *, uint8_t *);
177 
178 int	smic_probe(struct ipmi_softc *);
179 int	smic_reset(struct ipmi_softc *);
180 int	smic_sendmsg(struct ipmi_softc *, int, const uint8_t *);
181 int	smic_recvmsg(struct ipmi_softc *, int, int *, uint8_t *);
182 
183 struct dmd_ipmi {
184 	uint8_t	dmd_sig[4];		/* Signature 'IPMI' */
185 	uint8_t	dmd_i2c_address;	/* Address of BMC */
186 	uint8_t	dmd_nvram_address;	/* Address of NVRAM */
187 	uint8_t	dmd_if_type;		/* IPMI Interface Type */
188 	uint8_t	dmd_if_rev;		/* IPMI Interface Revision */
189 } __packed;
190 
191 
192 #define APP_NETFN			0x06
193 #define APP_GET_DEVICE_ID		0x01
194 #define APP_RESET_WATCHDOG		0x22
195 #define APP_SET_WATCHDOG_TIMER		0x24
196 #define APP_GET_WATCHDOG_TIMER		0x25
197 
198 #define TRANSPORT_NETFN			0xC
199 #define BRIDGE_NETFN			0x2
200 
201 #define STORAGE_NETFN			0x0A
202 #define STORAGE_GET_FRU_INV_AREA	0x10
203 #define STORAGE_READ_FRU_DATA		0x11
204 #define STORAGE_RESERVE_SDR		0x22
205 #define STORAGE_GET_SDR			0x23
206 #define STORAGE_ADD_SDR			0x24
207 #define STORAGE_ADD_PARTIAL_SDR		0x25
208 #define STORAGE_DELETE_SDR		0x26
209 #define STORAGE_RESERVE_SEL		0x42
210 #define STORAGE_GET_SEL			0x43
211 #define STORAGE_ADD_SEL			0x44
212 #define STORAGE_ADD_PARTIAL_SEL		0x45
213 #define STORAGE_DELETE_SEL		0x46
214 
215 #define SE_NETFN			0x04
216 #define SE_GET_SDR_INFO			0x20
217 #define SE_GET_SDR			0x21
218 #define SE_RESERVE_SDR			0x22
219 #define SE_GET_SENSOR_FACTOR		0x23
220 #define SE_SET_SENSOR_HYSTERESIS	0x24
221 #define SE_GET_SENSOR_HYSTERESIS	0x25
222 #define SE_SET_SENSOR_THRESHOLD		0x26
223 #define SE_GET_SENSOR_THRESHOLD		0x27
224 #define SE_SET_SENSOR_EVENT_ENABLE	0x28
225 #define SE_GET_SENSOR_EVENT_ENABLE	0x29
226 #define SE_REARM_SENSOR_EVENTS		0x2A
227 #define SE_GET_SENSOR_EVENT_STATUS	0x2B
228 #define SE_GET_SENSOR_READING		0x2D
229 #define SE_SET_SENSOR_TYPE		0x2E
230 #define SE_GET_SENSOR_TYPE		0x2F
231 
232 struct sdrhdr {
233 	uint16_t	record_id;		/* SDR Record ID */
234 	uint8_t	sdr_version;		/* SDR Version */
235 	uint8_t	record_type;		/* SDR Record Type */
236 	uint8_t	record_length;		/* SDR Record Length */
237 } __packed;
238 
239 /* SDR: Record Type 1 */
240 struct sdrtype1 {
241 	struct sdrhdr	sdrhdr;
242 
243 	uint8_t	owner_id;
244 	uint8_t	owner_lun;
245 	uint8_t	sensor_num;
246 
247 	uint8_t	entity_id;
248 	uint8_t	entity_instance;
249 	uint8_t	sensor_init;
250 	uint8_t	sensor_caps;
251 	uint8_t	sensor_type;
252 	uint8_t	event_code;
253 	uint16_t	trigger_mask;
254 	uint16_t	reading_mask;
255 	uint16_t	settable_mask;
256 	uint8_t	units1;
257 	uint8_t	units2;
258 	uint8_t	units3;
259 	uint8_t	linear;
260 	uint8_t	m;
261 	uint8_t	m_tolerance;
262 	uint8_t	b;
263 	uint8_t	b_accuracy;
264 	uint8_t	accuracyexp;
265 	uint8_t	rbexp;
266 	uint8_t	analogchars;
267 	uint8_t	nominalreading;
268 	uint8_t	normalmax;
269 	uint8_t	normalmin;
270 	uint8_t	sensormax;
271 	uint8_t	sensormin;
272 	uint8_t	uppernr;
273 	uint8_t	upperc;
274 	uint8_t	uppernc;
275 	uint8_t	lowernr;
276 	uint8_t	lowerc;
277 	uint8_t	lowernc;
278 	uint8_t	physt;
279 	uint8_t	nhyst;
280 	uint8_t	resvd[2];
281 	uint8_t	oem;
282 	uint8_t	typelen;
283 	uint8_t	name[1];
284 } __packed;
285 
286 /* SDR: Record Type 2 */
287 struct sdrtype2 {
288 	struct sdrhdr	sdrhdr;
289 
290 	uint8_t	owner_id;
291 	uint8_t	owner_lun;
292 	uint8_t	sensor_num;
293 
294 	uint8_t	entity_id;
295 	uint8_t	entity_instance;
296 	uint8_t	sensor_init;
297 	uint8_t	sensor_caps;
298 	uint8_t	sensor_type;
299 	uint8_t	event_code;
300 	uint16_t	trigger_mask;
301 	uint16_t	reading_mask;
302 	uint16_t	set_mask;
303 	uint8_t	units1;
304 	uint8_t	units2;
305 	uint8_t	units3;
306 	uint8_t	share1;
307 	uint8_t	share2;
308 	uint8_t	physt;
309 	uint8_t	nhyst;
310 	uint8_t	resvd[3];
311 	uint8_t	oem;
312 	uint8_t	typelen;
313 	uint8_t	name[1];
314 } __packed;
315 
316 int ipmi_probe(struct ipmi_attach_args *);
317 
318 #endif				/* _IPMIVAR_H_ */
319