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