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