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