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