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