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