summaryrefslogtreecommitdiff
path: root/sys/arch/x86/include/ipmivar.h
blob: 10051edcdb240f714b5dba4d695826b5b173a813 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
/* $NetBSD: ipmivar.h,v 1.11 2010/08/01 08:16:14 mlelstv Exp $ */

/*
 * Copyright (c) 2005 Jordan Hargrave
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#include <sys/mutex.h>
#include <sys/condvar.h>

#include <dev/sysmon/sysmonvar.h>

#ifndef _IPMIVAR_H_
#define _IPMIVAR_H_

#define IPMI_IF_KCS		1
#define IPMI_IF_SMIC		2
#define IPMI_IF_BT		3

#define IPMI_IF_KCS_NREGS	2
#define IPMI_IF_SMIC_NREGS	3
#define IPMI_IF_BT_NREGS	3

struct ipmi_thread;
struct ipmi_softc;

struct ipmi_attach_args {
	bus_space_tag_t	iaa_iot;
	bus_space_tag_t	iaa_memt;

	int		iaa_if_type;
	int		iaa_if_rev;
	int		iaa_if_iotype;
	int		iaa_if_iobase;
	int		iaa_if_iospacing;
	int		iaa_if_irq;
	int		iaa_if_irqlvl;
};

struct ipmi_if {
	const char	*name;
	int		nregs;
	void		*(*buildmsg)(struct ipmi_softc *, int, int, int,
			    const void *, int *);
	int		(*sendmsg)(struct ipmi_softc *, int, const uint8_t *);
	int		(*recvmsg)(struct ipmi_softc *, int, int *, uint8_t *);
	int		(*reset)(struct ipmi_softc *);
	int		(*probe)(struct ipmi_softc *);
};

struct ipmi_softc {
	device_t		sc_dev;

	struct ipmi_if		*sc_if;		/* Interface layer */
	int			sc_if_iospacing; /* Spacing of I/O ports */
	int			sc_if_rev;	/* IPMI Revision */
	struct ipmi_attach_args	sc_ia;

	void			*sc_ih;		/* Interrupt/IO handles */
	bus_space_tag_t		sc_iot;
	bus_space_handle_t	sc_ioh;

	int			sc_btseq;

	struct lwp		*sc_kthread;

	int			sc_max_retries;

	kmutex_t		sc_poll_mtx;
	kcondvar_t		sc_poll_cv;

	kmutex_t		sc_cmd_mtx;
	kmutex_t		sc_sleep_mtx;
	kcondvar_t		sc_cmd_sleep;

	struct ipmi_bmc_args	*sc_iowait_args;

	struct ipmi_sensor	*current_sensor;
	volatile bool		sc_thread_running;
	volatile bool		sc_tickle_due;
	struct sysmon_wdog	sc_wdog;
	struct sysmon_envsys	*sc_envsys;
	envsys_data_t		*sc_sensor;
	int 		sc_nsensors; /* total number of sensors */

	char		sc_buf[64];
	bool		sc_buf_rsvd;
};

struct ipmi_thread {
	struct ipmi_softc   *sc;
	volatile int	    running;
};

#define IPMI_WDOG_USE_NOLOG		__BIT(7)
#define IPMI_WDOG_USE_NOSTOP		__BIT(6)
#define IPMI_WDOG_USE_RSVD1		__BITS(5, 3)
#define IPMI_WDOG_USE_USE_MASK		__BITS(2, 0)
#define IPMI_WDOG_USE_USE_RSVD		__SHIFTIN(0, IPMI_WDOG_USE_USE_MASK);
#define IPMI_WDOG_USE_USE_FRB2		__SHIFTIN(1, IPMI_WDOG_USE_USE_MASK);
#define IPMI_WDOG_USE_USE_POST		__SHIFTIN(2, IPMI_WDOG_USE_USE_MASK);
#define IPMI_WDOG_USE_USE_OSLOAD	__SHIFTIN(3, IPMI_WDOG_USE_USE_MASK);
#define IPMI_WDOG_USE_USE_OS		__SHIFTIN(4, IPMI_WDOG_USE_USE_MASK);
#define IPMI_WDOG_USE_USE_OEM		__SHIFTIN(5, IPMI_WDOG_USE_USE_MASK);

