master
c 2,699 lines 82.6 KB
Raw
1 /*
2 * IPMI BMC emulation
3 *
4 * Copyright (c) 2015 Corey Minyard, MontaVista Software, LLC
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25 #include "qemu/osdep.h"
26 #include "system/system.h"
27 #include "qemu/timer.h"
28 #include "hw/ipmi/ipmi.h"
29 #include "qemu/error-report.h"
30 #include "qapi/error.h"
31 #include "qemu/module.h"
32 #include "hw/core/loader.h"
33 #include "hw/core/qdev-properties.h"
34 #include "hw/core/qdev-properties-system.h"
35 #include "migration/vmstate.h"
36 #include "net/net.h"
37
38 #define IPMI_NETFN_CHASSIS 0x00
39
40 #define IPMI_CMD_GET_CHASSIS_CAPABILITIES 0x00
41 #define IPMI_CMD_GET_CHASSIS_STATUS 0x01
42 #define IPMI_CMD_CHASSIS_CONTROL 0x02
43 #define IPMI_CMD_GET_SYS_RESTART_CAUSE 0x09
44
45 #define IPMI_NETFN_SENSOR_EVENT 0x04
46
47 #define IPMI_CMD_PLATFORM_EVENT_MSG 0x02
48 #define IPMI_CMD_SET_SENSOR_EVT_ENABLE 0x28
49 #define IPMI_CMD_GET_SENSOR_EVT_ENABLE 0x29
50 #define IPMI_CMD_REARM_SENSOR_EVTS 0x2a
51 #define IPMI_CMD_GET_SENSOR_EVT_STATUS 0x2b
52 #define IPMI_CMD_GET_SENSOR_READING 0x2d
53 #define IPMI_CMD_SET_SENSOR_TYPE 0x2e
54 #define IPMI_CMD_GET_SENSOR_TYPE 0x2f
55 #define IPMI_CMD_SET_SENSOR_READING 0x30
56
57 /* #define IPMI_NETFN_APP 0x06 In ipmi.h */
58
59 #define IPMI_CMD_GET_DEVICE_ID 0x01
60 #define IPMI_CMD_COLD_RESET 0x02
61 #define IPMI_CMD_WARM_RESET 0x03
62 #define IPMI_CMD_SET_ACPI_POWER_STATE 0x06
63 #define IPMI_CMD_GET_ACPI_POWER_STATE 0x07
64 #define IPMI_CMD_GET_DEVICE_GUID 0x08
65 #define IPMI_CMD_RESET_WATCHDOG_TIMER 0x22
66 #define IPMI_CMD_SET_WATCHDOG_TIMER 0x24
67 #define IPMI_CMD_GET_WATCHDOG_TIMER 0x25
68 #define IPMI_CMD_SET_BMC_GLOBAL_ENABLES 0x2e
69 #define IPMI_CMD_GET_BMC_GLOBAL_ENABLES 0x2f
70 #define IPMI_CMD_CLR_MSG_FLAGS 0x30
71 #define IPMI_CMD_GET_MSG_FLAGS 0x31
72 #define IPMI_CMD_GET_MSG 0x33
73 #define IPMI_CMD_SEND_MSG 0x34
74 #define IPMI_CMD_READ_EVT_MSG_BUF 0x35
75 #define IPMI_CMD_GET_CHANNEL_ACCESS 0x41
76 #define IPMI_CMD_GET_CHANNEL_INFO 0x42
77
78 #define IPMI_NETFN_STORAGE 0x0a
79
80 #define IPMI_CMD_GET_SDR_REP_INFO 0x20
81 #define IPMI_CMD_GET_SDR_REP_ALLOC_INFO 0x21
82 #define IPMI_CMD_RESERVE_SDR_REP 0x22
83 #define IPMI_CMD_GET_SDR 0x23
84 #define IPMI_CMD_ADD_SDR 0x24
85 #define IPMI_CMD_PARTIAL_ADD_SDR 0x25
86 #define IPMI_CMD_DELETE_SDR 0x26
87 #define IPMI_CMD_CLEAR_SDR_REP 0x27
88 #define IPMI_CMD_GET_SDR_REP_TIME 0x28
89 #define IPMI_CMD_SET_SDR_REP_TIME 0x29
90 #define IPMI_CMD_ENTER_SDR_REP_UPD_MODE 0x2A
91 #define IPMI_CMD_EXIT_SDR_REP_UPD_MODE 0x2B
92 #define IPMI_CMD_RUN_INIT_AGENT 0x2C
93 #define IPMI_CMD_GET_FRU_AREA_INFO 0x10
94 #define IPMI_CMD_READ_FRU_DATA 0x11
95 #define IPMI_CMD_WRITE_FRU_DATA 0x12
96 #define IPMI_CMD_GET_SEL_INFO 0x40
97 #define IPMI_CMD_GET_SEL_ALLOC_INFO 0x41
98 #define IPMI_CMD_RESERVE_SEL 0x42
99 #define IPMI_CMD_GET_SEL_ENTRY 0x43
100 #define IPMI_CMD_ADD_SEL_ENTRY 0x44
101 #define IPMI_CMD_PARTIAL_ADD_SEL_ENTRY 0x45
102 #define IPMI_CMD_DELETE_SEL_ENTRY 0x46
103 #define IPMI_CMD_CLEAR_SEL 0x47
104 #define IPMI_CMD_GET_SEL_TIME 0x48
105 #define IPMI_CMD_SET_SEL_TIME 0x49
106
107 #define IPMI_NETFN_TRANSPORT 0x0c
108
109 #define IPMI_CMD_SET_LAN_CONFIG 0x01
110 #define IPMI_CMD_GET_LAN_CONFIG 0x02
111
112
113 /* Same as a timespec struct. */
114 struct ipmi_time {
115 long tv_sec;
116 long tv_nsec;
117 };
118
119 #define MAX_SEL_SIZE 128
120
121 typedef struct IPMISel {
122 uint8_t sel[MAX_SEL_SIZE][16];
123 unsigned int next_free;
124 long time_offset;
125 uint16_t reservation;
126 uint8_t last_addition[4];
127 uint8_t last_clear[4];
128 uint8_t overflow;
129 } IPMISel;
130
131 #define MAX_SDR_SIZE 16384
132
133 typedef struct IPMISdr {
134 uint8_t sdr[MAX_SDR_SIZE];
135 unsigned int next_free;
136 uint16_t next_rec_id;
137 uint16_t reservation;
138 uint8_t last_addition[4];
139 uint8_t last_clear[4];
140 uint8_t overflow;
141 } IPMISdr;
142
143 typedef struct IPMIFru {
144 char *filename;
145 unsigned int nentries;
146 uint16_t areasize;
147 uint8_t *data;
148 } IPMIFru;
149
150 typedef struct IPMISensor {
151 uint8_t status;
152 uint8_t reading;
153 uint16_t states_suppt;
154 uint16_t assert_suppt;
155 uint16_t deassert_suppt;
156 uint16_t states;
157 uint16_t assert_states;
158 uint16_t deassert_states;
159 uint16_t assert_enable;
160 uint16_t deassert_enable;
161 uint8_t sensor_type;
162 uint8_t evt_reading_type_code;
163 } IPMISensor;
164 #define IPMI_SENSOR_GET_PRESENT(s) ((s)->status & 0x01)
165 #define IPMI_SENSOR_SET_PRESENT(s, v) ((s)->status = (s->status & ~0x01) | \
166 !!(v))
167 #define IPMI_SENSOR_GET_SCAN_ON(s) ((s)->status & 0x40)
168 #define IPMI_SENSOR_SET_SCAN_ON(s, v) ((s)->status = (s->status & ~0x40) | \
169 ((!!(v)) << 6))
170 #define IPMI_SENSOR_GET_EVENTS_ON(s) ((s)->status & 0x80)
171 #define IPMI_SENSOR_SET_EVENTS_ON(s, v) ((s)->status = (s->status & ~0x80) | \
172 ((!!(v)) << 7))
173 #define IPMI_SENSOR_GET_RET_STATUS(s) ((s)->status & 0xc0)
174 #define IPMI_SENSOR_SET_RET_STATUS(s, v) ((s)->status = (s->status & ~0xc0) | \
175 (v & 0xc0))
176 #define IPMI_SENSOR_IS_DISCRETE(s) ((s)->evt_reading_type_code != 1)
177
178 #define MAX_SENSORS 20
179 #define IPMI_WATCHDOG_SENSOR 0
180
181 #define NBYTES_IP 4
182 #define NBYTES_MAC 6
183
184 typedef struct IPMILan {
185 uint8_t channel;
186 uint8_t ipaddr[NBYTES_IP];
187 uint8_t ipsrc;
188 MACAddr macaddr;
189 uint8_t netmask[NBYTES_IP];
190 uint8_t defgw_ipaddr[NBYTES_IP];
191 MACAddr defgw_macaddr;
192
193 char *arg_ipaddr;
194 char *arg_netmask;
195 char *arg_defgw_ipaddr;
196 } IPMILan;
197
198 #define MAX_NETFNS 64
199
200 typedef struct IPMIRcvBufEntry {
201 QTAILQ_ENTRY(IPMIRcvBufEntry) entry;
202 uint8_t len;
203 uint8_t buf[MAX_IPMI_MSG_SIZE];
204 } IPMIRcvBufEntry;
205
206 struct IPMIBmcSim {
207 IPMIBmc parent;
208
209 QEMUTimer *timer;
210
211 uint8_t bmc_global_enables;
212 uint8_t msg_flags;
213
214 bool watchdog_initialized;
215 uint8_t watchdog_use;
216 uint8_t watchdog_action;
217 uint8_t watchdog_pretimeout; /* In seconds */
218 uint8_t watchdog_expired;
219 uint16_t watchdog_timeout; /* in 100's of milliseconds */
220
221 bool watchdog_running;
222 bool watchdog_preaction_ran;
223 int64_t watchdog_expiry;
224
225 uint8_t device_id;
226 uint8_t ipmi_version;
227 uint8_t device_rev;
228 uint8_t fwrev1;
229 uint8_t fwrev2;
230 uint32_t mfg_id;
231 uint16_t product_id;
232
233 uint8_t restart_cause;
234
235 uint8_t acpi_power_state[2];
236 QemuUUID uuid;
237
238 IPMISel sel;
239 IPMISdr sdr;
240 IPMIFru fru;
241 IPMISensor sensors[MAX_SENSORS];
242 char *sdr_filename;
243 IPMILan lan;
244
245 /* Odd netfns are for responses, so we only need the even ones. */
246 const IPMINetfn *netfns[MAX_NETFNS / 2];
247
248 /* We allow one event in the buffer */
249 uint8_t evtbuf[16];
250
251 QTAILQ_HEAD(, IPMIRcvBufEntry) rcvbufs;
252 };
253
254 #define IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK (1 << 3)
255 #define IPMI_BMC_MSG_FLAG_EVT_BUF_FULL (1 << 1)
256 #define IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE (1 << 0)
257 #define IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(s) \
258 (IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK & (s)->msg_flags)
259 #define IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(s) \
260 (IPMI_BMC_MSG_FLAG_EVT_BUF_FULL & (s)->msg_flags)
261 #define IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(s) \
262 (IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE & (s)->msg_flags)
263
264 #define IPMI_BMC_GLOBAL_ENABLES_SUPPORTED 0x0f
265 #define IPMI_BMC_RCV_MSG_QUEUE_INT_BIT 0
266 #define IPMI_BMC_EVBUF_FULL_INT_BIT 1
267 #define IPMI_BMC_EVENT_MSG_BUF_BIT 2
268 #define IPMI_BMC_EVENT_LOG_BIT 3
269 #define IPMI_BMC_MSG_INTS_ON(s) ((s)->bmc_global_enables & \
270 (1 << IPMI_BMC_RCV_MSG_QUEUE_INT_BIT))
271 #define IPMI_BMC_EVBUF_FULL_INT_ENABLED(s) ((s)->bmc_global_enables & \
272 (1 << IPMI_BMC_EVBUF_FULL_INT_BIT))
273 #define IPMI_BMC_EVENT_LOG_ENABLED(s) ((s)->bmc_global_enables & \
274 (1 << IPMI_BMC_EVENT_LOG_BIT))
275 #define IPMI_BMC_EVENT_MSG_BUF_ENABLED(s) ((s)->bmc_global_enables & \
276 (1 << IPMI_BMC_EVENT_MSG_BUF_BIT))
277
278 #define IPMI_BMC_WATCHDOG_USE_MASK 0xc7
279 #define IPMI_BMC_WATCHDOG_ACTION_MASK 0x77
280 #define IPMI_BMC_WATCHDOG_GET_USE(s) ((s)->watchdog_use & 0x7)
281 #define IPMI_BMC_WATCHDOG_GET_DONT_LOG(s) (((s)->watchdog_use >> 7) & 0x1)
282 #define IPMI_BMC_WATCHDOG_GET_DONT_STOP(s) (((s)->watchdog_use >> 6) & 0x1)
283 #define IPMI_BMC_WATCHDOG_GET_PRE_ACTION(s) (((s)->watchdog_action >> 4) & 0x7)
284 #define IPMI_BMC_WATCHDOG_PRE_NONE 0
285 #define IPMI_BMC_WATCHDOG_PRE_SMI 1
286 #define IPMI_BMC_WATCHDOG_PRE_NMI 2
287 #define IPMI_BMC_WATCHDOG_PRE_MSG_INT 3
288 #define IPMI_BMC_WATCHDOG_GET_ACTION(s) ((s)->watchdog_action & 0x7)
289 #define IPMI_BMC_WATCHDOG_ACTION_NONE 0
290 #define IPMI_BMC_WATCHDOG_ACTION_RESET 1
291 #define IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN 2
292 #define IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE 3
293
294 #define IPMI_CHANNEL_IMPLEMENTATION_MIN 0x1
295 #define IPMI_CHANNEL_IMPLEMENTATION_MAX 0xb
296 #define IPMI_CHANNEL_IS_IMPLEMENTATION_SPECIFIC(c) \
297 (IPMI_CHANNEL_IMPLEMENTATION_MIN <= (c) && \
298 (c) <= IPMI_CHANNEL_IMPLEMENTATION_MAX)
299
300 #define IPMI_BMC_CHANNEL_IS_LAN(ibs, c) \
301 ((ibs)->lan.channel != 0 && (ibs)->lan.channel == (c))
302
303 #define IPMI_BMC_LAN_CFG_CC_PARAM_NOT_SUPPORTED 0x80
304 #define IPMI_BMC_LAN_CFG_CC_PARAM_READONLY 0x82
305
306 #define IPMI_BMC_LAN_CFG_PARAM_SET_IN_PROGRESS 0x00
307 #define IPMI_BMC_LAN_CFG_PARAM_AUTH_TYPE_SUPPORT 0x01
308 #define IPMI_BMC_LAN_CFG_PARAM_AUTH_TYPE_ENABLES 0x02
309 #define IPMI_BMC_LAN_CFG_PARAM_IP_ADDR 0x03
310 #define IPMI_BMC_LAN_CFG_PARAM_IP_ADDR_SOURCE 0x04
311 #define IPMI_BMC_LAN_CFG_PARAM_MAC_ADDR 0x05
312 #define IPMI_BMC_LAN_CFG_PARAM_SUBNET_MASK 0x06
313 #define IPMI_BMC_LAN_CFG_PARAM_IPV4_HDR_PARAMS 0x07
314 #define IPMI_BMC_LAN_CFG_PARAM_DEFAULT_GW_IP_ADDR 0x0c
315 #define IPMI_BMC_LAN_CFG_PARAM_DEFAULT_GW_MAC_ADDR 0x0d
316 #define IPMI_BMC_LAN_CFG_PARAM_BACKUP_GW_ADDR 0x0e
317 #define IPMI_BMC_LAN_CFG_PARAM_BACKUP_GW_MAC_ADDR 0x0f
318 #define IPMI_BMC_LAN_CFG_PARAM_COMMUNITY_STRING 0x10
319 #define IPMI_BMC_LAN_CFG_PARAM_NUM_DESTINATIONS 0x11
320
321 #define IPMI_BMC_LAN_CFG_PARAMETER_REVISION 0x11
322
323 #define IPMI_BMC_LAN_CFG_IS_VALID_IP_SOURCE(v) (0x0 <= (v) && (v) <= 0x4)
324
325 #define RSP_BUFFER_INITIALIZER { }
326
327 static inline void rsp_buffer_pushmore(RspBuffer *rsp, uint8_t *bytes,
328 unsigned int n)
329 {
330 if (rsp->len + n >= sizeof(rsp->buffer)) {
331 rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
332 return;
333 }
334
335 memcpy(&rsp->buffer[rsp->len], bytes, n);
336 rsp->len += n;
337 }
338
339 static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs);
340
341 static void ipmi_gettime(struct ipmi_time *time)
342 {
343 int64_t stime;
344
345 stime = qemu_clock_get_ns(QEMU_CLOCK_HOST);
346 time->tv_sec = stime / 1000000000LL;
347 time->tv_nsec = stime % 1000000000LL;
348 }
349
350 static int64_t ipmi_getmonotime(void)
351 {
352 return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
353 }
354
355 static void ipmi_timeout(void *opaque)
356 {
357 IPMIBmcSim *ibs = opaque;
358
359 ipmi_sim_handle_timeout(ibs);
360 }
361
362 static void set_timestamp(IPMIBmcSim *ibs, uint8_t *ts)
363 {
364 unsigned int val;
365 struct ipmi_time now;
366
367 ipmi_gettime(&now);
368 val = now.tv_sec + ibs->sel.time_offset;
369 ts[0] = val & 0xff;
370 ts[1] = (val >> 8) & 0xff;
371 ts[2] = (val >> 16) & 0xff;
372 ts[3] = (val >> 24) & 0xff;
373 }
374
375 static void sdr_inc_reservation(IPMISdr *sdr)
376 {
377 sdr->reservation++;
378 if (sdr->reservation == 0) {
379 sdr->reservation = 1;
380 }
381 }
382
383 static int sdr_add_entry(IPMIBmcSim *ibs,
384 const struct ipmi_sdr_header *sdrh_entry,
385 unsigned int len, uint16_t *recid)
386 {
387 struct ipmi_sdr_header *sdrh =
388 (struct ipmi_sdr_header *) &ibs->sdr.sdr[ibs->sdr.next_free];
389
390 if ((len < IPMI_SDR_HEADER_SIZE) || (len > 255)) {
391 return 1;
392 }
393
394 if (ipmi_sdr_length(sdrh_entry) != len) {
395 return 1;
396 }
397
398 if (ibs->sdr.next_free + len > MAX_SDR_SIZE) {
399 ibs->sdr.overflow = 1;
400 return 1;
401 }
402
403 memcpy(sdrh, sdrh_entry, len);
404 sdrh->rec_id[0] = ibs->sdr.next_rec_id & 0xff;
405 sdrh->rec_id[1] = (ibs->sdr.next_rec_id >> 8) & 0xff;
406 sdrh->sdr_version = 0x51; /* Conform to IPMI 1.5 spec */
407
408 if (recid) {
409 *recid = ibs->sdr.next_rec_id;
410 }
411 ibs->sdr.next_rec_id++;
412 set_timestamp(ibs, ibs->sdr.last_addition);
413 ibs->sdr.next_free += len;
414 sdr_inc_reservation(&ibs->sdr);
415 return 0;
416 }
417
418 static int sdr_find_entry(IPMISdr *sdr, uint16_t recid,
419 unsigned int *retpos, uint16_t *nextrec)
420 {
421 unsigned int pos = *retpos;
422
423 while (pos < sdr->next_free) {
424 struct ipmi_sdr_header *sdrh =
425 (struct ipmi_sdr_header *) &sdr->sdr[pos];
426 uint16_t trec = ipmi_sdr_recid(sdrh);
427 unsigned int nextpos = pos + ipmi_sdr_length(sdrh);
428
429 if (trec == recid) {
430 if (nextrec) {
431 if (nextpos >= sdr->next_free) {
432 *nextrec = 0xffff;
433 } else {
434 *nextrec = (sdr->sdr[nextpos] |
435 (sdr->sdr[nextpos + 1] << 8));
436 }
437 }
438 *retpos = pos;
439 return 0;
440 }
441 pos = nextpos;
442 }
443 return 1;
444 }
445
446 int ipmi_bmc_sdr_find(IPMIBmc *b, uint16_t recid,
447 const struct ipmi_sdr_compact **sdr, uint16_t *nextrec)
448
449 {
450 IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
451 unsigned int pos;
452
453 pos = 0;
454 if (sdr_find_entry(&ibs->sdr, recid, &pos, nextrec)) {
455 return -1;
456 }
457
458 *sdr = (const struct ipmi_sdr_compact *) &ibs->sdr.sdr[pos];
459 return 0;
460 }
461
462 static void sel_inc_reservation(IPMISel *sel)
463 {
464 sel->reservation++;
465 if (sel->reservation == 0) {
466 sel->reservation = 1;
467 }
468 }
469
470 /* Returns 1 if the SEL is full and can't hold the event. */
471 static int sel_add_event(IPMIBmcSim *ibs, uint8_t *event)
472 {
473 uint8_t ts[4];
474
475 event[0] = 0xff;
476 event[1] = 0xff;
477 set_timestamp(ibs, ts);
478 if (event[2] < 0xe0) { /* Don't set timestamps for type 0xe0-0xff. */
479 memcpy(event + 3, ts, 4);
480 }
481 if (ibs->sel.next_free == MAX_SEL_SIZE) {
482 ibs->sel.overflow = 1;
483 return 1;
484 }
485 event[0] = ibs->sel.next_free & 0xff;
486 event[1] = (ibs->sel.next_free >> 8) & 0xff;
487 memcpy(ibs->sel.last_addition, ts, 4);
488 memcpy(ibs->sel.sel[ibs->sel.next_free], event, 16);
489 ibs->sel.next_free++;
490 sel_inc_reservation(&ibs->sel);
491 return 0;
492 }
493
494 static int attn_set(IPMIBmcSim *ibs)
495 {
496 return IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(ibs)
497 || IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs)
498 || IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(ibs);
499 }
500
501 static int attn_irq_enabled(IPMIBmcSim *ibs)
502 {
503 return (IPMI_BMC_MSG_INTS_ON(ibs) &&
504 (IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(ibs) ||
505 IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(ibs)))
506 || (IPMI_BMC_EVBUF_FULL_INT_ENABLED(ibs) &&
507 IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs));
508 }
509
510 void ipmi_bmc_gen_event(IPMIBmc *b, uint8_t *evt, bool log)
511 {
512 IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
513 IPMIInterface *s = ibs->parent.intf;
514 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
515
516 if (!IPMI_BMC_EVENT_MSG_BUF_ENABLED(ibs)) {
517 return;
518 }
519
520 if (log && IPMI_BMC_EVENT_LOG_ENABLED(ibs)) {
521 sel_add_event(ibs, evt);
522 }
523
524 if (ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL) {
525 return;
526 }
527
528 memcpy(ibs->evtbuf, evt, 16);
529 ibs->msg_flags |= IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
530 k->set_atn(s, 1, attn_irq_enabled(ibs));
531 }
532 static void gen_event(IPMIBmcSim *ibs, unsigned int sens_num, uint8_t deassert,
533 uint8_t evd1, uint8_t evd2, uint8_t evd3)
534 {
535 IPMIInterface *s = ibs->parent.intf;
536 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
537 uint8_t evt[16];
538 IPMISensor *sens = ibs->sensors + sens_num;
539
540 if (!IPMI_BMC_EVENT_MSG_BUF_ENABLED(ibs)) {
541 return;
542 }
543 if (!IPMI_SENSOR_GET_EVENTS_ON(sens)) {
544 return;
545 }
546
547 evt[2] = 0x2; /* System event record */
548 evt[7] = ibs->parent.slave_addr;
549 evt[8] = 0;
550 evt[9] = 0x04; /* Format version */
551 evt[10] = sens->sensor_type;
552 evt[11] = sens_num;
553 evt[12] = sens->evt_reading_type_code | (!!deassert << 7);
554 evt[13] = evd1;
555 evt[14] = evd2;
556 evt[15] = evd3;
557
558 if (IPMI_BMC_EVENT_LOG_ENABLED(ibs)) {
559 sel_add_event(ibs, evt);
560 }
561
562 if (ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL) {
563 return;
564 }
565
566 memcpy(ibs->evtbuf, evt, 16);
567 ibs->msg_flags |= IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
568 k->set_atn(s, 1, attn_irq_enabled(ibs));
569 }
570
571 static void sensor_set_discrete_bit(IPMIBmcSim *ibs, unsigned int sensor,
572 unsigned int bit, unsigned int val,
573 uint8_t evd1, uint8_t evd2, uint8_t evd3,
574 bool do_log)
575 {
576 IPMISensor *sens;
577 uint16_t mask;
578
579 if (sensor >= MAX_SENSORS) {
580 return;
581 }
582 if (bit >= 16) {
583 return;
584 }
585
586 mask = (1 << bit);
587 sens = ibs->sensors + sensor;
588 if (val) {
589 sens->states |= mask & sens->states_suppt;
590 if (sens->assert_states & mask) {
591 return; /* Already asserted */
592 }
593 sens->assert_states |= mask & sens->assert_suppt;
594 if (do_log && (sens->assert_enable & mask & sens->assert_states)) {
595 /* Send an event on assert */
596 gen_event(ibs, sensor, 0, evd1, evd2, evd3);
597 }
598 } else {
599 sens->states &= ~(mask & sens->states_suppt);
600 if (sens->deassert_states & mask) {
601 return; /* Already deasserted */
602 }
603 sens->deassert_states |= mask & sens->deassert_suppt;
604 if (do_log && (sens->deassert_enable & mask & sens->deassert_states)) {
605 /* Send an event on deassert */
606 gen_event(ibs, sensor, 1, evd1, evd2, evd3);
607 }
608 }
609 }
610
611 static void ipmi_init_sensors_from_sdrs(IPMIBmcSim *s)
612 {
613 unsigned int i, pos;
614 IPMISensor *sens;
615
616 for (i = 0; i < MAX_SENSORS; i++) {
617 memset(s->sensors + i, 0, sizeof(*sens));
618 }
619
620 pos = 0;
621 for (i = 0; !sdr_find_entry(&s->sdr, i, &pos, NULL); i++) {
622 struct ipmi_sdr_compact *sdr =
623 (struct ipmi_sdr_compact *) &s->sdr.sdr[pos];
624 unsigned int len = sdr->header.rec_length;
625
626 if (len < 20) {
627 continue;
628 }
629 if (sdr->header.rec_type != IPMI_SDR_COMPACT_TYPE) {
630 continue; /* Not a sensor SDR we set from */
631 }
632
633 if (sdr->sensor_owner_number >= MAX_SENSORS) {
634 continue;
635 }
636 sens = s->sensors + sdr->sensor_owner_number;
637
638 IPMI_SENSOR_SET_PRESENT(sens, 1);
639 IPMI_SENSOR_SET_SCAN_ON(sens, (sdr->sensor_init >> 6) & 1);
640 IPMI_SENSOR_SET_EVENTS_ON(sens, (sdr->sensor_init >> 5) & 1);
641 sens->assert_suppt = sdr->assert_mask[0] | (sdr->assert_mask[1] << 8);
642 sens->deassert_suppt =
643 sdr->deassert_mask[0] | (sdr->deassert_mask[1] << 8);
644 sens->states_suppt =
645 sdr->discrete_mask[0] | (sdr->discrete_mask[1] << 8);
646 sens->sensor_type = sdr->sensor_type;
647 sens->evt_reading_type_code = sdr->reading_type & 0x7f;
648
649 /* Enable all the events that are supported. */
650 sens->assert_enable = sens->assert_suppt;
651 sens->deassert_enable = sens->deassert_suppt;
652 }
653 }
654
655 int ipmi_sim_register_netfn(IPMIBmcSim *s, unsigned int netfn,
656 const IPMINetfn *netfnd)
657 {
658 if ((netfn & 1) || (netfn >= MAX_NETFNS) || (s->netfns[netfn / 2])) {
659 return -1;
660 }
661 s->netfns[netfn / 2] = netfnd;
662 return 0;
663 }
664
665 static const IPMICmdHandler *ipmi_get_handler(IPMIBmcSim *ibs,
666 unsigned int netfn,
667 unsigned int cmd)
668 {
669 const IPMICmdHandler *hdl;
670
671 if (netfn & 1 || netfn >= MAX_NETFNS || !ibs->netfns[netfn / 2]) {
672 return NULL;
673 }
674
675 if (cmd >= ibs->netfns[netfn / 2]->cmd_nums) {
676 return NULL;
677 }
678
679 hdl = &ibs->netfns[netfn / 2]->cmd_handlers[cmd];
680 if (!hdl->cmd_handler) {
681 return NULL;
682 }
683
684 return hdl;
685 }
686
687 static void next_timeout(IPMIBmcSim *ibs)
688 {
689 int64_t next;
690 if (ibs->watchdog_running) {
691 next = ibs->watchdog_expiry;
692 } else {
693 /* Wait a minute */
694 next = ipmi_getmonotime() + 60 * 1000000000LL;
695 }
696 timer_mod_ns(ibs->timer, next);
697 }
698
699 static void ipmi_sim_handle_command(IPMIBmc *b,
700 uint8_t *cmd, unsigned int cmd_len,
701 unsigned int max_cmd_len,
702 uint8_t msg_id)
703 {
704 IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
705 IPMIInterface *s = ibs->parent.intf;
706 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
707 const IPMICmdHandler *hdl;
708 RspBuffer rsp = RSP_BUFFER_INITIALIZER;
709
710 /* Set up the response, set the low bit of NETFN. */
711 /* Note that max_rsp_len must be at least 3 */
712 if (sizeof(rsp.buffer) < 3) {
713 rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
714 goto out;
715 }
716
717 rsp_buffer_push(&rsp, cmd[0] | 0x04);
718 rsp_buffer_push(&rsp, cmd[1]);
719 rsp_buffer_push(&rsp, 0); /* Assume success */
720
721 /* If it's too short or it was truncated, return an error. */
722 if (cmd_len < 2) {
723 rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
724 goto out;
725 }
726 if (cmd_len > max_cmd_len) {
727 rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
728 goto out;
729 }
730
731 if ((cmd[0] & 0x03) != 0) {
732 /* Only have stuff on LUN 0 */
733 rsp_buffer_set_error(&rsp, IPMI_CC_COMMAND_INVALID_FOR_LUN);
734 goto out;
735 }
736
737 hdl = ipmi_get_handler(ibs, cmd[0] >> 2, cmd[1]);
738 if (!hdl) {
739 rsp_buffer_set_error(&rsp, IPMI_CC_INVALID_CMD);
740 goto out;
741 }
742
743 if (cmd_len < hdl->cmd_len_min) {
744 rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
745 goto out;
746 }
747
748 hdl->cmd_handler(ibs, cmd, cmd_len, &rsp);
749
750 out:
751 k->handle_rsp(s, msg_id, rsp.buffer, rsp.len);
752
753 next_timeout(ibs);
754 }
755
756 static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs)
757 {
758 IPMIInterface *s = ibs->parent.intf;
759 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
760 bool do_log = !IPMI_BMC_WATCHDOG_GET_DONT_LOG(ibs);
761
762 if (!ibs->watchdog_running) {
763 goto out;
764 }
765
766 if (!ibs->watchdog_preaction_ran) {
767 switch (IPMI_BMC_WATCHDOG_GET_PRE_ACTION(ibs)) {
768 case IPMI_BMC_WATCHDOG_PRE_NMI:
769 ibs->msg_flags |= IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK;
770 k->do_hw_op(s, IPMI_SEND_NMI, 0);
771 sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 8, 1,
772 0xc8, (2 << 4) | 0xf, 0xff,
773 do_log);
774 break;
775
776 case IPMI_BMC_WATCHDOG_PRE_MSG_INT:
777 ibs->msg_flags |= IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK;
778 k->set_atn(s, 1, attn_irq_enabled(ibs));
779 sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 8, 1,
780 0xc8, (3 << 4) | 0xf, 0xff,
781 do_log);
782 break;
783
784 default:
785 goto do_full_expiry;
786 }
787
788 ibs->watchdog_preaction_ran = 1;
789 /* Issued the pretimeout, do the rest of the timeout now. */
790 ibs->watchdog_expiry = ipmi_getmonotime();
791 ibs->watchdog_expiry += ibs->watchdog_pretimeout * 1000000000LL;
792 goto out;
793 }
794
795 do_full_expiry:
796 ibs->watchdog_running = 0; /* Stop the watchdog on a timeout */
797 ibs->watchdog_expired |= (1 << IPMI_BMC_WATCHDOG_GET_USE(ibs));
798 switch (IPMI_BMC_WATCHDOG_GET_ACTION(ibs)) {
799 case IPMI_BMC_WATCHDOG_ACTION_NONE:
800 sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 0, 1,
801 0xc0, ibs->watchdog_use & 0xf, 0xff,
802 do_log);
803 break;
804
805 case IPMI_BMC_WATCHDOG_ACTION_RESET:
806 sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 1, 1,
807 0xc1, ibs->watchdog_use & 0xf, 0xff,
808 do_log);
809 k->do_hw_op(s, IPMI_RESET_CHASSIS, 0);
810 break;
811
812 case IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN:
813 sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 2, 1,
814 0xc2, ibs->watchdog_use & 0xf, 0xff,
815 do_log);
816 k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 0);
817 break;
818
819 case IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE:
820 sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 2, 1,
821 0xc3, ibs->watchdog_use & 0xf, 0xff,
822 do_log);
823 k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 0);
824 break;
825 }
826
827 out:
828 next_timeout(ibs);
829 }
830
831 static void chassis_capabilities(IPMIBmcSim *ibs,
832 uint8_t *cmd, unsigned int cmd_len,
833 RspBuffer *rsp)
834 {
835 rsp_buffer_push(rsp, 0);
836 rsp_buffer_push(rsp, ibs->parent.slave_addr);
837 rsp_buffer_push(rsp, ibs->parent.slave_addr);
838 rsp_buffer_push(rsp, ibs->parent.slave_addr);
839 rsp_buffer_push(rsp, ibs->parent.slave_addr);
840 }
841
842 static void chassis_status(IPMIBmcSim *ibs,
843 uint8_t *cmd, unsigned int cmd_len,
844 RspBuffer *rsp)
845 {
846 rsp_buffer_push(rsp, 0x61); /* Unknown power restore, power is on */
847 rsp_buffer_push(rsp, 0);
848 rsp_buffer_push(rsp, 0);
849 rsp_buffer_push(rsp, 0);
850 }
851
852 static void chassis_control(IPMIBmcSim *ibs,
853 uint8_t *cmd, unsigned int cmd_len,
854 RspBuffer *rsp)
855 {
856 IPMIInterface *s = ibs->parent.intf;
857 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
858
859 switch (cmd[2] & 0xf) {
860 case 0: /* power down */
861 rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 0));
862 break;
863 case 1: /* power up */
864 rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWERON_CHASSIS, 0));
865 break;
866 case 2: /* power cycle */
867 rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 0));
868 break;
869 case 3: /* hard reset */
870 rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_RESET_CHASSIS, 0));
871 break;
872 case 4: /* pulse diagnostic interrupt */
873 rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_PULSE_DIAG_IRQ, 0));
874 break;
875 case 5: /* soft shutdown via ACPI by overtemp emulation */
876 rsp_buffer_set_error(rsp, k->do_hw_op(s,
877 IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP, 0));
878 break;
879 default:
880 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
881 return;
882 }
883 }
884
885 static void chassis_get_sys_restart_cause(IPMIBmcSim *ibs,
886 uint8_t *cmd, unsigned int cmd_len,
887 RspBuffer *rsp)
888
889 {
890 rsp_buffer_push(rsp, ibs->restart_cause & 0xf); /* Restart Cause */
891 rsp_buffer_push(rsp, 0); /* Channel 0 */
892 }
893
894 static void get_device_id(IPMIBmcSim *ibs,
895 uint8_t *cmd, unsigned int cmd_len,
896 RspBuffer *rsp)
897 {
898 rsp_buffer_push(rsp, ibs->device_id);
899 rsp_buffer_push(rsp, ibs->device_rev & 0xf);
900 rsp_buffer_push(rsp, ibs->fwrev1 & 0x7f);
901 rsp_buffer_push(rsp, ibs->fwrev2);
902 rsp_buffer_push(rsp, ibs->ipmi_version);
903 rsp_buffer_push(rsp, 0x07); /* sensor, SDR, and SEL. */
904 rsp_buffer_push(rsp, ibs->mfg_id & 0xff);
905 rsp_buffer_push(rsp, (ibs->mfg_id >> 8) & 0xff);
906 rsp_buffer_push(rsp, (ibs->mfg_id >> 16) & 0xff);
907 rsp_buffer_push(rsp, ibs->product_id & 0xff);
908 rsp_buffer_push(rsp, (ibs->product_id >> 8) & 0xff);
909 }
910
911 static void set_global_enables(IPMIBmcSim *ibs, uint8_t val)
912 {
913 IPMIInterface *s = ibs->parent.intf;
914 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
915 bool irqs_on;
916
917 ibs->bmc_global_enables = val;
918
919 irqs_on = val & (IPMI_BMC_EVBUF_FULL_INT_BIT |
920 IPMI_BMC_RCV_MSG_QUEUE_INT_BIT);
921
922 k->set_irq_enable(s, irqs_on);
923 }
924
925 static void cold_reset(IPMIBmcSim *ibs,
926 uint8_t *cmd, unsigned int cmd_len,
927 RspBuffer *rsp)
928 {
929 IPMIInterface *s = ibs->parent.intf;
930 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
931
932 /* Disable all interrupts */
933 set_global_enables(ibs, 1 << IPMI_BMC_EVENT_LOG_BIT);
934
935 if (k->reset) {
936 k->reset(s, true);
937 }
938 }
939
940 static void warm_reset(IPMIBmcSim *ibs,
941 uint8_t *cmd, unsigned int cmd_len,
942 RspBuffer *rsp)
943 {
944 IPMIInterface *s = ibs->parent.intf;
945 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
946
947 if (k->reset) {
948 k->reset(s, false);
949 }
950 }
951 static void set_acpi_power_state(IPMIBmcSim *ibs,
952 uint8_t *cmd, unsigned int cmd_len,
953 RspBuffer *rsp)
954 {
955 ibs->acpi_power_state[0] = cmd[2];
956 ibs->acpi_power_state[1] = cmd[3];
957 }
958
959 static void get_acpi_power_state(IPMIBmcSim *ibs,
960 uint8_t *cmd, unsigned int cmd_len,
961 RspBuffer *rsp)
962 {
963 rsp_buffer_push(rsp, ibs->acpi_power_state[0]);
964 rsp_buffer_push(rsp, ibs->acpi_power_state[1]);
965 }
966
967 static void get_device_guid(IPMIBmcSim *ibs,
968 uint8_t *cmd, unsigned int cmd_len,
969 RspBuffer *rsp)
970 {
971 unsigned int i;
972
973 /* An uninitialized uuid is all zeros, use that to know if it is set. */
974 for (i = 0; i < 16; i++) {
975 if (ibs->uuid.data[i]) {
976 goto uuid_set;
977 }
978 }
979 /* No uuid is set, return an error. */
980 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_CMD);
981 return;
982
983 uuid_set:
984 for (i = 0; i < 16; i++) {
985 rsp_buffer_push(rsp, ibs->uuid.data[i]);
986 }
987 }
988
989 static void set_bmc_global_enables(IPMIBmcSim *ibs,
990 uint8_t *cmd, unsigned int cmd_len,
991 RspBuffer *rsp)
992 {
993 uint8_t val = cmd[2];
994
995 if (val & ~IPMI_BMC_GLOBAL_ENABLES_SUPPORTED) {
996 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
997 return;
998 }
999
1000 set_global_enables(ibs, val);
1001 }
1002
1003 static void get_bmc_global_enables(IPMIBmcSim *ibs,
1004 uint8_t *cmd, unsigned int cmd_len,
1005 RspBuffer *rsp)
1006 {
1007 rsp_buffer_push(rsp, ibs->bmc_global_enables);
1008 }
1009
1010 static void clr_msg_flags(IPMIBmcSim *ibs,
1011 uint8_t *cmd, unsigned int cmd_len,
1012 RspBuffer *rsp)
1013 {
1014 IPMIInterface *s = ibs->parent.intf;
1015 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
1016
1017 ibs->msg_flags &= ~cmd[2];
1018 k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
1019 }
1020
1021 static void get_msg_flags(IPMIBmcSim *ibs,
1022 uint8_t *cmd, unsigned int cmd_len,
1023 RspBuffer *rsp)
1024 {
1025 rsp_buffer_push(rsp, ibs->msg_flags);
1026 }
1027
1028 static void read_evt_msg_buf(IPMIBmcSim *ibs,
1029 uint8_t *cmd, unsigned int cmd_len,
1030 RspBuffer *rsp)
1031 {
1032 IPMIInterface *s = ibs->parent.intf;
1033 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
1034 unsigned int i;
1035
1036 if (!(ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL)) {
1037 rsp_buffer_set_error(rsp, 0x80);
1038 return;
1039 }
1040 for (i = 0; i < 16; i++) {
1041 rsp_buffer_push(rsp, ibs->evtbuf[i]);
1042 }
1043 ibs->msg_flags &= ~IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
1044 k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
1045 }
1046
1047 static void get_msg(IPMIBmcSim *ibs,
1048 uint8_t *cmd, unsigned int cmd_len,
1049 RspBuffer *rsp)
1050 {
1051 IPMIRcvBufEntry *msg;
1052
1053 if (QTAILQ_EMPTY(&ibs->rcvbufs)) {
1054 rsp_buffer_set_error(rsp, 0x80); /* Queue empty */
1055 return;
1056 }
1057 rsp_buffer_push(rsp, 0); /* Channel 0 */
1058 msg = QTAILQ_FIRST(&ibs->rcvbufs);
1059 rsp_buffer_pushmore(rsp, msg->buf, msg->len);
1060 QTAILQ_REMOVE(&ibs->rcvbufs, msg, entry);
1061 g_free(msg);
1062
1063 if (QTAILQ_EMPTY(&ibs->rcvbufs)) {
1064 IPMIInterface *s = ibs->parent.intf;
1065 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
1066
1067 ibs->msg_flags &= ~IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;
1068 k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
1069 }
1070 }
1071
1072 static unsigned char
1073 ipmb_checksum(unsigned char *data, int size, unsigned char csum)
1074 {
1075 for (; size > 0; size--, data++) {
1076 csum += *data;
1077 }
1078
1079 return -csum;
1080 }
1081
1082 static void send_msg(IPMIBmcSim *ibs,
1083 uint8_t *cmd, unsigned int cmd_len,
1084 RspBuffer *rsp)
1085 {
1086 IPMIInterface *s = ibs->parent.intf;
1087 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
1088 IPMIRcvBufEntry *msg;
1089 uint8_t *buf;
1090 uint8_t netfn, rqLun, rsLun, rqSeq;
1091
1092 if (cmd[2] != IPMI_CHANNEL_IPMB) {
1093 /* We only handle channel 0h (IPMB) with no options */
1094 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1095 return;
1096 }
1097
1098 if (cmd_len < 10) {
1099 rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
1100 return;
1101 }
1102
1103 if (cmd[3] != 0x40) {
1104 /* We only emulate a MC at address 0x40. */
1105 rsp_buffer_set_error(rsp, 0x83); /* NAK on write */
1106 return;
1107 }
1108
1109 cmd += 3; /* Skip the header. */
1110 cmd_len -= 3;
1111
1112 /*
1113 * At this point we "send" the message successfully. Any error will
1114 * be returned in the response.
1115 */
1116 if (ipmb_checksum(cmd, cmd_len, 0) != 0 ||
1117 cmd[3] != 0x20) { /* Improper response address */
1118 return; /* No response */
1119 }
1120
1121 netfn = cmd[1] >> 2;
1122 rqLun = cmd[4] & 0x3;
1123 rsLun = cmd[1] & 0x3;
1124 rqSeq = cmd[4] >> 2;
1125
1126 if (rqLun != 2) {
1127 /* We only support LUN 2 coming back to us. */
1128 return;
1129 }
1130
1131 msg = g_malloc(sizeof(*msg));
1132 msg->buf[0] = ((netfn | 1) << 2) | rqLun; /* NetFN, and make a response */
1133 msg->buf[1] = ipmb_checksum(msg->buf, 1, 0);
1134 msg->buf[2] = cmd[0]; /* rsSA */
1135 msg->buf[3] = (rqSeq << 2) | rsLun;
1136 msg->buf[4] = cmd[5]; /* Cmd */
1137 msg->buf[5] = 0; /* Completion Code */
1138 msg->len = 6;
1139
1140 if ((cmd[1] >> 2) != IPMI_NETFN_APP || cmd[5] != IPMI_CMD_GET_DEVICE_ID) {
1141 /* Not a command we handle. */
1142 msg->buf[5] = IPMI_CC_INVALID_CMD;
1143 goto end_msg;
1144 }
1145
1146 buf = msg->buf + msg->len; /* After the CC */
1147 buf[0] = 0;
1148 buf[1] = 0;
1149 buf[2] = 0;
1150 buf[3] = 0;
1151 buf[4] = 0x51;
1152 buf[5] = 0;
1153 buf[6] = 0;
1154 buf[7] = 0;
1155 buf[8] = 0;
1156 buf[9] = 0;
1157 buf[10] = 0;
1158 msg->len += 11;
1159
1160 end_msg:
1161 msg->buf[msg->len] = ipmb_checksum(msg->buf, msg->len, 0);
1162 msg->len++;
1163 QTAILQ_INSERT_TAIL(&ibs->rcvbufs, msg, entry);
1164 ibs->msg_flags |= IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;
1165 k->set_atn(s, 1, attn_irq_enabled(ibs));
1166 }
1167
1168 static void do_watchdog_reset(IPMIBmcSim *ibs)
1169 {
1170 if (IPMI_BMC_WATCHDOG_GET_ACTION(ibs) ==
1171 IPMI_BMC_WATCHDOG_ACTION_NONE) {
1172 ibs->watchdog_running = 0;
1173 return;
1174 }
1175 ibs->watchdog_preaction_ran = 0;
1176
1177
1178 /* Timeout is in tenths of a second, offset is in seconds */
1179 ibs->watchdog_expiry = ipmi_getmonotime();
1180 ibs->watchdog_expiry += ibs->watchdog_timeout * 100000000LL;
1181 if (IPMI_BMC_WATCHDOG_GET_PRE_ACTION(ibs) != IPMI_BMC_WATCHDOG_PRE_NONE) {
1182 ibs->watchdog_expiry -= ibs->watchdog_pretimeout * 1000000000LL;
1183 }
1184 ibs->watchdog_running = 1;
1185 }
1186
1187 static void reset_watchdog_timer(IPMIBmcSim *ibs,
1188 uint8_t *cmd, unsigned int cmd_len,
1189 RspBuffer *rsp)
1190 {
1191 if (!ibs->watchdog_initialized) {
1192 rsp_buffer_set_error(rsp, 0x80);
1193 return;
1194 }
1195 do_watchdog_reset(ibs);
1196 }
1197
1198 static void set_watchdog_timer(IPMIBmcSim *ibs,
1199 uint8_t *cmd, unsigned int cmd_len,
1200 RspBuffer *rsp)
1201 {
1202 IPMIInterface *s = ibs->parent.intf;
1203 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
1204 unsigned int val;
1205
1206 val = cmd[2] & 0x7; /* Validate use */
1207 if (val == 0 || val > 5) {
1208 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1209 return;
1210 }
1211 val = cmd[3] & 0x7; /* Validate action */
1212 switch (val) {
1213 case IPMI_BMC_WATCHDOG_ACTION_NONE:
1214 break;
1215
1216 case IPMI_BMC_WATCHDOG_ACTION_RESET:
1217 rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_RESET_CHASSIS, 1));
1218 break;
1219
1220 case IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN:
1221 rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 1));
1222 break;
1223
1224 case IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE:
1225 rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 1));
1226 break;
1227
1228 default:
1229 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1230 }
1231 if (rsp->buffer[2]) {
1232 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1233 return;
1234 }
1235
1236 val = (cmd[3] >> 4) & 0x7; /* Validate preaction */
1237 switch (val) {
1238 case IPMI_BMC_WATCHDOG_PRE_MSG_INT:
1239 case IPMI_BMC_WATCHDOG_PRE_NONE:
1240 break;
1241
1242 case IPMI_BMC_WATCHDOG_PRE_NMI:
1243 if (k->do_hw_op(s, IPMI_SEND_NMI, 1)) {
1244 /* NMI not supported. */
1245 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1246 return;
1247 }
1248 break;
1249
1250 default:
1251 /* We don't support PRE_SMI */
1252 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1253 return;
1254 }
1255
1256 ibs->watchdog_initialized = 1;
1257 ibs->watchdog_use = cmd[2] & IPMI_BMC_WATCHDOG_USE_MASK;
1258 ibs->watchdog_action = cmd[3] & IPMI_BMC_WATCHDOG_ACTION_MASK;
1259 ibs->watchdog_pretimeout = cmd[4];
1260 ibs->watchdog_expired &= ~cmd[5];
1261 ibs->watchdog_timeout = cmd[6] | (((uint16_t) cmd[7]) << 8);
1262 if (ibs->watchdog_running & IPMI_BMC_WATCHDOG_GET_DONT_STOP(ibs)) {
1263 do_watchdog_reset(ibs);
1264 } else {
1265 ibs->watchdog_running = 0;
1266 }
1267 }
1268
1269 static void get_watchdog_timer(IPMIBmcSim *ibs,
1270 uint8_t *cmd, unsigned int cmd_len,
1271 RspBuffer *rsp)
1272 {
1273 rsp_buffer_push(rsp, ibs->watchdog_use);
1274 rsp_buffer_push(rsp, ibs->watchdog_action);
1275 rsp_buffer_push(rsp, ibs->watchdog_pretimeout);
1276 rsp_buffer_push(rsp, ibs->watchdog_expired);
1277 rsp_buffer_push(rsp, ibs->watchdog_timeout & 0xff);
1278 rsp_buffer_push(rsp, (ibs->watchdog_timeout >> 8) & 0xff);
1279 if (ibs->watchdog_running) {
1280 long timeout;
1281 timeout = ((ibs->watchdog_expiry - ipmi_getmonotime() + 50000000)
1282 / 100000000);
1283 rsp_buffer_push(rsp, timeout & 0xff);
1284 rsp_buffer_push(rsp, (timeout >> 8) & 0xff);
1285 } else {
1286 rsp_buffer_push(rsp, 0);
1287 rsp_buffer_push(rsp, 0);
1288 }
1289 }
1290
1291 static void get_channel_access(IPMIBmcSim *ibs,
1292 uint8_t *cmd, unsigned int cmd_len,
1293 RspBuffer *rsp)
1294 {
1295 uint8_t channel = cmd[2] & 0xf;
1296
1297 if (channel == IPMI_CHANNEL_IPMB || channel == IPMI_CHANNEL_SYSTEM ||
1298 IPMI_BMC_CHANNEL_IS_LAN(ibs, channel)) {
1299 /* alerting disabled */
1300 /* per message authentication disabled */
1301 /* user level authentication disabled */
1302 /* channel always available */
1303 rsp_buffer_push(rsp, 0x20 | 0x10 | 0x08 | 0x02);
1304 rsp_buffer_push(rsp, 0x04); /* privilege limit: ADMINISTRATOR */
1305 } else {
1306 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1307 }
1308 }
1309
1310 static void get_channel_info(IPMIBmcSim *ibs,
1311 uint8_t *cmd, unsigned int cmd_len,
1312 RspBuffer *rsp)
1313 {
1314 IPMIInterface *s = ibs->parent.intf;
1315 IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
1316 IPMIFwInfo info = {};
1317 uint8_t ch = cmd[2] & 0x0f;
1318
1319 if (ch == 0x0e) { /* "This channel" */
1320 ch = IPMI_CHANNEL_SYSTEM;
1321 }
1322 rsp_buffer_push(rsp, ch);
1323
1324 if (k->get_fwinfo) {
1325 k->get_fwinfo(s, &info);
1326 }
1327
1328 /* Only define channel 0h (IPMB), LAN, and Fh (system interface) */
1329 if (ch == IPMI_CHANNEL_IPMB) {
1330 rsp_buffer_push(rsp, IPMI_CHANNEL_MEDIUM_IPMB);
1331 rsp_buffer_push(rsp, IPMI_CHANNEL_PROTOCOL_IPMB);
1332 } else if (IPMI_BMC_CHANNEL_IS_LAN(ibs, ch)) {
1333 rsp_buffer_push(rsp, IPMI_CHANNEL_MEDIUM_802_3_LAN);
1334 rsp_buffer_push(rsp, IPMI_CHANNEL_PROTOCOL_IPMB);
1335 } else if (ch == IPMI_CHANNEL_SYSTEM) {
1336 rsp_buffer_push(rsp, IPMI_CHANNEL_MEDIUM_SYSTEM);
1337 rsp_buffer_push(rsp, info.ipmi_channel_protocol);
1338 } else {
1339 /* Not a supported channel */
1340 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1341 return;
1342 }
1343
1344 rsp_buffer_push(rsp, 0x00); /* Session-less */
1345
1346 /* IPMI Enterprise Number for Vendor ID */
1347 rsp_buffer_push(rsp, 0xf2);
1348 rsp_buffer_push(rsp, 0x1b);
1349 rsp_buffer_push(rsp, 0x00);
1350
1351 if (ch == IPMI_CHANNEL_SYSTEM) {
1352 uint8_t irq;
1353
1354 if (info.irq_source == IPMI_ISA_IRQ) {
1355 irq = info.interrupt_number;
1356 } else if (info.irq_source == IPMI_PCI_IRQ) {
1357 irq = 0x10 + info.interrupt_number;
1358 } else {
1359 irq = 0xff; /* no interrupt / unspecified */
1360 }
1361
1362 /* Both interrupts use the same irq number */
1363 rsp_buffer_push(rsp, irq);
1364 rsp_buffer_push(rsp, irq);
1365 } else {
1366 /* Reserved */
1367 rsp_buffer_push(rsp, 0x00);
1368 rsp_buffer_push(rsp, 0x00);
1369 }
1370 }
1371
1372 static void get_sdr_rep_info(IPMIBmcSim *ibs,
1373 uint8_t *cmd, unsigned int cmd_len,
1374 RspBuffer *rsp)
1375 {
1376 unsigned int i;
1377
1378 rsp_buffer_push(rsp, 0x51); /* Conform to IPMI 1.5 spec */
1379 rsp_buffer_push(rsp, ibs->sdr.next_rec_id & 0xff);
1380 rsp_buffer_push(rsp, (ibs->sdr.next_rec_id >> 8) & 0xff);
1381 rsp_buffer_push(rsp, (MAX_SDR_SIZE - ibs->sdr.next_free) & 0xff);
1382 rsp_buffer_push(rsp, ((MAX_SDR_SIZE - ibs->sdr.next_free) >> 8) & 0xff);
1383 for (i = 0; i < 4; i++) {
1384 rsp_buffer_push(rsp, ibs->sdr.last_addition[i]);
1385 }
1386 for (i = 0; i < 4; i++) {
1387 rsp_buffer_push(rsp, ibs->sdr.last_clear[i]);
1388 }
1389 /* Only modal support, reserve supported */
1390 rsp_buffer_push(rsp, (ibs->sdr.overflow << 7) | 0x22);
1391 }
1392
1393 static void reserve_sdr_rep(IPMIBmcSim *ibs,
1394 uint8_t *cmd, unsigned int cmd_len,
1395 RspBuffer *rsp)
1396 {
1397 rsp_buffer_push(rsp, ibs->sdr.reservation & 0xff);
1398 rsp_buffer_push(rsp, (ibs->sdr.reservation >> 8) & 0xff);
1399 }
1400
1401 static void get_sdr(IPMIBmcSim *ibs,
1402 uint8_t *cmd, unsigned int cmd_len,
1403 RspBuffer *rsp)
1404 {
1405 unsigned int pos;
1406 uint16_t nextrec;
1407 struct ipmi_sdr_header *sdrh;
1408
1409 if (cmd[6]) {
1410 if ((cmd[2] | (cmd[3] << 8)) != ibs->sdr.reservation) {
1411 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
1412 return;
1413 }
1414 }
1415
1416 pos = 0;
1417 if (sdr_find_entry(&ibs->sdr, cmd[4] | (cmd[5] << 8),
1418 &pos, &nextrec)) {
1419 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1420 return;
1421 }
1422
1423 sdrh = (struct ipmi_sdr_header *) &ibs->sdr.sdr[pos];
1424
1425 if (cmd[6] > ipmi_sdr_length(sdrh)) {
1426 rsp_buffer_set_error(rsp, IPMI_CC_PARM_OUT_OF_RANGE);
1427 return;
1428 }
1429
1430 rsp_buffer_push(rsp, nextrec & 0xff);
1431 rsp_buffer_push(rsp, (nextrec >> 8) & 0xff);
1432
1433 if (cmd[7] == 0xff) {
1434 cmd[7] = ipmi_sdr_length(sdrh) - cmd[6];
1435 }
1436
1437 if ((cmd[7] + rsp->len) > sizeof(rsp->buffer)) {
1438 rsp_buffer_set_error(rsp, IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES);
1439 return;
1440 }
1441
1442 rsp_buffer_pushmore(rsp, ibs->sdr.sdr + pos + cmd[6], cmd[7]);
1443 }
1444
1445 static void add_sdr(IPMIBmcSim *ibs,
1446 uint8_t *cmd, unsigned int cmd_len,
1447 RspBuffer *rsp)
1448 {
1449 uint16_t recid;
1450 struct ipmi_sdr_header *sdrh = (struct ipmi_sdr_header *) cmd + 2;
1451
1452 if (sdr_add_entry(ibs, sdrh, cmd_len - 2, &recid)) {
1453 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1454 return;
1455 }
1456 rsp_buffer_push(rsp, recid & 0xff);
1457 rsp_buffer_push(rsp, (recid >> 8) & 0xff);
1458 }
1459
1460 static void clear_sdr_rep(IPMIBmcSim *ibs,
1461 uint8_t *cmd, unsigned int cmd_len,
1462 RspBuffer *rsp)
1463 {
1464 if ((cmd[2] | (cmd[3] << 8)) != ibs->sdr.reservation) {
1465 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
1466 return;
1467 }
1468
1469 if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
1470 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1471 return;
1472 }
1473 if (cmd[7] == 0xaa) {
1474 ibs->sdr.next_free = 0;
1475 ibs->sdr.overflow = 0;
1476 set_timestamp(ibs, ibs->sdr.last_clear);
1477 rsp_buffer_push(rsp, 1); /* Erasure complete */
1478 sdr_inc_reservation(&ibs->sdr);
1479 } else if (cmd[7] == 0) {
1480 rsp_buffer_push(rsp, 1); /* Erasure complete */
1481 } else {
1482 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1483 return;
1484 }
1485 }
1486
1487 static void get_sel_info(IPMIBmcSim *ibs,
1488 uint8_t *cmd, unsigned int cmd_len,
1489 RspBuffer *rsp)
1490 {
1491 unsigned int i, val;
1492
1493 rsp_buffer_push(rsp, 0x51); /* Conform to IPMI 1.5 */
1494 rsp_buffer_push(rsp, ibs->sel.next_free & 0xff);
1495 rsp_buffer_push(rsp, (ibs->sel.next_free >> 8) & 0xff);
1496 val = (MAX_SEL_SIZE - ibs->sel.next_free) * 16;
1497 rsp_buffer_push(rsp, val & 0xff);
1498 rsp_buffer_push(rsp, (val >> 8) & 0xff);
1499 for (i = 0; i < 4; i++) {
1500 rsp_buffer_push(rsp, ibs->sel.last_addition[i]);
1501 }
1502 for (i = 0; i < 4; i++) {
1503 rsp_buffer_push(rsp, ibs->sel.last_clear[i]);
1504 }
1505 /* Only support Reserve SEL */
1506 rsp_buffer_push(rsp, (ibs->sel.overflow << 7) | 0x02);
1507 }
1508
1509 static void get_fru_area_info(IPMIBmcSim *ibs,
1510 uint8_t *cmd, unsigned int cmd_len,
1511 RspBuffer *rsp)
1512 {
1513 uint8_t fruid;
1514 uint16_t fru_entry_size;
1515
1516 fruid = cmd[2];
1517
1518 if (fruid >= ibs->fru.nentries) {
1519 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1520 return;
1521 }
1522
1523 fru_entry_size = ibs->fru.areasize;
1524
1525 rsp_buffer_push(rsp, fru_entry_size & 0xff);
1526 rsp_buffer_push(rsp, fru_entry_size >> 8 & 0xff);
1527 rsp_buffer_push(rsp, 0x0);
1528 }
1529
1530 static void read_fru_data(IPMIBmcSim *ibs,
1531 uint8_t *cmd, unsigned int cmd_len,
1532 RspBuffer *rsp)
1533 {
1534 uint8_t fruid;
1535 uint16_t offset;
1536 int i;
1537 uint8_t *fru_entry;
1538 unsigned int count;
1539
1540 fruid = cmd[2];
1541 offset = (cmd[3] | cmd[4] << 8);
1542
1543 if (fruid >= ibs->fru.nentries) {
1544 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1545 return;
1546 }
1547
1548 if (offset >= ibs->fru.areasize - 1) {
1549 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1550 return;
1551 }
1552
1553 fru_entry = &ibs->fru.data[fruid * ibs->fru.areasize];
1554
1555 count = MIN(cmd[5], ibs->fru.areasize - offset);
1556
1557 rsp_buffer_push(rsp, count & 0xff);
1558 for (i = 0; i < count; i++) {
1559 rsp_buffer_push(rsp, fru_entry[offset + i]);
1560 }
1561 }
1562
1563 static void write_fru_data(IPMIBmcSim *ibs,
1564 uint8_t *cmd, unsigned int cmd_len,
1565 RspBuffer *rsp)
1566 {
1567 uint8_t fruid;
1568 uint16_t offset;
1569 uint8_t *fru_entry;
1570 unsigned int count;
1571
1572 fruid = cmd[2];
1573 offset = (cmd[3] | cmd[4] << 8);
1574
1575 if (fruid >= ibs->fru.nentries) {
1576 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1577 return;
1578 }
1579
1580 if (offset >= ibs->fru.areasize - 1) {
1581 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1582 return;
1583 }
1584
1585 fru_entry = &ibs->fru.data[fruid * ibs->fru.areasize];
1586
1587 count = MIN(cmd_len - 5, ibs->fru.areasize - offset);
1588
1589 memcpy(fru_entry + offset, cmd + 5, count);
1590
1591 rsp_buffer_push(rsp, count & 0xff);
1592 }
1593
1594 static void reserve_sel(IPMIBmcSim *ibs,
1595 uint8_t *cmd, unsigned int cmd_len,
1596 RspBuffer *rsp)
1597 {
1598 rsp_buffer_push(rsp, ibs->sel.reservation & 0xff);
1599 rsp_buffer_push(rsp, (ibs->sel.reservation >> 8) & 0xff);
1600 }
1601
1602 static void get_sel_entry(IPMIBmcSim *ibs,
1603 uint8_t *cmd, unsigned int cmd_len,
1604 RspBuffer *rsp)
1605 {
1606 unsigned int val;
1607
1608 if (cmd[6]) {
1609 if ((cmd[2] | (cmd[3] << 8)) != ibs->sel.reservation) {
1610 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
1611 return;
1612 }
1613 }
1614 if (ibs->sel.next_free == 0) {
1615 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1616 return;
1617 }
1618 if (cmd[6] > 15) {
1619 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1620 return;
1621 }
1622 if (cmd[7] == 0xff) {
1623 cmd[7] = 16;
1624 } else if ((cmd[7] + cmd[6]) > 16) {
1625 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1626 return;
1627 } else {
1628 cmd[7] += cmd[6];
1629 }
1630
1631 val = cmd[4] | (cmd[5] << 8);
1632 if (val == 0xffff) {
1633 val = ibs->sel.next_free - 1;
1634 } else if (val >= ibs->sel.next_free) {
1635 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1636 return;
1637 }
1638 if ((val + 1) == ibs->sel.next_free) {
1639 rsp_buffer_push(rsp, 0xff);
1640 rsp_buffer_push(rsp, 0xff);
1641 } else {
1642 rsp_buffer_push(rsp, (val + 1) & 0xff);
1643 rsp_buffer_push(rsp, ((val + 1) >> 8) & 0xff);
1644 }
1645 for (; cmd[6] < cmd[7]; cmd[6]++) {
1646 rsp_buffer_push(rsp, ibs->sel.sel[val][cmd[6]]);
1647 }
1648 }
1649
1650 static void add_sel_entry(IPMIBmcSim *ibs,
1651 uint8_t *cmd, unsigned int cmd_len,
1652 RspBuffer *rsp)
1653 {
1654 if (sel_add_event(ibs, cmd + 2)) {
1655 rsp_buffer_set_error(rsp, IPMI_CC_OUT_OF_SPACE);
1656 return;
1657 }
1658 /* sel_add_event fills in the record number. */
1659 rsp_buffer_push(rsp, cmd[2]);
1660 rsp_buffer_push(rsp, cmd[3]);
1661 }
1662
1663 static void clear_sel(IPMIBmcSim *ibs,
1664 uint8_t *cmd, unsigned int cmd_len,
1665 RspBuffer *rsp)
1666 {
1667 if ((cmd[2] | (cmd[3] << 8)) != ibs->sel.reservation) {
1668 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
1669 return;
1670 }
1671
1672 if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
1673 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1674 return;
1675 }
1676 if (cmd[7] == 0xaa) {
1677 ibs->sel.next_free = 0;
1678 ibs->sel.overflow = 0;
1679 set_timestamp(ibs, ibs->sdr.last_clear);
1680 rsp_buffer_push(rsp, 1); /* Erasure complete */
1681 sel_inc_reservation(&ibs->sel);
1682 } else if (cmd[7] == 0) {
1683 rsp_buffer_push(rsp, 1); /* Erasure complete */
1684 } else {
1685 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1686 return;
1687 }
1688 }
1689
1690 static void get_sel_time(IPMIBmcSim *ibs,
1691 uint8_t *cmd, unsigned int cmd_len,
1692 RspBuffer *rsp)
1693 {
1694 uint32_t val;
1695 struct ipmi_time now;
1696
1697 ipmi_gettime(&now);
1698 val = now.tv_sec + ibs->sel.time_offset;
1699 rsp_buffer_push(rsp, val & 0xff);
1700 rsp_buffer_push(rsp, (val >> 8) & 0xff);
1701 rsp_buffer_push(rsp, (val >> 16) & 0xff);
1702 rsp_buffer_push(rsp, (val >> 24) & 0xff);
1703 }
1704
1705 static void set_sel_time(IPMIBmcSim *ibs,
1706 uint8_t *cmd, unsigned int cmd_len,
1707 RspBuffer *rsp)
1708 {
1709 uint32_t val;
1710 struct ipmi_time now;
1711
1712 val = cmd[2] | (cmd[3] << 8) | (cmd[4] << 16) | (cmd[5] << 24);
1713 ipmi_gettime(&now);
1714 ibs->sel.time_offset = now.tv_sec - ((long) val);
1715 }
1716
1717 static void platform_event_msg(IPMIBmcSim *ibs,
1718 uint8_t *cmd, unsigned int cmd_len,
1719 RspBuffer *rsp)
1720 {
1721 uint8_t event[16];
1722
1723 event[2] = 2; /* System event record */
1724 event[7] = cmd[2]; /* Generator ID */
1725 event[8] = 0;
1726 event[9] = cmd[3]; /* EvMRev */
1727 event[10] = cmd[4]; /* Sensor type */
1728 event[11] = cmd[5]; /* Sensor number */
1729 event[12] = cmd[6]; /* Event dir / Event type */
1730 event[13] = cmd[7]; /* Event data 1 */
1731 event[14] = cmd[8]; /* Event data 2 */
1732 event[15] = cmd[9]; /* Event data 3 */
1733
1734 if (sel_add_event(ibs, event)) {
1735 rsp_buffer_set_error(rsp, IPMI_CC_OUT_OF_SPACE);
1736 }
1737 }
1738
1739 static void set_sensor_evt_enable(IPMIBmcSim *ibs,
1740 uint8_t *cmd, unsigned int cmd_len,
1741 RspBuffer *rsp)
1742 {
1743 IPMISensor *sens;
1744
1745 if ((cmd[2] >= MAX_SENSORS) ||
1746 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1747 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1748 return;
1749 }
1750 sens = ibs->sensors + cmd[2];
1751 switch ((cmd[3] >> 4) & 0x3) {
1752 case 0: /* Do not change */
1753 break;
1754 case 1: /* Enable bits */
1755 if (cmd_len > 4) {
1756 sens->assert_enable |= cmd[4];
1757 }
1758 if (cmd_len > 5) {
1759 sens->assert_enable |= cmd[5] << 8;
1760 }
1761 if (cmd_len > 6) {
1762 sens->deassert_enable |= cmd[6];
1763 }
1764 if (cmd_len > 7) {
1765 sens->deassert_enable |= cmd[7] << 8;
1766 }
1767 break;
1768 case 2: /* Disable bits */
1769 if (cmd_len > 4) {
1770 sens->assert_enable &= ~cmd[4];
1771 }
1772 if (cmd_len > 5) {
1773 sens->assert_enable &= ~(cmd[5] << 8);
1774 }
1775 if (cmd_len > 6) {
1776 sens->deassert_enable &= ~cmd[6];
1777 }
1778 if (cmd_len > 7) {
1779 sens->deassert_enable &= ~(cmd[7] << 8);
1780 }
1781 break;
1782 case 3:
1783 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1784 return;
1785 }
1786 IPMI_SENSOR_SET_RET_STATUS(sens, cmd[3]);
1787 }
1788
1789 static void get_sensor_evt_enable(IPMIBmcSim *ibs,
1790 uint8_t *cmd, unsigned int cmd_len,
1791 RspBuffer *rsp)
1792 {
1793 IPMISensor *sens;
1794
1795 if ((cmd[2] >= MAX_SENSORS) ||
1796 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1797 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1798 return;
1799 }
1800 sens = ibs->sensors + cmd[2];
1801 rsp_buffer_push(rsp, IPMI_SENSOR_GET_RET_STATUS(sens));
1802 rsp_buffer_push(rsp, sens->assert_enable & 0xff);
1803 rsp_buffer_push(rsp, (sens->assert_enable >> 8) & 0xff);
1804 rsp_buffer_push(rsp, sens->deassert_enable & 0xff);
1805 rsp_buffer_push(rsp, (sens->deassert_enable >> 8) & 0xff);
1806 }
1807
1808 static void rearm_sensor_evts(IPMIBmcSim *ibs,
1809 uint8_t *cmd, unsigned int cmd_len,
1810 RspBuffer *rsp)
1811 {
1812 IPMISensor *sens;
1813
1814 if ((cmd[2] >= MAX_SENSORS) ||
1815 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1816 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1817 return;
1818 }
1819 sens = ibs->sensors + cmd[2];
1820
1821 if ((cmd[3] & 0x80) == 0) {
1822 /* Just clear everything */
1823 sens->states = 0;
1824 return;
1825 }
1826 }
1827
1828 static void get_sensor_evt_status(IPMIBmcSim *ibs,
1829 uint8_t *cmd, unsigned int cmd_len,
1830 RspBuffer *rsp)
1831 {
1832 IPMISensor *sens;
1833
1834 if ((cmd[2] >= MAX_SENSORS) ||
1835 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1836 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1837 return;
1838 }
1839 sens = ibs->sensors + cmd[2];
1840 rsp_buffer_push(rsp, sens->reading);
1841 rsp_buffer_push(rsp, IPMI_SENSOR_GET_RET_STATUS(sens));
1842 rsp_buffer_push(rsp, sens->assert_states & 0xff);
1843 rsp_buffer_push(rsp, (sens->assert_states >> 8) & 0xff);
1844 rsp_buffer_push(rsp, sens->deassert_states & 0xff);
1845 rsp_buffer_push(rsp, (sens->deassert_states >> 8) & 0xff);
1846 }
1847
1848 static void get_sensor_reading(IPMIBmcSim *ibs,
1849 uint8_t *cmd, unsigned int cmd_len,
1850 RspBuffer *rsp)
1851 {
1852 IPMISensor *sens;
1853
1854 if ((cmd[2] >= MAX_SENSORS) ||
1855 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1856 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1857 return;
1858 }
1859 sens = ibs->sensors + cmd[2];
1860 rsp_buffer_push(rsp, sens->reading);
1861 rsp_buffer_push(rsp, IPMI_SENSOR_GET_RET_STATUS(sens));
1862 rsp_buffer_push(rsp, sens->states & 0xff);
1863 if (IPMI_SENSOR_IS_DISCRETE(sens)) {
1864 rsp_buffer_push(rsp, (sens->states >> 8) & 0xff);
1865 }
1866 }
1867
1868 static void set_sensor_type(IPMIBmcSim *ibs,
1869 uint8_t *cmd, unsigned int cmd_len,
1870 RspBuffer *rsp)
1871 {
1872 IPMISensor *sens;
1873
1874
1875 if ((cmd[2] >= MAX_SENSORS) ||
1876 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1877 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1878 return;
1879 }
1880 sens = ibs->sensors + cmd[2];
1881 sens->sensor_type = cmd[3];
1882 sens->evt_reading_type_code = cmd[4] & 0x7f;
1883 }
1884
1885 static void get_sensor_type(IPMIBmcSim *ibs,
1886 uint8_t *cmd, unsigned int cmd_len,
1887 RspBuffer *rsp)
1888 {
1889 IPMISensor *sens;
1890
1891
1892 if ((cmd[2] >= MAX_SENSORS) ||
1893 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1894 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1895 return;
1896 }
1897 sens = ibs->sensors + cmd[2];
1898 rsp_buffer_push(rsp, sens->sensor_type);
1899 rsp_buffer_push(rsp, sens->evt_reading_type_code);
1900 }
1901
1902 /*
1903 * bytes parameter
1904 * 1 sensor number
1905 * 2 operation (see below for bits meaning)
1906 * 3 sensor reading
1907 * 4:5 assertion states (optional)
1908 * 6:7 deassertion states (optional)
1909 * 8:10 event data 1,2,3 (optional)
1910 */
1911 static void set_sensor_reading(IPMIBmcSim *ibs,
1912 uint8_t *cmd, unsigned int cmd_len,
1913 RspBuffer *rsp)
1914 {
1915 IPMISensor *sens;
1916 uint8_t evd1 = 0;
1917 uint8_t evd2 = 0;
1918 uint8_t evd3 = 0;
1919 uint8_t new_reading = 0;
1920 uint16_t new_assert_states = 0;
1921 uint16_t new_deassert_states = 0;
1922 bool change_reading = false;
1923 bool change_assert = false;
1924 bool change_deassert = false;
1925 enum {
1926 SENSOR_GEN_EVENT_NONE,
1927 SENSOR_GEN_EVENT_DATA,
1928 SENSOR_GEN_EVENT_BMC,
1929 } do_gen_event = SENSOR_GEN_EVENT_NONE;
1930
1931 if ((cmd[2] >= MAX_SENSORS) ||
1932 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1933 rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1934 return;
1935 }
1936
1937 sens = ibs->sensors + cmd[2];
1938
1939 /* [1:0] Sensor Reading operation */
1940 switch ((cmd[3]) & 0x3) {
1941 case 0: /* Do not change */
1942 break;
1943 case 1: /* write given value to sensor reading byte */
1944 new_reading = cmd[4];
1945 if (sens->reading != new_reading) {
1946 change_reading = true;
1947 }
1948 break;
1949 case 2:
1950 case 3:
1951 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1952 return;
1953 }
1954
1955 /* [3:2] Deassertion bits operation */
1956 switch ((cmd[3] >> 2) & 0x3) {
1957 case 0: /* Do not change */
1958 break;
1959 case 1: /* write given value */
1960 if (cmd_len > 7) {
1961 new_deassert_states = cmd[7];
1962 change_deassert = true;
1963 }
1964 if (cmd_len > 8) {
1965 new_deassert_states |= (cmd[8] << 8);
1966 }
1967 break;
1968
1969 case 2: /* mask on */
1970 if (cmd_len > 7) {
1971 new_deassert_states = (sens->deassert_states | cmd[7]);
1972 change_deassert = true;
1973 }
1974 if (cmd_len > 8) {
1975 new_deassert_states |= (sens->deassert_states | (cmd[8] << 8));
1976 }
1977 break;
1978
1979 case 3: /* mask off */
1980 if (cmd_len > 7) {
1981 new_deassert_states = (sens->deassert_states & cmd[7]);
1982 change_deassert = true;
1983 }
1984 if (cmd_len > 8) {
1985 new_deassert_states |= (sens->deassert_states & (cmd[8] << 8));
1986 }
1987 break;
1988 }
1989
1990 if (change_deassert && (new_deassert_states == sens->deassert_states)) {
1991 change_deassert = false;
1992 }
1993
1994 /* [5:4] Assertion bits operation */
1995 switch ((cmd[3] >> 4) & 0x3) {
1996 case 0: /* Do not change */
1997 break;
1998 case 1: /* write given value */
1999 if (cmd_len > 5) {
2000 new_assert_states = cmd[5];
2001 change_assert = true;
2002 }
2003 if (cmd_len > 6) {
2004 new_assert_states |= (cmd[6] << 8);
2005 }
2006 break;
2007
2008 case 2: /* mask on */
2009 if (cmd_len > 5) {
2010 new_assert_states = (sens->assert_states | cmd[5]);
2011 change_assert = true;
2012 }
2013 if (cmd_len > 6) {
2014 new_assert_states |= (sens->assert_states | (cmd[6] << 8));
2015 }
2016 break;
2017
2018 case 3: /* mask off */
2019 if (cmd_len > 5) {
2020 new_assert_states = (sens->assert_states & cmd[5]);
2021 change_assert = true;
2022 }
2023 if (cmd_len > 6) {
2024 new_assert_states |= (sens->assert_states & (cmd[6] << 8));
2025 }
2026 break;
2027 }
2028
2029 if (change_assert && (new_assert_states == sens->assert_states)) {
2030 change_assert = false;
2031 }
2032
2033 if (cmd_len > 9) {
2034 evd1 = cmd[9];
2035 }
2036 if (cmd_len > 10) {
2037 evd2 = cmd[10];
2038 }
2039 if (cmd_len > 11) {
2040 evd3 = cmd[11];
2041 }
2042
2043 /* [7:6] Event Data Bytes operation */
2044 switch ((cmd[3] >> 6) & 0x3) {
2045 case 0: /*
2046 * Don’t use Event Data bytes from this command. BMC will
2047 * generate it's own Event Data bytes based on its sensor
2048 * implementation.
2049 */
2050 evd1 = evd2 = evd3 = 0x0;
2051 do_gen_event = SENSOR_GEN_EVENT_BMC;
2052 break;
2053 case 1: /*
2054 * Write given values to event data bytes including bits
2055 * [3:0] Event Data 1.
2056 */
2057 do_gen_event = SENSOR_GEN_EVENT_DATA;
2058 break;
2059 case 2: /*
2060 * Write given values to event data bytes excluding bits
2061 * [3:0] Event Data 1.
2062 */
2063 evd1 &= 0xf0;
2064 do_gen_event = SENSOR_GEN_EVENT_DATA;
2065 break;
2066 case 3:
2067 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
2068 return;
2069 }
2070
2071 /*
2072 * Event Data Bytes operation and parameter are inconsistent. The
2073 * Specs are not clear on that topic but generating an error seems
2074 * correct.
2075 */
2076 if (do_gen_event == SENSOR_GEN_EVENT_DATA && cmd_len < 10) {
2077 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
2078 return;
2079 }
2080
2081 /* commit values */
2082 if (change_reading) {
2083 sens->reading = new_reading;
2084 }
2085
2086 if (change_assert) {
2087 sens->assert_states = new_assert_states;
2088 }
2089
2090 if (change_deassert) {
2091 sens->deassert_states = new_deassert_states;
2092 }
2093
2094 /* TODO: handle threshold sensor */
2095 if (!IPMI_SENSOR_IS_DISCRETE(sens)) {
2096 return;
2097 }
2098
2099 switch (do_gen_event) {
2100 case SENSOR_GEN_EVENT_DATA: {
2101 unsigned int bit = evd1 & 0xf;
2102 uint16_t mask = (1 << bit);
2103
2104 if (sens->assert_states & mask & sens->assert_enable) {
2105 gen_event(ibs, cmd[2], 0, evd1, evd2, evd3);
2106 }
2107
2108 if (sens->deassert_states & mask & sens->deassert_enable) {
2109 gen_event(ibs, cmd[2], 1, evd1, evd2, evd3);
2110 }
2111 break;
2112 }
2113 case SENSOR_GEN_EVENT_BMC:
2114 /*
2115 * TODO: generate event and event data bytes depending on the
2116 * sensor
2117 */
2118 break;
2119 case SENSOR_GEN_EVENT_NONE:
2120 break;
2121 }
2122 }
2123
2124 static inline bool is_ipv4_netmask_valid(const void *buf)
2125 {
2126 uint32_t netmask = ldl_be_p(buf);
2127
2128 return netmask != 0 && clo32(netmask) + ctz32(netmask) == 32;
2129 }
2130
2131 /*
2132 * Request data (from cmd[2] on):
2133 * bytes meaning
2134 * 1 [bits 3:0] channel number
2135 * 2 parameter selector
2136 * [3:N] configuration parameter data (from cmd[4] on)
2137 */
2138 static void set_lan_config(IPMIBmcSim *ibs,
2139 uint8_t *cmd, unsigned int cmd_len,
2140 RspBuffer *rsp)
2141 {
2142 uint8_t channel;
2143 uint8_t *param; /* pointer to configuration parameter data */
2144 unsigned int param_len;
2145
2146 if (ibs->lan.channel == 0) {
2147 /* LAN channel disabled. Fail as if this command were not defined. */
2148 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_CMD);
2149 return;
2150 }
2151 if (cmd_len < 5) {
2152 rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
2153 return;
2154 }
2155 channel = cmd[2] & 0xf;
2156 param = cmd + 4;
2157 param_len = cmd_len - 4;
2158
2159 if (!IPMI_BMC_CHANNEL_IS_LAN(ibs, channel)) {
2160 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
2161 return;
2162 }
2163
2164 switch (cmd[3]) {
2165 case IPMI_BMC_LAN_CFG_PARAM_IP_ADDR:
2166 if (param_len < NBYTES_IP) {
2167 rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
2168 return;
2169 }
2170 memcpy(ibs->lan.ipaddr, param, NBYTES_IP);
2171 break;
2172
2173 case IPMI_BMC_LAN_CFG_PARAM_IP_ADDR_SOURCE:
2174 if (param_len < 1) {
2175 rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
2176 return;
2177 }
2178 if (!IPMI_BMC_LAN_CFG_IS_VALID_IP_SOURCE(*param)) {
2179 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
2180 return;
2181 }
2182 ibs->lan.ipsrc = *param;
2183 break;
2184
2185 case IPMI_BMC_LAN_CFG_PARAM_MAC_ADDR:
2186 if (param_len < NBYTES_MAC) {
2187 rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
2188 return;
2189 }
2190 memcpy(ibs->lan.macaddr.a, param, NBYTES_MAC);
2191 break;
2192
2193 case IPMI_BMC_LAN_CFG_PARAM_SUBNET_MASK:
2194 if (param_len < NBYTES_IP) {
2195 rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
2196 return;
2197 }
2198 if (!is_ipv4_netmask_valid(param)) {
2199 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
2200 return;
2201 }
2202 memcpy(ibs->lan.netmask, param, NBYTES_IP);
2203 break;
2204
2205 case IPMI_BMC_LAN_CFG_PARAM_DEFAULT_GW_IP_ADDR:
2206 if (param_len < NBYTES_IP) {
2207 rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
2208 return;
2209 }
2210 memcpy(ibs->lan.defgw_ipaddr, param, NBYTES_IP);
2211 break;
2212
2213 case IPMI_BMC_LAN_CFG_PARAM_DEFAULT_GW_MAC_ADDR:
2214 if (param_len < NBYTES_MAC) {
2215 rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
2216 return;
2217 }
2218 memcpy(ibs->lan.defgw_macaddr.a, param, NBYTES_MAC);
2219 break;
2220
2221 case IPMI_BMC_LAN_CFG_PARAM_SET_IN_PROGRESS:
2222 case IPMI_BMC_LAN_CFG_PARAM_AUTH_TYPE_SUPPORT:
2223 case IPMI_BMC_LAN_CFG_PARAM_AUTH_TYPE_ENABLES:
2224 case IPMI_BMC_LAN_CFG_PARAM_IPV4_HDR_PARAMS:
2225 case IPMI_BMC_LAN_CFG_PARAM_BACKUP_GW_ADDR:
2226 case IPMI_BMC_LAN_CFG_PARAM_BACKUP_GW_MAC_ADDR:
2227 case IPMI_BMC_LAN_CFG_PARAM_COMMUNITY_STRING:
2228 case IPMI_BMC_LAN_CFG_PARAM_NUM_DESTINATIONS:
2229 rsp_buffer_set_error(rsp, IPMI_BMC_LAN_CFG_CC_PARAM_READONLY);
2230 return;
2231
2232 default:
2233 rsp_buffer_set_error(rsp, IPMI_BMC_LAN_CFG_CC_PARAM_NOT_SUPPORTED);
2234 return;
2235 }
2236 }
2237
2238 /*
2239 * Request data (from cmd[2] to cmd[5] inclusive):
2240 * bytes meaning
2241 * 1 [bit 7] revision only flag, [bits 3:0] channel number
2242 * 2 parameter selector
2243 * 3 set selector
2244 * 4 block selector
2245 */
2246 static void get_lan_config(IPMIBmcSim *ibs,
2247 uint8_t *cmd, unsigned int cmd_len,
2248 RspBuffer *rsp)
2249 {
2250 uint8_t channel;
2251
2252 if (ibs->lan.channel == 0) {
2253 /* LAN channel disabled. Fail as if this command were not defined. */
2254 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_CMD);
2255 return;
2256 }
2257 if (cmd_len < 6) {
2258 rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
2259 return;
2260 }
2261 channel = cmd[2] & 0xf;
2262
2263 rsp_buffer_push(rsp, IPMI_BMC_LAN_CFG_PARAMETER_REVISION);
2264 if (cmd[2] & 0x80) {
2265 /* The requester only requests parameter revision, not the parameter */
2266 return;
2267 }
2268 if (!IPMI_BMC_CHANNEL_IS_LAN(ibs, channel)) {
2269 rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
2270 return;
2271 }
2272
2273 switch (cmd[3]) {
2274 case IPMI_BMC_LAN_CFG_PARAM_SET_IN_PROGRESS:
2275 rsp_buffer_push(rsp, 0x0); /* set complete */
2276 break;
2277
2278 case IPMI_BMC_LAN_CFG_PARAM_AUTH_TYPE_SUPPORT:
2279 rsp_buffer_push(rsp, 0x01); /* Authentication type "none" supported */
2280 break;
2281
2282 case IPMI_BMC_LAN_CFG_PARAM_AUTH_TYPE_ENABLES:
2283 /* Only authentication type "none" enabled */
2284 rsp_buffer_push(rsp, 0x01); /* for privilege level "Callback" */
2285 rsp_buffer_push(rsp, 0x01); /* for privilege level "User" */
2286 rsp_buffer_push(rsp, 0x01); /* for privilege level "Operator" */
2287 rsp_buffer_push(rsp, 0x01); /* for privilege level "Administrator" */
2288 rsp_buffer_push(rsp, 0x01); /* for privilege level "OEM" */
2289 break;
2290
2291 case IPMI_BMC_LAN_CFG_PARAM_IP_ADDR:
2292 rsp_buffer_pushmore(rsp, ibs->lan.ipaddr, NBYTES_IP);
2293 break;
2294
2295 case IPMI_BMC_LAN_CFG_PARAM_IP_ADDR_SOURCE:
2296 rsp_buffer_push(rsp, ibs->lan.ipsrc);
2297 break;
2298
2299 case IPMI_BMC_LAN_CFG_PARAM_MAC_ADDR:
2300 rsp_buffer_pushmore(rsp, ibs->lan.macaddr.a, NBYTES_MAC);
2301 break;
2302
2303 case IPMI_BMC_LAN_CFG_PARAM_SUBNET_MASK:
2304 rsp_buffer_pushmore(rsp, ibs->lan.netmask, NBYTES_IP);
2305 break;
2306
2307 case IPMI_BMC_LAN_CFG_PARAM_IPV4_HDR_PARAMS:
2308 /* TTL 0x40 */
2309 rsp_buffer_push(rsp, 0x40);
2310 /* don't fragment */
2311 rsp_buffer_push(rsp, 0x40);
2312 /* precedence 0x0, minimize delay */
2313 rsp_buffer_push(rsp, 0x10);
2314 break;
2315
2316 case IPMI_BMC_LAN_CFG_PARAM_DEFAULT_GW_IP_ADDR:
2317 rsp_buffer_pushmore(rsp, ibs->lan.defgw_ipaddr, NBYTES_IP);
2318 break;
2319
2320 case IPMI_BMC_LAN_CFG_PARAM_DEFAULT_GW_MAC_ADDR:
2321 rsp_buffer_pushmore(rsp, ibs->lan.defgw_macaddr.a, NBYTES_MAC);
2322 break;
2323
2324 case IPMI_BMC_LAN_CFG_PARAM_BACKUP_GW_ADDR:
2325 /* 0.0.0.0 */
2326 rsp_buffer_push(rsp, 0x00);
2327 rsp_buffer_push(rsp, 0x00);
2328 rsp_buffer_push(rsp, 0x00);
2329 rsp_buffer_push(rsp, 0x00);
2330 break;
2331
2332 case IPMI_BMC_LAN_CFG_PARAM_BACKUP_GW_MAC_ADDR:
2333 /* 00:00:00:00:00:00 */
2334 rsp_buffer_push(rsp, 0x00);
2335 rsp_buffer_push(rsp, 0x00);
2336 rsp_buffer_push(rsp, 0x00);
2337 rsp_buffer_push(rsp, 0x00);
2338 rsp_buffer_push(rsp, 0x00);
2339 rsp_buffer_push(rsp, 0x00);
2340 break;
2341
2342 case IPMI_BMC_LAN_CFG_PARAM_COMMUNITY_STRING:
2343 {
2344 static uint8_t community_str[18] = "public";
2345
2346 rsp_buffer_pushmore(rsp, community_str, sizeof(community_str));
2347 }
2348 break;
2349
2350 case IPMI_BMC_LAN_CFG_PARAM_NUM_DESTINATIONS:
2351 rsp_buffer_push(rsp, 0x00); /* LAN Alerting not supported */
2352 break;
2353
2354 default:
2355 rsp_buffer_set_error(rsp, IPMI_BMC_LAN_CFG_CC_PARAM_NOT_SUPPORTED);
2356 return;
2357 };
2358 }
2359
2360 static const IPMICmdHandler chassis_cmds[] = {
2361 [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = { chassis_capabilities },
2362 [IPMI_CMD_GET_CHASSIS_STATUS] = { chassis_status },
2363 [IPMI_CMD_CHASSIS_CONTROL] = { chassis_control, 3 },
2364 [IPMI_CMD_GET_SYS_RESTART_CAUSE] = { chassis_get_sys_restart_cause }
2365 };
2366 static const IPMINetfn chassis_netfn = {
2367 .cmd_nums = ARRAY_SIZE(chassis_cmds),
2368 .cmd_handlers = chassis_cmds
2369 };
2370
2371 static const IPMICmdHandler sensor_event_cmds[] = {
2372 [IPMI_CMD_PLATFORM_EVENT_MSG] = { platform_event_msg, 10 },
2373 [IPMI_CMD_SET_SENSOR_EVT_ENABLE] = { set_sensor_evt_enable, 4 },
2374 [IPMI_CMD_GET_SENSOR_EVT_ENABLE] = { get_sensor_evt_enable, 3 },
2375 [IPMI_CMD_REARM_SENSOR_EVTS] = { rearm_sensor_evts, 4 },
2376 [IPMI_CMD_GET_SENSOR_EVT_STATUS] = { get_sensor_evt_status, 3 },
2377 [IPMI_CMD_GET_SENSOR_READING] = { get_sensor_reading, 3 },
2378 [IPMI_CMD_SET_SENSOR_TYPE] = { set_sensor_type, 5 },
2379 [IPMI_CMD_GET_SENSOR_TYPE] = { get_sensor_type, 3 },
2380 [IPMI_CMD_SET_SENSOR_READING] = { set_sensor_reading, 5 },
2381 };
2382 static const IPMINetfn sensor_event_netfn = {
2383 .cmd_nums = ARRAY_SIZE(sensor_event_cmds),
2384 .cmd_handlers = sensor_event_cmds
2385 };
2386
2387 static const IPMICmdHandler app_cmds[] = {
2388 [IPMI_CMD_GET_DEVICE_ID] = { get_device_id },
2389 [IPMI_CMD_COLD_RESET] = { cold_reset },
2390 [IPMI_CMD_WARM_RESET] = { warm_reset },
2391 [IPMI_CMD_SET_ACPI_POWER_STATE] = { set_acpi_power_state, 4 },
2392 [IPMI_CMD_GET_ACPI_POWER_STATE] = { get_acpi_power_state },
2393 [IPMI_CMD_GET_DEVICE_GUID] = { get_device_guid },
2394 [IPMI_CMD_SET_BMC_GLOBAL_ENABLES] = { set_bmc_global_enables, 3 },
2395 [IPMI_CMD_GET_BMC_GLOBAL_ENABLES] = { get_bmc_global_enables },
2396 [IPMI_CMD_CLR_MSG_FLAGS] = { clr_msg_flags, 3 },
2397 [IPMI_CMD_GET_MSG_FLAGS] = { get_msg_flags },
2398 [IPMI_CMD_GET_MSG] = { get_msg },
2399 [IPMI_CMD_SEND_MSG] = { send_msg, 3 },
2400 [IPMI_CMD_READ_EVT_MSG_BUF] = { read_evt_msg_buf },
2401 [IPMI_CMD_RESET_WATCHDOG_TIMER] = { reset_watchdog_timer },
2402 [IPMI_CMD_SET_WATCHDOG_TIMER] = { set_watchdog_timer, 8 },
2403 [IPMI_CMD_GET_WATCHDOG_TIMER] = { get_watchdog_timer },
2404 [IPMI_CMD_GET_CHANNEL_ACCESS] = { get_channel_access, 4 },
2405 [IPMI_CMD_GET_CHANNEL_INFO] = { get_channel_info, 3 },
2406 };
2407 static const IPMINetfn app_netfn = {
2408 .cmd_nums = ARRAY_SIZE(app_cmds),
2409 .cmd_handlers = app_cmds
2410 };
2411
2412 static const IPMICmdHandler storage_cmds[] = {
2413 [IPMI_CMD_GET_FRU_AREA_INFO] = { get_fru_area_info, 3 },
2414 [IPMI_CMD_READ_FRU_DATA] = { read_fru_data, 5 },
2415 [IPMI_CMD_WRITE_FRU_DATA] = { write_fru_data, 5 },
2416 [IPMI_CMD_GET_SDR_REP_INFO] = { get_sdr_rep_info },
2417 [IPMI_CMD_RESERVE_SDR_REP] = { reserve_sdr_rep },
2418 [IPMI_CMD_GET_SDR] = { get_sdr, 8 },
2419 [IPMI_CMD_ADD_SDR] = { add_sdr },
2420 [IPMI_CMD_CLEAR_SDR_REP] = { clear_sdr_rep, 8 },
2421 [IPMI_CMD_GET_SEL_INFO] = { get_sel_info },
2422 [IPMI_CMD_RESERVE_SEL] = { reserve_sel },
2423 [IPMI_CMD_GET_SEL_ENTRY] = { get_sel_entry, 8 },
2424 [IPMI_CMD_ADD_SEL_ENTRY] = { add_sel_entry, 18 },
2425 [IPMI_CMD_CLEAR_SEL] = { clear_sel, 8 },
2426 [IPMI_CMD_GET_SEL_TIME] = { get_sel_time },
2427 [IPMI_CMD_SET_SEL_TIME] = { set_sel_time, 6 },
2428 };
2429
2430 static const IPMINetfn storage_netfn = {
2431 .cmd_nums = ARRAY_SIZE(storage_cmds),
2432 .cmd_handlers = storage_cmds
2433 };
2434
2435 static const IPMICmdHandler transport_cmds[] = {
2436 [IPMI_CMD_SET_LAN_CONFIG] = { set_lan_config },
2437 [IPMI_CMD_GET_LAN_CONFIG] = { get_lan_config },
2438 };
2439 static const IPMINetfn transport_netfn = {
2440 .cmd_nums = ARRAY_SIZE(transport_cmds),
2441 .cmd_handlers = transport_cmds
2442 };
2443
2444
2445 static void register_cmds(IPMIBmcSim *s)
2446 {
2447 ipmi_sim_register_netfn(s, IPMI_NETFN_CHASSIS, &chassis_netfn);
2448 ipmi_sim_register_netfn(s, IPMI_NETFN_SENSOR_EVENT, &sensor_event_netfn);
2449 ipmi_sim_register_netfn(s, IPMI_NETFN_APP, &app_netfn);
2450 ipmi_sim_register_netfn(s, IPMI_NETFN_STORAGE, &storage_netfn);
2451 ipmi_sim_register_netfn(s, IPMI_NETFN_TRANSPORT, &transport_netfn);
2452 }
2453
2454 static uint8_t init_sdrs[] = {
2455 /* Watchdog device */
2456 0x00, 0x00, 0x51, 0x02, 35, 0x20, 0x00, 0x00,
2457 0x23, 0x01, 0x63, 0x00, 0x23, 0x6f, 0x0f, 0x01,
2458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
2460 'W', 'a', 't', 'c', 'h', 'd', 'o', 'g',
2461 };
2462
2463 static void ipmi_sdr_init(IPMIBmcSim *ibs)
2464 {
2465 unsigned int i;
2466 int len;
2467 size_t sdrs_size;
2468 uint8_t *sdrs;
2469
2470 sdrs_size = sizeof(init_sdrs);
2471 sdrs = init_sdrs;
2472 if (ibs->sdr_filename &&
2473 !g_file_get_contents(ibs->sdr_filename, (gchar **) &sdrs, &sdrs_size,
2474 NULL)) {
2475 error_report("failed to load sdr file '%s'", ibs->sdr_filename);
2476 sdrs_size = sizeof(init_sdrs);
2477 sdrs = init_sdrs;
2478 }
2479
2480 for (i = 0; i < sdrs_size; i += len) {
2481 struct ipmi_sdr_header *sdrh;
2482
2483 if (i + IPMI_SDR_HEADER_SIZE > sdrs_size) {
2484 error_report("Problem with recid 0x%4.4x", i);
2485 break;
2486 }
2487 sdrh = (struct ipmi_sdr_header *) &sdrs[i];
2488 len = ipmi_sdr_length(sdrh);
2489 if (i + len > sdrs_size) {
2490 error_report("Problem with recid 0x%4.4x", i);
2491 break;
2492 }
2493 sdr_add_entry(ibs, sdrh, len, NULL);
2494 }
2495
2496 if (sdrs != init_sdrs) {
2497 g_free(sdrs);
2498 }
2499 }
2500
2501 static const VMStateDescription vmstate_ipmi_sim_lan = {
2502 .name = TYPE_IPMI_BMC_SIMULATOR "-lan",
2503 .version_id = 1,
2504 .minimum_version_id = 1,
2505 .fields = (const VMStateField[]) {
2506 VMSTATE_UINT8(channel, IPMILan),
2507 VMSTATE_UINT8_ARRAY(ipaddr, IPMILan, NBYTES_IP),
2508 VMSTATE_UINT8(ipsrc, IPMILan),
2509 VMSTATE_UINT8_ARRAY(macaddr.a, IPMILan, NBYTES_MAC),
2510 VMSTATE_UINT8_ARRAY(netmask, IPMILan, NBYTES_IP),
2511 VMSTATE_UINT8_ARRAY(defgw_ipaddr, IPMILan, NBYTES_IP),
2512 VMSTATE_UINT8_ARRAY(defgw_macaddr.a, IPMILan, NBYTES_MAC),
2513 VMSTATE_END_OF_LIST()
2514 }
2515 };
2516
2517 static const VMStateDescription vmstate_ipmi_sim = {
2518 .name = TYPE_IPMI_BMC_SIMULATOR,
2519 .version_id = 2,
2520 .minimum_version_id = 1,
2521 .fields = (const VMStateField[]) {
2522 VMSTATE_UINT8(bmc_global_enables, IPMIBmcSim),
2523 VMSTATE_UINT8(msg_flags, IPMIBmcSim),
2524 VMSTATE_BOOL(watchdog_initialized, IPMIBmcSim),
2525 VMSTATE_UINT8(watchdog_use, IPMIBmcSim),
2526 VMSTATE_UINT8(watchdog_action, IPMIBmcSim),
2527 VMSTATE_UINT8(watchdog_pretimeout, IPMIBmcSim),
2528 VMSTATE_UINT8(watchdog_expired, IPMIBmcSim),
2529 VMSTATE_UINT16(watchdog_timeout, IPMIBmcSim),
2530 VMSTATE_BOOL(watchdog_running, IPMIBmcSim),
2531 VMSTATE_BOOL(watchdog_preaction_ran, IPMIBmcSim),
2532 VMSTATE_INT64(watchdog_expiry, IPMIBmcSim),
2533 VMSTATE_UINT8_ARRAY(evtbuf, IPMIBmcSim, 16),
2534 VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].status, IPMIBmcSim),
2535 VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].reading, IPMIBmcSim),
2536 VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].states, IPMIBmcSim),
2537 VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_states, IPMIBmcSim),
2538 VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].deassert_states,
2539 IPMIBmcSim),
2540 VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_enable, IPMIBmcSim),
2541 VMSTATE_STRUCT(lan, IPMIBmcSim, 2, vmstate_ipmi_sim_lan, IPMILan),
2542 VMSTATE_END_OF_LIST()
2543 }
2544 };
2545
2546 static void ipmi_fru_init(IPMIFru *fru)
2547 {
2548 int fsize;
2549 int size = 0;
2550
2551 if (!fru->filename) {
2552 goto out;
2553 }
2554
2555 fsize = get_image_size(fru->filename, NULL);
2556 if (fsize > 0) {
2557 size = QEMU_ALIGN_UP(fsize, fru->areasize);
2558 fru->data = g_malloc0(size);
2559 if (load_image_size(fru->filename, fru->data, fsize) != fsize) {
2560 error_report("Could not load file '%s'", fru->filename);
2561 g_free(fru->data);
2562 fru->data = NULL;
2563 }
2564 } else {
2565 error_report("Could not get file size '%s'", fru->filename);
2566 }
2567
2568 out:
2569 if (!fru->data) {
2570 /* give one default FRU */
2571 size = fru->areasize;
2572 fru->data = g_malloc0(size);
2573 }
2574
2575 fru->nentries = size / fru->areasize;
2576 }
2577
2578 static void ipmi_lan_init(IPMILan *lan, Error **errp)
2579 {
2580 struct in_addr ip;
2581
2582 /*
2583 * `lan->channel` can be either 0 (meaning LAN channel disabled) or
2584 * a valid IPMI implementation-specific channel.
2585 */
2586 if (lan->channel != 0 &&
2587 !IPMI_CHANNEL_IS_IMPLEMENTATION_SPECIFIC(lan->channel)) {
2588 error_setg(errp, "invalid LAN channel %d", lan->channel);
2589 return;
2590 }
2591 if (lan->arg_ipaddr) {
2592 if (inet_pton(AF_INET, lan->arg_ipaddr, &ip) != 1) {
2593 error_setg(errp, "invalid ip address '%s'", lan->arg_ipaddr);
2594 return;
2595 }
2596 memcpy(lan->ipaddr, &ip.s_addr, NBYTES_IP);
2597 }
2598 if (!IPMI_BMC_LAN_CFG_IS_VALID_IP_SOURCE(lan->ipsrc)) {
2599 error_setg(errp, "invalid ip source %d", lan->ipsrc);
2600 return;
2601 }
2602 if (lan->arg_netmask) {
2603 if (inet_pton(AF_INET, lan->arg_netmask, &ip) != 1 ||
2604 !is_ipv4_netmask_valid(&ip.s_addr)) {
2605 error_setg(errp, "invalid subnet mask '%s'", lan->arg_netmask);
2606 return;
2607 }
2608 memcpy(lan->netmask, &ip.s_addr, NBYTES_IP);
2609 }
2610 if (lan->arg_defgw_ipaddr) {
2611 if (inet_pton(AF_INET, lan->arg_defgw_ipaddr, &ip) != 1) {
2612 error_setg(errp, "invalid ip address '%s'", lan->arg_defgw_ipaddr);
2613 return;
2614 }
2615 memcpy(lan->defgw_ipaddr, &ip.s_addr, NBYTES_IP);
2616 }
2617 }
2618
2619 static void ipmi_sim_realize(DeviceState *dev, Error **errp)
2620 {
2621 IPMIBmc *b = IPMI_BMC(dev);
2622 unsigned int i;
2623 IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
2624
2625 QTAILQ_INIT(&ibs->rcvbufs);
2626
2627 ibs->bmc_global_enables = (1 << IPMI_BMC_EVENT_LOG_BIT);
2628 ibs->device_id = 0x20;
2629 ibs->ipmi_version = 0x02; /* IPMI 2.0 */
2630 ibs->restart_cause = 0;
2631 for (i = 0; i < 4; i++) {
2632 ibs->sel.last_addition[i] = 0xff;
2633 ibs->sel.last_clear[i] = 0xff;
2634 ibs->sdr.last_addition[i] = 0xff;
2635 ibs->sdr.last_clear[i] = 0xff;
2636 }
2637
2638 ipmi_sdr_init(ibs);
2639
2640 ipmi_fru_init(&ibs->fru);
2641
2642 ibs->acpi_power_state[0] = 0;
2643 ibs->acpi_power_state[1] = 0;
2644
2645 ipmi_init_sensors_from_sdrs(ibs);
2646
2647 ipmi_lan_init(&ibs->lan, errp);
2648
2649 register_cmds(ibs);
2650
2651 ibs->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ipmi_timeout, ibs);
2652 }
2653
2654 static const Property ipmi_sim_properties[] = {
2655 DEFINE_PROP_UINT16("fruareasize", IPMIBmcSim, fru.areasize, 1024),
2656 DEFINE_PROP_STRING("frudatafile", IPMIBmcSim, fru.filename),
2657 DEFINE_PROP_STRING("sdrfile", IPMIBmcSim, sdr_filename),
2658 DEFINE_PROP_UINT8("device_id", IPMIBmcSim, device_id, 0x20),
2659 DEFINE_PROP_UINT8("ipmi_version", IPMIBmcSim, ipmi_version, 0x02),
2660 DEFINE_PROP_UINT8("device_rev", IPMIBmcSim, device_rev, 0),
2661 DEFINE_PROP_UINT8("fwrev1", IPMIBmcSim, fwrev1, 0),
2662 DEFINE_PROP_UINT8("fwrev2", IPMIBmcSim, fwrev2, 0),
2663 DEFINE_PROP_UINT32("mfg_id", IPMIBmcSim, mfg_id, 0),
2664 DEFINE_PROP_UINT16("product_id", IPMIBmcSim, product_id, 0),
2665 DEFINE_PROP_UUID_NODEFAULT("guid", IPMIBmcSim, uuid),
2666 DEFINE_PROP_UINT8("lan.channel", IPMIBmcSim, lan.channel, 0),
2667 DEFINE_PROP_STRING("lan.ipaddr", IPMIBmcSim, lan.arg_ipaddr),
2668 DEFINE_PROP_UINT8("lan.ipsrc", IPMIBmcSim, lan.ipsrc, 0),
2669 DEFINE_PROP_MACADDR("lan.macaddr", IPMIBmcSim, lan.macaddr),
2670 DEFINE_PROP_STRING("lan.netmask", IPMIBmcSim, lan.arg_netmask),
2671 DEFINE_PROP_STRING("lan.defgw_ipaddr", IPMIBmcSim, lan.arg_defgw_ipaddr),
2672 DEFINE_PROP_MACADDR("lan.defgw_macaddr", IPMIBmcSim, lan.defgw_macaddr),
2673 };
2674
2675 static void ipmi_sim_class_init(ObjectClass *oc, const void *data)
2676 {
2677 DeviceClass *dc = DEVICE_CLASS(oc);
2678 IPMIBmcClass *bk = IPMI_BMC_CLASS(oc);
2679
2680 dc->hotpluggable = false;
2681 dc->realize = ipmi_sim_realize;
2682 dc->vmsd = &vmstate_ipmi_sim;
2683 device_class_set_props(dc, ipmi_sim_properties);
2684 bk->handle_command = ipmi_sim_handle_command;
2685 }
2686
2687 static const TypeInfo ipmi_sim_type = {
2688 .name = TYPE_IPMI_BMC_SIMULATOR,
2689 .parent = TYPE_IPMI_BMC,
2690 .instance_size = sizeof(IPMIBmcSim),
2691 .class_init = ipmi_sim_class_init,
2692 };
2693
2694 static void ipmi_sim_register_types(void)
2695 {
2696 type_register_static(&ipmi_sim_type);
2697 }
2698
2699 type_init(ipmi_sim_register_types)