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