xref: /openbmc/qemu/hw/ipmi/ipmi_bmc_sim.c (revision ad30c0b0)
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 <stdio.h>
26 #include <string.h>
27 #include <stdint.h>
28 #include "qemu/timer.h"
29 #include "hw/ipmi/ipmi.h"
30 #include "qemu/error-report.h"
31 
32 #define IPMI_NETFN_CHASSIS            0x00
33 #define IPMI_NETFN_CHASSIS_MAXCMD         0x03
34 
35 #define IPMI_CMD_GET_CHASSIS_CAPABILITIES 0x00
36 #define IPMI_CMD_GET_CHASSIS_STATUS       0x01
37 #define IPMI_CMD_CHASSIS_CONTROL          0x02
38 
39 #define IPMI_NETFN_SENSOR_EVENT       0x04
40 #define IPMI_NETFN_SENSOR_EVENT_MAXCMD    0x2e
41 
42 #define IPMI_CMD_SET_SENSOR_EVT_ENABLE    0x28
43 #define IPMI_CMD_GET_SENSOR_EVT_ENABLE    0x29
44 #define IPMI_CMD_REARM_SENSOR_EVTS        0x2a
45 #define IPMI_CMD_GET_SENSOR_EVT_STATUS    0x2b
46 #define IPMI_CMD_GET_SENSOR_READING       0x2d
47 
48 /* #define IPMI_NETFN_APP             0x06 In ipmi.h */
49 #define IPMI_NETFN_APP_MAXCMD             0x36
50 
51 #define IPMI_CMD_GET_DEVICE_ID            0x01
52 #define IPMI_CMD_COLD_RESET               0x02
53 #define IPMI_CMD_WARM_RESET               0x03
54 #define IPMI_CMD_RESET_WATCHDOG_TIMER     0x22
55 #define IPMI_CMD_SET_WATCHDOG_TIMER       0x24
56 #define IPMI_CMD_GET_WATCHDOG_TIMER       0x25
57 #define IPMI_CMD_SET_BMC_GLOBAL_ENABLES   0x2e
58 #define IPMI_CMD_GET_BMC_GLOBAL_ENABLES   0x2f
59 #define IPMI_CMD_CLR_MSG_FLAGS            0x30
60 #define IPMI_CMD_GET_MSG_FLAGS            0x31
61 #define IPMI_CMD_GET_MSG                  0x33
62 #define IPMI_CMD_SEND_MSG                 0x34
63 #define IPMI_CMD_READ_EVT_MSG_BUF         0x35
64 
65 #define IPMI_NETFN_STORAGE            0x0a
66 #define IPMI_NETFN_STORAGE_MAXCMD         0x4a
67 
68 #define IPMI_CMD_GET_SDR_REP_INFO         0x20
69 #define IPMI_CMD_GET_SDR_REP_ALLOC_INFO   0x21
70 #define IPMI_CMD_RESERVE_SDR_REP          0x22
71 #define IPMI_CMD_GET_SDR                  0x23
72 #define IPMI_CMD_ADD_SDR                  0x24
73 #define IPMI_CMD_PARTIAL_ADD_SDR          0x25
74 #define IPMI_CMD_DELETE_SDR               0x26
75 #define IPMI_CMD_CLEAR_SDR_REP            0x27
76 #define IPMI_CMD_GET_SDR_REP_TIME         0x28
77 #define IPMI_CMD_SET_SDR_REP_TIME         0x29
78 #define IPMI_CMD_ENTER_SDR_REP_UPD_MODE   0x2A
79 #define IPMI_CMD_EXIT_SDR_REP_UPD_MODE    0x2B
80 #define IPMI_CMD_RUN_INIT_AGENT           0x2C
81 #define IPMI_CMD_GET_SEL_INFO             0x40
82 #define IPMI_CMD_GET_SEL_ALLOC_INFO       0x41
83 #define IPMI_CMD_RESERVE_SEL              0x42
84 #define IPMI_CMD_GET_SEL_ENTRY            0x43
85 #define IPMI_CMD_ADD_SEL_ENTRY            0x44
86 #define IPMI_CMD_PARTIAL_ADD_SEL_ENTRY    0x45
87 #define IPMI_CMD_DELETE_SEL_ENTRY         0x46
88 #define IPMI_CMD_CLEAR_SEL                0x47
89 #define IPMI_CMD_GET_SEL_TIME             0x48
90 #define IPMI_CMD_SET_SEL_TIME             0x49
91 
92 
93 /* Same as a timespec struct. */
94 struct ipmi_time {
95     long tv_sec;
96     long tv_nsec;
97 };
98 
99 #define MAX_SEL_SIZE 128
100 
101 typedef struct IPMISel {
102     uint8_t sel[MAX_SEL_SIZE][16];
103     unsigned int next_free;
104     long time_offset;
105     uint16_t reservation;
106     uint8_t last_addition[4];
107     uint8_t last_clear[4];
108     uint8_t overflow;
109 } IPMISel;
110 
111 #define MAX_SDR_SIZE 16384
112 
113 typedef struct IPMISdr {
114     uint8_t sdr[MAX_SDR_SIZE];
115     unsigned int next_free;
116     uint16_t next_rec_id;
117     uint16_t reservation;
118     uint8_t last_addition[4];
119     uint8_t last_clear[4];
120     uint8_t overflow;
121 } IPMISdr;
122 
123 typedef struct IPMISensor {
124     uint8_t status;
125     uint8_t reading;
126     uint16_t states_suppt;
127     uint16_t assert_suppt;
128     uint16_t deassert_suppt;
129     uint16_t states;
130     uint16_t assert_states;
131     uint16_t deassert_states;
132     uint16_t assert_enable;
133     uint16_t deassert_enable;
134     uint8_t  sensor_type;
135     uint8_t  evt_reading_type_code;
136 } IPMISensor;
137 #define IPMI_SENSOR_GET_PRESENT(s)       ((s)->status & 0x01)
138 #define IPMI_SENSOR_SET_PRESENT(s, v)    ((s)->status = (s->status & ~0x01) | \
139                                              !!(v))
140 #define IPMI_SENSOR_GET_SCAN_ON(s)       ((s)->status & 0x40)
141 #define IPMI_SENSOR_SET_SCAN_ON(s, v)    ((s)->status = (s->status & ~0x40) | \
142                                              ((!!(v)) << 6))
143 #define IPMI_SENSOR_GET_EVENTS_ON(s)     ((s)->status & 0x80)
144 #define IPMI_SENSOR_SET_EVENTS_ON(s, v)  ((s)->status = (s->status & ~0x80) | \
145                                              ((!!(v)) << 7))
146 #define IPMI_SENSOR_GET_RET_STATUS(s)    ((s)->status & 0xc0)
147 #define IPMI_SENSOR_SET_RET_STATUS(s, v) ((s)->status = (s->status & ~0xc0) | \
148                                              (v & 0xc0))
149 #define IPMI_SENSOR_IS_DISCRETE(s) ((s)->evt_reading_type_code != 1)
150 
151 #define MAX_SENSORS 20
152 #define IPMI_WATCHDOG_SENSOR 0
153 
154 typedef struct IPMIBmcSim IPMIBmcSim;
155 
156 #define MAX_NETFNS 64
157 typedef void (*IPMICmdHandler)(IPMIBmcSim *s,
158                                uint8_t *cmd, unsigned int cmd_len,
159                                uint8_t *rsp, unsigned int *rsp_len,
160                                unsigned int max_rsp_len);
161 typedef struct IPMINetfn {
162     unsigned int cmd_nums;
163     const IPMICmdHandler *cmd_handlers;
164 } IPMINetfn;
165 
166 typedef struct IPMIRcvBufEntry {
167     QTAILQ_ENTRY(IPMIRcvBufEntry) entry;
168     uint8_t len;
169     uint8_t buf[MAX_IPMI_MSG_SIZE];
170 } IPMIRcvBufEntry;
171 
172 #define TYPE_IPMI_BMC_SIMULATOR "ipmi-bmc-sim"
173 #define IPMI_BMC_SIMULATOR(obj) OBJECT_CHECK(IPMIBmcSim, (obj), \
174                                         TYPE_IPMI_BMC_SIMULATOR)
175 struct IPMIBmcSim {
176     IPMIBmc parent;
177 
178     QEMUTimer *timer;
179 
180     uint8_t bmc_global_enables;
181     uint8_t msg_flags;
182 
183     bool     watchdog_initialized;
184     uint8_t  watchdog_use;
185     uint8_t  watchdog_action;
186     uint8_t  watchdog_pretimeout; /* In seconds */
187     bool     watchdog_expired;
188     uint16_t watchdog_timeout; /* in 100's of milliseconds */
189 
190     bool     watchdog_running;
191     bool     watchdog_preaction_ran;
192     int64_t  watchdog_expiry;
193 
194     uint8_t device_id;
195     uint8_t ipmi_version;
196     uint8_t device_rev;
197     uint8_t fwrev1;
198     uint8_t fwrev2;
199     uint8_t mfg_id[3];
200     uint8_t product_id[2];
201 
202     IPMISel sel;
203     IPMISdr sdr;
204     IPMISensor sensors[MAX_SENSORS];
205 
206     /* Odd netfns are for responses, so we only need the even ones. */
207     const IPMINetfn *netfns[MAX_NETFNS / 2];
208 
209     QemuMutex lock;
210     /* We allow one event in the buffer */
211     uint8_t evtbuf[16];
212 
213     QTAILQ_HEAD(, IPMIRcvBufEntry) rcvbufs;
214 };
215 
216 #define IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK        (1 << 3)
217 #define IPMI_BMC_MSG_FLAG_EVT_BUF_FULL                 (1 << 1)
218 #define IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE                (1 << 0)
219 #define IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(s) \
220     (IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK & (s)->msg_flags)
221 #define IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(s) \
222     (IPMI_BMC_MSG_FLAG_EVT_BUF_FULL & (s)->msg_flags)
223 #define IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(s) \
224     (IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE & (s)->msg_flags)
225 
226 #define IPMI_BMC_RCV_MSG_QUEUE_INT_BIT    0
227 #define IPMI_BMC_EVBUF_FULL_INT_BIT       1
228 #define IPMI_BMC_EVENT_MSG_BUF_BIT        2
229 #define IPMI_BMC_EVENT_LOG_BIT            3
230 #define IPMI_BMC_MSG_INTS_ON(s) ((s)->bmc_global_enables & \
231                                  (1 << IPMI_BMC_RCV_MSG_QUEUE_INT_BIT))
232 #define IPMI_BMC_EVBUF_FULL_INT_ENABLED(s) ((s)->bmc_global_enables & \
233                                         (1 << IPMI_BMC_EVBUF_FULL_INT_BIT))
234 #define IPMI_BMC_EVENT_LOG_ENABLED(s) ((s)->bmc_global_enables & \
235                                        (1 << IPMI_BMC_EVENT_LOG_BIT))
236 #define IPMI_BMC_EVENT_MSG_BUF_ENABLED(s) ((s)->bmc_global_enables & \
237                                            (1 << IPMI_BMC_EVENT_MSG_BUF_BIT))
238 
239 #define IPMI_BMC_WATCHDOG_USE_MASK 0xc7
240 #define IPMI_BMC_WATCHDOG_ACTION_MASK 0x77
241 #define IPMI_BMC_WATCHDOG_GET_USE(s) ((s)->watchdog_use & 0x7)
242 #define IPMI_BMC_WATCHDOG_GET_DONT_LOG(s) (((s)->watchdog_use >> 7) & 0x1)
243 #define IPMI_BMC_WATCHDOG_GET_DONT_STOP(s) (((s)->watchdog_use >> 6) & 0x1)
244 #define IPMI_BMC_WATCHDOG_GET_PRE_ACTION(s) (((s)->watchdog_action >> 4) & 0x7)
245 #define IPMI_BMC_WATCHDOG_PRE_NONE               0
246 #define IPMI_BMC_WATCHDOG_PRE_SMI                1
247 #define IPMI_BMC_WATCHDOG_PRE_NMI                2
248 #define IPMI_BMC_WATCHDOG_PRE_MSG_INT            3
249 #define IPMI_BMC_WATCHDOG_GET_ACTION(s) ((s)->watchdog_action & 0x7)
250 #define IPMI_BMC_WATCHDOG_ACTION_NONE            0
251 #define IPMI_BMC_WATCHDOG_ACTION_RESET           1
252 #define IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN      2
253 #define IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE     3
254 
255 
256 /* Add a byte to the response. */
257 #define IPMI_ADD_RSP_DATA(b) \
258     do {                                                   \
259         if (*rsp_len >= max_rsp_len) {                     \
260             rsp[2] = IPMI_CC_REQUEST_DATA_TRUNCATED;       \
261             goto out;                                      \
262         }                                                  \
263         rsp[(*rsp_len)++] = (b);                           \
264     } while (0)
265 
266 /* Verify that the received command is a certain length. */
267 #define IPMI_CHECK_CMD_LEN(l) \
268     if (cmd_len < l) {                                     \
269         rsp[2] = IPMI_CC_REQUEST_DATA_LENGTH_INVALID;      \
270         goto out; \
271     }
272 
273 /* Check that the reservation in the command is valid. */
274 #define IPMI_CHECK_RESERVATION(off, r) \
275     do {                                                   \
276         if ((cmd[off] | (cmd[off + 1] << 8)) != r) {       \
277             rsp[2] = IPMI_CC_INVALID_RESERVATION;          \
278             goto out;                                      \
279         }                                                  \
280     } while (0)
281 
282 
283 static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs);
284 
285 static void ipmi_gettime(struct ipmi_time *time)
286 {
287     int64_t stime;
288 
289     stime = qemu_clock_get_ns(QEMU_CLOCK_HOST);
290     time->tv_sec = stime / 1000000000LL;
291     time->tv_nsec = stime % 1000000000LL;
292 }
293 
294 static int64_t ipmi_getmonotime(void)
295 {
296     return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
297 }
298 
299 static void ipmi_timeout(void *opaque)
300 {
301     IPMIBmcSim *ibs = opaque;
302 
303     ipmi_sim_handle_timeout(ibs);
304 }
305 
306 static void set_timestamp(IPMIBmcSim *ibs, uint8_t *ts)
307 {
308     unsigned int val;
309     struct ipmi_time now;
310 
311     ipmi_gettime(&now);
312     val = now.tv_sec + ibs->sel.time_offset;
313     ts[0] = val & 0xff;
314     ts[1] = (val >> 8) & 0xff;
315     ts[2] = (val >> 16) & 0xff;
316     ts[3] = (val >> 24) & 0xff;
317 }
318 
319 static void sdr_inc_reservation(IPMISdr *sdr)
320 {
321     sdr->reservation++;
322     if (sdr->reservation == 0) {
323         sdr->reservation = 1;
324     }
325 }
326 
327 static int sdr_add_entry(IPMIBmcSim *ibs, const uint8_t *entry,
328                          unsigned int len, uint16_t *recid)
329 {
330     if ((len < 5) || (len > 255)) {
331         return 1;
332     }
333 
334     if (entry[4] != len - 5) {
335         return 1;
336     }
337 
338     if (ibs->sdr.next_free + len > MAX_SDR_SIZE) {
339         ibs->sdr.overflow = 1;
340         return 1;
341     }
342 
343     memcpy(ibs->sdr.sdr + ibs->sdr.next_free, entry, len);
344     ibs->sdr.sdr[ibs->sdr.next_free] = ibs->sdr.next_rec_id & 0xff;
345     ibs->sdr.sdr[ibs->sdr.next_free+1] = (ibs->sdr.next_rec_id >> 8) & 0xff;
346     ibs->sdr.sdr[ibs->sdr.next_free+2] = 0x51; /* Conform to IPMI 1.5 spec */
347 
348     if (recid) {
349         *recid = ibs->sdr.next_rec_id;
350     }
351     ibs->sdr.next_rec_id++;
352     set_timestamp(ibs, ibs->sdr.last_addition);
353     ibs->sdr.next_free += len;
354     sdr_inc_reservation(&ibs->sdr);
355     return 0;
356 }
357 
358 static int sdr_find_entry(IPMISdr *sdr, uint16_t recid,
359                           unsigned int *retpos, uint16_t *nextrec)
360 {
361     unsigned int pos = *retpos;
362 
363     while (pos < sdr->next_free) {
364         uint16_t trec = sdr->sdr[pos] | (sdr->sdr[pos + 1] << 8);
365         unsigned int nextpos = pos + sdr->sdr[pos + 4];
366 
367         if (trec == recid) {
368             if (nextrec) {
369                 if (nextpos >= sdr->next_free) {
370                     *nextrec = 0xffff;
371                 } else {
372                     *nextrec = (sdr->sdr[nextpos] |
373                                 (sdr->sdr[nextpos + 1] << 8));
374                 }
375             }
376             *retpos = pos;
377             return 0;
378         }
379         pos = nextpos;
380     }
381     return 1;
382 }
383 
384 static void sel_inc_reservation(IPMISel *sel)
385 {
386     sel->reservation++;
387     if (sel->reservation == 0) {
388         sel->reservation = 1;
389     }
390 }
391 
392 /* Returns 1 if the SEL is full and can't hold the event. */
393 static int sel_add_event(IPMIBmcSim *ibs, uint8_t *event)
394 {
395     event[0] = 0xff;
396     event[1] = 0xff;
397     set_timestamp(ibs, event + 3);
398     if (ibs->sel.next_free == MAX_SEL_SIZE) {
399         ibs->sel.overflow = 1;
400         return 1;
401     }
402     event[0] = ibs->sel.next_free & 0xff;
403     event[1] = (ibs->sel.next_free >> 8) & 0xff;
404     memcpy(ibs->sel.last_addition, event + 3, 4);
405     memcpy(ibs->sel.sel[ibs->sel.next_free], event, 16);
406     ibs->sel.next_free++;
407     sel_inc_reservation(&ibs->sel);
408     return 0;
409 }
410 
411 static int attn_set(IPMIBmcSim *ibs)
412 {
413     return IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(ibs)
414         || IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs)
415         || IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(ibs);
416 }
417 
418 static int attn_irq_enabled(IPMIBmcSim *ibs)
419 {
420     return (IPMI_BMC_MSG_INTS_ON(ibs) && IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(ibs))
421         || (IPMI_BMC_EVBUF_FULL_INT_ENABLED(ibs) &&
422             IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs));
423 }
424 
425 static void gen_event(IPMIBmcSim *ibs, unsigned int sens_num, uint8_t deassert,
426                       uint8_t evd1, uint8_t evd2, uint8_t evd3)
427 {
428     IPMIInterface *s = ibs->parent.intf;
429     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
430     uint8_t evt[16];
431     IPMISensor *sens = ibs->sensors + sens_num;
432 
433     if (!IPMI_BMC_EVENT_MSG_BUF_ENABLED(ibs)) {
434         return;
435     }
436     if (!IPMI_SENSOR_GET_EVENTS_ON(sens)) {
437         return;
438     }
439 
440     evt[2] = 0x2; /* System event record */
441     evt[7] = ibs->parent.slave_addr;
442     evt[8] = 0;
443     evt[9] = 0x04; /* Format version */
444     evt[10] = sens->sensor_type;
445     evt[11] = sens_num;
446     evt[12] = sens->evt_reading_type_code | (!!deassert << 7);
447     evt[13] = evd1;
448     evt[14] = evd2;
449     evt[15] = evd3;
450 
451     if (IPMI_BMC_EVENT_LOG_ENABLED(ibs)) {
452         sel_add_event(ibs, evt);
453     }
454 
455     if (ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL) {
456         goto out;
457     }
458 
459     memcpy(ibs->evtbuf, evt, 16);
460     ibs->msg_flags |= IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
461     k->set_atn(s, 1, attn_irq_enabled(ibs));
462  out:
463     return;
464 }
465 
466 static void sensor_set_discrete_bit(IPMIBmcSim *ibs, unsigned int sensor,
467                                     unsigned int bit, unsigned int val,
468                                     uint8_t evd1, uint8_t evd2, uint8_t evd3)
469 {
470     IPMISensor *sens;
471     uint16_t mask;
472 
473     if (sensor >= MAX_SENSORS) {
474         return;
475     }
476     if (bit >= 16) {
477         return;
478     }
479 
480     mask = (1 << bit);
481     sens = ibs->sensors + sensor;
482     if (val) {
483         sens->states |= mask & sens->states_suppt;
484         if (sens->assert_states & mask) {
485             return; /* Already asserted */
486         }
487         sens->assert_states |= mask & sens->assert_suppt;
488         if (sens->assert_enable & mask & sens->assert_states) {
489             /* Send an event on assert */
490             gen_event(ibs, sensor, 0, evd1, evd2, evd3);
491         }
492     } else {
493         sens->states &= ~(mask & sens->states_suppt);
494         if (sens->deassert_states & mask) {
495             return; /* Already deasserted */
496         }
497         sens->deassert_states |= mask & sens->deassert_suppt;
498         if (sens->deassert_enable & mask & sens->deassert_states) {
499             /* Send an event on deassert */
500             gen_event(ibs, sensor, 1, evd1, evd2, evd3);
501         }
502     }
503 }
504 
505 static void ipmi_init_sensors_from_sdrs(IPMIBmcSim *s)
506 {
507     unsigned int i, pos;
508     IPMISensor *sens;
509 
510     for (i = 0; i < MAX_SENSORS; i++) {
511         memset(s->sensors + i, 0, sizeof(*sens));
512     }
513 
514     pos = 0;
515     for (i = 0; !sdr_find_entry(&s->sdr, i, &pos, NULL); i++) {
516         uint8_t *sdr = s->sdr.sdr + pos;
517         unsigned int len = sdr[4];
518 
519         if (len < 20) {
520             continue;
521         }
522         if ((sdr[3] < 1) || (sdr[3] > 2)) {
523             continue; /* Not a sensor SDR we set from */
524         }
525 
526         if (sdr[7] > MAX_SENSORS) {
527             continue;
528         }
529         sens = s->sensors + sdr[7];
530 
531         IPMI_SENSOR_SET_PRESENT(sens, 1);
532         IPMI_SENSOR_SET_SCAN_ON(sens, (sdr[10] >> 6) & 1);
533         IPMI_SENSOR_SET_EVENTS_ON(sens, (sdr[10] >> 5) & 1);
534         sens->assert_suppt = sdr[14] | (sdr[15] << 8);
535         sens->deassert_suppt = sdr[16] | (sdr[17] << 8);
536         sens->states_suppt = sdr[18] | (sdr[19] << 8);
537         sens->sensor_type = sdr[12];
538         sens->evt_reading_type_code = sdr[13] & 0x7f;
539 
540         /* Enable all the events that are supported. */
541         sens->assert_enable = sens->assert_suppt;
542         sens->deassert_enable = sens->deassert_suppt;
543     }
544 }
545 
546 static int ipmi_register_netfn(IPMIBmcSim *s, unsigned int netfn,
547                                const IPMINetfn *netfnd)
548 {
549     if ((netfn & 1) || (netfn > MAX_NETFNS) || (s->netfns[netfn / 2])) {
550         return -1;
551     }
552     s->netfns[netfn / 2] = netfnd;
553     return 0;
554 }
555 
556 static void next_timeout(IPMIBmcSim *ibs)
557 {
558     int64_t next;
559     if (ibs->watchdog_running) {
560         next = ibs->watchdog_expiry;
561     } else {
562         /* Wait a minute */
563         next = ipmi_getmonotime() + 60 * 1000000000LL;
564     }
565     timer_mod_ns(ibs->timer, next);
566 }
567 
568 static void ipmi_sim_handle_command(IPMIBmc *b,
569                                     uint8_t *cmd, unsigned int cmd_len,
570                                     unsigned int max_cmd_len,
571                                     uint8_t msg_id)
572 {
573     IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
574     IPMIInterface *s = ibs->parent.intf;
575     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
576     unsigned int netfn;
577     uint8_t rsp[MAX_IPMI_MSG_SIZE];
578     unsigned int rsp_len_holder = 0;
579     unsigned int *rsp_len = &rsp_len_holder;
580     unsigned int max_rsp_len = sizeof(rsp);
581 
582     /* Set up the response, set the low bit of NETFN. */
583     /* Note that max_rsp_len must be at least 3 */
584     IPMI_ADD_RSP_DATA(cmd[0] | 0x04);
585     IPMI_ADD_RSP_DATA(cmd[1]);
586     IPMI_ADD_RSP_DATA(0); /* Assume success */
587 
588     /* If it's too short or it was truncated, return an error. */
589     if (cmd_len < 2) {
590         rsp[2] = IPMI_CC_REQUEST_DATA_LENGTH_INVALID;
591         goto out;
592     }
593     if (cmd_len > max_cmd_len) {
594         rsp[2] = IPMI_CC_REQUEST_DATA_TRUNCATED;
595         goto out;
596     }
597 
598     if ((cmd[0] & 0x03) != 0) {
599         /* Only have stuff on LUN 0 */
600         rsp[2] = IPMI_CC_COMMAND_INVALID_FOR_LUN;
601         goto out;
602     }
603 
604     netfn = cmd[0] >> 2;
605 
606     /* Odd netfns are not valid, make sure the command is registered */
607     if ((netfn & 1) || !ibs->netfns[netfn / 2] ||
608                         (cmd[1] >= ibs->netfns[netfn / 2]->cmd_nums) ||
609                         (!ibs->netfns[netfn / 2]->cmd_handlers[cmd[1]])) {
610         rsp[2] = IPMI_CC_INVALID_CMD;
611         goto out;
612     }
613 
614     ibs->netfns[netfn / 2]->cmd_handlers[cmd[1]](ibs, cmd, cmd_len, rsp, rsp_len,
615                                                 max_rsp_len);
616 
617  out:
618     k->handle_rsp(s, msg_id, rsp, *rsp_len);
619 
620     next_timeout(ibs);
621 }
622 
623 static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs)
624 {
625     IPMIInterface *s = ibs->parent.intf;
626     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
627 
628     if (!ibs->watchdog_running) {
629         goto out;
630     }
631 
632     if (!ibs->watchdog_preaction_ran) {
633         switch (IPMI_BMC_WATCHDOG_GET_PRE_ACTION(ibs)) {
634         case IPMI_BMC_WATCHDOG_PRE_NMI:
635             ibs->msg_flags |= IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK;
636             k->do_hw_op(s, IPMI_SEND_NMI, 0);
637             sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 8, 1,
638                                     0xc8, (2 << 4) | 0xf, 0xff);
639             break;
640 
641         case IPMI_BMC_WATCHDOG_PRE_MSG_INT:
642             ibs->msg_flags |= IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK;
643             k->set_atn(s, 1, attn_irq_enabled(ibs));
644             sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 8, 1,
645                                     0xc8, (3 << 4) | 0xf, 0xff);
646             break;
647 
648         default:
649             goto do_full_expiry;
650         }
651 
652         ibs->watchdog_preaction_ran = 1;
653         /* Issued the pretimeout, do the rest of the timeout now. */
654         ibs->watchdog_expiry = ipmi_getmonotime();
655         ibs->watchdog_expiry += ibs->watchdog_pretimeout * 1000000000LL;
656         goto out;
657     }
658 
659  do_full_expiry:
660     ibs->watchdog_running = 0; /* Stop the watchdog on a timeout */
661     ibs->watchdog_expired |= (1 << IPMI_BMC_WATCHDOG_GET_USE(ibs));
662     switch (IPMI_BMC_WATCHDOG_GET_ACTION(ibs)) {
663     case IPMI_BMC_WATCHDOG_ACTION_NONE:
664         sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 0, 1,
665                                 0xc0, ibs->watchdog_use & 0xf, 0xff);
666         break;
667 
668     case IPMI_BMC_WATCHDOG_ACTION_RESET:
669         sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 1, 1,
670                                 0xc1, ibs->watchdog_use & 0xf, 0xff);
671         k->do_hw_op(s, IPMI_RESET_CHASSIS, 0);
672         break;
673 
674     case IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN:
675         sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 2, 1,
676                                 0xc2, ibs->watchdog_use & 0xf, 0xff);
677         k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 0);
678         break;
679 
680     case IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE:
681         sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 2, 1,
682                                 0xc3, ibs->watchdog_use & 0xf, 0xff);
683         k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 0);
684         break;
685     }
686 
687  out:
688     next_timeout(ibs);
689 }
690 
691 static void chassis_capabilities(IPMIBmcSim *ibs,
692                                  uint8_t *cmd, unsigned int cmd_len,
693                                  uint8_t *rsp, unsigned int *rsp_len,
694                                  unsigned int max_rsp_len)
695 {
696     IPMI_ADD_RSP_DATA(0);
697     IPMI_ADD_RSP_DATA(ibs->parent.slave_addr);
698     IPMI_ADD_RSP_DATA(ibs->parent.slave_addr);
699     IPMI_ADD_RSP_DATA(ibs->parent.slave_addr);
700     IPMI_ADD_RSP_DATA(ibs->parent.slave_addr);
701  out:
702     return;
703 }
704 
705 static void chassis_status(IPMIBmcSim *ibs,
706                            uint8_t *cmd, unsigned int cmd_len,
707                            uint8_t *rsp, unsigned int *rsp_len,
708                            unsigned int max_rsp_len)
709 {
710     IPMI_ADD_RSP_DATA(0x61); /* Unknown power restore, power is on */
711     IPMI_ADD_RSP_DATA(0);
712     IPMI_ADD_RSP_DATA(0);
713     IPMI_ADD_RSP_DATA(0);
714  out:
715     return;
716 }
717 
718 static void chassis_control(IPMIBmcSim *ibs,
719                             uint8_t *cmd, unsigned int cmd_len,
720                             uint8_t *rsp, unsigned int *rsp_len,
721                             unsigned int max_rsp_len)
722 {
723     IPMIInterface *s = ibs->parent.intf;
724     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
725 
726     IPMI_CHECK_CMD_LEN(3);
727     switch (cmd[2] & 0xf) {
728     case 0: /* power down */
729         rsp[2] = k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 0);
730         break;
731     case 1: /* power up */
732         rsp[2] = k->do_hw_op(s, IPMI_POWERON_CHASSIS, 0);
733         break;
734     case 2: /* power cycle */
735         rsp[2] = k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 0);
736         break;
737     case 3: /* hard reset */
738         rsp[2] = k->do_hw_op(s, IPMI_RESET_CHASSIS, 0);
739         break;
740     case 4: /* pulse diagnostic interrupt */
741         rsp[2] = k->do_hw_op(s, IPMI_PULSE_DIAG_IRQ, 0);
742         break;
743     case 5: /* soft shutdown via ACPI by overtemp emulation */
744         rsp[2] = k->do_hw_op(s,
745                              IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP, 0);
746         break;
747     default:
748         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
749         goto out;
750     }
751  out:
752     return;
753 }
754 
755 static void get_device_id(IPMIBmcSim *ibs,
756                           uint8_t *cmd, unsigned int cmd_len,
757                           uint8_t *rsp, unsigned int *rsp_len,
758                           unsigned int max_rsp_len)
759 {
760     IPMI_ADD_RSP_DATA(ibs->device_id);
761     IPMI_ADD_RSP_DATA(ibs->device_rev & 0xf);
762     IPMI_ADD_RSP_DATA(ibs->fwrev1 & 0x7f);
763     IPMI_ADD_RSP_DATA(ibs->fwrev2);
764     IPMI_ADD_RSP_DATA(ibs->ipmi_version);
765     IPMI_ADD_RSP_DATA(0x07); /* sensor, SDR, and SEL. */
766     IPMI_ADD_RSP_DATA(ibs->mfg_id[0]);
767     IPMI_ADD_RSP_DATA(ibs->mfg_id[1]);
768     IPMI_ADD_RSP_DATA(ibs->mfg_id[2]);
769     IPMI_ADD_RSP_DATA(ibs->product_id[0]);
770     IPMI_ADD_RSP_DATA(ibs->product_id[1]);
771  out:
772     return;
773 }
774 
775 static void set_global_enables(IPMIBmcSim *ibs, uint8_t val)
776 {
777     IPMIInterface *s = ibs->parent.intf;
778     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
779     bool irqs_on;
780 
781     ibs->bmc_global_enables = val;
782 
783     irqs_on = val & (IPMI_BMC_EVBUF_FULL_INT_BIT |
784                      IPMI_BMC_RCV_MSG_QUEUE_INT_BIT);
785 
786     k->set_irq_enable(s, irqs_on);
787 }
788 
789 static void cold_reset(IPMIBmcSim *ibs,
790                        uint8_t *cmd, unsigned int cmd_len,
791                        uint8_t *rsp, unsigned int *rsp_len,
792                        unsigned int max_rsp_len)
793 {
794     IPMIInterface *s = ibs->parent.intf;
795     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
796 
797     /* Disable all interrupts */
798     set_global_enables(ibs, 1 << IPMI_BMC_EVENT_LOG_BIT);
799 
800     if (k->reset) {
801         k->reset(s, true);
802     }
803 }
804 
805 static void warm_reset(IPMIBmcSim *ibs,
806                        uint8_t *cmd, unsigned int cmd_len,
807                        uint8_t *rsp, unsigned int *rsp_len,
808                        unsigned int max_rsp_len)
809 {
810     IPMIInterface *s = ibs->parent.intf;
811     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
812 
813     if (k->reset) {
814         k->reset(s, false);
815     }
816 }
817 
818 static void set_bmc_global_enables(IPMIBmcSim *ibs,
819                                    uint8_t *cmd, unsigned int cmd_len,
820                                    uint8_t *rsp, unsigned int *rsp_len,
821                                    unsigned int max_rsp_len)
822 {
823     IPMI_CHECK_CMD_LEN(3);
824     set_global_enables(ibs, cmd[2]);
825  out:
826     return;
827 }
828 
829 static void get_bmc_global_enables(IPMIBmcSim *ibs,
830                                    uint8_t *cmd, unsigned int cmd_len,
831                                    uint8_t *rsp, unsigned int *rsp_len,
832                                    unsigned int max_rsp_len)
833 {
834     IPMI_ADD_RSP_DATA(ibs->bmc_global_enables);
835  out:
836     return;
837 }
838 
839 static void clr_msg_flags(IPMIBmcSim *ibs,
840                           uint8_t *cmd, unsigned int cmd_len,
841                           uint8_t *rsp, unsigned int *rsp_len,
842                           unsigned int max_rsp_len)
843 {
844     IPMIInterface *s = ibs->parent.intf;
845     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
846 
847     IPMI_CHECK_CMD_LEN(3);
848     ibs->msg_flags &= ~cmd[2];
849     k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
850  out:
851     return;
852 }
853 
854 static void get_msg_flags(IPMIBmcSim *ibs,
855                           uint8_t *cmd, unsigned int cmd_len,
856                           uint8_t *rsp, unsigned int *rsp_len,
857                           unsigned int max_rsp_len)
858 {
859     IPMI_ADD_RSP_DATA(ibs->msg_flags);
860  out:
861     return;
862 }
863 
864 static void read_evt_msg_buf(IPMIBmcSim *ibs,
865                              uint8_t *cmd, unsigned int cmd_len,
866                              uint8_t *rsp, unsigned int *rsp_len,
867                             unsigned int max_rsp_len)
868 {
869     IPMIInterface *s = ibs->parent.intf;
870     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
871     unsigned int i;
872 
873     if (!(ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL)) {
874         rsp[2] = 0x80;
875         goto out;
876     }
877     for (i = 0; i < 16; i++) {
878         IPMI_ADD_RSP_DATA(ibs->evtbuf[i]);
879     }
880     ibs->msg_flags &= ~IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
881     k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
882  out:
883     return;
884 }
885 
886 static void get_msg(IPMIBmcSim *ibs,
887                     uint8_t *cmd, unsigned int cmd_len,
888                     uint8_t *rsp, unsigned int *rsp_len,
889                     unsigned int max_rsp_len)
890 {
891     IPMIRcvBufEntry *msg;
892 
893     qemu_mutex_lock(&ibs->lock);
894     if (QTAILQ_EMPTY(&ibs->rcvbufs)) {
895         rsp[2] = 0x80; /* Queue empty */
896         goto out;
897     }
898     rsp[3] = 0; /* Channel 0 */
899     *rsp_len += 1;
900     msg = QTAILQ_FIRST(&ibs->rcvbufs);
901     memcpy(rsp + 4, msg->buf, msg->len);
902     *rsp_len += msg->len;
903     QTAILQ_REMOVE(&ibs->rcvbufs, msg, entry);
904     g_free(msg);
905 
906     if (QTAILQ_EMPTY(&ibs->rcvbufs)) {
907         IPMIInterface *s = ibs->parent.intf;
908         IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
909 
910         ibs->msg_flags &= ~IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;
911         k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
912     }
913 
914  out:
915     qemu_mutex_unlock(&ibs->lock);
916     return;
917 }
918 
919 static unsigned char
920 ipmb_checksum(unsigned char *data, int size, unsigned char csum)
921 {
922     for (; size > 0; size--, data++) {
923             csum += *data;
924     }
925 
926     return -csum;
927 }
928 
929 static void send_msg(IPMIBmcSim *ibs,
930                      uint8_t *cmd, unsigned int cmd_len,
931                      uint8_t *rsp, unsigned int *rsp_len,
932                      unsigned int max_rsp_len)
933 {
934     IPMIInterface *s = ibs->parent.intf;
935     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
936     IPMIRcvBufEntry *msg;
937     uint8_t *buf;
938     uint8_t netfn, rqLun, rsLun, rqSeq;
939 
940     IPMI_CHECK_CMD_LEN(3);
941 
942     if (cmd[2] != 0) {
943         /* We only handle channel 0 with no options */
944         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
945         goto out;
946     }
947 
948     IPMI_CHECK_CMD_LEN(10);
949     if (cmd[3] != 0x40) {
950         /* We only emulate a MC at address 0x40. */
951         rsp[2] = 0x83; /* NAK on write */
952         goto out;
953     }
954 
955     cmd += 3; /* Skip the header. */
956     cmd_len -= 3;
957 
958     /*
959      * At this point we "send" the message successfully.  Any error will
960      * be returned in the response.
961      */
962     if (ipmb_checksum(cmd, cmd_len, 0) != 0 ||
963         cmd[3] != 0x20) { /* Improper response address */
964         goto out; /* No response */
965     }
966 
967     netfn = cmd[1] >> 2;
968     rqLun = cmd[4] & 0x3;
969     rsLun = cmd[1] & 0x3;
970     rqSeq = cmd[4] >> 2;
971 
972     if (rqLun != 2) {
973         /* We only support LUN 2 coming back to us. */
974         goto out;
975     }
976 
977     msg = g_malloc(sizeof(*msg));
978     msg->buf[0] = ((netfn | 1) << 2) | rqLun; /* NetFN, and make a response */
979     msg->buf[1] = ipmb_checksum(msg->buf, 1, 0);
980     msg->buf[2] = cmd[0]; /* rsSA */
981     msg->buf[3] = (rqSeq << 2) | rsLun;
982     msg->buf[4] = cmd[5]; /* Cmd */
983     msg->buf[5] = 0; /* Completion Code */
984     msg->len = 6;
985 
986     if ((cmd[1] >> 2) != IPMI_NETFN_APP || cmd[5] != IPMI_CMD_GET_DEVICE_ID) {
987         /* Not a command we handle. */
988         msg->buf[5] = IPMI_CC_INVALID_CMD;
989         goto end_msg;
990     }
991 
992     buf = msg->buf + msg->len; /* After the CC */
993     buf[0] = 0;
994     buf[1] = 0;
995     buf[2] = 0;
996     buf[3] = 0;
997     buf[4] = 0x51;
998     buf[5] = 0;
999     buf[6] = 0;
1000     buf[7] = 0;
1001     buf[8] = 0;
1002     buf[9] = 0;
1003     buf[10] = 0;
1004     msg->len += 11;
1005 
1006  end_msg:
1007     msg->buf[msg->len] = ipmb_checksum(msg->buf, msg->len, 0);
1008     msg->len++;
1009     qemu_mutex_lock(&ibs->lock);
1010     QTAILQ_INSERT_TAIL(&ibs->rcvbufs, msg, entry);
1011     ibs->msg_flags |= IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;
1012     k->set_atn(s, 1, attn_irq_enabled(ibs));
1013     qemu_mutex_unlock(&ibs->lock);
1014 
1015  out:
1016     return;
1017 }
1018 
1019 static void do_watchdog_reset(IPMIBmcSim *ibs)
1020 {
1021     if (IPMI_BMC_WATCHDOG_GET_ACTION(ibs) ==
1022         IPMI_BMC_WATCHDOG_ACTION_NONE) {
1023         ibs->watchdog_running = 0;
1024         return;
1025     }
1026     ibs->watchdog_preaction_ran = 0;
1027 
1028 
1029     /* Timeout is in tenths of a second, offset is in seconds */
1030     ibs->watchdog_expiry = ipmi_getmonotime();
1031     ibs->watchdog_expiry += ibs->watchdog_timeout * 100000000LL;
1032     if (IPMI_BMC_WATCHDOG_GET_PRE_ACTION(ibs) != IPMI_BMC_WATCHDOG_PRE_NONE) {
1033         ibs->watchdog_expiry -= ibs->watchdog_pretimeout * 1000000000LL;
1034     }
1035     ibs->watchdog_running = 1;
1036 }
1037 
1038 static void reset_watchdog_timer(IPMIBmcSim *ibs,
1039                                  uint8_t *cmd, unsigned int cmd_len,
1040                                  uint8_t *rsp, unsigned int *rsp_len,
1041                                  unsigned int max_rsp_len)
1042 {
1043     if (!ibs->watchdog_initialized) {
1044         rsp[2] = 0x80;
1045         goto out;
1046     }
1047     do_watchdog_reset(ibs);
1048  out:
1049     return;
1050 }
1051 
1052 static void set_watchdog_timer(IPMIBmcSim *ibs,
1053                                uint8_t *cmd, unsigned int cmd_len,
1054                                uint8_t *rsp, unsigned int *rsp_len,
1055                                unsigned int max_rsp_len)
1056 {
1057     IPMIInterface *s = ibs->parent.intf;
1058     IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
1059     unsigned int val;
1060 
1061     IPMI_CHECK_CMD_LEN(8);
1062     val = cmd[2] & 0x7; /* Validate use */
1063     if (val == 0 || val > 5) {
1064         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1065         goto out;
1066     }
1067     val = cmd[3] & 0x7; /* Validate action */
1068     switch (val) {
1069     case IPMI_BMC_WATCHDOG_ACTION_NONE:
1070         break;
1071 
1072     case IPMI_BMC_WATCHDOG_ACTION_RESET:
1073         rsp[2] = k->do_hw_op(s, IPMI_RESET_CHASSIS, 1);
1074         break;
1075 
1076     case IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN:
1077         rsp[2] = k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 1);
1078         break;
1079 
1080     case IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE:
1081         rsp[2] = k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 1);
1082         break;
1083 
1084     default:
1085         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1086     }
1087     if (rsp[2]) {
1088         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1089         goto out;
1090     }
1091 
1092     val = (cmd[3] >> 4) & 0x7; /* Validate preaction */
1093     switch (val) {
1094     case IPMI_BMC_WATCHDOG_PRE_MSG_INT:
1095     case IPMI_BMC_WATCHDOG_PRE_NONE:
1096         break;
1097 
1098     case IPMI_BMC_WATCHDOG_PRE_NMI:
1099         if (!k->do_hw_op(s, IPMI_SEND_NMI, 1)) {
1100             /* NMI not supported. */
1101             rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1102             goto out;
1103         }
1104     default:
1105         /* We don't support PRE_SMI */
1106         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1107         goto out;
1108     }
1109 
1110     ibs->watchdog_initialized = 1;
1111     ibs->watchdog_use = cmd[2] & IPMI_BMC_WATCHDOG_USE_MASK;
1112     ibs->watchdog_action = cmd[3] & IPMI_BMC_WATCHDOG_ACTION_MASK;
1113     ibs->watchdog_pretimeout = cmd[4];
1114     ibs->watchdog_expired &= ~cmd[5];
1115     ibs->watchdog_timeout = cmd[6] | (((uint16_t) cmd[7]) << 8);
1116     if (ibs->watchdog_running & IPMI_BMC_WATCHDOG_GET_DONT_STOP(ibs)) {
1117         do_watchdog_reset(ibs);
1118     } else {
1119         ibs->watchdog_running = 0;
1120     }
1121  out:
1122     return;
1123 }
1124 
1125 static void get_watchdog_timer(IPMIBmcSim *ibs,
1126                                uint8_t *cmd, unsigned int cmd_len,
1127                                uint8_t *rsp, unsigned int *rsp_len,
1128                                unsigned int max_rsp_len)
1129 {
1130     IPMI_ADD_RSP_DATA(ibs->watchdog_use);
1131     IPMI_ADD_RSP_DATA(ibs->watchdog_action);
1132     IPMI_ADD_RSP_DATA(ibs->watchdog_pretimeout);
1133     IPMI_ADD_RSP_DATA(ibs->watchdog_expired);
1134     if (ibs->watchdog_running) {
1135         long timeout;
1136         timeout = ((ibs->watchdog_expiry - ipmi_getmonotime() + 50000000)
1137                    / 100000000);
1138         IPMI_ADD_RSP_DATA(timeout & 0xff);
1139         IPMI_ADD_RSP_DATA((timeout >> 8) & 0xff);
1140     } else {
1141         IPMI_ADD_RSP_DATA(0);
1142         IPMI_ADD_RSP_DATA(0);
1143     }
1144  out:
1145     return;
1146 }
1147 
1148 static void get_sdr_rep_info(IPMIBmcSim *ibs,
1149                              uint8_t *cmd, unsigned int cmd_len,
1150                              uint8_t *rsp, unsigned int *rsp_len,
1151                              unsigned int max_rsp_len)
1152 {
1153     unsigned int i;
1154 
1155     IPMI_ADD_RSP_DATA(0x51); /* Conform to IPMI 1.5 spec */
1156     IPMI_ADD_RSP_DATA(ibs->sdr.next_rec_id & 0xff);
1157     IPMI_ADD_RSP_DATA((ibs->sdr.next_rec_id >> 8) & 0xff);
1158     IPMI_ADD_RSP_DATA((MAX_SDR_SIZE - ibs->sdr.next_free) & 0xff);
1159     IPMI_ADD_RSP_DATA(((MAX_SDR_SIZE - ibs->sdr.next_free) >> 8) & 0xff);
1160     for (i = 0; i < 4; i++) {
1161         IPMI_ADD_RSP_DATA(ibs->sdr.last_addition[i]);
1162     }
1163     for (i = 0; i < 4; i++) {
1164         IPMI_ADD_RSP_DATA(ibs->sdr.last_clear[i]);
1165     }
1166     /* Only modal support, reserve supported */
1167     IPMI_ADD_RSP_DATA((ibs->sdr.overflow << 7) | 0x22);
1168  out:
1169     return;
1170 }
1171 
1172 static void reserve_sdr_rep(IPMIBmcSim *ibs,
1173                             uint8_t *cmd, unsigned int cmd_len,
1174                             uint8_t *rsp, unsigned int *rsp_len,
1175                             unsigned int max_rsp_len)
1176 {
1177     IPMI_ADD_RSP_DATA(ibs->sdr.reservation & 0xff);
1178     IPMI_ADD_RSP_DATA((ibs->sdr.reservation >> 8) & 0xff);
1179  out:
1180     return;
1181 }
1182 
1183 static void get_sdr(IPMIBmcSim *ibs,
1184                     uint8_t *cmd, unsigned int cmd_len,
1185                     uint8_t *rsp, unsigned int *rsp_len,
1186                     unsigned int max_rsp_len)
1187 {
1188     unsigned int pos;
1189     uint16_t nextrec;
1190 
1191     IPMI_CHECK_CMD_LEN(8);
1192     if (cmd[6]) {
1193         IPMI_CHECK_RESERVATION(2, ibs->sdr.reservation);
1194     }
1195     pos = 0;
1196     if (sdr_find_entry(&ibs->sdr, cmd[4] | (cmd[5] << 8),
1197                        &pos, &nextrec)) {
1198         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1199         goto out;
1200     }
1201     if (cmd[6] > (ibs->sdr.sdr[pos + 4])) {
1202         rsp[2] = IPMI_CC_PARM_OUT_OF_RANGE;
1203         goto out;
1204     }
1205 
1206     IPMI_ADD_RSP_DATA(nextrec & 0xff);
1207     IPMI_ADD_RSP_DATA((nextrec >> 8) & 0xff);
1208 
1209     if (cmd[7] == 0xff) {
1210         cmd[7] = ibs->sdr.sdr[pos + 4] - cmd[6];
1211     }
1212 
1213     if ((cmd[7] + *rsp_len) > max_rsp_len) {
1214         rsp[2] = IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES;
1215         goto out;
1216     }
1217     memcpy(rsp + *rsp_len, ibs->sdr.sdr + pos + cmd[6], cmd[7]);
1218     *rsp_len += cmd[7];
1219  out:
1220     return;
1221 }
1222 
1223 static void add_sdr(IPMIBmcSim *ibs,
1224                     uint8_t *cmd, unsigned int cmd_len,
1225                     uint8_t *rsp, unsigned int *rsp_len,
1226                     unsigned int max_rsp_len)
1227 {
1228     uint16_t recid;
1229 
1230     if (sdr_add_entry(ibs, cmd + 2, cmd_len - 2, &recid)) {
1231         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1232         goto out;
1233     }
1234     IPMI_ADD_RSP_DATA(recid & 0xff);
1235     IPMI_ADD_RSP_DATA((recid >> 8) & 0xff);
1236  out:
1237     return;
1238 }
1239 
1240 static void clear_sdr_rep(IPMIBmcSim *ibs,
1241                           uint8_t *cmd, unsigned int cmd_len,
1242                           uint8_t *rsp, unsigned int *rsp_len,
1243                           unsigned int max_rsp_len)
1244 {
1245     IPMI_CHECK_CMD_LEN(8);
1246     IPMI_CHECK_RESERVATION(2, ibs->sdr.reservation);
1247     if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
1248         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1249         goto out;
1250     }
1251     if (cmd[7] == 0xaa) {
1252         ibs->sdr.next_free = 0;
1253         ibs->sdr.overflow = 0;
1254         set_timestamp(ibs, ibs->sdr.last_clear);
1255         IPMI_ADD_RSP_DATA(1); /* Erasure complete */
1256         sdr_inc_reservation(&ibs->sdr);
1257     } else if (cmd[7] == 0) {
1258         IPMI_ADD_RSP_DATA(1); /* Erasure complete */
1259     } else {
1260         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1261         goto out;
1262     }
1263  out:
1264     return;
1265 }
1266 
1267 static void get_sel_info(IPMIBmcSim *ibs,
1268                          uint8_t *cmd, unsigned int cmd_len,
1269                          uint8_t *rsp, unsigned int *rsp_len,
1270                          unsigned int max_rsp_len)
1271 {
1272     unsigned int i, val;
1273 
1274     IPMI_ADD_RSP_DATA(0x51); /* Conform to IPMI 1.5 */
1275     IPMI_ADD_RSP_DATA(ibs->sel.next_free & 0xff);
1276     IPMI_ADD_RSP_DATA((ibs->sel.next_free >> 8) & 0xff);
1277     val = (MAX_SEL_SIZE - ibs->sel.next_free) * 16;
1278     IPMI_ADD_RSP_DATA(val & 0xff);
1279     IPMI_ADD_RSP_DATA((val >> 8) & 0xff);
1280     for (i = 0; i < 4; i++) {
1281         IPMI_ADD_RSP_DATA(ibs->sel.last_addition[i]);
1282     }
1283     for (i = 0; i < 4; i++) {
1284         IPMI_ADD_RSP_DATA(ibs->sel.last_clear[i]);
1285     }
1286     /* Only support Reserve SEL */
1287     IPMI_ADD_RSP_DATA((ibs->sel.overflow << 7) | 0x02);
1288  out:
1289     return;
1290 }
1291 
1292 static void reserve_sel(IPMIBmcSim *ibs,
1293                         uint8_t *cmd, unsigned int cmd_len,
1294                         uint8_t *rsp, unsigned int *rsp_len,
1295                         unsigned int max_rsp_len)
1296 {
1297     IPMI_ADD_RSP_DATA(ibs->sel.reservation & 0xff);
1298     IPMI_ADD_RSP_DATA((ibs->sel.reservation >> 8) & 0xff);
1299  out:
1300     return;
1301 }
1302 
1303 static void get_sel_entry(IPMIBmcSim *ibs,
1304                           uint8_t *cmd, unsigned int cmd_len,
1305                           uint8_t *rsp, unsigned int *rsp_len,
1306                           unsigned int max_rsp_len)
1307 {
1308     unsigned int val;
1309 
1310     IPMI_CHECK_CMD_LEN(8);
1311     if (cmd[6]) {
1312         IPMI_CHECK_RESERVATION(2, ibs->sel.reservation);
1313     }
1314     if (ibs->sel.next_free == 0) {
1315         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1316         goto out;
1317     }
1318     if (cmd[6] > 15) {
1319         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1320         goto out;
1321     }
1322     if (cmd[7] == 0xff) {
1323         cmd[7] = 16;
1324     } else if ((cmd[7] + cmd[6]) > 16) {
1325         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1326         goto out;
1327     } else {
1328         cmd[7] += cmd[6];
1329     }
1330 
1331     val = cmd[4] | (cmd[5] << 8);
1332     if (val == 0xffff) {
1333         val = ibs->sel.next_free - 1;
1334     } else if (val >= ibs->sel.next_free) {
1335         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1336         goto out;
1337     }
1338     if ((val + 1) == ibs->sel.next_free) {
1339         IPMI_ADD_RSP_DATA(0xff);
1340         IPMI_ADD_RSP_DATA(0xff);
1341     } else {
1342         IPMI_ADD_RSP_DATA((val + 1) & 0xff);
1343         IPMI_ADD_RSP_DATA(((val + 1) >> 8) & 0xff);
1344     }
1345     for (; cmd[6] < cmd[7]; cmd[6]++) {
1346         IPMI_ADD_RSP_DATA(ibs->sel.sel[val][cmd[6]]);
1347     }
1348  out:
1349     return;
1350 }
1351 
1352 static void add_sel_entry(IPMIBmcSim *ibs,
1353                           uint8_t *cmd, unsigned int cmd_len,
1354                           uint8_t *rsp, unsigned int *rsp_len,
1355                           unsigned int max_rsp_len)
1356 {
1357     IPMI_CHECK_CMD_LEN(18);
1358     if (sel_add_event(ibs, cmd + 2)) {
1359         rsp[2] = IPMI_CC_OUT_OF_SPACE;
1360         goto out;
1361     }
1362     /* sel_add_event fills in the record number. */
1363     IPMI_ADD_RSP_DATA(cmd[2]);
1364     IPMI_ADD_RSP_DATA(cmd[3]);
1365  out:
1366     return;
1367 }
1368 
1369 static void clear_sel(IPMIBmcSim *ibs,
1370                       uint8_t *cmd, unsigned int cmd_len,
1371                       uint8_t *rsp, unsigned int *rsp_len,
1372                       unsigned int max_rsp_len)
1373 {
1374     IPMI_CHECK_CMD_LEN(8);
1375     IPMI_CHECK_RESERVATION(2, ibs->sel.reservation);
1376     if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
1377         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1378         goto out;
1379     }
1380     if (cmd[7] == 0xaa) {
1381         ibs->sel.next_free = 0;
1382         ibs->sel.overflow = 0;
1383         set_timestamp(ibs, ibs->sdr.last_clear);
1384         IPMI_ADD_RSP_DATA(1); /* Erasure complete */
1385         sel_inc_reservation(&ibs->sel);
1386     } else if (cmd[7] == 0) {
1387         IPMI_ADD_RSP_DATA(1); /* Erasure complete */
1388     } else {
1389         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1390         goto out;
1391     }
1392  out:
1393     return;
1394 }
1395 
1396 static void get_sel_time(IPMIBmcSim *ibs,
1397                          uint8_t *cmd, unsigned int cmd_len,
1398                          uint8_t *rsp, unsigned int *rsp_len,
1399                          unsigned int max_rsp_len)
1400 {
1401     uint32_t val;
1402     struct ipmi_time now;
1403 
1404     ipmi_gettime(&now);
1405     val = now.tv_sec + ibs->sel.time_offset;
1406     IPMI_ADD_RSP_DATA(val & 0xff);
1407     IPMI_ADD_RSP_DATA((val >> 8) & 0xff);
1408     IPMI_ADD_RSP_DATA((val >> 16) & 0xff);
1409     IPMI_ADD_RSP_DATA((val >> 24) & 0xff);
1410  out:
1411     return;
1412 }
1413 
1414 static void set_sel_time(IPMIBmcSim *ibs,
1415                          uint8_t *cmd, unsigned int cmd_len,
1416                          uint8_t *rsp, unsigned int *rsp_len,
1417                          unsigned int max_rsp_len)
1418 {
1419     uint32_t val;
1420     struct ipmi_time now;
1421 
1422     IPMI_CHECK_CMD_LEN(6);
1423     val = cmd[2] | (cmd[3] << 8) | (cmd[4] << 16) | (cmd[5] << 24);
1424     ipmi_gettime(&now);
1425     ibs->sel.time_offset = now.tv_sec - ((long) val);
1426  out:
1427     return;
1428 }
1429 
1430 static void set_sensor_evt_enable(IPMIBmcSim *ibs,
1431                                   uint8_t *cmd, unsigned int cmd_len,
1432                                   uint8_t *rsp, unsigned int *rsp_len,
1433                                   unsigned int max_rsp_len)
1434 {
1435     IPMISensor *sens;
1436 
1437     IPMI_CHECK_CMD_LEN(4);
1438     if ((cmd[2] > MAX_SENSORS) ||
1439             !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1440         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1441         goto out;
1442     }
1443     sens = ibs->sensors + cmd[2];
1444     switch ((cmd[3] >> 4) & 0x3) {
1445     case 0: /* Do not change */
1446         break;
1447     case 1: /* Enable bits */
1448         if (cmd_len > 4) {
1449             sens->assert_enable |= cmd[4];
1450         }
1451         if (cmd_len > 5) {
1452             sens->assert_enable |= cmd[5] << 8;
1453         }
1454         if (cmd_len > 6) {
1455             sens->deassert_enable |= cmd[6];
1456         }
1457         if (cmd_len > 7) {
1458             sens->deassert_enable |= cmd[7] << 8;
1459         }
1460         break;
1461     case 2: /* Disable bits */
1462         if (cmd_len > 4) {
1463             sens->assert_enable &= ~cmd[4];
1464         }
1465         if (cmd_len > 5) {
1466             sens->assert_enable &= ~(cmd[5] << 8);
1467         }
1468         if (cmd_len > 6) {
1469             sens->deassert_enable &= ~cmd[6];
1470         }
1471         if (cmd_len > 7) {
1472             sens->deassert_enable &= ~(cmd[7] << 8);
1473         }
1474         break;
1475     case 3:
1476         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1477         goto out;
1478     }
1479     IPMI_SENSOR_SET_RET_STATUS(sens, cmd[3]);
1480  out:
1481     return;
1482 }
1483 
1484 static void get_sensor_evt_enable(IPMIBmcSim *ibs,
1485                                   uint8_t *cmd, unsigned int cmd_len,
1486                                   uint8_t *rsp, unsigned int *rsp_len,
1487                                   unsigned int max_rsp_len)
1488 {
1489     IPMISensor *sens;
1490 
1491     IPMI_CHECK_CMD_LEN(3);
1492     if ((cmd[2] > MAX_SENSORS) ||
1493         !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1494         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1495         goto out;
1496     }
1497     sens = ibs->sensors + cmd[2];
1498     IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens));
1499     IPMI_ADD_RSP_DATA(sens->assert_enable & 0xff);
1500     IPMI_ADD_RSP_DATA((sens->assert_enable >> 8) & 0xff);
1501     IPMI_ADD_RSP_DATA(sens->deassert_enable & 0xff);
1502     IPMI_ADD_RSP_DATA((sens->deassert_enable >> 8) & 0xff);
1503  out:
1504     return;
1505 }
1506 
1507 static void rearm_sensor_evts(IPMIBmcSim *ibs,
1508                               uint8_t *cmd, unsigned int cmd_len,
1509                               uint8_t *rsp, unsigned int *rsp_len,
1510                               unsigned int max_rsp_len)
1511 {
1512     IPMISensor *sens;
1513 
1514     IPMI_CHECK_CMD_LEN(4);
1515     if ((cmd[2] > MAX_SENSORS) ||
1516         !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1517         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1518         goto out;
1519     }
1520     sens = ibs->sensors + cmd[2];
1521 
1522     if ((cmd[3] & 0x80) == 0) {
1523         /* Just clear everything */
1524         sens->states = 0;
1525         goto out;
1526     }
1527  out:
1528     return;
1529 }
1530 
1531 static void get_sensor_evt_status(IPMIBmcSim *ibs,
1532                                   uint8_t *cmd, unsigned int cmd_len,
1533                                   uint8_t *rsp, unsigned int *rsp_len,
1534                                   unsigned int max_rsp_len)
1535 {
1536     IPMISensor *sens;
1537 
1538     IPMI_CHECK_CMD_LEN(3);
1539     if ((cmd[2] > MAX_SENSORS) ||
1540         !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1541         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1542         goto out;
1543     }
1544     sens = ibs->sensors + cmd[2];
1545     IPMI_ADD_RSP_DATA(sens->reading);
1546     IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens));
1547     IPMI_ADD_RSP_DATA(sens->assert_states & 0xff);
1548     IPMI_ADD_RSP_DATA((sens->assert_states >> 8) & 0xff);
1549     IPMI_ADD_RSP_DATA(sens->deassert_states & 0xff);
1550     IPMI_ADD_RSP_DATA((sens->deassert_states >> 8) & 0xff);
1551  out:
1552     return;
1553 }
1554 
1555 static void get_sensor_reading(IPMIBmcSim *ibs,
1556                                uint8_t *cmd, unsigned int cmd_len,
1557                                uint8_t *rsp, unsigned int *rsp_len,
1558                                unsigned int max_rsp_len)
1559 {
1560     IPMISensor *sens;
1561 
1562     IPMI_CHECK_CMD_LEN(3);
1563     if ((cmd[2] > MAX_SENSORS) ||
1564             !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1565         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1566         goto out;
1567     }
1568     sens = ibs->sensors + cmd[2];
1569     IPMI_ADD_RSP_DATA(sens->reading);
1570     IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens));
1571     IPMI_ADD_RSP_DATA(sens->states & 0xff);
1572     if (IPMI_SENSOR_IS_DISCRETE(sens)) {
1573         IPMI_ADD_RSP_DATA((sens->states >> 8) & 0xff);
1574     }
1575  out:
1576     return;
1577 }
1578 
1579 static const IPMICmdHandler chassis_cmds[IPMI_NETFN_CHASSIS_MAXCMD] = {
1580     [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = chassis_capabilities,
1581     [IPMI_CMD_GET_CHASSIS_STATUS] = chassis_status,
1582     [IPMI_CMD_CHASSIS_CONTROL] = chassis_control
1583 };
1584 static const IPMINetfn chassis_netfn = {
1585     .cmd_nums = IPMI_NETFN_CHASSIS_MAXCMD,
1586     .cmd_handlers = chassis_cmds
1587 };
1588 
1589 static const IPMICmdHandler
1590 sensor_event_cmds[IPMI_NETFN_SENSOR_EVENT_MAXCMD] = {
1591     [IPMI_CMD_SET_SENSOR_EVT_ENABLE] = set_sensor_evt_enable,
1592     [IPMI_CMD_GET_SENSOR_EVT_ENABLE] = get_sensor_evt_enable,
1593     [IPMI_CMD_REARM_SENSOR_EVTS] = rearm_sensor_evts,
1594     [IPMI_CMD_GET_SENSOR_EVT_STATUS] = get_sensor_evt_status,
1595     [IPMI_CMD_GET_SENSOR_READING] = get_sensor_reading
1596 };
1597 static const IPMINetfn sensor_event_netfn = {
1598     .cmd_nums = IPMI_NETFN_SENSOR_EVENT_MAXCMD,
1599     .cmd_handlers = sensor_event_cmds
1600 };
1601 
1602 static const IPMICmdHandler app_cmds[IPMI_NETFN_APP_MAXCMD] = {
1603     [IPMI_CMD_GET_DEVICE_ID] = get_device_id,
1604     [IPMI_CMD_COLD_RESET] = cold_reset,
1605     [IPMI_CMD_WARM_RESET] = warm_reset,
1606     [IPMI_CMD_SET_BMC_GLOBAL_ENABLES] = set_bmc_global_enables,
1607     [IPMI_CMD_GET_BMC_GLOBAL_ENABLES] = get_bmc_global_enables,
1608     [IPMI_CMD_CLR_MSG_FLAGS] = clr_msg_flags,
1609     [IPMI_CMD_GET_MSG_FLAGS] = get_msg_flags,
1610     [IPMI_CMD_GET_MSG] = get_msg,
1611     [IPMI_CMD_SEND_MSG] = send_msg,
1612     [IPMI_CMD_READ_EVT_MSG_BUF] = read_evt_msg_buf,
1613     [IPMI_CMD_RESET_WATCHDOG_TIMER] = reset_watchdog_timer,
1614     [IPMI_CMD_SET_WATCHDOG_TIMER] = set_watchdog_timer,
1615     [IPMI_CMD_GET_WATCHDOG_TIMER] = get_watchdog_timer,
1616 };
1617 static const IPMINetfn app_netfn = {
1618     .cmd_nums = IPMI_NETFN_APP_MAXCMD,
1619     .cmd_handlers = app_cmds
1620 };
1621 
1622 static const IPMICmdHandler storage_cmds[IPMI_NETFN_STORAGE_MAXCMD] = {
1623     [IPMI_CMD_GET_SDR_REP_INFO] = get_sdr_rep_info,
1624     [IPMI_CMD_RESERVE_SDR_REP] = reserve_sdr_rep,
1625     [IPMI_CMD_GET_SDR] = get_sdr,
1626     [IPMI_CMD_ADD_SDR] = add_sdr,
1627     [IPMI_CMD_CLEAR_SDR_REP] = clear_sdr_rep,
1628     [IPMI_CMD_GET_SEL_INFO] = get_sel_info,
1629     [IPMI_CMD_RESERVE_SEL] = reserve_sel,
1630     [IPMI_CMD_GET_SEL_ENTRY] = get_sel_entry,
1631     [IPMI_CMD_ADD_SEL_ENTRY] = add_sel_entry,
1632     [IPMI_CMD_CLEAR_SEL] = clear_sel,
1633     [IPMI_CMD_GET_SEL_TIME] = get_sel_time,
1634     [IPMI_CMD_SET_SEL_TIME] = set_sel_time,
1635 };
1636 
1637 static const IPMINetfn storage_netfn = {
1638     .cmd_nums = IPMI_NETFN_STORAGE_MAXCMD,
1639     .cmd_handlers = storage_cmds
1640 };
1641 
1642 static void register_cmds(IPMIBmcSim *s)
1643 {
1644     ipmi_register_netfn(s, IPMI_NETFN_CHASSIS, &chassis_netfn);
1645     ipmi_register_netfn(s, IPMI_NETFN_SENSOR_EVENT, &sensor_event_netfn);
1646     ipmi_register_netfn(s, IPMI_NETFN_APP, &app_netfn);
1647     ipmi_register_netfn(s, IPMI_NETFN_STORAGE, &storage_netfn);
1648 }
1649 
1650 static const uint8_t init_sdrs[] = {
1651     /* Watchdog device */
1652     0x00, 0x00, 0x51, 0x02,   35, 0x20, 0x00, 0x00,
1653     0x23, 0x01, 0x63, 0x00, 0x23, 0x6f, 0x0f, 0x01,
1654     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1655     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
1656     'W',  'a',  't',  'c',  'h',  'd',  'o',  'g',
1657     /* End */
1658     0xff, 0xff, 0x00, 0x00, 0x00
1659 };
1660 
1661 static const VMStateDescription vmstate_ipmi_sim = {
1662     .name = TYPE_IPMI_BMC_SIMULATOR,
1663     .version_id = 1,
1664     .minimum_version_id = 1,
1665     .fields      = (VMStateField[]) {
1666         VMSTATE_UINT8(bmc_global_enables, IPMIBmcSim),
1667         VMSTATE_UINT8(msg_flags, IPMIBmcSim),
1668         VMSTATE_BOOL(watchdog_initialized, IPMIBmcSim),
1669         VMSTATE_UINT8(watchdog_use, IPMIBmcSim),
1670         VMSTATE_UINT8(watchdog_action, IPMIBmcSim),
1671         VMSTATE_UINT8(watchdog_pretimeout, IPMIBmcSim),
1672         VMSTATE_BOOL(watchdog_expired, IPMIBmcSim),
1673         VMSTATE_UINT16(watchdog_timeout, IPMIBmcSim),
1674         VMSTATE_BOOL(watchdog_running, IPMIBmcSim),
1675         VMSTATE_BOOL(watchdog_preaction_ran, IPMIBmcSim),
1676         VMSTATE_INT64(watchdog_expiry, IPMIBmcSim),
1677         VMSTATE_UINT8_ARRAY(evtbuf, IPMIBmcSim, 16),
1678         VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].status, IPMIBmcSim),
1679         VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].reading, IPMIBmcSim),
1680         VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].states, IPMIBmcSim),
1681         VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_states, IPMIBmcSim),
1682         VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].deassert_states,
1683                        IPMIBmcSim),
1684         VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_enable, IPMIBmcSim),
1685         VMSTATE_END_OF_LIST()
1686     }
1687 };
1688 
1689 static void ipmi_sim_init(Object *obj)
1690 {
1691     IPMIBmc *b = IPMI_BMC(obj);
1692     unsigned int i;
1693     unsigned int recid;
1694     IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
1695 
1696     qemu_mutex_init(&ibs->lock);
1697     QTAILQ_INIT(&ibs->rcvbufs);
1698 
1699     ibs->bmc_global_enables = (1 << IPMI_BMC_EVENT_LOG_BIT);
1700     ibs->device_id = 0x20;
1701     ibs->ipmi_version = 0x02; /* IPMI 2.0 */
1702     for (i = 0; i < 4; i++) {
1703         ibs->sel.last_addition[i] = 0xff;
1704         ibs->sel.last_clear[i] = 0xff;
1705         ibs->sdr.last_addition[i] = 0xff;
1706         ibs->sdr.last_clear[i] = 0xff;
1707     }
1708 
1709     for (i = 0;;) {
1710         int len;
1711         if ((i + 5) > sizeof(init_sdrs)) {
1712             error_report("Problem with recid 0x%4.4x: \n", i);
1713             return;
1714         }
1715         len = init_sdrs[i + 4];
1716         recid = init_sdrs[i] | (init_sdrs[i + 1] << 8);
1717         if (recid == 0xffff) {
1718             break;
1719         }
1720         if ((i + len + 5) > sizeof(init_sdrs)) {
1721             error_report("Problem with recid 0x%4.4x\n", i);
1722             return;
1723         }
1724         sdr_add_entry(ibs, init_sdrs + i, len, NULL);
1725         i += len + 5;
1726     }
1727 
1728     ipmi_init_sensors_from_sdrs(ibs);
1729     register_cmds(ibs);
1730 
1731     ibs->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ipmi_timeout, ibs);
1732 
1733     vmstate_register(NULL, 0, &vmstate_ipmi_sim, ibs);
1734 }
1735 
1736 static void ipmi_sim_class_init(ObjectClass *oc, void *data)
1737 {
1738     IPMIBmcClass *bk = IPMI_BMC_CLASS(oc);
1739 
1740     bk->handle_command = ipmi_sim_handle_command;
1741 }
1742 
1743 static const TypeInfo ipmi_sim_type = {
1744     .name          = TYPE_IPMI_BMC_SIMULATOR,
1745     .parent        = TYPE_IPMI_BMC,
1746     .instance_size = sizeof(IPMIBmcSim),
1747     .instance_init = ipmi_sim_init,
1748     .class_init    = ipmi_sim_class_init,
1749 };
1750 
1751 static void ipmi_sim_register_types(void)
1752 {
1753     type_register_static(&ipmi_sim_type);
1754 }
1755 
1756 type_init(ipmi_sim_register_types)
1757