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