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