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