#define IPMI_WDOG_ACT_PRE_RSVD1		__BIT(7)
#define IPMI_WDOG_ACT_PRE_MASK		__BITS(6, 4)
#define IPMI_WDOG_ACT_PRE_DISABLED	__SHIFTIN(0, IPMI_WDOG_ACT_MASK)
#define IPMI_WDOG_ACT_PRE_SMI		__SHIFTIN(1, IPMI_WDOG_ACT_MASK)
#define IPMI_WDOG_ACT_PRE_NMI		__SHIFTIN(2, IPMI_WDOG_ACT_MASK)
#define IPMI_WDOG_ACT_PRE_INTERRUPT	__SHIFTIN(3, IPMI_WDOG_ACT_MASK)
#define IPMI_WDOG_ACT_PRE_RSVD0		__BIT(3)
#define IPMI_WDOG_ACT_MASK		__BITS(2, 0)
#define IPMI_WDOG_ACT_DISABLED		__SHIFTIN(0, IPMI_WDOG_ACT_MASK)
#define IPMI_WDOG_ACT_RESET		__SHIFTIN(1, IPMI_WDOG_ACT_MASK)
#define IPMI_WDOG_ACT_PWROFF		__SHIFTIN(2, IPMI_WDOG_ACT_MASK)
#define IPMI_WDOG_ACT_PWRCYCLE		__SHIFTIN(3, IPMI_WDOG_ACT_MASK)

#define IPMI_WDOG_FLAGS_RSVD1		__BITS(7, 6)
#define IPMI_WDOG_FLAGS_OEM		__BIT(5)
#define IPMI_WDOG_FLAGS_OS		__BIT(4)
#define IPMI_WDOG_FLAGS_OSLOAD		__BIT(3)
#define IPMI_WDOG_FLAGS_POST		__BIT(2)
#define IPMI_WDOG_FLAGS_FRB2		__BIT(1)
#define IPMI_WDOG_FLAGS_RSVD0		__BIT(0)

struct ipmi_set_watchdog {
	uint8_t		wdog_use;
	uint8_t		wdog_action;
	uint8_t		wdog_pretimeout;
	uint8_t		wdog_flags;
	uint16_t		wdog_timeout;
} __packed;

struct ipmi_get_watchdog {
	uint8_t		wdog_use;
	uint8_t		wdog_action;
	uint8_t		wdog_pretimeout;
	uint8_t		wdog_flags;
	uint16_t		wdog_timeout;
	uint16_t		wdog_countdown;
} __packed;

void	ipmi_poll_thread(void *);

int	kcs_probe(struct ipmi_softc *);
int	kcs_reset(struct ipmi_softc *);
int	kcs_sendmsg(struct ipmi_softc *, int, const uint8_t *);
int	kcs_recvmsg(struct ipmi_softc *, int, int *len, uint8_t *);

int	bt_probe(struct ipmi_softc *);
int	bt_reset(struct ipmi_softc *);
int	bt_sendmsg(struct ipmi_softc *, int, const uint8_t *);
int	bt_recvmsg(struct ipmi_softc *, int, int *, uint8_t *);

int	smic_probe(struct ipmi_softc *);
int	smic_reset(struct ipmi_softc *);
int	smic_sendmsg(struct ipmi_softc *, int, const uint8_t *);
int	smic_recvmsg(struct ipmi_softc *, int, int *, uint8_t *);

struct dmd_ipmi {
	uint8_t	dmd_sig[4];		/* Signature 'IPMI' */
	uint8_t	dmd_i2c_address;	/* Address of BMC */
	uint8_t	dmd_nvram_address;	/* Address of NVRAM */
	uint8_t	dmd_if_type;		/* IPMI Interface Type */
	uint8_t	dmd_if_rev;		/* IPMI Interface Revision */
} __packed;


#define APP_NETFN			0x06
#define APP_GET_DEVICE_ID		0x01
#define APP_RESET_WATCHDOG		0x22
#define APP_SET_WATCHDOG_TIMER		0x24
#define APP_GET_WATCHDOG_TIMER		0x25

#define TRANSPORT_NETFN			0xC
#define BRIDGE_NETFN			0x2

