1 /* 2 * QEMU ISA IPMI KCS 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 "qemu/log.h" 27 #include "qemu/module.h" 28 #include "qapi/error.h" 29 #include "hw/hw.h" 30 #include "hw/ipmi/ipmi.h" 31 #include "hw/irq.h" 32 #include "hw/isa/isa.h" 33 34 #define IPMI_KCS_OBF_BIT 0 35 #define IPMI_KCS_IBF_BIT 1 36 #define IPMI_KCS_SMS_ATN_BIT 2 37 #define IPMI_KCS_CD_BIT 3 38 39 #define IPMI_KCS_OBF_MASK (1 << IPMI_KCS_OBF_BIT) 40 #define IPMI_KCS_GET_OBF(d) (((d) >> IPMI_KCS_OBF_BIT) & 0x1) 41 #define IPMI_KCS_SET_OBF(d, v) (d) = (((d) & ~IPMI_KCS_OBF_MASK) | \ 42 (((v) & 1) << IPMI_KCS_OBF_BIT)) 43 #define IPMI_KCS_IBF_MASK (1 << IPMI_KCS_IBF_BIT) 44 #define IPMI_KCS_GET_IBF(d) (((d) >> IPMI_KCS_IBF_BIT) & 0x1) 45 #define IPMI_KCS_SET_IBF(d, v) (d) = (((d) & ~IPMI_KCS_IBF_MASK) | \ 46 (((v) & 1) << IPMI_KCS_IBF_BIT)) 47 #define IPMI_KCS_SMS_ATN_MASK (1 << IPMI_KCS_SMS_ATN_BIT) 48 #define IPMI_KCS_GET_SMS_ATN(d) (((d) >> IPMI_KCS_SMS_ATN_BIT) & 0x1) 49 #define IPMI_KCS_SET_SMS_ATN(d, v) (d) = (((d) & ~IPMI_KCS_SMS_ATN_MASK) | \ 50 (((v) & 1) << IPMI_KCS_SMS_ATN_BIT)) 51 #define IPMI_KCS_CD_MASK (1 << IPMI_KCS_CD_BIT) 52 #define IPMI_KCS_GET_CD(d) (((d) >> IPMI_KCS_CD_BIT) & 0x1) 53 #define IPMI_KCS_SET_CD(d, v) (d) = (((d) & ~IPMI_KCS_CD_MASK) | \ 54 (((v) & 1) << IPMI_KCS_CD_BIT)) 55 56 #define IPMI_KCS_IDLE_STATE 0 57 #define IPMI_KCS_READ_STATE 1 58 #define IPMI_KCS_WRITE_STATE 2 59 #define IPMI_KCS_ERROR_STATE 3 60 61 #define IPMI_KCS_GET_STATE(d) (((d) >> 6) & 0x3) 62 #define IPMI_KCS_SET_STATE(d, v) ((d) = ((d) & ~0xc0) | (((v) & 0x3) << 6)) 63 64 #define IPMI_KCS_ABORT_STATUS_CMD 0x60 65 #define IPMI_KCS_WRITE_START_CMD 0x61 66 #define IPMI_KCS_WRITE_END_CMD 0x62 67 #define IPMI_KCS_READ_CMD 0x68 68 69 #define IPMI_KCS_STATUS_NO_ERR 0x00 70 #define IPMI_KCS_STATUS_ABORTED_ERR 0x01 71 #define IPMI_KCS_STATUS_BAD_CC_ERR 0x02 72 #define IPMI_KCS_STATUS_LENGTH_ERR 0x06 73 74 typedef struct IPMIKCS { 75 IPMIBmc *bmc; 76 77 bool do_wake; 78 79 qemu_irq irq; 80 81 uint32_t io_base; 82 unsigned long io_length; 83 MemoryRegion io; 84 85 bool obf_irq_set; 86 bool atn_irq_set; 87 bool use_irq; 88 bool irqs_enabled; 89 90 uint8_t outmsg[MAX_IPMI_MSG_SIZE]; 91 uint32_t outpos; 92 uint32_t outlen; 93 94 uint8_t inmsg[MAX_IPMI_MSG_SIZE]; 95 uint32_t inlen; 96 bool write_end; 97 98 uint8_t status_reg; 99 uint8_t data_out_reg; 100 101 int16_t data_in_reg; /* -1 means not written */ 102 int16_t cmd_reg; 103 104 /* 105 * This is a response number that we send with the command to make 106 * sure that the response matches the command. 107 */ 108 uint8_t waiting_rsp; 109 } IPMIKCS; 110 111 #define SET_OBF() \ 112 do { \ 113 IPMI_KCS_SET_OBF(ik->status_reg, 1); \ 114 if (ik->use_irq && ik->irqs_enabled && !ik->obf_irq_set) { \ 115 ik->obf_irq_set = 1; \ 116 if (!ik->atn_irq_set) { \ 117 qemu_irq_raise(ik->irq); \ 118 } \ 119 } \ 120 } while (0) 121 122 static void ipmi_kcs_signal(IPMIKCS *ik, IPMIInterface *ii) 123 { 124 IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); 125 126 ik->do_wake = 1; 127 while (ik->do_wake) { 128 ik->do_wake = 0; 129 iic->handle_if_event(ii); 130 } 131 } 132 133 static void ipmi_kcs_handle_event(IPMIInterface *ii) 134 { 135 IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); 136 IPMIKCS *ik = iic->get_backend_data(ii); 137 138 if (ik->cmd_reg == IPMI_KCS_ABORT_STATUS_CMD) { 139 if (IPMI_KCS_GET_STATE(ik->status_reg) != IPMI_KCS_ERROR_STATE) { 140 ik->waiting_rsp++; /* Invalidate the message */ 141 ik->outmsg[0] = IPMI_KCS_STATUS_ABORTED_ERR; 142 ik->outlen = 1; 143 ik->outpos = 0; 144 IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_ERROR_STATE); 145 SET_OBF(); 146 } 147 goto out; 148 } 149 150 switch (IPMI_KCS_GET_STATE(ik->status_reg)) { 151 case IPMI_KCS_IDLE_STATE: 152 if (ik->cmd_reg == IPMI_KCS_WRITE_START_CMD) { 153 IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_WRITE_STATE); 154 ik->cmd_reg = -1; 155 ik->write_end = 0; 156 ik->inlen = 0; 157 SET_OBF(); 158 } 159 break; 160 161 case IPMI_KCS_READ_STATE: 162 handle_read: 163 if (ik->outpos >= ik->outlen) { 164 IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_IDLE_STATE); 165 SET_OBF(); 166 } else if (ik->data_in_reg == IPMI_KCS_READ_CMD) { 167 ik->data_out_reg = ik->outmsg[ik->outpos]; 168 ik->outpos++; 169 SET_OBF(); 170 } else { 171 ik->outmsg[0] = IPMI_KCS_STATUS_BAD_CC_ERR; 172 ik->outlen = 1; 173 ik->outpos = 0; 174 IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_ERROR_STATE); 175 SET_OBF(); 176 goto out; 177 } 178 break; 179 180 case IPMI_KCS_WRITE_STATE: 181 if (ik->data_in_reg != -1) { 182 /* 183 * Don't worry about input overrun here, that will be 184 * handled in the BMC. 185 */ 186 if (ik->inlen < sizeof(ik->inmsg)) { 187 ik->inmsg[ik->inlen] = ik->data_in_reg; 188 } 189 ik->inlen++; 190 } 191 if (ik->write_end) { 192 IPMIBmcClass *bk = IPMI_BMC_GET_CLASS(ik->bmc); 193 ik->outlen = 0; 194 ik->write_end = 0; 195 ik->outpos = 0; 196 bk->handle_command(ik->bmc, ik->inmsg, ik->inlen, sizeof(ik->inmsg), 197 ik->waiting_rsp); 198 goto out_noibf; 199 } else if (ik->cmd_reg == IPMI_KCS_WRITE_END_CMD) { 200 ik->cmd_reg = -1; 201 ik->write_end = 1; 202 } 203 SET_OBF(); 204 break; 205 206 case IPMI_KCS_ERROR_STATE: 207 if (ik->data_in_reg != -1) { 208 IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_READ_STATE); 209 ik->data_in_reg = IPMI_KCS_READ_CMD; 210 goto handle_read; 211 } 212 break; 213 } 214 215 if (ik->cmd_reg != -1) { 216 /* Got an invalid command */ 217 ik->outmsg[0] = IPMI_KCS_STATUS_BAD_CC_ERR; 218 ik->outlen = 1; 219 ik->outpos = 0; 220 IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_ERROR_STATE); 221 } 222 223 out: 224 ik->cmd_reg = -1; 225 ik->data_in_reg = -1; 226 IPMI_KCS_SET_IBF(ik->status_reg, 0); 227 out_noibf: 228 return; 229 } 230 231 static void ipmi_kcs_handle_rsp(IPMIInterface *ii, uint8_t msg_id, 232 unsigned char *rsp, unsigned int rsp_len) 233 { 234 IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); 235 IPMIKCS *ik = iic->get_backend_data(ii); 236 237 if (ik->waiting_rsp == msg_id) { 238 ik->waiting_rsp++; 239 if (rsp_len > sizeof(ik->outmsg)) { 240 ik->outmsg[0] = rsp[0]; 241 ik->outmsg[1] = rsp[1]; 242 ik->outmsg[2] = IPMI_CC_CANNOT_RETURN_REQ_NUM_BYTES; 243 ik->outlen = 3; 244 } else { 245 memcpy(ik->outmsg, rsp, rsp_len); 246 ik->outlen = rsp_len; 247 } 248 IPMI_KCS_SET_STATE(ik->status_reg, IPMI_KCS_READ_STATE); 249 ik->data_in_reg = IPMI_KCS_READ_CMD; 250 ipmi_kcs_signal(ik, ii); 251 } 252 } 253 254 255 static uint64_t ipmi_kcs_ioport_read(void *opaque, hwaddr addr, unsigned size) 256 { 257 IPMIInterface *ii = opaque; 258 IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); 259 IPMIKCS *ik = iic->get_backend_data(ii); 260 uint32_t ret; 261 262 switch (addr & 1) { 263 case 0: 264 ret = ik->data_out_reg; 265 IPMI_KCS_SET_OBF(ik->status_reg, 0); 266 if (ik->obf_irq_set) { 267 ik->obf_irq_set = 0; 268 if (!ik->atn_irq_set) { 269 qemu_irq_lower(ik->irq); 270 } 271 } 272 break; 273 case 1: 274 ret = ik->status_reg; 275 if (ik->atn_irq_set) { 276 ik->atn_irq_set = 0; 277 if (!ik->obf_irq_set) { 278 qemu_irq_lower(ik->irq); 279 } 280 } 281 break; 282 } 283 return ret; 284 } 285 286 static void ipmi_kcs_ioport_write(void *opaque, hwaddr addr, uint64_t val, 287 unsigned size) 288 { 289 IPMIInterface *ii = opaque; 290 IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); 291 IPMIKCS *ik = iic->get_backend_data(ii); 292 293 if (IPMI_KCS_GET_IBF(ik->status_reg)) { 294 return; 295 } 296 297 switch (addr & 1) { 298 case 0: 299 ik->data_in_reg = val; 300 break; 301 302 case 1: 303 ik->cmd_reg = val; 304 break; 305 } 306 IPMI_KCS_SET_IBF(ik->status_reg, 1); 307 ipmi_kcs_signal(ik, ii); 308 } 309 310 const MemoryRegionOps ipmi_kcs_io_ops = { 311 .read = ipmi_kcs_ioport_read, 312 .write = ipmi_kcs_ioport_write, 313 .impl = { 314 .min_access_size = 1, 315 .max_access_size = 1, 316 }, 317 .endianness = DEVICE_LITTLE_ENDIAN, 318 }; 319 320 static void ipmi_kcs_set_atn(IPMIInterface *ii, int val, int irq) 321 { 322 IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); 323 IPMIKCS *ik = iic->get_backend_data(ii); 324 325 IPMI_KCS_SET_SMS_ATN(ik->status_reg, val); 326 if (val) { 327 if (irq && !ik->atn_irq_set && ik->use_irq && ik->irqs_enabled) { 328 ik->atn_irq_set = 1; 329 if (!ik->obf_irq_set) { 330 qemu_irq_raise(ik->irq); 331 } 332 } 333 } else { 334 if (ik->atn_irq_set) { 335 ik->atn_irq_set = 0; 336 if (!ik->obf_irq_set) { 337 qemu_irq_lower(ik->irq); 338 } 339 } 340 } 341 } 342 343 static void ipmi_kcs_set_irq_enable(IPMIInterface *ii, int val) 344 { 345 IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); 346 IPMIKCS *ik = iic->get_backend_data(ii); 347 348 ik->irqs_enabled = val; 349 } 350 351 static void ipmi_kcs_init(IPMIInterface *ii, Error **errp) 352 { 353 IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); 354 IPMIKCS *ik = iic->get_backend_data(ii); 355 356 ik->io_length = 2; 357 memory_region_init_io(&ik->io, NULL, &ipmi_kcs_io_ops, ii, "ipmi-kcs", 2); 358 } 359 360 #define TYPE_ISA_IPMI_KCS "isa-ipmi-kcs" 361 #define ISA_IPMI_KCS(obj) OBJECT_CHECK(ISAIPMIKCSDevice, (obj), \ 362 TYPE_ISA_IPMI_KCS) 363 364 typedef struct ISAIPMIKCSDevice { 365 ISADevice dev; 366 int32_t isairq; 367 IPMIKCS kcs; 368 uint32_t uuid; 369 } ISAIPMIKCSDevice; 370 371 static void ipmi_kcs_get_fwinfo(IPMIInterface *ii, IPMIFwInfo *info) 372 { 373 ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii); 374 375 info->interface_name = "kcs"; 376 info->interface_type = IPMI_SMBIOS_KCS; 377 info->ipmi_spec_major_revision = 2; 378 info->ipmi_spec_minor_revision = 0; 379 info->base_address = iik->kcs.io_base; 380 info->i2c_slave_address = iik->kcs.bmc->slave_addr; 381 info->register_length = iik->kcs.io_length; 382 info->register_spacing = 1; 383 info->memspace = IPMI_MEMSPACE_IO; 384 info->irq_type = IPMI_LEVEL_IRQ; 385 info->interrupt_number = iik->isairq; 386 info->uuid = iik->uuid; 387 } 388 389 static void ipmi_kcs_class_init(IPMIInterfaceClass *iic) 390 { 391 iic->init = ipmi_kcs_init; 392 iic->set_atn = ipmi_kcs_set_atn; 393 iic->handle_rsp = ipmi_kcs_handle_rsp; 394 iic->handle_if_event = ipmi_kcs_handle_event; 395 iic->set_irq_enable = ipmi_kcs_set_irq_enable; 396 iic->get_fwinfo = ipmi_kcs_get_fwinfo; 397 } 398 399 static void ipmi_isa_realize(DeviceState *dev, Error **errp) 400 { 401 ISADevice *isadev = ISA_DEVICE(dev); 402 ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(dev); 403 IPMIInterface *ii = IPMI_INTERFACE(dev); 404 IPMIInterfaceClass *iic = IPMI_INTERFACE_GET_CLASS(ii); 405 406 if (!iik->kcs.bmc) { 407 error_setg(errp, "IPMI device requires a bmc attribute to be set"); 408 return; 409 } 410 411 iik->uuid = ipmi_next_uuid(); 412 413 iik->kcs.bmc->intf = ii; 414 415 iic->init(ii, errp); 416 if (*errp) 417 return; 418 419 if (iik->isairq > 0) { 420 isa_init_irq(isadev, &iik->kcs.irq, iik->isairq); 421 iik->kcs.use_irq = 1; 422 } 423 424 qdev_set_legacy_instance_id(dev, iik->kcs.io_base, iik->kcs.io_length); 425 426 isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base); 427 } 428 429 static int ipmi_kcs_vmstate_post_load(void *opaque, int version) 430 { 431 IPMIKCS *ik = opaque; 432 433 /* Make sure all the values are sane. */ 434 if (ik->outpos >= MAX_IPMI_MSG_SIZE || ik->outlen >= MAX_IPMI_MSG_SIZE || 435 ik->outpos >= ik->outlen) { 436 qemu_log_mask(LOG_GUEST_ERROR, 437 "ipmi:kcs: vmstate transfer received bad out values: %d %d\n", 438 ik->outpos, ik->outlen); 439 ik->outpos = 0; 440 ik->outlen = 0; 441 } 442 443 if (ik->inlen >= MAX_IPMI_MSG_SIZE) { 444 qemu_log_mask(LOG_GUEST_ERROR, 445 "ipmi:kcs: vmstate transfer received bad in value: %d\n", 446 ik->inlen); 447 ik->inlen = 0; 448 } 449 450 return 0; 451 } 452 453 static bool vmstate_kcs_before_version2(void *opaque, int version) 454 { 455 return version <= 1; 456 } 457 458 static const VMStateDescription vmstate_IPMIKCS = { 459 .name = TYPE_IPMI_INTERFACE_PREFIX "kcs", 460 .version_id = 2, 461 .minimum_version_id = 1, 462 .post_load = ipmi_kcs_vmstate_post_load, 463 .fields = (VMStateField[]) { 464 VMSTATE_BOOL(obf_irq_set, IPMIKCS), 465 VMSTATE_BOOL(atn_irq_set, IPMIKCS), 466 VMSTATE_UNUSED_TEST(vmstate_kcs_before_version2, 1), /* Was use_irq */ 467 VMSTATE_BOOL(irqs_enabled, IPMIKCS), 468 VMSTATE_UINT32(outpos, IPMIKCS), 469 VMSTATE_UINT32_V(outlen, IPMIKCS, 2), 470 VMSTATE_UINT8_ARRAY(outmsg, IPMIKCS, MAX_IPMI_MSG_SIZE), 471 VMSTATE_UINT32_V(inlen, IPMIKCS, 2), 472 VMSTATE_UINT8_ARRAY(inmsg, IPMIKCS, MAX_IPMI_MSG_SIZE), 473 VMSTATE_BOOL(write_end, IPMIKCS), 474 VMSTATE_UINT8(status_reg, IPMIKCS), 475 VMSTATE_UINT8(data_out_reg, IPMIKCS), 476 VMSTATE_INT16(data_in_reg, IPMIKCS), 477 VMSTATE_INT16(cmd_reg, IPMIKCS), 478 VMSTATE_UINT8(waiting_rsp, IPMIKCS), 479 VMSTATE_END_OF_LIST() 480 } 481 }; 482 483 static const VMStateDescription vmstate_ISAIPMIKCSDevice = { 484 .name = TYPE_IPMI_INTERFACE, 485 .version_id = 2, 486 .minimum_version_id = 1, 487 .fields = (VMStateField[]) { 488 VMSTATE_VSTRUCT_TEST(kcs, ISAIPMIKCSDevice, vmstate_kcs_before_version2, 489 0, vmstate_IPMIKCS, IPMIKCS, 1), 490 VMSTATE_VSTRUCT_V(kcs, ISAIPMIKCSDevice, 2, vmstate_IPMIKCS, 491 IPMIKCS, 2), 492 VMSTATE_END_OF_LIST() 493 } 494 }; 495 496 static void isa_ipmi_kcs_init(Object *obj) 497 { 498 ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(obj); 499 500 ipmi_bmc_find_and_link(obj, (Object **) &iik->kcs.bmc); 501 502 /* 503 * Version 1 had an incorrect name, it clashed with the BT 504 * IPMI device, so receive it, but transmit a different 505 * version. 506 */ 507 vmstate_register(NULL, 0, &vmstate_ISAIPMIKCSDevice, iik); 508 } 509 510 static void *isa_ipmi_kcs_get_backend_data(IPMIInterface *ii) 511 { 512 ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii); 513 514 return &iik->kcs; 515 } 516 517 static Property ipmi_isa_properties[] = { 518 DEFINE_PROP_UINT32("ioport", ISAIPMIKCSDevice, kcs.io_base, 0xca2), 519 DEFINE_PROP_INT32("irq", ISAIPMIKCSDevice, isairq, 5), 520 DEFINE_PROP_END_OF_LIST(), 521 }; 522 523 static void isa_ipmi_kcs_class_init(ObjectClass *oc, void *data) 524 { 525 DeviceClass *dc = DEVICE_CLASS(oc); 526 IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc); 527 528 dc->realize = ipmi_isa_realize; 529 dc->props = ipmi_isa_properties; 530 531 iic->get_backend_data = isa_ipmi_kcs_get_backend_data; 532 ipmi_kcs_class_init(iic); 533 } 534 535 static const TypeInfo isa_ipmi_kcs_info = { 536 .name = TYPE_ISA_IPMI_KCS, 537 .parent = TYPE_ISA_DEVICE, 538 .instance_size = sizeof(ISAIPMIKCSDevice), 539 .instance_init = isa_ipmi_kcs_init, 540 .class_init = isa_ipmi_kcs_class_init, 541 .interfaces = (InterfaceInfo[]) { 542 { TYPE_IPMI_INTERFACE }, 543 { } 544 } 545 }; 546 547 static void ipmi_register_types(void) 548 { 549 type_register_static(&isa_ipmi_kcs_info); 550 } 551 552 type_init(ipmi_register_types) 553