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