25
#include "qemu/osdep.h"
26
#include "sysemu/sysemu.h"
27
#include "qemu/timer.h"
28
#include "hw/ipmi/ipmi.h"
29
#include "qemu/error-report.h"
30
#include "qemu/module.h"
32
#include "hw/qdev-properties.h"
33
#include "hw/qdev-properties-system.h"
34
#include "migration/vmstate.h"
36
#define IPMI_NETFN_CHASSIS 0x00
38
#define IPMI_CMD_GET_CHASSIS_CAPABILITIES 0x00
39
#define IPMI_CMD_GET_CHASSIS_STATUS 0x01
40
#define IPMI_CMD_CHASSIS_CONTROL 0x02
41
#define IPMI_CMD_GET_SYS_RESTART_CAUSE 0x09
43
#define IPMI_NETFN_SENSOR_EVENT 0x04
45
#define IPMI_CMD_PLATFORM_EVENT_MSG 0x02
46
#define IPMI_CMD_SET_SENSOR_EVT_ENABLE 0x28
47
#define IPMI_CMD_GET_SENSOR_EVT_ENABLE 0x29
48
#define IPMI_CMD_REARM_SENSOR_EVTS 0x2a
49
#define IPMI_CMD_GET_SENSOR_EVT_STATUS 0x2b
50
#define IPMI_CMD_GET_SENSOR_READING 0x2d
51
#define IPMI_CMD_SET_SENSOR_TYPE 0x2e
52
#define IPMI_CMD_GET_SENSOR_TYPE 0x2f
53
#define IPMI_CMD_SET_SENSOR_READING 0x30
57
#define IPMI_CMD_GET_DEVICE_ID 0x01
58
#define IPMI_CMD_COLD_RESET 0x02
59
#define IPMI_CMD_WARM_RESET 0x03
60
#define IPMI_CMD_SET_ACPI_POWER_STATE 0x06
61
#define IPMI_CMD_GET_ACPI_POWER_STATE 0x07
62
#define IPMI_CMD_GET_DEVICE_GUID 0x08
63
#define IPMI_CMD_RESET_WATCHDOG_TIMER 0x22
64
#define IPMI_CMD_SET_WATCHDOG_TIMER 0x24
65
#define IPMI_CMD_GET_WATCHDOG_TIMER 0x25
66
#define IPMI_CMD_SET_BMC_GLOBAL_ENABLES 0x2e
67
#define IPMI_CMD_GET_BMC_GLOBAL_ENABLES 0x2f
68
#define IPMI_CMD_CLR_MSG_FLAGS 0x30
69
#define IPMI_CMD_GET_MSG_FLAGS 0x31
70
#define IPMI_CMD_GET_MSG 0x33
71
#define IPMI_CMD_SEND_MSG 0x34
72
#define IPMI_CMD_READ_EVT_MSG_BUF 0x35
74
#define IPMI_NETFN_STORAGE 0x0a
76
#define IPMI_CMD_GET_SDR_REP_INFO 0x20
77
#define IPMI_CMD_GET_SDR_REP_ALLOC_INFO 0x21
78
#define IPMI_CMD_RESERVE_SDR_REP 0x22
79
#define IPMI_CMD_GET_SDR 0x23
80
#define IPMI_CMD_ADD_SDR 0x24
81
#define IPMI_CMD_PARTIAL_ADD_SDR 0x25
82
#define IPMI_CMD_DELETE_SDR 0x26
83
#define IPMI_CMD_CLEAR_SDR_REP 0x27
84
#define IPMI_CMD_GET_SDR_REP_TIME 0x28
85
#define IPMI_CMD_SET_SDR_REP_TIME 0x29
86
#define IPMI_CMD_ENTER_SDR_REP_UPD_MODE 0x2A
87
#define IPMI_CMD_EXIT_SDR_REP_UPD_MODE 0x2B
88
#define IPMI_CMD_RUN_INIT_AGENT 0x2C
89
#define IPMI_CMD_GET_FRU_AREA_INFO 0x10
90
#define IPMI_CMD_READ_FRU_DATA 0x11
91
#define IPMI_CMD_WRITE_FRU_DATA 0x12
92
#define IPMI_CMD_GET_SEL_INFO 0x40
93
#define IPMI_CMD_GET_SEL_ALLOC_INFO 0x41
94
#define IPMI_CMD_RESERVE_SEL 0x42
95
#define IPMI_CMD_GET_SEL_ENTRY 0x43
96
#define IPMI_CMD_ADD_SEL_ENTRY 0x44
97
#define IPMI_CMD_PARTIAL_ADD_SEL_ENTRY 0x45
98
#define IPMI_CMD_DELETE_SEL_ENTRY 0x46
99
#define IPMI_CMD_CLEAR_SEL 0x47
100
#define IPMI_CMD_GET_SEL_TIME 0x48
101
#define IPMI_CMD_SET_SEL_TIME 0x49
110
#define MAX_SEL_SIZE 128
112
typedef struct IPMISel {
113
uint8_t sel[MAX_SEL_SIZE][16];
114
unsigned int next_free;
116
uint16_t reservation;
117
uint8_t last_addition[4];
118
uint8_t last_clear[4];
122
#define MAX_SDR_SIZE 16384
124
typedef struct IPMISdr {
125
uint8_t sdr[MAX_SDR_SIZE];
126
unsigned int next_free;
127
uint16_t next_rec_id;
128
uint16_t reservation;
129
uint8_t last_addition[4];
130
uint8_t last_clear[4];
134
typedef struct IPMIFru {
136
unsigned int nentries;
141
typedef struct IPMISensor {
144
uint16_t states_suppt;
145
uint16_t assert_suppt;
146
uint16_t deassert_suppt;
148
uint16_t assert_states;
149
uint16_t deassert_states;
150
uint16_t assert_enable;
151
uint16_t deassert_enable;
153
uint8_t evt_reading_type_code;
155
#define IPMI_SENSOR_GET_PRESENT(s) ((s)->status & 0x01)
156
#define IPMI_SENSOR_SET_PRESENT(s, v) ((s)->status = (s->status & ~0x01) | \
158
#define IPMI_SENSOR_GET_SCAN_ON(s) ((s)->status & 0x40)
159
#define IPMI_SENSOR_SET_SCAN_ON(s, v) ((s)->status = (s->status & ~0x40) | \
161
#define IPMI_SENSOR_GET_EVENTS_ON(s) ((s)->status & 0x80)
162
#define IPMI_SENSOR_SET_EVENTS_ON(s, v) ((s)->status = (s->status & ~0x80) | \
164
#define IPMI_SENSOR_GET_RET_STATUS(s) ((s)->status & 0xc0)
165
#define IPMI_SENSOR_SET_RET_STATUS(s, v) ((s)->status = (s->status & ~0xc0) | \
167
#define IPMI_SENSOR_IS_DISCRETE(s) ((s)->evt_reading_type_code != 1)
169
#define MAX_SENSORS 20
170
#define IPMI_WATCHDOG_SENSOR 0
174
typedef struct IPMIRcvBufEntry {
175
QTAILQ_ENTRY(IPMIRcvBufEntry) entry;
177
uint8_t buf[MAX_IPMI_MSG_SIZE];
185
uint8_t bmc_global_enables;
188
bool watchdog_initialized;
189
uint8_t watchdog_use;
190
uint8_t watchdog_action;
191
uint8_t watchdog_pretimeout;
192
uint8_t watchdog_expired;
193
uint16_t watchdog_timeout;
195
bool watchdog_running;
196
bool watchdog_preaction_ran;
197
int64_t watchdog_expiry;
200
uint8_t ipmi_version;
207
uint8_t restart_cause;
209
uint8_t acpi_power_state[2];
215
IPMISensor sensors[MAX_SENSORS];
219
const IPMINetfn *netfns[MAX_NETFNS / 2];
224
QTAILQ_HEAD(, IPMIRcvBufEntry) rcvbufs;
227
#define IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK (1 << 3)
228
#define IPMI_BMC_MSG_FLAG_EVT_BUF_FULL (1 << 1)
229
#define IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE (1 << 0)
230
#define IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(s) \
231
(IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK & (s)->msg_flags)
232
#define IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(s) \
233
(IPMI_BMC_MSG_FLAG_EVT_BUF_FULL & (s)->msg_flags)
234
#define IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(s) \
235
(IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE & (s)->msg_flags)
237
#define IPMI_BMC_RCV_MSG_QUEUE_INT_BIT 0
238
#define IPMI_BMC_EVBUF_FULL_INT_BIT 1
239
#define IPMI_BMC_EVENT_MSG_BUF_BIT 2
240
#define IPMI_BMC_EVENT_LOG_BIT 3
241
#define IPMI_BMC_MSG_INTS_ON(s) ((s)->bmc_global_enables & \
242
(1 << IPMI_BMC_RCV_MSG_QUEUE_INT_BIT))
243
#define IPMI_BMC_EVBUF_FULL_INT_ENABLED(s) ((s)->bmc_global_enables & \
244
(1 << IPMI_BMC_EVBUF_FULL_INT_BIT))
245
#define IPMI_BMC_EVENT_LOG_ENABLED(s) ((s)->bmc_global_enables & \
246
(1 << IPMI_BMC_EVENT_LOG_BIT))
247
#define IPMI_BMC_EVENT_MSG_BUF_ENABLED(s) ((s)->bmc_global_enables & \
248
(1 << IPMI_BMC_EVENT_MSG_BUF_BIT))
250
#define IPMI_BMC_WATCHDOG_USE_MASK 0xc7
251
#define IPMI_BMC_WATCHDOG_ACTION_MASK 0x77
252
#define IPMI_BMC_WATCHDOG_GET_USE(s) ((s)->watchdog_use & 0x7)
253
#define IPMI_BMC_WATCHDOG_GET_DONT_LOG(s) (((s)->watchdog_use >> 7) & 0x1)
254
#define IPMI_BMC_WATCHDOG_GET_DONT_STOP(s) (((s)->watchdog_use >> 6) & 0x1)
255
#define IPMI_BMC_WATCHDOG_GET_PRE_ACTION(s) (((s)->watchdog_action >> 4) & 0x7)
256
#define IPMI_BMC_WATCHDOG_PRE_NONE 0
257
#define IPMI_BMC_WATCHDOG_PRE_SMI 1
258
#define IPMI_BMC_WATCHDOG_PRE_NMI 2
259
#define IPMI_BMC_WATCHDOG_PRE_MSG_INT 3
260
#define IPMI_BMC_WATCHDOG_GET_ACTION(s) ((s)->watchdog_action & 0x7)
261
#define IPMI_BMC_WATCHDOG_ACTION_NONE 0
262
#define IPMI_BMC_WATCHDOG_ACTION_RESET 1
263
#define IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN 2
264
#define IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE 3
266
#define RSP_BUFFER_INITIALIZER { }
268
static inline void rsp_buffer_pushmore(RspBuffer *rsp, uint8_t *bytes,
271
if (rsp->len + n >= sizeof(rsp->buffer)) {
272
rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
276
memcpy(&rsp->buffer[rsp->len], bytes, n);
280
static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs);
282
static void ipmi_gettime(struct ipmi_time *time)
286
stime = qemu_clock_get_ns(QEMU_CLOCK_HOST);
287
time->tv_sec = stime / 1000000000LL;
288
time->tv_nsec = stime % 1000000000LL;
291
static int64_t ipmi_getmonotime(void)
293
return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
296
static void ipmi_timeout(void *opaque)
298
IPMIBmcSim *ibs = opaque;
300
ipmi_sim_handle_timeout(ibs);
303
static void set_timestamp(IPMIBmcSim *ibs, uint8_t *ts)
306
struct ipmi_time now;
309
val = now.tv_sec + ibs->sel.time_offset;
311
ts[1] = (val >> 8) & 0xff;
312
ts[2] = (val >> 16) & 0xff;
313
ts[3] = (val >> 24) & 0xff;
316
static void sdr_inc_reservation(IPMISdr *sdr)
319
if (sdr->reservation == 0) {
320
sdr->reservation = 1;
324
static int sdr_add_entry(IPMIBmcSim *ibs,
325
const struct ipmi_sdr_header *sdrh_entry,
326
unsigned int len, uint16_t *recid)
328
struct ipmi_sdr_header *sdrh =
329
(struct ipmi_sdr_header *) &ibs->sdr.sdr[ibs->sdr.next_free];
331
if ((len < IPMI_SDR_HEADER_SIZE) || (len > 255)) {
335
if (ipmi_sdr_length(sdrh_entry) != len) {
339
if (ibs->sdr.next_free + len > MAX_SDR_SIZE) {
340
ibs->sdr.overflow = 1;
344
memcpy(sdrh, sdrh_entry, len);
345
sdrh->rec_id[0] = ibs->sdr.next_rec_id & 0xff;
346
sdrh->rec_id[1] = (ibs->sdr.next_rec_id >> 8) & 0xff;
347
sdrh->sdr_version = 0x51;
350
*recid = ibs->sdr.next_rec_id;
352
ibs->sdr.next_rec_id++;
353
set_timestamp(ibs, ibs->sdr.last_addition);
354
ibs->sdr.next_free += len;
355
sdr_inc_reservation(&ibs->sdr);
359
static int sdr_find_entry(IPMISdr *sdr, uint16_t recid,
360
unsigned int *retpos, uint16_t *nextrec)
362
unsigned int pos = *retpos;
364
while (pos < sdr->next_free) {
365
struct ipmi_sdr_header *sdrh =
366
(struct ipmi_sdr_header *) &sdr->sdr[pos];
367
uint16_t trec = ipmi_sdr_recid(sdrh);
368
unsigned int nextpos = pos + ipmi_sdr_length(sdrh);
372
if (nextpos >= sdr->next_free) {
375
*nextrec = (sdr->sdr[nextpos] |
376
(sdr->sdr[nextpos + 1] << 8));
387
int ipmi_bmc_sdr_find(IPMIBmc *b, uint16_t recid,
388
const struct ipmi_sdr_compact **sdr, uint16_t *nextrec)
391
IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
395
if (sdr_find_entry(&ibs->sdr, recid, &pos, nextrec)) {
399
*sdr = (const struct ipmi_sdr_compact *) &ibs->sdr.sdr[pos];
403
static void sel_inc_reservation(IPMISel *sel)
406
if (sel->reservation == 0) {
407
sel->reservation = 1;
412
static int sel_add_event(IPMIBmcSim *ibs, uint8_t *event)
418
set_timestamp(ibs, ts);
419
if (event[2] < 0xe0) {
420
memcpy(event + 3, ts, 4);
422
if (ibs->sel.next_free == MAX_SEL_SIZE) {
423
ibs->sel.overflow = 1;
426
event[0] = ibs->sel.next_free & 0xff;
427
event[1] = (ibs->sel.next_free >> 8) & 0xff;
428
memcpy(ibs->sel.last_addition, ts, 4);
429
memcpy(ibs->sel.sel[ibs->sel.next_free], event, 16);
430
ibs->sel.next_free++;
431
sel_inc_reservation(&ibs->sel);
435
static int attn_set(IPMIBmcSim *ibs)
437
return IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(ibs)
438
|| IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs)
439
|| IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(ibs);
442
static int attn_irq_enabled(IPMIBmcSim *ibs)
444
return (IPMI_BMC_MSG_INTS_ON(ibs) &&
445
(IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE_SET(ibs) ||
446
IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK_SET(ibs)))
447
|| (IPMI_BMC_EVBUF_FULL_INT_ENABLED(ibs) &&
448
IPMI_BMC_MSG_FLAG_EVT_BUF_FULL_SET(ibs));
451
void ipmi_bmc_gen_event(IPMIBmc *b, uint8_t *evt, bool log)
453
IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
454
IPMIInterface *s = ibs->parent.intf;
455
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
457
if (!IPMI_BMC_EVENT_MSG_BUF_ENABLED(ibs)) {
461
if (log && IPMI_BMC_EVENT_LOG_ENABLED(ibs)) {
462
sel_add_event(ibs, evt);
465
if (ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL) {
469
memcpy(ibs->evtbuf, evt, 16);
470
ibs->msg_flags |= IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
471
k->set_atn(s, 1, attn_irq_enabled(ibs));
475
static void gen_event(IPMIBmcSim *ibs, unsigned int sens_num, uint8_t deassert,
476
uint8_t evd1, uint8_t evd2, uint8_t evd3)
478
IPMIInterface *s = ibs->parent.intf;
479
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
481
IPMISensor *sens = ibs->sensors + sens_num;
483
if (!IPMI_BMC_EVENT_MSG_BUF_ENABLED(ibs)) {
486
if (!IPMI_SENSOR_GET_EVENTS_ON(sens)) {
491
evt[7] = ibs->parent.slave_addr;
494
evt[10] = sens->sensor_type;
496
evt[12] = sens->evt_reading_type_code | (!!deassert << 7);
501
if (IPMI_BMC_EVENT_LOG_ENABLED(ibs)) {
502
sel_add_event(ibs, evt);
505
if (ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL) {
509
memcpy(ibs->evtbuf, evt, 16);
510
ibs->msg_flags |= IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
511
k->set_atn(s, 1, attn_irq_enabled(ibs));
514
static void sensor_set_discrete_bit(IPMIBmcSim *ibs, unsigned int sensor,
515
unsigned int bit, unsigned int val,
516
uint8_t evd1, uint8_t evd2, uint8_t evd3)
521
if (sensor >= MAX_SENSORS) {
529
sens = ibs->sensors + sensor;
531
sens->states |= mask & sens->states_suppt;
532
if (sens->assert_states & mask) {
535
sens->assert_states |= mask & sens->assert_suppt;
536
if (sens->assert_enable & mask & sens->assert_states) {
538
gen_event(ibs, sensor, 0, evd1, evd2, evd3);
541
sens->states &= ~(mask & sens->states_suppt);
542
if (sens->deassert_states & mask) {
545
sens->deassert_states |= mask & sens->deassert_suppt;
546
if (sens->deassert_enable & mask & sens->deassert_states) {
548
gen_event(ibs, sensor, 1, evd1, evd2, evd3);
553
static void ipmi_init_sensors_from_sdrs(IPMIBmcSim *s)
558
for (i = 0; i < MAX_SENSORS; i++) {
559
memset(s->sensors + i, 0, sizeof(*sens));
563
for (i = 0; !sdr_find_entry(&s->sdr, i, &pos, NULL); i++) {
564
struct ipmi_sdr_compact *sdr =
565
(struct ipmi_sdr_compact *) &s->sdr.sdr[pos];
566
unsigned int len = sdr->header.rec_length;
571
if (sdr->header.rec_type != IPMI_SDR_COMPACT_TYPE) {
575
if (sdr->sensor_owner_number >= MAX_SENSORS) {
578
sens = s->sensors + sdr->sensor_owner_number;
580
IPMI_SENSOR_SET_PRESENT(sens, 1);
581
IPMI_SENSOR_SET_SCAN_ON(sens, (sdr->sensor_init >> 6) & 1);
582
IPMI_SENSOR_SET_EVENTS_ON(sens, (sdr->sensor_init >> 5) & 1);
583
sens->assert_suppt = sdr->assert_mask[0] | (sdr->assert_mask[1] << 8);
584
sens->deassert_suppt =
585
sdr->deassert_mask[0] | (sdr->deassert_mask[1] << 8);
587
sdr->discrete_mask[0] | (sdr->discrete_mask[1] << 8);
588
sens->sensor_type = sdr->sensor_type;
589
sens->evt_reading_type_code = sdr->reading_type & 0x7f;
592
sens->assert_enable = sens->assert_suppt;
593
sens->deassert_enable = sens->deassert_suppt;
597
int ipmi_sim_register_netfn(IPMIBmcSim *s, unsigned int netfn,
598
const IPMINetfn *netfnd)
600
if ((netfn & 1) || (netfn >= MAX_NETFNS) || (s->netfns[netfn / 2])) {
603
s->netfns[netfn / 2] = netfnd;
607
static const IPMICmdHandler *ipmi_get_handler(IPMIBmcSim *ibs,
611
const IPMICmdHandler *hdl;
613
if (netfn & 1 || netfn >= MAX_NETFNS || !ibs->netfns[netfn / 2]) {
617
if (cmd >= ibs->netfns[netfn / 2]->cmd_nums) {
621
hdl = &ibs->netfns[netfn / 2]->cmd_handlers[cmd];
622
if (!hdl->cmd_handler) {
629
static void next_timeout(IPMIBmcSim *ibs)
632
if (ibs->watchdog_running) {
633
next = ibs->watchdog_expiry;
636
next = ipmi_getmonotime() + 60 * 1000000000LL;
638
timer_mod_ns(ibs->timer, next);
641
static void ipmi_sim_handle_command(IPMIBmc *b,
642
uint8_t *cmd, unsigned int cmd_len,
643
unsigned int max_cmd_len,
646
IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
647
IPMIInterface *s = ibs->parent.intf;
648
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
649
const IPMICmdHandler *hdl;
650
RspBuffer rsp = RSP_BUFFER_INITIALIZER;
654
if (sizeof(rsp.buffer) < 3) {
655
rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
659
rsp_buffer_push(&rsp, cmd[0] | 0x04);
660
rsp_buffer_push(&rsp, cmd[1]);
661
rsp_buffer_push(&rsp, 0);
665
rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
668
if (cmd_len > max_cmd_len) {
669
rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_TRUNCATED);
673
if ((cmd[0] & 0x03) != 0) {
675
rsp_buffer_set_error(&rsp, IPMI_CC_COMMAND_INVALID_FOR_LUN);
679
hdl = ipmi_get_handler(ibs, cmd[0] >> 2, cmd[1]);
681
rsp_buffer_set_error(&rsp, IPMI_CC_INVALID_CMD);
685
if (cmd_len < hdl->cmd_len_min) {
686
rsp_buffer_set_error(&rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
690
hdl->cmd_handler(ibs, cmd, cmd_len, &rsp);
693
k->handle_rsp(s, msg_id, rsp.buffer, rsp.len);
698
static void ipmi_sim_handle_timeout(IPMIBmcSim *ibs)
700
IPMIInterface *s = ibs->parent.intf;
701
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
703
if (!ibs->watchdog_running) {
707
if (!ibs->watchdog_preaction_ran) {
708
switch (IPMI_BMC_WATCHDOG_GET_PRE_ACTION(ibs)) {
709
case IPMI_BMC_WATCHDOG_PRE_NMI:
710
ibs->msg_flags |= IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK;
711
k->do_hw_op(s, IPMI_SEND_NMI, 0);
712
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 8, 1,
713
0xc8, (2 << 4) | 0xf, 0xff);
716
case IPMI_BMC_WATCHDOG_PRE_MSG_INT:
717
ibs->msg_flags |= IPMI_BMC_MSG_FLAG_WATCHDOG_TIMEOUT_MASK;
718
k->set_atn(s, 1, attn_irq_enabled(ibs));
719
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 8, 1,
720
0xc8, (3 << 4) | 0xf, 0xff);
727
ibs->watchdog_preaction_ran = 1;
729
ibs->watchdog_expiry = ipmi_getmonotime();
730
ibs->watchdog_expiry += ibs->watchdog_pretimeout * 1000000000LL;
735
ibs->watchdog_running = 0;
736
ibs->watchdog_expired |= (1 << IPMI_BMC_WATCHDOG_GET_USE(ibs));
737
switch (IPMI_BMC_WATCHDOG_GET_ACTION(ibs)) {
738
case IPMI_BMC_WATCHDOG_ACTION_NONE:
739
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 0, 1,
740
0xc0, ibs->watchdog_use & 0xf, 0xff);
743
case IPMI_BMC_WATCHDOG_ACTION_RESET:
744
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 1, 1,
745
0xc1, ibs->watchdog_use & 0xf, 0xff);
746
k->do_hw_op(s, IPMI_RESET_CHASSIS, 0);
749
case IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN:
750
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 2, 1,
751
0xc2, ibs->watchdog_use & 0xf, 0xff);
752
k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 0);
755
case IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE:
756
sensor_set_discrete_bit(ibs, IPMI_WATCHDOG_SENSOR, 2, 1,
757
0xc3, ibs->watchdog_use & 0xf, 0xff);
758
k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 0);
766
static void chassis_capabilities(IPMIBmcSim *ibs,
767
uint8_t *cmd, unsigned int cmd_len,
770
rsp_buffer_push(rsp, 0);
771
rsp_buffer_push(rsp, ibs->parent.slave_addr);
772
rsp_buffer_push(rsp, ibs->parent.slave_addr);
773
rsp_buffer_push(rsp, ibs->parent.slave_addr);
774
rsp_buffer_push(rsp, ibs->parent.slave_addr);
777
static void chassis_status(IPMIBmcSim *ibs,
778
uint8_t *cmd, unsigned int cmd_len,
781
rsp_buffer_push(rsp, 0x61);
782
rsp_buffer_push(rsp, 0);
783
rsp_buffer_push(rsp, 0);
784
rsp_buffer_push(rsp, 0);
787
static void chassis_control(IPMIBmcSim *ibs,
788
uint8_t *cmd, unsigned int cmd_len,
791
IPMIInterface *s = ibs->parent.intf;
792
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
794
switch (cmd[2] & 0xf) {
796
rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 0));
799
rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWERON_CHASSIS, 0));
802
rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 0));
805
rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_RESET_CHASSIS, 0));
808
rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_PULSE_DIAG_IRQ, 0));
811
rsp_buffer_set_error(rsp, k->do_hw_op(s,
812
IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP, 0));
815
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
820
static void chassis_get_sys_restart_cause(IPMIBmcSim *ibs,
821
uint8_t *cmd, unsigned int cmd_len,
825
rsp_buffer_push(rsp, ibs->restart_cause & 0xf);
826
rsp_buffer_push(rsp, 0);
829
static void get_device_id(IPMIBmcSim *ibs,
830
uint8_t *cmd, unsigned int cmd_len,
833
rsp_buffer_push(rsp, ibs->device_id);
834
rsp_buffer_push(rsp, ibs->device_rev & 0xf);
835
rsp_buffer_push(rsp, ibs->fwrev1 & 0x7f);
836
rsp_buffer_push(rsp, ibs->fwrev2);
837
rsp_buffer_push(rsp, ibs->ipmi_version);
838
rsp_buffer_push(rsp, 0x07);
839
rsp_buffer_push(rsp, ibs->mfg_id & 0xff);
840
rsp_buffer_push(rsp, (ibs->mfg_id >> 8) & 0xff);
841
rsp_buffer_push(rsp, (ibs->mfg_id >> 16) & 0xff);
842
rsp_buffer_push(rsp, ibs->product_id & 0xff);
843
rsp_buffer_push(rsp, (ibs->product_id >> 8) & 0xff);
846
static void set_global_enables(IPMIBmcSim *ibs, uint8_t val)
848
IPMIInterface *s = ibs->parent.intf;
849
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
852
ibs->bmc_global_enables = val;
854
irqs_on = val & (IPMI_BMC_EVBUF_FULL_INT_BIT |
855
IPMI_BMC_RCV_MSG_QUEUE_INT_BIT);
857
k->set_irq_enable(s, irqs_on);
860
static void cold_reset(IPMIBmcSim *ibs,
861
uint8_t *cmd, unsigned int cmd_len,
864
IPMIInterface *s = ibs->parent.intf;
865
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
868
set_global_enables(ibs, 1 << IPMI_BMC_EVENT_LOG_BIT);
875
static void warm_reset(IPMIBmcSim *ibs,
876
uint8_t *cmd, unsigned int cmd_len,
879
IPMIInterface *s = ibs->parent.intf;
880
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
886
static void set_acpi_power_state(IPMIBmcSim *ibs,
887
uint8_t *cmd, unsigned int cmd_len,
890
ibs->acpi_power_state[0] = cmd[2];
891
ibs->acpi_power_state[1] = cmd[3];
894
static void get_acpi_power_state(IPMIBmcSim *ibs,
895
uint8_t *cmd, unsigned int cmd_len,
898
rsp_buffer_push(rsp, ibs->acpi_power_state[0]);
899
rsp_buffer_push(rsp, ibs->acpi_power_state[1]);
902
static void get_device_guid(IPMIBmcSim *ibs,
903
uint8_t *cmd, unsigned int cmd_len,
909
for (i = 0; i < 16; i++) {
910
if (ibs->uuid.data[i]) {
915
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_CMD);
919
for (i = 0; i < 16; i++) {
920
rsp_buffer_push(rsp, ibs->uuid.data[i]);
924
static void set_bmc_global_enables(IPMIBmcSim *ibs,
925
uint8_t *cmd, unsigned int cmd_len,
928
set_global_enables(ibs, cmd[2]);
931
static void get_bmc_global_enables(IPMIBmcSim *ibs,
932
uint8_t *cmd, unsigned int cmd_len,
935
rsp_buffer_push(rsp, ibs->bmc_global_enables);
938
static void clr_msg_flags(IPMIBmcSim *ibs,
939
uint8_t *cmd, unsigned int cmd_len,
942
IPMIInterface *s = ibs->parent.intf;
943
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
945
ibs->msg_flags &= ~cmd[2];
946
k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
949
static void get_msg_flags(IPMIBmcSim *ibs,
950
uint8_t *cmd, unsigned int cmd_len,
953
rsp_buffer_push(rsp, ibs->msg_flags);
956
static void read_evt_msg_buf(IPMIBmcSim *ibs,
957
uint8_t *cmd, unsigned int cmd_len,
960
IPMIInterface *s = ibs->parent.intf;
961
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
964
if (!(ibs->msg_flags & IPMI_BMC_MSG_FLAG_EVT_BUF_FULL)) {
965
rsp_buffer_set_error(rsp, 0x80);
968
for (i = 0; i < 16; i++) {
969
rsp_buffer_push(rsp, ibs->evtbuf[i]);
971
ibs->msg_flags &= ~IPMI_BMC_MSG_FLAG_EVT_BUF_FULL;
972
k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
975
static void get_msg(IPMIBmcSim *ibs,
976
uint8_t *cmd, unsigned int cmd_len,
979
IPMIRcvBufEntry *msg;
981
if (QTAILQ_EMPTY(&ibs->rcvbufs)) {
982
rsp_buffer_set_error(rsp, 0x80);
985
rsp_buffer_push(rsp, 0);
986
msg = QTAILQ_FIRST(&ibs->rcvbufs);
987
rsp_buffer_pushmore(rsp, msg->buf, msg->len);
988
QTAILQ_REMOVE(&ibs->rcvbufs, msg, entry);
991
if (QTAILQ_EMPTY(&ibs->rcvbufs)) {
992
IPMIInterface *s = ibs->parent.intf;
993
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
995
ibs->msg_flags &= ~IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;
996
k->set_atn(s, attn_set(ibs), attn_irq_enabled(ibs));
1004
ipmb_checksum(unsigned char *data, int size, unsigned char csum)
1006
for (; size > 0; size--, data++) {
1013
static void send_msg(IPMIBmcSim *ibs,
1014
uint8_t *cmd, unsigned int cmd_len,
1017
IPMIInterface *s = ibs->parent.intf;
1018
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
1019
IPMIRcvBufEntry *msg;
1021
uint8_t netfn, rqLun, rsLun, rqSeq;
1025
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1030
rsp_buffer_set_error(rsp, IPMI_CC_REQUEST_DATA_LENGTH_INVALID);
1034
if (cmd[3] != 0x40) {
1036
rsp_buffer_set_error(rsp, 0x83);
1047
if (ipmb_checksum(cmd, cmd_len, 0) != 0 ||
1052
netfn = cmd[1] >> 2;
1053
rqLun = cmd[4] & 0x3;
1054
rsLun = cmd[1] & 0x3;
1055
rqSeq = cmd[4] >> 2;
1062
msg = g_malloc(sizeof(*msg));
1063
msg->buf[0] = ((netfn | 1) << 2) | rqLun;
1064
msg->buf[1] = ipmb_checksum(msg->buf, 1, 0);
1065
msg->buf[2] = cmd[0];
1066
msg->buf[3] = (rqSeq << 2) | rsLun;
1067
msg->buf[4] = cmd[5];
1071
if ((cmd[1] >> 2) != IPMI_NETFN_APP || cmd[5] != IPMI_CMD_GET_DEVICE_ID) {
1073
msg->buf[5] = IPMI_CC_INVALID_CMD;
1077
buf = msg->buf + msg->len;
1092
msg->buf[msg->len] = ipmb_checksum(msg->buf, msg->len, 0);
1094
QTAILQ_INSERT_TAIL(&ibs->rcvbufs, msg, entry);
1095
ibs->msg_flags |= IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;
1096
k->set_atn(s, 1, attn_irq_enabled(ibs));
1099
static void do_watchdog_reset(IPMIBmcSim *ibs)
1101
if (IPMI_BMC_WATCHDOG_GET_ACTION(ibs) ==
1102
IPMI_BMC_WATCHDOG_ACTION_NONE) {
1103
ibs->watchdog_running = 0;
1106
ibs->watchdog_preaction_ran = 0;
1110
ibs->watchdog_expiry = ipmi_getmonotime();
1111
ibs->watchdog_expiry += ibs->watchdog_timeout * 100000000LL;
1112
if (IPMI_BMC_WATCHDOG_GET_PRE_ACTION(ibs) != IPMI_BMC_WATCHDOG_PRE_NONE) {
1113
ibs->watchdog_expiry -= ibs->watchdog_pretimeout * 1000000000LL;
1115
ibs->watchdog_running = 1;
1118
static void reset_watchdog_timer(IPMIBmcSim *ibs,
1119
uint8_t *cmd, unsigned int cmd_len,
1122
if (!ibs->watchdog_initialized) {
1123
rsp_buffer_set_error(rsp, 0x80);
1126
do_watchdog_reset(ibs);
1129
static void set_watchdog_timer(IPMIBmcSim *ibs,
1130
uint8_t *cmd, unsigned int cmd_len,
1133
IPMIInterface *s = ibs->parent.intf;
1134
IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);
1138
if (val == 0 || val > 5) {
1139
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1144
case IPMI_BMC_WATCHDOG_ACTION_NONE:
1147
case IPMI_BMC_WATCHDOG_ACTION_RESET:
1148
rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_RESET_CHASSIS, 1));
1151
case IPMI_BMC_WATCHDOG_ACTION_POWER_DOWN:
1152
rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWEROFF_CHASSIS, 1));
1155
case IPMI_BMC_WATCHDOG_ACTION_POWER_CYCLE:
1156
rsp_buffer_set_error(rsp, k->do_hw_op(s, IPMI_POWERCYCLE_CHASSIS, 1));
1160
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1162
if (rsp->buffer[2]) {
1163
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1167
val = (cmd[3] >> 4) & 0x7;
1169
case IPMI_BMC_WATCHDOG_PRE_MSG_INT:
1170
case IPMI_BMC_WATCHDOG_PRE_NONE:
1173
case IPMI_BMC_WATCHDOG_PRE_NMI:
1174
if (k->do_hw_op(s, IPMI_SEND_NMI, 1)) {
1176
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1183
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1187
ibs->watchdog_initialized = 1;
1188
ibs->watchdog_use = cmd[2] & IPMI_BMC_WATCHDOG_USE_MASK;
1189
ibs->watchdog_action = cmd[3] & IPMI_BMC_WATCHDOG_ACTION_MASK;
1190
ibs->watchdog_pretimeout = cmd[4];
1191
ibs->watchdog_expired &= ~cmd[5];
1192
ibs->watchdog_timeout = cmd[6] | (((uint16_t) cmd[7]) << 8);
1193
if (ibs->watchdog_running & IPMI_BMC_WATCHDOG_GET_DONT_STOP(ibs)) {
1194
do_watchdog_reset(ibs);
1196
ibs->watchdog_running = 0;
1200
static void get_watchdog_timer(IPMIBmcSim *ibs,
1201
uint8_t *cmd, unsigned int cmd_len,
1204
rsp_buffer_push(rsp, ibs->watchdog_use);
1205
rsp_buffer_push(rsp, ibs->watchdog_action);
1206
rsp_buffer_push(rsp, ibs->watchdog_pretimeout);
1207
rsp_buffer_push(rsp, ibs->watchdog_expired);
1208
rsp_buffer_push(rsp, ibs->watchdog_timeout & 0xff);
1209
rsp_buffer_push(rsp, (ibs->watchdog_timeout >> 8) & 0xff);
1210
if (ibs->watchdog_running) {
1212
timeout = ((ibs->watchdog_expiry - ipmi_getmonotime() + 50000000)
1214
rsp_buffer_push(rsp, timeout & 0xff);
1215
rsp_buffer_push(rsp, (timeout >> 8) & 0xff);
1217
rsp_buffer_push(rsp, 0);
1218
rsp_buffer_push(rsp, 0);
1222
static void get_sdr_rep_info(IPMIBmcSim *ibs,
1223
uint8_t *cmd, unsigned int cmd_len,
1228
rsp_buffer_push(rsp, 0x51);
1229
rsp_buffer_push(rsp, ibs->sdr.next_rec_id & 0xff);
1230
rsp_buffer_push(rsp, (ibs->sdr.next_rec_id >> 8) & 0xff);
1231
rsp_buffer_push(rsp, (MAX_SDR_SIZE - ibs->sdr.next_free) & 0xff);
1232
rsp_buffer_push(rsp, ((MAX_SDR_SIZE - ibs->sdr.next_free) >> 8) & 0xff);
1233
for (i = 0; i < 4; i++) {
1234
rsp_buffer_push(rsp, ibs->sdr.last_addition[i]);
1236
for (i = 0; i < 4; i++) {
1237
rsp_buffer_push(rsp, ibs->sdr.last_clear[i]);
1240
rsp_buffer_push(rsp, (ibs->sdr.overflow << 7) | 0x22);
1243
static void reserve_sdr_rep(IPMIBmcSim *ibs,
1244
uint8_t *cmd, unsigned int cmd_len,
1247
rsp_buffer_push(rsp, ibs->sdr.reservation & 0xff);
1248
rsp_buffer_push(rsp, (ibs->sdr.reservation >> 8) & 0xff);
1251
static void get_sdr(IPMIBmcSim *ibs,
1252
uint8_t *cmd, unsigned int cmd_len,
1257
struct ipmi_sdr_header *sdrh;
1260
if ((cmd[2] | (cmd[3] << 8)) != ibs->sdr.reservation) {
1261
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
1267
if (sdr_find_entry(&ibs->sdr, cmd[4] | (cmd[5] << 8),
1269
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1273
sdrh = (struct ipmi_sdr_header *) &ibs->sdr.sdr[pos];
1275
if (cmd[6] > ipmi_sdr_length(sdrh)) {
1276
rsp_buffer_set_error(rsp, IPMI_CC_PARM_OUT_OF_RANGE);
1280
rsp_buffer_push(rsp, nextrec & 0xff);
1281
rsp_buffer_push(rsp, (nextrec >> 8) & 0xff);
1283
if (cmd[7] == 0xff) {
1284
cmd[7] = ipmi_sdr_length(sdrh) - cmd[6];
1287
if ((cmd[7] + rsp->len) > sizeof(rsp->buffer)) {
1288
rsp_buffer_set_error(rsp, IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES);
1292
rsp_buffer_pushmore(rsp, ibs->sdr.sdr + pos + cmd[6], cmd[7]);
1295
static void add_sdr(IPMIBmcSim *ibs,
1296
uint8_t *cmd, unsigned int cmd_len,
1300
struct ipmi_sdr_header *sdrh = (struct ipmi_sdr_header *) cmd + 2;
1302
if (sdr_add_entry(ibs, sdrh, cmd_len - 2, &recid)) {
1303
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1306
rsp_buffer_push(rsp, recid & 0xff);
1307
rsp_buffer_push(rsp, (recid >> 8) & 0xff);
1310
static void clear_sdr_rep(IPMIBmcSim *ibs,
1311
uint8_t *cmd, unsigned int cmd_len,
1314
if ((cmd[2] | (cmd[3] << 8)) != ibs->sdr.reservation) {
1315
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
1319
if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
1320
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1323
if (cmd[7] == 0xaa) {
1324
ibs->sdr.next_free = 0;
1325
ibs->sdr.overflow = 0;
1326
set_timestamp(ibs, ibs->sdr.last_clear);
1327
rsp_buffer_push(rsp, 1);
1328
sdr_inc_reservation(&ibs->sdr);
1329
} else if (cmd[7] == 0) {
1330
rsp_buffer_push(rsp, 1);
1332
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1337
static void get_sel_info(IPMIBmcSim *ibs,
1338
uint8_t *cmd, unsigned int cmd_len,
1341
unsigned int i, val;
1343
rsp_buffer_push(rsp, 0x51);
1344
rsp_buffer_push(rsp, ibs->sel.next_free & 0xff);
1345
rsp_buffer_push(rsp, (ibs->sel.next_free >> 8) & 0xff);
1346
val = (MAX_SEL_SIZE - ibs->sel.next_free) * 16;
1347
rsp_buffer_push(rsp, val & 0xff);
1348
rsp_buffer_push(rsp, (val >> 8) & 0xff);
1349
for (i = 0; i < 4; i++) {
1350
rsp_buffer_push(rsp, ibs->sel.last_addition[i]);
1352
for (i = 0; i < 4; i++) {
1353
rsp_buffer_push(rsp, ibs->sel.last_clear[i]);
1356
rsp_buffer_push(rsp, (ibs->sel.overflow << 7) | 0x02);
1359
static void get_fru_area_info(IPMIBmcSim *ibs,
1360
uint8_t *cmd, unsigned int cmd_len,
1364
uint16_t fru_entry_size;
1368
if (fruid >= ibs->fru.nentries) {
1369
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1373
fru_entry_size = ibs->fru.areasize;
1375
rsp_buffer_push(rsp, fru_entry_size & 0xff);
1376
rsp_buffer_push(rsp, fru_entry_size >> 8 & 0xff);
1377
rsp_buffer_push(rsp, 0x0);
1380
static void read_fru_data(IPMIBmcSim *ibs,
1381
uint8_t *cmd, unsigned int cmd_len,
1391
offset = (cmd[3] | cmd[4] << 8);
1393
if (fruid >= ibs->fru.nentries) {
1394
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1398
if (offset >= ibs->fru.areasize - 1) {
1399
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1403
fru_entry = &ibs->fru.data[fruid * ibs->fru.areasize];
1405
count = MIN(cmd[5], ibs->fru.areasize - offset);
1407
rsp_buffer_push(rsp, count & 0xff);
1408
for (i = 0; i < count; i++) {
1409
rsp_buffer_push(rsp, fru_entry[offset + i]);
1413
static void write_fru_data(IPMIBmcSim *ibs,
1414
uint8_t *cmd, unsigned int cmd_len,
1423
offset = (cmd[3] | cmd[4] << 8);
1425
if (fruid >= ibs->fru.nentries) {
1426
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1430
if (offset >= ibs->fru.areasize - 1) {
1431
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1435
fru_entry = &ibs->fru.data[fruid * ibs->fru.areasize];
1437
count = MIN(cmd_len - 5, ibs->fru.areasize - offset);
1439
memcpy(fru_entry + offset, cmd + 5, count);
1441
rsp_buffer_push(rsp, count & 0xff);
1444
static void reserve_sel(IPMIBmcSim *ibs,
1445
uint8_t *cmd, unsigned int cmd_len,
1448
rsp_buffer_push(rsp, ibs->sel.reservation & 0xff);
1449
rsp_buffer_push(rsp, (ibs->sel.reservation >> 8) & 0xff);
1452
static void get_sel_entry(IPMIBmcSim *ibs,
1453
uint8_t *cmd, unsigned int cmd_len,
1459
if ((cmd[2] | (cmd[3] << 8)) != ibs->sel.reservation) {
1460
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
1464
if (ibs->sel.next_free == 0) {
1465
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1469
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1472
if (cmd[7] == 0xff) {
1474
} else if ((cmd[7] + cmd[6]) > 16) {
1475
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1481
val = cmd[4] | (cmd[5] << 8);
1482
if (val == 0xffff) {
1483
val = ibs->sel.next_free - 1;
1484
} else if (val >= ibs->sel.next_free) {
1485
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1488
if ((val + 1) == ibs->sel.next_free) {
1489
rsp_buffer_push(rsp, 0xff);
1490
rsp_buffer_push(rsp, 0xff);
1492
rsp_buffer_push(rsp, (val + 1) & 0xff);
1493
rsp_buffer_push(rsp, ((val + 1) >> 8) & 0xff);
1495
for (; cmd[6] < cmd[7]; cmd[6]++) {
1496
rsp_buffer_push(rsp, ibs->sel.sel[val][cmd[6]]);
1500
static void add_sel_entry(IPMIBmcSim *ibs,
1501
uint8_t *cmd, unsigned int cmd_len,
1504
if (sel_add_event(ibs, cmd + 2)) {
1505
rsp_buffer_set_error(rsp, IPMI_CC_OUT_OF_SPACE);
1509
rsp_buffer_push(rsp, cmd[2]);
1510
rsp_buffer_push(rsp, cmd[3]);
1513
static void clear_sel(IPMIBmcSim *ibs,
1514
uint8_t *cmd, unsigned int cmd_len,
1517
if ((cmd[2] | (cmd[3] << 8)) != ibs->sel.reservation) {
1518
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_RESERVATION);
1522
if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') {
1523
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1526
if (cmd[7] == 0xaa) {
1527
ibs->sel.next_free = 0;
1528
ibs->sel.overflow = 0;
1529
set_timestamp(ibs, ibs->sdr.last_clear);
1530
rsp_buffer_push(rsp, 1);
1531
sel_inc_reservation(&ibs->sel);
1532
} else if (cmd[7] == 0) {
1533
rsp_buffer_push(rsp, 1);
1535
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1540
static void get_sel_time(IPMIBmcSim *ibs,
1541
uint8_t *cmd, unsigned int cmd_len,
1545
struct ipmi_time now;
1548
val = now.tv_sec + ibs->sel.time_offset;
1549
rsp_buffer_push(rsp, val & 0xff);
1550
rsp_buffer_push(rsp, (val >> 8) & 0xff);
1551
rsp_buffer_push(rsp, (val >> 16) & 0xff);
1552
rsp_buffer_push(rsp, (val >> 24) & 0xff);
1555
static void set_sel_time(IPMIBmcSim *ibs,
1556
uint8_t *cmd, unsigned int cmd_len,
1560
struct ipmi_time now;
1562
val = cmd[2] | (cmd[3] << 8) | (cmd[4] << 16) | (cmd[5] << 24);
1564
ibs->sel.time_offset = now.tv_sec - ((long) val);
1567
static void platform_event_msg(IPMIBmcSim *ibs,
1568
uint8_t *cmd, unsigned int cmd_len,
1584
if (sel_add_event(ibs, event)) {
1585
rsp_buffer_set_error(rsp, IPMI_CC_OUT_OF_SPACE);
1589
static void set_sensor_evt_enable(IPMIBmcSim *ibs,
1590
uint8_t *cmd, unsigned int cmd_len,
1595
if ((cmd[2] >= MAX_SENSORS) ||
1596
!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1597
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1600
sens = ibs->sensors + cmd[2];
1601
switch ((cmd[3] >> 4) & 0x3) {
1606
sens->assert_enable |= cmd[4];
1609
sens->assert_enable |= cmd[5] << 8;
1612
sens->deassert_enable |= cmd[6];
1615
sens->deassert_enable |= cmd[7] << 8;
1620
sens->assert_enable &= ~cmd[4];
1623
sens->assert_enable &= ~(cmd[5] << 8);
1626
sens->deassert_enable &= ~cmd[6];
1629
sens->deassert_enable &= ~(cmd[7] << 8);
1633
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1636
IPMI_SENSOR_SET_RET_STATUS(sens, cmd[3]);
1639
static void get_sensor_evt_enable(IPMIBmcSim *ibs,
1640
uint8_t *cmd, unsigned int cmd_len,
1645
if ((cmd[2] >= MAX_SENSORS) ||
1646
!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1647
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1650
sens = ibs->sensors + cmd[2];
1651
rsp_buffer_push(rsp, IPMI_SENSOR_GET_RET_STATUS(sens));
1652
rsp_buffer_push(rsp, sens->assert_enable & 0xff);
1653
rsp_buffer_push(rsp, (sens->assert_enable >> 8) & 0xff);
1654
rsp_buffer_push(rsp, sens->deassert_enable & 0xff);
1655
rsp_buffer_push(rsp, (sens->deassert_enable >> 8) & 0xff);
1658
static void rearm_sensor_evts(IPMIBmcSim *ibs,
1659
uint8_t *cmd, unsigned int cmd_len,
1664
if ((cmd[2] >= MAX_SENSORS) ||
1665
!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1666
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1669
sens = ibs->sensors + cmd[2];
1671
if ((cmd[3] & 0x80) == 0) {
1678
static void get_sensor_evt_status(IPMIBmcSim *ibs,
1679
uint8_t *cmd, unsigned int cmd_len,
1684
if ((cmd[2] >= MAX_SENSORS) ||
1685
!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1686
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1689
sens = ibs->sensors + cmd[2];
1690
rsp_buffer_push(rsp, sens->reading);
1691
rsp_buffer_push(rsp, IPMI_SENSOR_GET_RET_STATUS(sens));
1692
rsp_buffer_push(rsp, sens->assert_states & 0xff);
1693
rsp_buffer_push(rsp, (sens->assert_states >> 8) & 0xff);
1694
rsp_buffer_push(rsp, sens->deassert_states & 0xff);
1695
rsp_buffer_push(rsp, (sens->deassert_states >> 8) & 0xff);
1698
static void get_sensor_reading(IPMIBmcSim *ibs,
1699
uint8_t *cmd, unsigned int cmd_len,
1704
if ((cmd[2] >= MAX_SENSORS) ||
1705
!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1706
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1709
sens = ibs->sensors + cmd[2];
1710
rsp_buffer_push(rsp, sens->reading);
1711
rsp_buffer_push(rsp, IPMI_SENSOR_GET_RET_STATUS(sens));
1712
rsp_buffer_push(rsp, sens->states & 0xff);
1713
if (IPMI_SENSOR_IS_DISCRETE(sens)) {
1714
rsp_buffer_push(rsp, (sens->states >> 8) & 0xff);
1718
static void set_sensor_type(IPMIBmcSim *ibs,
1719
uint8_t *cmd, unsigned int cmd_len,
1725
if ((cmd[2] >= MAX_SENSORS) ||
1726
!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1727
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1730
sens = ibs->sensors + cmd[2];
1731
sens->sensor_type = cmd[3];
1732
sens->evt_reading_type_code = cmd[4] & 0x7f;
1735
static void get_sensor_type(IPMIBmcSim *ibs,
1736
uint8_t *cmd, unsigned int cmd_len,
1742
if ((cmd[2] >= MAX_SENSORS) ||
1743
!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1744
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1747
sens = ibs->sensors + cmd[2];
1748
rsp_buffer_push(rsp, sens->sensor_type);
1749
rsp_buffer_push(rsp, sens->evt_reading_type_code);
1761
static void set_sensor_reading(IPMIBmcSim *ibs,
1762
uint8_t *cmd, unsigned int cmd_len,
1769
uint8_t new_reading = 0;
1770
uint16_t new_assert_states = 0;
1771
uint16_t new_deassert_states = 0;
1772
bool change_reading = false;
1773
bool change_assert = false;
1774
bool change_deassert = false;
1776
SENSOR_GEN_EVENT_NONE,
1777
SENSOR_GEN_EVENT_DATA,
1778
SENSOR_GEN_EVENT_BMC,
1779
} do_gen_event = SENSOR_GEN_EVENT_NONE;
1781
if ((cmd[2] >= MAX_SENSORS) ||
1782
!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
1783
rsp_buffer_set_error(rsp, IPMI_CC_REQ_ENTRY_NOT_PRESENT);
1787
sens = ibs->sensors + cmd[2];
1790
switch ((cmd[3]) & 0x3) {
1794
new_reading = cmd[4];
1795
if (sens->reading != new_reading) {
1796
change_reading = true;
1801
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1806
switch ((cmd[3] >> 2) & 0x3) {
1811
new_deassert_states = cmd[7];
1812
change_deassert = true;
1815
new_deassert_states |= (cmd[8] << 8);
1821
new_deassert_states = (sens->deassert_states | cmd[7]);
1822
change_deassert = true;
1825
new_deassert_states |= (sens->deassert_states | (cmd[8] << 8));
1831
new_deassert_states = (sens->deassert_states & cmd[7]);
1832
change_deassert = true;
1835
new_deassert_states |= (sens->deassert_states & (cmd[8] << 8));
1840
if (change_deassert && (new_deassert_states == sens->deassert_states)) {
1841
change_deassert = false;
1845
switch ((cmd[3] >> 4) & 0x3) {
1850
new_assert_states = cmd[5];
1851
change_assert = true;
1854
new_assert_states |= (cmd[6] << 8);
1860
new_assert_states = (sens->assert_states | cmd[5]);
1861
change_assert = true;
1864
new_assert_states |= (sens->assert_states | (cmd[6] << 8));
1870
new_assert_states = (sens->assert_states & cmd[5]);
1871
change_assert = true;
1874
new_assert_states |= (sens->assert_states & (cmd[6] << 8));
1879
if (change_assert && (new_assert_states == sens->assert_states)) {
1880
change_assert = false;
1894
switch ((cmd[3] >> 6) & 0x3) {
1900
evd1 = evd2 = evd3 = 0x0;
1901
do_gen_event = SENSOR_GEN_EVENT_BMC;
1907
do_gen_event = SENSOR_GEN_EVENT_DATA;
1914
do_gen_event = SENSOR_GEN_EVENT_DATA;
1917
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1926
if (do_gen_event == SENSOR_GEN_EVENT_DATA && cmd_len < 10) {
1927
rsp_buffer_set_error(rsp, IPMI_CC_INVALID_DATA_FIELD);
1932
if (change_reading) {
1933
sens->reading = new_reading;
1936
if (change_assert) {
1937
sens->assert_states = new_assert_states;
1940
if (change_deassert) {
1941
sens->deassert_states = new_deassert_states;
1945
if (!IPMI_SENSOR_IS_DISCRETE(sens)) {
1949
switch (do_gen_event) {
1950
case SENSOR_GEN_EVENT_DATA: {
1951
unsigned int bit = evd1 & 0xf;
1952
uint16_t mask = (1 << bit);
1954
if (sens->assert_states & mask & sens->assert_enable) {
1955
gen_event(ibs, cmd[2], 0, evd1, evd2, evd3);
1958
if (sens->deassert_states & mask & sens->deassert_enable) {
1959
gen_event(ibs, cmd[2], 1, evd1, evd2, evd3);
1963
case SENSOR_GEN_EVENT_BMC:
1969
case SENSOR_GEN_EVENT_NONE:
1974
static const IPMICmdHandler chassis_cmds[] = {
1975
[IPMI_CMD_GET_CHASSIS_CAPABILITIES] = { chassis_capabilities },
1976
[IPMI_CMD_GET_CHASSIS_STATUS] = { chassis_status },
1977
[IPMI_CMD_CHASSIS_CONTROL] = { chassis_control, 3 },
1978
[IPMI_CMD_GET_SYS_RESTART_CAUSE] = { chassis_get_sys_restart_cause }
1980
static const IPMINetfn chassis_netfn = {
1981
.cmd_nums = ARRAY_SIZE(chassis_cmds),
1982
.cmd_handlers = chassis_cmds
1985
static const IPMICmdHandler sensor_event_cmds[] = {
1986
[IPMI_CMD_PLATFORM_EVENT_MSG] = { platform_event_msg, 10 },
1987
[IPMI_CMD_SET_SENSOR_EVT_ENABLE] = { set_sensor_evt_enable, 4 },
1988
[IPMI_CMD_GET_SENSOR_EVT_ENABLE] = { get_sensor_evt_enable, 3 },
1989
[IPMI_CMD_REARM_SENSOR_EVTS] = { rearm_sensor_evts, 4 },
1990
[IPMI_CMD_GET_SENSOR_EVT_STATUS] = { get_sensor_evt_status, 3 },
1991
[IPMI_CMD_GET_SENSOR_READING] = { get_sensor_reading, 3 },
1992
[IPMI_CMD_SET_SENSOR_TYPE] = { set_sensor_type, 5 },
1993
[IPMI_CMD_GET_SENSOR_TYPE] = { get_sensor_type, 3 },
1994
[IPMI_CMD_SET_SENSOR_READING] = { set_sensor_reading, 5 },
1996
static const IPMINetfn sensor_event_netfn = {
1997
.cmd_nums = ARRAY_SIZE(sensor_event_cmds),
1998
.cmd_handlers = sensor_event_cmds
2001
static const IPMICmdHandler app_cmds[] = {
2002
[IPMI_CMD_GET_DEVICE_ID] = { get_device_id },
2003
[IPMI_CMD_COLD_RESET] = { cold_reset },
2004
[IPMI_CMD_WARM_RESET] = { warm_reset },
2005
[IPMI_CMD_SET_ACPI_POWER_STATE] = { set_acpi_power_state, 4 },
2006
[IPMI_CMD_GET_ACPI_POWER_STATE] = { get_acpi_power_state },
2007
[IPMI_CMD_GET_DEVICE_GUID] = { get_device_guid },
2008
[IPMI_CMD_SET_BMC_GLOBAL_ENABLES] = { set_bmc_global_enables, 3 },
2009
[IPMI_CMD_GET_BMC_GLOBAL_ENABLES] = { get_bmc_global_enables },
2010
[IPMI_CMD_CLR_MSG_FLAGS] = { clr_msg_flags, 3 },
2011
[IPMI_CMD_GET_MSG_FLAGS] = { get_msg_flags },
2012
[IPMI_CMD_GET_MSG] = { get_msg },
2013
[IPMI_CMD_SEND_MSG] = { send_msg, 3 },
2014
[IPMI_CMD_READ_EVT_MSG_BUF] = { read_evt_msg_buf },
2015
[IPMI_CMD_RESET_WATCHDOG_TIMER] = { reset_watchdog_timer },
2016
[IPMI_CMD_SET_WATCHDOG_TIMER] = { set_watchdog_timer, 8 },
2017
[IPMI_CMD_GET_WATCHDOG_TIMER] = { get_watchdog_timer },
2019
static const IPMINetfn app_netfn = {
2020
.cmd_nums = ARRAY_SIZE(app_cmds),
2021
.cmd_handlers = app_cmds
2024
static const IPMICmdHandler storage_cmds[] = {
2025
[IPMI_CMD_GET_FRU_AREA_INFO] = { get_fru_area_info, 3 },
2026
[IPMI_CMD_READ_FRU_DATA] = { read_fru_data, 5 },
2027
[IPMI_CMD_WRITE_FRU_DATA] = { write_fru_data, 5 },
2028
[IPMI_CMD_GET_SDR_REP_INFO] = { get_sdr_rep_info },
2029
[IPMI_CMD_RESERVE_SDR_REP] = { reserve_sdr_rep },
2030
[IPMI_CMD_GET_SDR] = { get_sdr, 8 },
2031
[IPMI_CMD_ADD_SDR] = { add_sdr },
2032
[IPMI_CMD_CLEAR_SDR_REP] = { clear_sdr_rep, 8 },
2033
[IPMI_CMD_GET_SEL_INFO] = { get_sel_info },
2034
[IPMI_CMD_RESERVE_SEL] = { reserve_sel },
2035
[IPMI_CMD_GET_SEL_ENTRY] = { get_sel_entry, 8 },
2036
[IPMI_CMD_ADD_SEL_ENTRY] = { add_sel_entry, 18 },
2037
[IPMI_CMD_CLEAR_SEL] = { clear_sel, 8 },
2038
[IPMI_CMD_GET_SEL_TIME] = { get_sel_time },
2039
[IPMI_CMD_SET_SEL_TIME] = { set_sel_time, 6 },
2042
static const IPMINetfn storage_netfn = {
2043
.cmd_nums = ARRAY_SIZE(storage_cmds),
2044
.cmd_handlers = storage_cmds
2047
static void register_cmds(IPMIBmcSim *s)
2049
ipmi_sim_register_netfn(s, IPMI_NETFN_CHASSIS, &chassis_netfn);
2050
ipmi_sim_register_netfn(s, IPMI_NETFN_SENSOR_EVENT, &sensor_event_netfn);
2051
ipmi_sim_register_netfn(s, IPMI_NETFN_APP, &app_netfn);
2052
ipmi_sim_register_netfn(s, IPMI_NETFN_STORAGE, &storage_netfn);
2055
static uint8_t init_sdrs[] = {
2057
0x00, 0x00, 0x51, 0x02, 35, 0x20, 0x00, 0x00,
2058
0x23, 0x01, 0x63, 0x00, 0x23, 0x6f, 0x0f, 0x01,
2059
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2060
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8,
2061
'W', 'a', 't', 'c', 'h', 'd', 'o', 'g',
2064
static void ipmi_sdr_init(IPMIBmcSim *ibs)
2071
sdrs_size = sizeof(init_sdrs);
2073
if (ibs->sdr_filename &&
2074
!g_file_get_contents(ibs->sdr_filename, (gchar **) &sdrs, &sdrs_size,
2076
error_report("failed to load sdr file '%s'", ibs->sdr_filename);
2077
sdrs_size = sizeof(init_sdrs);
2081
for (i = 0; i < sdrs_size; i += len) {
2082
struct ipmi_sdr_header *sdrh;
2084
if (i + IPMI_SDR_HEADER_SIZE > sdrs_size) {
2085
error_report("Problem with recid 0x%4.4x", i);
2088
sdrh = (struct ipmi_sdr_header *) &sdrs[i];
2089
len = ipmi_sdr_length(sdrh);
2090
if (i + len > sdrs_size) {
2091
error_report("Problem with recid 0x%4.4x", i);
2094
sdr_add_entry(ibs, sdrh, len, NULL);
2097
if (sdrs != init_sdrs) {
2102
static const VMStateDescription vmstate_ipmi_sim = {
2103
.name = TYPE_IPMI_BMC_SIMULATOR,
2105
.minimum_version_id = 1,
2106
.fields = (const VMStateField[]) {
2107
VMSTATE_UINT8(bmc_global_enables, IPMIBmcSim),
2108
VMSTATE_UINT8(msg_flags, IPMIBmcSim),
2109
VMSTATE_BOOL(watchdog_initialized, IPMIBmcSim),
2110
VMSTATE_UINT8(watchdog_use, IPMIBmcSim),
2111
VMSTATE_UINT8(watchdog_action, IPMIBmcSim),
2112
VMSTATE_UINT8(watchdog_pretimeout, IPMIBmcSim),
2113
VMSTATE_UINT8(watchdog_expired, IPMIBmcSim),
2114
VMSTATE_UINT16(watchdog_timeout, IPMIBmcSim),
2115
VMSTATE_BOOL(watchdog_running, IPMIBmcSim),
2116
VMSTATE_BOOL(watchdog_preaction_ran, IPMIBmcSim),
2117
VMSTATE_INT64(watchdog_expiry, IPMIBmcSim),
2118
VMSTATE_UINT8_ARRAY(evtbuf, IPMIBmcSim, 16),
2119
VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].status, IPMIBmcSim),
2120
VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].reading, IPMIBmcSim),
2121
VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].states, IPMIBmcSim),
2122
VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_states, IPMIBmcSim),
2123
VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].deassert_states,
2125
VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_enable, IPMIBmcSim),
2126
VMSTATE_END_OF_LIST()
2130
static void ipmi_fru_init(IPMIFru *fru)
2135
if (!fru->filename) {
2139
fsize = get_image_size(fru->filename);
2141
size = QEMU_ALIGN_UP(fsize, fru->areasize);
2142
fru->data = g_malloc0(size);
2143
if (load_image_size(fru->filename, fru->data, fsize) != fsize) {
2144
error_report("Could not load file '%s'", fru->filename);
2153
size = fru->areasize;
2154
fru->data = g_malloc0(size);
2157
fru->nentries = size / fru->areasize;
2160
static void ipmi_sim_realize(DeviceState *dev, Error **errp)
2162
IPMIBmc *b = IPMI_BMC(dev);
2164
IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b);
2166
QTAILQ_INIT(&ibs->rcvbufs);
2168
ibs->bmc_global_enables = (1 << IPMI_BMC_EVENT_LOG_BIT);
2169
ibs->device_id = 0x20;
2170
ibs->ipmi_version = 0x02;
2171
ibs->restart_cause = 0;
2172
for (i = 0; i < 4; i++) {
2173
ibs->sel.last_addition[i] = 0xff;
2174
ibs->sel.last_clear[i] = 0xff;
2175
ibs->sdr.last_addition[i] = 0xff;
2176
ibs->sdr.last_clear[i] = 0xff;
2181
ipmi_fru_init(&ibs->fru);
2183
ibs->acpi_power_state[0] = 0;
2184
ibs->acpi_power_state[1] = 0;
2186
ipmi_init_sensors_from_sdrs(ibs);
2189
ibs->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ipmi_timeout, ibs);
2191
vmstate_register(NULL, 0, &vmstate_ipmi_sim, ibs);
2194
static Property ipmi_sim_properties[] = {
2195
DEFINE_PROP_UINT16("fruareasize", IPMIBmcSim, fru.areasize, 1024),
2196
DEFINE_PROP_STRING("frudatafile", IPMIBmcSim, fru.filename),
2197
DEFINE_PROP_STRING("sdrfile", IPMIBmcSim, sdr_filename),
2198
DEFINE_PROP_UINT8("device_id", IPMIBmcSim, device_id, 0x20),
2199
DEFINE_PROP_UINT8("ipmi_version", IPMIBmcSim, ipmi_version, 0x02),
2200
DEFINE_PROP_UINT8("device_rev", IPMIBmcSim, device_rev, 0),
2201
DEFINE_PROP_UINT8("fwrev1", IPMIBmcSim, fwrev1, 0),
2202
DEFINE_PROP_UINT8("fwrev2", IPMIBmcSim, fwrev2, 0),
2203
DEFINE_PROP_UINT32("mfg_id", IPMIBmcSim, mfg_id, 0),
2204
DEFINE_PROP_UINT16("product_id", IPMIBmcSim, product_id, 0),
2205
DEFINE_PROP_UUID_NODEFAULT("guid", IPMIBmcSim, uuid),
2206
DEFINE_PROP_END_OF_LIST(),
2209
static void ipmi_sim_class_init(ObjectClass *oc, void *data)
2211
DeviceClass *dc = DEVICE_CLASS(oc);
2212
IPMIBmcClass *bk = IPMI_BMC_CLASS(oc);
2214
dc->hotpluggable = false;
2215
dc->realize = ipmi_sim_realize;
2216
device_class_set_props(dc, ipmi_sim_properties);
2217
bk->handle_command = ipmi_sim_handle_command;
2220
static const TypeInfo ipmi_sim_type = {
2221
.name = TYPE_IPMI_BMC_SIMULATOR,
2222
.parent = TYPE_IPMI_BMC,
2223
.instance_size = sizeof(IPMIBmcSim),
2224
.class_init = ipmi_sim_class_init,
2227
static void ipmi_sim_register_types(void)
2229
type_register_static(&ipmi_sim_type);
2232
type_init(ipmi_sim_register_types)