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