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