xref: /qemu/hw/ipmi/ipmi_bmc_sim.c (revision 6e9965d4)
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         break;
1139 
1140     default:
1141         /* We don't support PRE_SMI */
1142         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1143         return;
1144     }
1145 
1146     ibs->watchdog_initialized = 1;
1147     ibs->watchdog_use = cmd[2] & IPMI_BMC_WATCHDOG_USE_MASK;
1148     ibs->watchdog_action = cmd[3] & IPMI_BMC_WATCHDOG_ACTION_MASK;
1149     ibs->watchdog_pretimeout = cmd[4];
1150     ibs->watchdog_expired &= ~cmd[5];
1151     ibs->watchdog_timeout = cmd[6] | (((uint16_t) cmd[7]) << 8);
1152     if (ibs->watchdog_running & IPMI_BMC_WATCHDOG_GET_DONT_STOP(ibs)) {
1153         do_watchdog_reset(ibs);
1154     } else {
1155         ibs->watchdog_running = 0;
1156     }
1157 }
1158 
1159 static void get_watchdog_timer(IPMIBmcSim *ibs,
1160                                uint8_t *cmd, unsigned int cmd_len,
1161                                uint8_t *rsp, unsigned int *rsp_len,
1162                                unsigned int max_rsp_len)
1163 {
1164     IPMI_ADD_RSP_DATA(ibs->watchdog_use);
1165     IPMI_ADD_RSP_DATA(ibs->watchdog_action);
1166     IPMI_ADD_RSP_DATA(ibs->watchdog_pretimeout);
1167     IPMI_ADD_RSP_DATA(ibs->watchdog_expired);
1168     if (ibs->watchdog_running) {
1169         long timeout;
1170         timeout = ((ibs->watchdog_expiry - ipmi_getmonotime() + 50000000)
1171                    / 100000000);
1172         IPMI_ADD_RSP_DATA(timeout & 0xff);
1173         IPMI_ADD_RSP_DATA((timeout >> 8) & 0xff);
1174     } else {
1175         IPMI_ADD_RSP_DATA(0);
1176         IPMI_ADD_RSP_DATA(0);
1177     }
1178 }
1179 
1180 static void get_sdr_rep_info(IPMIBmcSim *ibs,
1181                              uint8_t *cmd, unsigned int cmd_len,
1182                              uint8_t *rsp, unsigned int *rsp_len,
1183                              unsigned int max_rsp_len)
1184 {
1185     unsigned int i;
1186 
1187     IPMI_ADD_RSP_DATA(0x51); /* Conform to IPMI 1.5 spec */
1188     IPMI_ADD_RSP_DATA(ibs->sdr.next_rec_id & 0xff);
1189     IPMI_ADD_RSP_DATA((ibs->sdr.next_rec_id >> 8) & 0xff);
1190     IPMI_ADD_RSP_DATA((MAX_SDR_SIZE - ibs->sdr.next_free) & 0xff);
1191     IPMI_ADD_RSP_DATA(((MAX_SDR_SIZE - ibs->sdr.next_free) >> 8) & 0xff);
1192     for (i = 0; i < 4; i++) {
1193         IPMI_ADD_RSP_DATA(ibs->sdr.last_addition[i]);
1194     }
1195     for (i = 0; i < 4; i++) {
1196         IPMI_ADD_RSP_DATA(ibs->sdr.last_clear[i]);
1197     }
1198     /* Only modal support, reserve supported */
1199     IPMI_ADD_RSP_DATA((ibs->sdr.overflow << 7) | 0x22);
1200 }
1201 
1202 static void reserve_sdr_rep(IPMIBmcSim *ibs,
1203                             uint8_t *cmd, unsigned int cmd_len,
1204                             uint8_t *rsp, unsigned int *rsp_len,
1205                             unsigned int max_rsp_len)
1206 {
1207     IPMI_ADD_RSP_DATA(ibs->sdr.reservation & 0xff);
1208     IPMI_ADD_RSP_DATA((ibs->sdr.reservation >> 8) & 0xff);
1209 }
1210 
1211 static void get_sdr(IPMIBmcSim *ibs,
1212                     uint8_t *cmd, unsigned int cmd_len,
1213                     uint8_t *rsp, unsigned int *rsp_len,
1214                     unsigned int max_rsp_len)
1215 {
1216     unsigned int pos;
1217     uint16_t nextrec;
1218     struct ipmi_sdr_header *sdrh;
1219 
1220     IPMI_CHECK_CMD_LEN(8);
1221     if (cmd[6]) {
1222         IPMI_CHECK_RESERVATION(2, ibs->sdr.reservation);
1223     }
1224     pos = 0;
1225     if (sdr_find_entry(&ibs->sdr, cmd[4] | (cmd[5] << 8),
1226                        &pos, &nextrec)) {
1227         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1228         return;
1229     }
1230 
1231     sdrh = (struct ipmi_sdr_header *) &ibs->sdr.sdr[pos];
1232 
1233     if (cmd[6] > ipmi_sdr_length(sdrh)) {
1234         rsp[2] = IPMI_CC_PARM_OUT_OF_RANGE;
1235         return;
1236     }
1237 
1238     IPMI_ADD_RSP_DATA(nextrec & 0xff);
1239     IPMI_ADD_RSP_DATA((nextrec >> 8) & 0xff);
1240 
1241     if (cmd[7] == 0xff) {
1242         cmd[7] = ipmi_sdr_length(sdrh) - cmd[6];
1243     }
1244 
1245     if ((cmd[7] + *rsp_len) > max_rsp_len) {
1246         rsp[2] = IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES;
1247         return;
1248     }
1249     memcpy(rsp + *rsp_len, ibs->sdr.sdr + pos + cmd[6], cmd[7]);
1250     *rsp_len += cmd[7];
1251 }
1252 
1253 static void add_sdr(IPMIBmcSim *ibs,
1254                     uint8_t *cmd, unsigned int cmd_len,
1255                     uint8_t *rsp, unsigned int *rsp_len,
1256                     unsigned int max_rsp_len)
1257 {
1258     uint16_t recid;
1259     struct ipmi_sdr_header *sdrh = (struct ipmi_sdr_header *) cmd + 2;
1260 
1261     if (sdr_add_entry(ibs, sdrh, cmd_len - 2, &recid)) {
1262         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1263         return;
1264     }
1265     IPMI_ADD_RSP_DATA(recid & 0xff);
1266     IPMI_ADD_RSP_DATA((recid >> 8) & 0xff);
1267 }
1268 
1269 static void clear_sdr_rep(IPMIBmcSim *ibs,
1270                           uint8_t *cmd, unsigned int cmd_len,
1271                           uint8_t *rsp, unsigned int *rsp_len,
1272                           unsigned int max_rsp_len)
1273 {
1274     IPMI_CHECK_CMD_LEN(8);
1275     IPMI_CHECK_RESERVATION(2, ibs->sdr.reservation);
1276     if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
1277         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1278         return;
1279     }
1280     if (cmd[7] == 0xaa) {
1281         ibs->sdr.next_free = 0;
1282         ibs->sdr.overflow = 0;
1283         set_timestamp(ibs, ibs->sdr.last_clear);
1284         IPMI_ADD_RSP_DATA(1); /* Erasure complete */
1285         sdr_inc_reservation(&ibs->sdr);
1286     } else if (cmd[7] == 0) {
1287         IPMI_ADD_RSP_DATA(1); /* Erasure complete */
1288     } else {
1289         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1290         return;
1291     }
1292 }
1293 
1294 static void get_sel_info(IPMIBmcSim *ibs,
1295                          uint8_t *cmd, unsigned int cmd_len,
1296                          uint8_t *rsp, unsigned int *rsp_len,
1297                          unsigned int max_rsp_len)
1298 {
1299     unsigned int i, val;
1300 
1301     IPMI_ADD_RSP_DATA(0x51); /* Conform to IPMI 1.5 */
1302     IPMI_ADD_RSP_DATA(ibs->sel.next_free & 0xff);
1303     IPMI_ADD_RSP_DATA((ibs->sel.next_free >> 8) & 0xff);
1304     val = (MAX_SEL_SIZE - ibs->sel.next_free) * 16;
1305     IPMI_ADD_RSP_DATA(val & 0xff);
1306     IPMI_ADD_RSP_DATA((val >> 8) & 0xff);
1307     for (i = 0; i < 4; i++) {
1308         IPMI_ADD_RSP_DATA(ibs->sel.last_addition[i]);
1309     }
1310     for (i = 0; i < 4; i++) {
1311         IPMI_ADD_RSP_DATA(ibs->sel.last_clear[i]);
1312     }
1313     /* Only support Reserve SEL */
1314     IPMI_ADD_RSP_DATA((ibs->sel.overflow << 7) | 0x02);
1315 }
1316 
1317 static void reserve_sel(IPMIBmcSim *ibs,
1318                         uint8_t *cmd, unsigned int cmd_len,
1319                         uint8_t *rsp, unsigned int *rsp_len,
1320                         unsigned int max_rsp_len)
1321 {
1322     IPMI_ADD_RSP_DATA(ibs->sel.reservation & 0xff);
1323     IPMI_ADD_RSP_DATA((ibs->sel.reservation >> 8) & 0xff);
1324 }
1325 
1326 static void get_sel_entry(IPMIBmcSim *ibs,
1327                           uint8_t *cmd, unsigned int cmd_len,
1328                           uint8_t *rsp, unsigned int *rsp_len,
1329                           unsigned int max_rsp_len)
1330 {
1331     unsigned int val;
1332 
1333     IPMI_CHECK_CMD_LEN(8);
1334     if (cmd[6]) {
1335         IPMI_CHECK_RESERVATION(2, ibs->sel.reservation);
1336     }
1337     if (ibs->sel.next_free == 0) {
1338         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1339         return;
1340     }
1341     if (cmd[6] > 15) {
1342         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1343         return;
1344     }
1345     if (cmd[7] == 0xff) {
1346         cmd[7] = 16;
1347     } else if ((cmd[7] + cmd[6]) > 16) {
1348         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1349         return;
1350     } else {
1351         cmd[7] += cmd[6];
1352     }
1353 
1354     val = cmd[4] | (cmd[5] << 8);
1355     if (val == 0xffff) {
1356         val = ibs->sel.next_free - 1;
1357     } else if (val >= ibs->sel.next_free) {
1358         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1359         return;
1360     }
1361     if ((val + 1) == ibs->sel.next_free) {
1362         IPMI_ADD_RSP_DATA(0xff);
1363         IPMI_ADD_RSP_DATA(0xff);
1364     } else {
1365         IPMI_ADD_RSP_DATA((val + 1) & 0xff);
1366         IPMI_ADD_RSP_DATA(((val + 1) >> 8) & 0xff);
1367     }
1368     for (; cmd[6] < cmd[7]; cmd[6]++) {
1369         IPMI_ADD_RSP_DATA(ibs->sel.sel[val][cmd[6]]);
1370     }
1371 }
1372 
1373 static void add_sel_entry(IPMIBmcSim *ibs,
1374                           uint8_t *cmd, unsigned int cmd_len,
1375                           uint8_t *rsp, unsigned int *rsp_len,
1376                           unsigned int max_rsp_len)
1377 {
1378     IPMI_CHECK_CMD_LEN(18);
1379     if (sel_add_event(ibs, cmd + 2)) {
1380         rsp[2] = IPMI_CC_OUT_OF_SPACE;
1381         return;
1382     }
1383     /* sel_add_event fills in the record number. */
1384     IPMI_ADD_RSP_DATA(cmd[2]);
1385     IPMI_ADD_RSP_DATA(cmd[3]);
1386 }
1387 
1388 static void clear_sel(IPMIBmcSim *ibs,
1389                       uint8_t *cmd, unsigned int cmd_len,
1390                       uint8_t *rsp, unsigned int *rsp_len,
1391                       unsigned int max_rsp_len)
1392 {
1393     IPMI_CHECK_CMD_LEN(8);
1394     IPMI_CHECK_RESERVATION(2, ibs->sel.reservation);
1395     if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
1396         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1397         return;
1398     }
1399     if (cmd[7] == 0xaa) {
1400         ibs->sel.next_free = 0;
1401         ibs->sel.overflow = 0;
1402         set_timestamp(ibs, ibs->sdr.last_clear);
1403         IPMI_ADD_RSP_DATA(1); /* Erasure complete */
1404         sel_inc_reservation(&ibs->sel);
1405     } else if (cmd[7] == 0) {
1406         IPMI_ADD_RSP_DATA(1); /* Erasure complete */
1407     } else {
1408         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1409         return;
1410     }
1411 }
1412 
1413 static void get_sel_time(IPMIBmcSim *ibs,
1414                          uint8_t *cmd, unsigned int cmd_len,
1415                          uint8_t *rsp, unsigned int *rsp_len,
1416                          unsigned int max_rsp_len)
1417 {
1418     uint32_t val;
1419     struct ipmi_time now;
1420 
1421     ipmi_gettime(&now);
1422     val = now.tv_sec + ibs->sel.time_offset;
1423     IPMI_ADD_RSP_DATA(val & 0xff);
1424     IPMI_ADD_RSP_DATA((val >> 8) & 0xff);
1425     IPMI_ADD_RSP_DATA((val >> 16) & 0xff);
1426     IPMI_ADD_RSP_DATA((val >> 24) & 0xff);
1427 }
1428 
1429 static void set_sel_time(IPMIBmcSim *ibs,
1430                          uint8_t *cmd, unsigned int cmd_len,
1431                          uint8_t *rsp, unsigned int *rsp_len,
1432                          unsigned int max_rsp_len)
1433 {
1434     uint32_t val;
1435     struct ipmi_time now;
1436 
1437     IPMI_CHECK_CMD_LEN(6);
1438     val = cmd[2] | (cmd[3] << 8) | (cmd[4] << 16) | (cmd[5] << 24);
1439     ipmi_gettime(&now);
1440     ibs->sel.time_offset = now.tv_sec - ((long) val);
1441 }
1442 
1443 static void set_sensor_evt_enable(IPMIBmcSim *ibs,
1444                                   uint8_t *cmd, unsigned int cmd_len,
1445                                   uint8_t *rsp, unsigned int *rsp_len,
1446                                   unsigned int max_rsp_len)
1447 {
1448     IPMISensor *sens;
1449 
1450     IPMI_CHECK_CMD_LEN(4);
1451     if ((cmd[2] > MAX_SENSORS) ||
1452             !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1453         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1454         return;
1455     }
1456     sens = ibs->sensors + cmd[2];
1457     switch ((cmd[3] >> 4) & 0x3) {
1458     case 0: /* Do not change */
1459         break;
1460     case 1: /* Enable bits */
1461         if (cmd_len > 4) {
1462             sens->assert_enable |= cmd[4];
1463         }
1464         if (cmd_len > 5) {
1465             sens->assert_enable |= cmd[5] << 8;
1466         }
1467         if (cmd_len > 6) {
1468             sens->deassert_enable |= cmd[6];
1469         }
1470         if (cmd_len > 7) {
1471             sens->deassert_enable |= cmd[7] << 8;
1472         }
1473         break;
1474     case 2: /* Disable bits */
1475         if (cmd_len > 4) {
1476             sens->assert_enable &= ~cmd[4];
1477         }
1478         if (cmd_len > 5) {
1479             sens->assert_enable &= ~(cmd[5] << 8);
1480         }
1481         if (cmd_len > 6) {
1482             sens->deassert_enable &= ~cmd[6];
1483         }
1484         if (cmd_len > 7) {
1485             sens->deassert_enable &= ~(cmd[7] << 8);
1486         }
1487         break;
1488     case 3:
1489         rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
1490         return;
1491     }
1492     IPMI_SENSOR_SET_RET_STATUS(sens, cmd[3]);
1493 }
1494 
1495 static void get_sensor_evt_enable(IPMIBmcSim *ibs,
1496                                   uint8_t *cmd, unsigned int cmd_len,
1497                                   uint8_t *rsp, unsigned int *rsp_len,
1498                                   unsigned int max_rsp_len)
1499 {
1500     IPMISensor *sens;
1501 
1502     IPMI_CHECK_CMD_LEN(3);
1503     if ((cmd[2] > MAX_SENSORS) ||
1504         !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1505         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1506         return;
1507     }
1508     sens = ibs->sensors + cmd[2];
1509     IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens));
1510     IPMI_ADD_RSP_DATA(sens->assert_enable & 0xff);
1511     IPMI_ADD_RSP_DATA((sens->assert_enable >> 8) & 0xff);
1512     IPMI_ADD_RSP_DATA(sens->deassert_enable & 0xff);
1513     IPMI_ADD_RSP_DATA((sens->deassert_enable >> 8) & 0xff);
1514 }
1515 
1516 static void rearm_sensor_evts(IPMIBmcSim *ibs,
1517                               uint8_t *cmd, unsigned int cmd_len,
1518                               uint8_t *rsp, unsigned int *rsp_len,
1519                               unsigned int max_rsp_len)
1520 {
1521     IPMISensor *sens;
1522 
1523     IPMI_CHECK_CMD_LEN(4);
1524     if ((cmd[2] > MAX_SENSORS) ||
1525         !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1526         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1527         return;
1528     }
1529     sens = ibs->sensors + cmd[2];
1530 
1531     if ((cmd[3] & 0x80) == 0) {
1532         /* Just clear everything */
1533         sens->states = 0;
1534         return;
1535     }
1536 }
1537 
1538 static void get_sensor_evt_status(IPMIBmcSim *ibs,
1539                                   uint8_t *cmd, unsigned int cmd_len,
1540                                   uint8_t *rsp, unsigned int *rsp_len,
1541                                   unsigned int max_rsp_len)
1542 {
1543     IPMISensor *sens;
1544 
1545     IPMI_CHECK_CMD_LEN(3);
1546     if ((cmd[2] > MAX_SENSORS) ||
1547         !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1548         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1549         return;
1550     }
1551     sens = ibs->sensors + cmd[2];
1552     IPMI_ADD_RSP_DATA(sens->reading);
1553     IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens));
1554     IPMI_ADD_RSP_DATA(sens->assert_states & 0xff);
1555     IPMI_ADD_RSP_DATA((sens->assert_states >> 8) & 0xff);
1556     IPMI_ADD_RSP_DATA(sens->deassert_states & 0xff);
1557     IPMI_ADD_RSP_DATA((sens->deassert_states >> 8) & 0xff);
1558 }
1559 
1560 static void get_sensor_reading(IPMIBmcSim *ibs,
1561                                uint8_t *cmd, unsigned int cmd_len,
1562                                uint8_t *rsp, unsigned int *rsp_len,
1563                                unsigned int max_rsp_len)
1564 {
1565     IPMISensor *sens;
1566 
1567     IPMI_CHECK_CMD_LEN(3);
1568     if ((cmd[2] > MAX_SENSORS) ||
1569             !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1570         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1571         return;
1572     }
1573     sens = ibs->sensors + cmd[2];
1574     IPMI_ADD_RSP_DATA(sens->reading);
1575     IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens));
1576     IPMI_ADD_RSP_DATA(sens->states & 0xff);
1577     if (IPMI_SENSOR_IS_DISCRETE(sens)) {
1578         IPMI_ADD_RSP_DATA((sens->states >> 8) & 0xff);
1579     }
1580 }
1581 
1582 static void set_sensor_type(IPMIBmcSim *ibs,
1583                                uint8_t *cmd, unsigned int cmd_len,
1584                                uint8_t *rsp, unsigned int *rsp_len,
1585                                unsigned int max_rsp_len)
1586 {
1587     IPMISensor *sens;
1588 
1589 
1590     IPMI_CHECK_CMD_LEN(5);
1591     if ((cmd[2] > MAX_SENSORS) ||
1592             !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1593         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1594         return;
1595     }
1596     sens = ibs->sensors + cmd[2];
1597     sens->sensor_type = cmd[3];
1598     sens->evt_reading_type_code = cmd[4] & 0x7f;
1599 }
1600 
1601 static void get_sensor_type(IPMIBmcSim *ibs,
1602                                uint8_t *cmd, unsigned int cmd_len,
1603                                uint8_t *rsp, unsigned int *rsp_len,
1604                                unsigned int max_rsp_len)
1605 {
1606     IPMISensor *sens;
1607 
1608 
1609     IPMI_CHECK_CMD_LEN(3);
1610     if ((cmd[2] > MAX_SENSORS) ||
1611             !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1612         rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
1613         return;
1614     }
1615     sens = ibs->sensors + cmd[2];
1616     IPMI_ADD_RSP_DATA(sens->sensor_type);
1617     IPMI_ADD_RSP_DATA(sens->evt_reading_type_code);
1618 }
1619 
1620 
1621 static const IPMICmdHandler chassis_cmds[] = {
1622     [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = chassis_capabilities,
1623     [IPMI_CMD_GET_CHASSIS_STATUS] = chassis_status,
1624     [IPMI_CMD_CHASSIS_CONTROL] = chassis_control,
1625     [IPMI_CMD_GET_SYS_RESTART_CAUSE] = chassis_get_sys_restart_cause
1626 };
1627 static const IPMINetfn chassis_netfn = {
1628     .cmd_nums = ARRAY_SIZE(chassis_cmds),
1629     .cmd_handlers = chassis_cmds
1630 };
1631 
1632 static const IPMICmdHandler sensor_event_cmds[] = {
1633     [IPMI_CMD_SET_SENSOR_EVT_ENABLE] = set_sensor_evt_enable,
1634     [IPMI_CMD_GET_SENSOR_EVT_ENABLE] = get_sensor_evt_enable,
1635     [IPMI_CMD_REARM_SENSOR_EVTS] = rearm_sensor_evts,
1636     [IPMI_CMD_GET_SENSOR_EVT_STATUS] = get_sensor_evt_status,
1637     [IPMI_CMD_GET_SENSOR_READING] = get_sensor_reading,
1638     [IPMI_CMD_SET_SENSOR_TYPE] = set_sensor_type,
1639     [IPMI_CMD_GET_SENSOR_TYPE] = get_sensor_type,
1640 };
1641 static const IPMINetfn sensor_event_netfn = {
1642     .cmd_nums = ARRAY_SIZE(sensor_event_cmds),
1643     .cmd_handlers = sensor_event_cmds
1644 };
1645 
1646 static const IPMICmdHandler app_cmds[] = {
1647     [IPMI_CMD_GET_DEVICE_ID] = get_device_id,
1648     [IPMI_CMD_COLD_RESET] = cold_reset,
1649     [IPMI_CMD_WARM_RESET] = warm_reset,
1650     [IPMI_CMD_SET_ACPI_POWER_STATE] = set_acpi_power_state,
1651     [IPMI_CMD_GET_ACPI_POWER_STATE] = get_acpi_power_state,
1652     [IPMI_CMD_GET_DEVICE_GUID] = get_device_guid,
1653     [IPMI_CMD_SET_BMC_GLOBAL_ENABLES] = set_bmc_global_enables,
1654     [IPMI_CMD_GET_BMC_GLOBAL_ENABLES] = get_bmc_global_enables,
1655     [IPMI_CMD_CLR_MSG_FLAGS] = clr_msg_flags,
1656     [IPMI_CMD_GET_MSG_FLAGS] = get_msg_flags,
1657     [IPMI_CMD_GET_MSG] = get_msg,
1658     [IPMI_CMD_SEND_MSG] = send_msg,
1659     [IPMI_CMD_READ_EVT_MSG_BUF] = read_evt_msg_buf,
1660     [IPMI_CMD_RESET_WATCHDOG_TIMER] = reset_watchdog_timer,
1661     [IPMI_CMD_SET_WATCHDOG_TIMER] = set_watchdog_timer,
1662     [IPMI_CMD_GET_WATCHDOG_TIMER] = get_watchdog_timer,
1663 };
1664 static const IPMINetfn app_netfn = {
1665     .cmd_nums = ARRAY_SIZE(app_cmds),
1666     .cmd_handlers = app_cmds
1667 };
1668 
1669 static const IPMICmdHandler storage_cmds[] = {
1670     [IPMI_CMD_GET_SDR_REP_INFO] = get_sdr_rep_info,
1671     [IPMI_CMD_RESERVE_SDR_REP] = reserve_sdr_rep,
1672     [IPMI_CMD_GET_SDR] = get_sdr,
1673     [IPMI_CMD_ADD_SDR] = add_sdr,
1674     [IPMI_CMD_CLEAR_SDR_REP] = clear_sdr_rep,
1675     [IPMI_CMD_GET_SEL_INFO] = get_sel_info,
1676     [IPMI_CMD_RESERVE_SEL] = reserve_sel,
1677     [IPMI_CMD_GET_SEL_ENTRY] = get_sel_entry,
1678     [IPMI_CMD_ADD_SEL_ENTRY] = add_sel_entry,
1679     [IPMI_CMD_CLEAR_SEL] = clear_sel,
1680     [IPMI_CMD_GET_SEL_TIME] = get_sel_time,
1681     [IPMI_CMD_SET_SEL_TIME] = set_sel_time,
1682 };
1683 
1684 static const IPMINetfn storage_netfn = {
1685     .cmd_nums = ARRAY_SIZE(storage_cmds),
1686     .cmd_handlers = storage_cmds
1687 };
1688 
1689 static void register_cmds(IPMIBmcSim *s)
1690 {
1691     ipmi_register_netfn(s, IPMI_NETFN_CHASSIS, &chassis_netfn);
1692     ipmi_register_netfn(s, IPMI_NETFN_SENSOR_EVENT, &sensor_event_netfn);
1693     ipmi_register_netfn(s, IPMI_NETFN_APP, &app_netfn);
1694     ipmi_register_netfn(s, IPMI_NETFN_STORAGE, &storage_netfn);
1695 }
1696 
1697 static const uint8_t init_sdrs[] = {
1698     /* Watchdog device */
1699     0x00, 0x00, 0x51, 0x02,   35, 0x20, 0x00, 0x00,
1700     0x23, 0x01, 0x63, 0x00, 0x23, 0x6f, 0x0f, 0x01,
1701     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1702     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
1703     'W',  'a',  't',  'c',  'h',  'd',  'o',  'g',
1704     /* End */
1705     0xff, 0xff, 0x00, 0x00, 0x00
1706 };
1707 
1708 static const VMStateDescription vmstate_ipmi_sim = {
1709     .name = TYPE_IPMI_BMC_SIMULATOR,
1710     .version_id = 1,
1711     .minimum_version_id = 1,
1712     .fields      = (VMStateField[]) {
1713         VMSTATE_UINT8(bmc_global_enables, IPMIBmcSim),
1714         VMSTATE_UINT8(msg_flags, IPMIBmcSim),
1715         VMSTATE_BOOL(watchdog_initialized, IPMIBmcSim),
1716         VMSTATE_UINT8(watchdog_use, IPMIBmcSim),
1717         VMSTATE_UINT8(watchdog_action, IPMIBmcSim),
1718         VMSTATE_UINT8(watchdog_pretimeout, IPMIBmcSim),
1719         VMSTATE_BOOL(watchdog_expired, IPMIBmcSim),
1720         VMSTATE_UINT16(watchdog_timeout, IPMIBmcSim),
1721         VMSTATE_BOOL(watchdog_running, IPMIBmcSim),
1722         VMSTATE_BOOL(watchdog_preaction_ran, IPMIBmcSim),
1723         VMSTATE_INT64(watchdog_expiry, IPMIBmcSim),
1724         VMSTATE_UINT8_ARRAY(evtbuf, IPMIBmcSim, 16),
1725         VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].status, IPMIBmcSim),
1726         VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].reading, IPMIBmcSim),
1727         VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].states, IPMIBmcSim),
1728         VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_states, IPMIBmcSim),
1729         VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].deassert_states,
1730                        IPMIBmcSim),
1731         VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_enable, IPMIBmcSim),
1732         VMSTATE_END_OF_LIST()
1733     }
1734 };
1735 
1736 static void ipmi_sim_init(Object *obj)
1737 {
1738     IPMIBmc *b = IPMI_BMC(obj);
1739     unsigned int i;
1740     unsigned int recid;
1741     IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
1742 
1743     qemu_mutex_init(&ibs->lock);
1744     QTAILQ_INIT(&ibs->rcvbufs);
1745 
1746     ibs->bmc_global_enables = (1 << IPMI_BMC_EVENT_LOG_BIT);
1747     ibs->device_id = 0x20;
1748     ibs->ipmi_version = 0x02; /* IPMI 2.0 */
1749     ibs->restart_cause = 0;
1750     for (i = 0; i < 4; i++) {
1751         ibs->sel.last_addition[i] = 0xff;
1752         ibs->sel.last_clear[i] = 0xff;
1753         ibs->sdr.last_addition[i] = 0xff;
1754         ibs->sdr.last_clear[i] = 0xff;
1755     }
1756 
1757     for (i = 0;;) {
1758         struct ipmi_sdr_header *sdrh;
1759         int len;
1760         if ((i + IPMI_SDR_HEADER_SIZE) > sizeof(init_sdrs)) {
1761             error_report("Problem with recid 0x%4.4x", i);
1762             return;
1763         }
1764         sdrh = (struct ipmi_sdr_header *) &init_sdrs[i];
1765         len = ipmi_sdr_length(sdrh);
1766         recid = ipmi_sdr_recid(sdrh);
1767         if (recid == 0xffff) {
1768             break;
1769         }
1770         if ((i + len) > sizeof(init_sdrs)) {
1771             error_report("Problem with recid 0x%4.4x", i);
1772             return;
1773         }
1774         sdr_add_entry(ibs, sdrh, len, NULL);
1775         i += len;
1776     }
1777 
1778     ibs->acpi_power_state[0] = 0;
1779     ibs->acpi_power_state[1] = 0;
1780 
1781     if (qemu_uuid_set) {
1782         memcpy(&ibs->uuid, qemu_uuid, 16);
1783     } else {
1784         memset(&ibs->uuid, 0, 16);
1785     }
1786 
1787     ipmi_init_sensors_from_sdrs(ibs);
1788     register_cmds(ibs);
1789 
1790     ibs->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ipmi_timeout, ibs);
1791 
1792     vmstate_register(NULL, 0, &vmstate_ipmi_sim, ibs);
1793 }
1794 
1795 static void ipmi_sim_class_init(ObjectClass *oc, void *data)
1796 {
1797     IPMIBmcClass *bk = IPMI_BMC_CLASS(oc);
1798 
1799     bk->handle_command = ipmi_sim_handle_command;
1800 }
1801 
1802 static const TypeInfo ipmi_sim_type = {
1803     .name          = TYPE_IPMI_BMC_SIMULATOR,
1804     .parent        = TYPE_IPMI_BMC,
1805     .instance_size = sizeof(IPMIBmcSim),
1806     .instance_init = ipmi_sim_init,
1807     .class_init    = ipmi_sim_class_init,
1808 };
1809 
1810 static void ipmi_sim_register_types(void)
1811 {
1812     type_register_static(&ipmi_sim_type);
1813 }
1814 
1815 type_init(ipmi_sim_register_types)
1816