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