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