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