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