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