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