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