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