#define STORAGE_NETFN			0x0A
#define STORAGE_GET_FRU_INV_AREA	0x10
#define STORAGE_READ_FRU_DATA		0x11
#define STORAGE_RESERVE_SDR		0x22
#define STORAGE_GET_SDR			0x23
#define STORAGE_ADD_SDR			0x24
#define STORAGE_ADD_PARTIAL_SDR		0x25
#define STORAGE_DELETE_SDR		0x26
#define STORAGE_RESERVE_SEL		0x42
#define STORAGE_GET_SEL			0x43
#define STORAGE_ADD_SEL			0x44
#define STORAGE_ADD_PARTIAL_SEL		0x45
#define STORAGE_DELETE_SEL		0x46

#define SE_NETFN			0x04
#define SE_GET_SDR_INFO			0x20
#define SE_GET_SDR			0x21
#define SE_RESERVE_SDR			0x22
#define SE_GET_SENSOR_FACTOR		0x23
#define SE_SET_SENSOR_HYSTERESIS	0x24
#define SE_GET_SENSOR_HYSTERESIS	0x25
#define SE_SET_SENSOR_THRESHOLD		0x26
#define SE_GET_SENSOR_THRESHOLD		0x27
#define SE_SET_SENSOR_EVENT_ENABLE	0x28
#define SE_GET_SENSOR_EVENT_ENABLE	0x29
#define SE_REARM_SENSOR_EVENTS		0x2A
#define SE_GET_SENSOR_EVENT_STATUS	0x2B
#define SE_GET_SENSOR_READING		0x2D
#define SE_SET_SENSOR_TYPE		0x2E
#define SE_GET_SENSOR_TYPE		0x2F

struct sdrhdr {
	uint16_t	record_id;		/* SDR Record ID */
	uint8_t	sdr_version;		/* SDR Version */
	uint8_t	record_type;		/* SDR Record Type */
	uint8_t	record_length;		/* SDR Record Length */
} __packed;

/* SDR: Record Type 1 */
struct sdrtype1 {
	struct sdrhdr	sdrhdr;

	uint8_t	owner_id;
	uint8_t	owner_lun;
	uint8_t	sensor_num;

	uint8_t	entity_id;
	uint8_t	entity_instance;
	uint8_t	sensor_init;
	uint8_t	sensor_caps;
	uint8_t	sensor_type;
	uint8_t	event_code;
	uint16_t	trigger_mask;
	uint16_t	reading_mask;
	uint16_t	settable_mask;
	uint8_t	units1;
	uint8_t	units2;
	uint8_t	units3;
	uint8_t	linear;
	uint8_t	m;
	uint8_t	m_tolerance;
	uint8_t	b;
	uint8_t	b_accuracy;
	uint8_t	accuracyexp;
	uint8_t	rbexp;
	uint8_t	analogchars;
	uint8_t	nominalreading;
	uint8_t	normalmax;
	uint8_t	normalmin;
	uint8_t	sensormax;
	uint8_t	sensormin;
	uint8_t	uppernr;
	uint8_t	upperc;
	uint8_t	uppernc;
	uint8_t	lowernr;
	uint8_t	lowerc;
	uint8_t	lowernc;
	uint8_t	physt;
	uint8_t	nhyst;
	uint8_t	resvd[2];
	uint8_t	oem;
	uint8_t	typelen;
	uint8_t	name[1];
} __packed;

/* SDR: Record Type 2 */
struct sdrtype2 {
	struct sdrhdr	sdrhdr;

	uint8_t	owner_id;
	uint8_t	owner_lun;
	uint8_t	sensor_num;

	uint8_t	entity_id;
	uint8_t	entity_instance;
	uint8_t	sensor_init;
	uint8_t	sensor_caps;
	uint8_t	sensor_type;
	uint8_t	event_code;
	uint16_t	trigger_mask;
	uint16_t	reading_mask;
	uint16_t	set_mask;
	uint8_t	units1;
	uint8_t	units2;
	uint8_t	units3;
	uint8_t	share1;
	uint8_t	share2;
	uint8_t	physt;
	uint8_t	nhyst;
	uint8_t	resvd[3];
	uint8_t	oem;
	uint8_t	typelen;
	uint8_t	name[1];
} __packed;

int ipmi_probe(struct ipmi_attach_args *);

#endif				/* _IPMIVAR_H_ */