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 break; 1139 1140 default: 1141 /* We don't support PRE_SMI */ 1142 rsp[2] = IPMI_CC_INVALID_DATA_FIELD; 1143 return; 1144 } 1145 1146 ibs->watchdog_initialized = 1; 1147 ibs->watchdog_use = cmd[2] & IPMI_BMC_WATCHDOG_USE_MASK; 1148 ibs->watchdog_action = cmd[3] & IPMI_BMC_WATCHDOG_ACTION_MASK; 1149 ibs->watchdog_pretimeout = cmd[4]; 1150 ibs->watchdog_expired &= ~cmd[5]; 1151 ibs->watchdog_timeout = cmd[6] | (((uint16_t) cmd[7]) << 8); 1152 if (ibs->watchdog_running & IPMI_BMC_WATCHDOG_GET_DONT_STOP(ibs)) { 1153 do_watchdog_reset(ibs); 1154 } else { 1155 ibs->watchdog_running = 0; 1156 } 1157 } 1158 1159 static void get_watchdog_timer(IPMIBmcSim *ibs, 1160 uint8_t *cmd, unsigned int cmd_len, 1161 uint8_t *rsp, unsigned int *rsp_len, 1162 unsigned int max_rsp_len) 1163 { 1164 IPMI_ADD_RSP_DATA(ibs->watchdog_use); 1165 IPMI_ADD_RSP_DATA(ibs->watchdog_action); 1166 IPMI_ADD_RSP_DATA(ibs->watchdog_pretimeout); 1167 IPMI_ADD_RSP_DATA(ibs->watchdog_expired); 1168 if (ibs->watchdog_running) { 1169 long timeout; 1170 timeout = ((ibs->watchdog_expiry - ipmi_getmonotime() + 50000000) 1171 / 100000000); 1172 IPMI_ADD_RSP_DATA(timeout & 0xff); 1173 IPMI_ADD_RSP_DATA((timeout >> 8) & 0xff); 1174 } else { 1175 IPMI_ADD_RSP_DATA(0); 1176 IPMI_ADD_RSP_DATA(0); 1177 } 1178 } 1179 1180 static void get_sdr_rep_info(IPMIBmcSim *ibs, 1181 uint8_t *cmd, unsigned int cmd_len, 1182 uint8_t *rsp, unsigned int *rsp_len, 1183 unsigned int max_rsp_len) 1184 { 1185 unsigned int i; 1186 1187 IPMI_ADD_RSP_DATA(0x51); /* Conform to IPMI 1.5 spec */ 1188 IPMI_ADD_RSP_DATA(ibs->sdr.next_rec_id & 0xff); 1189 IPMI_ADD_RSP_DATA((ibs->sdr.next_rec_id >> 8) & 0xff); 1190 IPMI_ADD_RSP_DATA((MAX_SDR_SIZE - ibs->sdr.next_free) & 0xff); 1191 IPMI_ADD_RSP_DATA(((MAX_SDR_SIZE - ibs->sdr.next_free) >> 8) & 0xff); 1192 for (i = 0; i < 4; i++) { 1193 IPMI_ADD_RSP_DATA(ibs->sdr.last_addition[i]); 1194 } 1195 for (i = 0; i < 4; i++) { 1196 IPMI_ADD_RSP_DATA(ibs->sdr.last_clear[i]); 1197 } 1198 /* Only modal support, reserve supported */ 1199 IPMI_ADD_RSP_DATA((ibs->sdr.overflow << 7) | 0x22); 1200 } 1201 1202 static void reserve_sdr_rep(IPMIBmcSim *ibs, 1203 uint8_t *cmd, unsigned int cmd_len, 1204 uint8_t *rsp, unsigned int *rsp_len, 1205 unsigned int max_rsp_len) 1206 { 1207 IPMI_ADD_RSP_DATA(ibs->sdr.reservation & 0xff); 1208 IPMI_ADD_RSP_DATA((ibs->sdr.reservation >> 8) & 0xff); 1209 } 1210 1211 static void get_sdr(IPMIBmcSim *ibs, 1212 uint8_t *cmd, unsigned int cmd_len, 1213 uint8_t *rsp, unsigned int *rsp_len, 1214 unsigned int max_rsp_len) 1215 { 1216 unsigned int pos; 1217 uint16_t nextrec; 1218 struct ipmi_sdr_header *sdrh; 1219 1220 IPMI_CHECK_CMD_LEN(8); 1221 if (cmd[6]) { 1222 IPMI_CHECK_RESERVATION(2, ibs->sdr.reservation); 1223 } 1224 pos = 0; 1225 if (sdr_find_entry(&ibs->sdr, cmd[4] | (cmd[5] << 8), 1226 &pos, &nextrec)) { 1227 rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; 1228 return; 1229 } 1230 1231 sdrh = (struct ipmi_sdr_header *) &ibs->sdr.sdr[pos]; 1232 1233 if (cmd[6] > ipmi_sdr_length(sdrh)) { 1234 rsp[2] = IPMI_CC_PARM_OUT_OF_RANGE; 1235 return; 1236 } 1237 1238 IPMI_ADD_RSP_DATA(nextrec & 0xff); 1239 IPMI_ADD_RSP_DATA((nextrec >> 8) & 0xff); 1240 1241 if (cmd[7] == 0xff) { 1242 cmd[7] = ipmi_sdr_length(sdrh) - cmd[6]; 1243 } 1244 1245 if ((cmd[7] + *rsp_len) > max_rsp_len) { 1246 rsp[2] = IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES; 1247 return; 1248 } 1249 memcpy(rsp + *rsp_len, ibs->sdr.sdr + pos + cmd[6], cmd[7]); 1250 *rsp_len += cmd[7]; 1251 } 1252 1253 static void add_sdr(IPMIBmcSim *ibs, 1254 uint8_t *cmd, unsigned int cmd_len, 1255 uint8_t *rsp, unsigned int *rsp_len, 1256 unsigned int max_rsp_len) 1257 { 1258 uint16_t recid; 1259 struct ipmi_sdr_header *sdrh = (struct ipmi_sdr_header *) cmd + 2; 1260 1261 if (sdr_add_entry(ibs, sdrh, cmd_len - 2, &recid)) { 1262 rsp[2] = IPMI_CC_INVALID_DATA_FIELD; 1263 return; 1264 } 1265 IPMI_ADD_RSP_DATA(recid & 0xff); 1266 IPMI_ADD_RSP_DATA((recid >> 8) & 0xff); 1267 } 1268 1269 static void clear_sdr_rep(IPMIBmcSim *ibs, 1270 uint8_t *cmd, unsigned int cmd_len, 1271 uint8_t *rsp, unsigned int *rsp_len, 1272 unsigned int max_rsp_len) 1273 { 1274 IPMI_CHECK_CMD_LEN(8); 1275 IPMI_CHECK_RESERVATION(2, ibs->sdr.reservation); 1276 if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') { 1277 rsp[2] = IPMI_CC_INVALID_DATA_FIELD; 1278 return; 1279 } 1280 if (cmd[7] == 0xaa) { 1281 ibs->sdr.next_free = 0; 1282 ibs->sdr.overflow = 0; 1283 set_timestamp(ibs, ibs->sdr.last_clear); 1284 IPMI_ADD_RSP_DATA(1); /* Erasure complete */ 1285 sdr_inc_reservation(&ibs->sdr); 1286 } else if (cmd[7] == 0) { 1287 IPMI_ADD_RSP_DATA(1); /* Erasure complete */ 1288 } else { 1289 rsp[2] = IPMI_CC_INVALID_DATA_FIELD; 1290 return; 1291 } 1292 } 1293 1294 static void get_sel_info(IPMIBmcSim *ibs, 1295 uint8_t *cmd, unsigned int cmd_len, 1296 uint8_t *rsp, unsigned int *rsp_len, 1297 unsigned int max_rsp_len) 1298 { 1299 unsigned int i, val; 1300 1301 IPMI_ADD_RSP_DATA(0x51); /* Conform to IPMI 1.5 */ 1302 IPMI_ADD_RSP_DATA(ibs->sel.next_free & 0xff); 1303 IPMI_ADD_RSP_DATA((ibs->sel.next_free >> 8) & 0xff); 1304 val = (MAX_SEL_SIZE - ibs->sel.next_free) * 16; 1305 IPMI_ADD_RSP_DATA(val & 0xff); 1306 IPMI_ADD_RSP_DATA((val >> 8) & 0xff); 1307 for (i = 0; i < 4; i++) { 1308 IPMI_ADD_RSP_DATA(ibs->sel.last_addition[i]); 1309 } 1310 for (i = 0; i < 4; i++) { 1311 IPMI_ADD_RSP_DATA(ibs->sel.last_clear[i]); 1312 } 1313 /* Only support Reserve SEL */ 1314 IPMI_ADD_RSP_DATA((ibs->sel.overflow << 7) | 0x02); 1315 } 1316 1317 static void reserve_sel(IPMIBmcSim *ibs, 1318 uint8_t *cmd, unsigned int cmd_len, 1319 uint8_t *rsp, unsigned int *rsp_len, 1320 unsigned int max_rsp_len) 1321 { 1322 IPMI_ADD_RSP_DATA(ibs->sel.reservation & 0xff); 1323 IPMI_ADD_RSP_DATA((ibs->sel.reservation >> 8) & 0xff); 1324 } 1325 1326 static void get_sel_entry(IPMIBmcSim *ibs, 1327 uint8_t *cmd, unsigned int cmd_len, 1328 uint8_t *rsp, unsigned int *rsp_len, 1329 unsigned int max_rsp_len) 1330 { 1331 unsigned int val; 1332 1333 IPMI_CHECK_CMD_LEN(8); 1334 if (cmd[6]) { 1335 IPMI_CHECK_RESERVATION(2, ibs->sel.reservation); 1336 } 1337 if (ibs->sel.next_free == 0) { 1338 rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; 1339 return; 1340 } 1341 if (cmd[6] > 15) { 1342 rsp[2] = IPMI_CC_INVALID_DATA_FIELD; 1343 return; 1344 } 1345 if (cmd[7] == 0xff) { 1346 cmd[7] = 16; 1347 } else if ((cmd[7] + cmd[6]) > 16) { 1348 rsp[2] = IPMI_CC_INVALID_DATA_FIELD; 1349 return; 1350 } else { 1351 cmd[7] += cmd[6]; 1352 } 1353 1354 val = cmd[4] | (cmd[5] << 8); 1355 if (val == 0xffff) { 1356 val = ibs->sel.next_free - 1; 1357 } else if (val >= ibs->sel.next_free) { 1358 rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; 1359 return; 1360 } 1361 if ((val + 1) == ibs->sel.next_free) { 1362 IPMI_ADD_RSP_DATA(0xff); 1363 IPMI_ADD_RSP_DATA(0xff); 1364 } else { 1365 IPMI_ADD_RSP_DATA((val + 1) & 0xff); 1366 IPMI_ADD_RSP_DATA(((val + 1) >> 8) & 0xff); 1367 } 1368 for (; cmd[6] < cmd[7]; cmd[6]++) { 1369 IPMI_ADD_RSP_DATA(ibs->sel.sel[val][cmd[6]]); 1370 } 1371 } 1372 1373 static void add_sel_entry(IPMIBmcSim *ibs, 1374 uint8_t *cmd, unsigned int cmd_len, 1375 uint8_t *rsp, unsigned int *rsp_len, 1376 unsigned int max_rsp_len) 1377 { 1378 IPMI_CHECK_CMD_LEN(18); 1379 if (sel_add_event(ibs, cmd + 2)) { 1380 rsp[2] = IPMI_CC_OUT_OF_SPACE; 1381 return; 1382 } 1383 /* sel_add_event fills in the record number. */ 1384 IPMI_ADD_RSP_DATA(cmd[2]); 1385 IPMI_ADD_RSP_DATA(cmd[3]); 1386 } 1387 1388 static void clear_sel(IPMIBmcSim *ibs, 1389 uint8_t *cmd, unsigned int cmd_len, 1390 uint8_t *rsp, unsigned int *rsp_len, 1391 unsigned int max_rsp_len) 1392 { 1393 IPMI_CHECK_CMD_LEN(8); 1394 IPMI_CHECK_RESERVATION(2, ibs->sel.reservation); 1395 if (cmd[4] != 'C' || cmd[5] != 'L' || cmd[6] != 'R') { 1396 rsp[2] = IPMI_CC_INVALID_DATA_FIELD; 1397 return; 1398 } 1399 if (cmd[7] == 0xaa) { 1400 ibs->sel.next_free = 0; 1401 ibs->sel.overflow = 0; 1402 set_timestamp(ibs, ibs->sdr.last_clear); 1403 IPMI_ADD_RSP_DATA(1); /* Erasure complete */ 1404 sel_inc_reservation(&ibs->sel); 1405 } else if (cmd[7] == 0) { 1406 IPMI_ADD_RSP_DATA(1); /* Erasure complete */ 1407 } else { 1408 rsp[2] = IPMI_CC_INVALID_DATA_FIELD; 1409 return; 1410 } 1411 } 1412 1413 static void get_sel_time(IPMIBmcSim *ibs, 1414 uint8_t *cmd, unsigned int cmd_len, 1415 uint8_t *rsp, unsigned int *rsp_len, 1416 unsigned int max_rsp_len) 1417 { 1418 uint32_t val; 1419 struct ipmi_time now; 1420 1421 ipmi_gettime(&now); 1422 val = now.tv_sec + ibs->sel.time_offset; 1423 IPMI_ADD_RSP_DATA(val & 0xff); 1424 IPMI_ADD_RSP_DATA((val >> 8) & 0xff); 1425 IPMI_ADD_RSP_DATA((val >> 16) & 0xff); 1426 IPMI_ADD_RSP_DATA((val >> 24) & 0xff); 1427 } 1428 1429 static void set_sel_time(IPMIBmcSim *ibs, 1430 uint8_t *cmd, unsigned int cmd_len, 1431 uint8_t *rsp, unsigned int *rsp_len, 1432 unsigned int max_rsp_len) 1433 { 1434 uint32_t val; 1435 struct ipmi_time now; 1436 1437 IPMI_CHECK_CMD_LEN(6); 1438 val = cmd[2] | (cmd[3] << 8) | (cmd[4] << 16) | (cmd[5] << 24); 1439 ipmi_gettime(&now); 1440 ibs->sel.time_offset = now.tv_sec - ((long) val); 1441 } 1442 1443 static void set_sensor_evt_enable(IPMIBmcSim *ibs, 1444 uint8_t *cmd, unsigned int cmd_len, 1445 uint8_t *rsp, unsigned int *rsp_len, 1446 unsigned int max_rsp_len) 1447 { 1448 IPMISensor *sens; 1449 1450 IPMI_CHECK_CMD_LEN(4); 1451 if ((cmd[2] >= MAX_SENSORS) || 1452 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) { 1453 rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; 1454 return; 1455 } 1456 sens = ibs->sensors + cmd[2]; 1457 switch ((cmd[3] >> 4) & 0x3) { 1458 case 0: /* Do not change */ 1459 break; 1460 case 1: /* Enable bits */ 1461 if (cmd_len > 4) { 1462 sens->assert_enable |= cmd[4]; 1463 } 1464 if (cmd_len > 5) { 1465 sens->assert_enable |= cmd[5] << 8; 1466 } 1467 if (cmd_len > 6) { 1468 sens->deassert_enable |= cmd[6]; 1469 } 1470 if (cmd_len > 7) { 1471 sens->deassert_enable |= cmd[7] << 8; 1472 } 1473 break; 1474 case 2: /* Disable bits */ 1475 if (cmd_len > 4) { 1476 sens->assert_enable &= ~cmd[4]; 1477 } 1478 if (cmd_len > 5) { 1479 sens->assert_enable &= ~(cmd[5] << 8); 1480 } 1481 if (cmd_len > 6) { 1482 sens->deassert_enable &= ~cmd[6]; 1483 } 1484 if (cmd_len > 7) { 1485 sens->deassert_enable &= ~(cmd[7] << 8); 1486 } 1487 break; 1488 case 3: 1489 rsp[2] = IPMI_CC_INVALID_DATA_FIELD; 1490 return; 1491 } 1492 IPMI_SENSOR_SET_RET_STATUS(sens, cmd[3]); 1493 } 1494 1495 static void get_sensor_evt_enable(IPMIBmcSim *ibs, 1496 uint8_t *cmd, unsigned int cmd_len, 1497 uint8_t *rsp, unsigned int *rsp_len, 1498 unsigned int max_rsp_len) 1499 { 1500 IPMISensor *sens; 1501 1502 IPMI_CHECK_CMD_LEN(3); 1503 if ((cmd[2] >= MAX_SENSORS) || 1504 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) { 1505 rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; 1506 return; 1507 } 1508 sens = ibs->sensors + cmd[2]; 1509 IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens)); 1510 IPMI_ADD_RSP_DATA(sens->assert_enable & 0xff); 1511 IPMI_ADD_RSP_DATA((sens->assert_enable >> 8) & 0xff); 1512 IPMI_ADD_RSP_DATA(sens->deassert_enable & 0xff); 1513 IPMI_ADD_RSP_DATA((sens->deassert_enable >> 8) & 0xff); 1514 } 1515 1516 static void rearm_sensor_evts(IPMIBmcSim *ibs, 1517 uint8_t *cmd, unsigned int cmd_len, 1518 uint8_t *rsp, unsigned int *rsp_len, 1519 unsigned int max_rsp_len) 1520 { 1521 IPMISensor *sens; 1522 1523 IPMI_CHECK_CMD_LEN(4); 1524 if ((cmd[2] >= MAX_SENSORS) || 1525 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) { 1526 rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; 1527 return; 1528 } 1529 sens = ibs->sensors + cmd[2]; 1530 1531 if ((cmd[3] & 0x80) == 0) { 1532 /* Just clear everything */ 1533 sens->states = 0; 1534 return; 1535 } 1536 } 1537 1538 static void get_sensor_evt_status(IPMIBmcSim *ibs, 1539 uint8_t *cmd, unsigned int cmd_len, 1540 uint8_t *rsp, unsigned int *rsp_len, 1541 unsigned int max_rsp_len) 1542 { 1543 IPMISensor *sens; 1544 1545 IPMI_CHECK_CMD_LEN(3); 1546 if ((cmd[2] >= MAX_SENSORS) || 1547 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) { 1548 rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; 1549 return; 1550 } 1551 sens = ibs->sensors + cmd[2]; 1552 IPMI_ADD_RSP_DATA(sens->reading); 1553 IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens)); 1554 IPMI_ADD_RSP_DATA(sens->assert_states & 0xff); 1555 IPMI_ADD_RSP_DATA((sens->assert_states >> 8) & 0xff); 1556 IPMI_ADD_RSP_DATA(sens->deassert_states & 0xff); 1557 IPMI_ADD_RSP_DATA((sens->deassert_states >> 8) & 0xff); 1558 } 1559 1560 static void get_sensor_reading(IPMIBmcSim *ibs, 1561 uint8_t *cmd, unsigned int cmd_len, 1562 uint8_t *rsp, unsigned int *rsp_len, 1563 unsigned int max_rsp_len) 1564 { 1565 IPMISensor *sens; 1566 1567 IPMI_CHECK_CMD_LEN(3); 1568 if ((cmd[2] >= MAX_SENSORS) || 1569 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) { 1570 rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; 1571 return; 1572 } 1573 sens = ibs->sensors + cmd[2]; 1574 IPMI_ADD_RSP_DATA(sens->reading); 1575 IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens)); 1576 IPMI_ADD_RSP_DATA(sens->states & 0xff); 1577 if (IPMI_SENSOR_IS_DISCRETE(sens)) { 1578 IPMI_ADD_RSP_DATA((sens->states >> 8) & 0xff); 1579 } 1580 } 1581 1582 static void set_sensor_type(IPMIBmcSim *ibs, 1583 uint8_t *cmd, unsigned int cmd_len, 1584 uint8_t *rsp, unsigned int *rsp_len, 1585 unsigned int max_rsp_len) 1586 { 1587 IPMISensor *sens; 1588 1589 1590 IPMI_CHECK_CMD_LEN(5); 1591 if ((cmd[2] >= MAX_SENSORS) || 1592 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) { 1593 rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; 1594 return; 1595 } 1596 sens = ibs->sensors + cmd[2]; 1597 sens->sensor_type = cmd[3]; 1598 sens->evt_reading_type_code = cmd[4] & 0x7f; 1599 } 1600 1601 static void get_sensor_type(IPMIBmcSim *ibs, 1602 uint8_t *cmd, unsigned int cmd_len, 1603 uint8_t *rsp, unsigned int *rsp_len, 1604 unsigned int max_rsp_len) 1605 { 1606 IPMISensor *sens; 1607 1608 1609 IPMI_CHECK_CMD_LEN(3); 1610 if ((cmd[2] >= MAX_SENSORS) || 1611 !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) { 1612 rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT; 1613 return; 1614 } 1615 sens = ibs->sensors + cmd[2]; 1616 IPMI_ADD_RSP_DATA(sens->sensor_type); 1617 IPMI_ADD_RSP_DATA(sens->evt_reading_type_code); 1618 } 1619 1620 1621 static const IPMICmdHandler chassis_cmds[] = { 1622 [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = chassis_capabilities, 1623 [IPMI_CMD_GET_CHASSIS_STATUS] = chassis_status, 1624 [IPMI_CMD_CHASSIS_CONTROL] = chassis_control, 1625 [IPMI_CMD_GET_SYS_RESTART_CAUSE] = chassis_get_sys_restart_cause 1626 }; 1627 static const IPMINetfn chassis_netfn = { 1628 .cmd_nums = ARRAY_SIZE(chassis_cmds), 1629 .cmd_handlers = chassis_cmds 1630 }; 1631 1632 static const IPMICmdHandler sensor_event_cmds[] = { 1633 [IPMI_CMD_SET_SENSOR_EVT_ENABLE] = set_sensor_evt_enable, 1634 [IPMI_CMD_GET_SENSOR_EVT_ENABLE] = get_sensor_evt_enable, 1635 [IPMI_CMD_REARM_SENSOR_EVTS] = rearm_sensor_evts, 1636 [IPMI_CMD_GET_SENSOR_EVT_STATUS] = get_sensor_evt_status, 1637 [IPMI_CMD_GET_SENSOR_READING] = get_sensor_reading, 1638 [IPMI_CMD_SET_SENSOR_TYPE] = set_sensor_type, 1639 [IPMI_CMD_GET_SENSOR_TYPE] = get_sensor_type, 1640 }; 1641 static const IPMINetfn sensor_event_netfn = { 1642 .cmd_nums = ARRAY_SIZE(sensor_event_cmds), 1643 .cmd_handlers = sensor_event_cmds 1644 }; 1645 1646 static const IPMICmdHandler app_cmds[] = { 1647 [IPMI_CMD_GET_DEVICE_ID] = get_device_id, 1648 [IPMI_CMD_COLD_RESET] = cold_reset, 1649 [IPMI_CMD_WARM_RESET] = warm_reset, 1650 [IPMI_CMD_SET_ACPI_POWER_STATE] = set_acpi_power_state, 1651 [IPMI_CMD_GET_ACPI_POWER_STATE] = get_acpi_power_state, 1652 [IPMI_CMD_GET_DEVICE_GUID] = get_device_guid, 1653 [IPMI_CMD_SET_BMC_GLOBAL_ENABLES] = set_bmc_global_enables, 1654 [IPMI_CMD_GET_BMC_GLOBAL_ENABLES] = get_bmc_global_enables, 1655 [IPMI_CMD_CLR_MSG_FLAGS] = clr_msg_flags, 1656 [IPMI_CMD_GET_MSG_FLAGS] = get_msg_flags, 1657 [IPMI_CMD_GET_MSG] = get_msg, 1658 [IPMI_CMD_SEND_MSG] = send_msg, 1659 [IPMI_CMD_READ_EVT_MSG_BUF] = read_evt_msg_buf, 1660 [IPMI_CMD_RESET_WATCHDOG_TIMER] = reset_watchdog_timer, 1661 [IPMI_CMD_SET_WATCHDOG_TIMER] = set_watchdog_timer, 1662 [IPMI_CMD_GET_WATCHDOG_TIMER] = get_watchdog_timer, 1663 }; 1664 static const IPMINetfn app_netfn = { 1665 .cmd_nums = ARRAY_SIZE(app_cmds), 1666 .cmd_handlers = app_cmds 1667 }; 1668 1669 static const IPMICmdHandler storage_cmds[] = { 1670 [IPMI_CMD_GET_SDR_REP_INFO] = get_sdr_rep_info, 1671 [IPMI_CMD_RESERVE_SDR_REP] = reserve_sdr_rep, 1672 [IPMI_CMD_GET_SDR] = get_sdr, 1673 [IPMI_CMD_ADD_SDR] = add_sdr, 1674 [IPMI_CMD_CLEAR_SDR_REP] = clear_sdr_rep, 1675 [IPMI_CMD_GET_SEL_INFO] = get_sel_info, 1676 [IPMI_CMD_RESERVE_SEL] = reserve_sel, 1677 [IPMI_CMD_GET_SEL_ENTRY] = get_sel_entry, 1678 [IPMI_CMD_ADD_SEL_ENTRY] = add_sel_entry, 1679 [IPMI_CMD_CLEAR_SEL] = clear_sel, 1680 [IPMI_CMD_GET_SEL_TIME] = get_sel_time, 1681 [IPMI_CMD_SET_SEL_TIME] = set_sel_time, 1682 }; 1683 1684 static const IPMINetfn storage_netfn = { 1685 .cmd_nums = ARRAY_SIZE(storage_cmds), 1686 .cmd_handlers = storage_cmds 1687 }; 1688 1689 static void register_cmds(IPMIBmcSim *s) 1690 { 1691 ipmi_register_netfn(s, IPMI_NETFN_CHASSIS, &chassis_netfn); 1692 ipmi_register_netfn(s, IPMI_NETFN_SENSOR_EVENT, &sensor_event_netfn); 1693 ipmi_register_netfn(s, IPMI_NETFN_APP, &app_netfn); 1694 ipmi_register_netfn(s, IPMI_NETFN_STORAGE, &storage_netfn); 1695 } 1696 1697 static const uint8_t init_sdrs[] = { 1698 /* Watchdog device */ 1699 0x00, 0x00, 0x51, 0x02, 35, 0x20, 0x00, 0x00, 1700 0x23, 0x01, 0x63, 0x00, 0x23, 0x6f, 0x0f, 0x01, 1701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 1703 'W', 'a', 't', 'c', 'h', 'd', 'o', 'g', 1704 /* End */ 1705 0xff, 0xff, 0x00, 0x00, 0x00 1706 }; 1707 1708 static const VMStateDescription vmstate_ipmi_sim = { 1709 .name = TYPE_IPMI_BMC_SIMULATOR, 1710 .version_id = 1, 1711 .minimum_version_id = 1, 1712 .fields = (VMStateField[]) { 1713 VMSTATE_UINT8(bmc_global_enables, IPMIBmcSim), 1714 VMSTATE_UINT8(msg_flags, IPMIBmcSim), 1715 VMSTATE_BOOL(watchdog_initialized, IPMIBmcSim), 1716 VMSTATE_UINT8(watchdog_use, IPMIBmcSim), 1717 VMSTATE_UINT8(watchdog_action, IPMIBmcSim), 1718 VMSTATE_UINT8(watchdog_pretimeout, IPMIBmcSim), 1719 VMSTATE_BOOL(watchdog_expired, IPMIBmcSim), 1720 VMSTATE_UINT16(watchdog_timeout, IPMIBmcSim), 1721 VMSTATE_BOOL(watchdog_running, IPMIBmcSim), 1722 VMSTATE_BOOL(watchdog_preaction_ran, IPMIBmcSim), 1723 VMSTATE_INT64(watchdog_expiry, IPMIBmcSim), 1724 VMSTATE_UINT8_ARRAY(evtbuf, IPMIBmcSim, 16), 1725 VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].status, IPMIBmcSim), 1726 VMSTATE_UINT8(sensors[IPMI_WATCHDOG_SENSOR].reading, IPMIBmcSim), 1727 VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].states, IPMIBmcSim), 1728 VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_states, IPMIBmcSim), 1729 VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].deassert_states, 1730 IPMIBmcSim), 1731 VMSTATE_UINT16(sensors[IPMI_WATCHDOG_SENSOR].assert_enable, IPMIBmcSim), 1732 VMSTATE_END_OF_LIST() 1733 } 1734 }; 1735 1736 static void ipmi_sim_init(Object *obj) 1737 { 1738 IPMIBmc *b = IPMI_BMC(obj); 1739 unsigned int i; 1740 unsigned int recid; 1741 IPMIBmcSim *ibs = IPMI_BMC_SIMULATOR(b); 1742 1743 qemu_mutex_init(&ibs->lock); 1744 QTAILQ_INIT(&ibs->rcvbufs); 1745 1746 ibs->bmc_global_enables = (1 << IPMI_BMC_EVENT_LOG_BIT); 1747 ibs->device_id = 0x20; 1748 ibs->ipmi_version = 0x02; /* IPMI 2.0 */ 1749 ibs->restart_cause = 0; 1750 for (i = 0; i < 4; i++) { 1751 ibs->sel.last_addition[i] = 0xff; 1752 ibs->sel.last_clear[i] = 0xff; 1753 ibs->sdr.last_addition[i] = 0xff; 1754 ibs->sdr.last_clear[i] = 0xff; 1755 } 1756 1757 for (i = 0;;) { 1758 struct ipmi_sdr_header *sdrh; 1759 int len; 1760 if ((i + IPMI_SDR_HEADER_SIZE) > sizeof(init_sdrs)) { 1761 error_report("Problem with recid 0x%4.4x", i); 1762 return; 1763 } 1764 sdrh = (struct ipmi_sdr_header *) &init_sdrs[i]; 1765 len = ipmi_sdr_length(sdrh); 1766 recid = ipmi_sdr_recid(sdrh); 1767 if (recid == 0xffff) { 1768 break; 1769 } 1770 if ((i + len) > sizeof(init_sdrs)) { 1771 error_report("Problem with recid 0x%4.4x", i); 1772 return; 1773 } 1774 sdr_add_entry(ibs, sdrh, len, NULL); 1775 i += len; 1776 } 1777 1778 ibs->acpi_power_state[0] = 0; 1779 ibs->acpi_power_state[1] = 0; 1780 1781 if (qemu_uuid_set) { 1782 memcpy(&ibs->uuid, qemu_uuid, 16); 1783 } else { 1784 memset(&ibs->uuid, 0, 16); 1785 } 1786 1787 ipmi_init_sensors_from_sdrs(ibs); 1788 register_cmds(ibs); 1789 1790 ibs->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ipmi_timeout, ibs); 1791 1792 vmstate_register(NULL, 0, &vmstate_ipmi_sim, ibs); 1793 } 1794 1795 static void ipmi_sim_class_init(ObjectClass *oc, void *data) 1796 { 1797 IPMIBmcClass *bk = IPMI_BMC_CLASS(oc); 1798 1799 bk->handle_command = ipmi_sim_handle_command; 1800 } 1801 1802 static const TypeInfo ipmi_sim_type = { 1803 .name = TYPE_IPMI_BMC_SIMULATOR, 1804 .parent = TYPE_IPMI_BMC, 1805 .instance_size = sizeof(IPMIBmcSim), 1806 .instance_init = ipmi_sim_init, 1807 .class_init = ipmi_sim_class_init, 1808 }; 1809 1810 static void ipmi_sim_register_types(void) 1811 { 1812 type_register_static(&ipmi_sim_type); 1813 } 1814 1815 type_init(ipmi_sim_register_types) 1816