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