1 /*- 2 * Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/types.h> 32 #include <sys/queue.h> 33 #include <sys/cpuset.h> 34 #include <sys/kernel.h> 35 #include <sys/lock.h> 36 #include <sys/malloc.h> 37 #include <sys/mutex.h> 38 #include <sys/systm.h> 39 40 #include <x86/apicreg.h> 41 #include <dev/ic/i8259.h> 42 43 #include <machine/vmm.h> 44 45 #include "vmm_ktr.h" 46 #include "vmm_lapic.h" 47 #include "vioapic.h" 48 #include "vatpic.h" 49 50 static MALLOC_DEFINE(M_VATPIC, "atpic", "bhyve virtual atpic (8259)"); 51 52 #define VATPIC_LOCK(vatpic) mtx_lock_spin(&((vatpic)->mtx)) 53 #define VATPIC_UNLOCK(vatpic) mtx_unlock_spin(&((vatpic)->mtx)) 54 #define VATPIC_LOCKED(vatpic) mtx_owned(&((vatpic)->mtx)) 55 56 enum irqstate { 57 IRQSTATE_ASSERT, 58 IRQSTATE_DEASSERT, 59 IRQSTATE_PULSE 60 }; 61 62 struct atpic { 63 bool ready; 64 int icw_num; 65 int rd_cmd_reg; 66 67 bool aeoi; 68 bool poll; 69 bool rotate; 70 71 int irq_base; 72 uint8_t request; /* Interrupt Request Register (IIR) */ 73 uint8_t service; /* Interrupt Service (ISR) */ 74 uint8_t mask; /* Interrupt Mask Register (IMR) */ 75 76 int acnt[8]; /* sum of pin asserts and deasserts */ 77 int priority; /* current pin priority */ 78 }; 79 80 struct vatpic { 81 struct vm *vm; 82 struct mtx mtx; 83 struct atpic atpic[2]; 84 uint8_t elc[2]; 85 }; 86 87 #define VATPIC_CTR0(vatpic, fmt) \ 88 VM_CTR0((vatpic)->vm, fmt) 89 90 #define VATPIC_CTR1(vatpic, fmt, a1) \ 91 VM_CTR1((vatpic)->vm, fmt, a1) 92 93 #define VATPIC_CTR2(vatpic, fmt, a1, a2) \ 94 VM_CTR2((vatpic)->vm, fmt, a1, a2) 95 96 #define VATPIC_CTR3(vatpic, fmt, a1, a2, a3) \ 97 VM_CTR3((vatpic)->vm, fmt, a1, a2, a3) 98 99 #define VATPIC_CTR4(vatpic, fmt, a1, a2, a3, a4) \ 100 VM_CTR4((vatpic)->vm, fmt, a1, a2, a3, a4) 101 102 103 static __inline int 104 vatpic_get_highest_isrpin(struct atpic *atpic) 105 { 106 int bit, pin; 107 int i; 108 109 for (i = 0; i <= 7; i++) { 110 pin = ((i + 7 - atpic->priority) & 0x7); 111 bit = (1 << pin); 112 113 if (atpic->service & bit) 114 return (pin); 115 } 116 117 return (-1); 118 } 119 120 static __inline int 121 vatpic_get_highest_irrpin(struct atpic *atpic) 122 { 123 int bit, pin; 124 int i, j; 125 126 for (i = 0; i <= 7; i++) { 127 pin = ((i + 7 - atpic->priority) & 0x7); 128 bit = (1 << pin); 129 if (atpic->service & bit) 130 break; 131 } 132 133 for (j = 0; j < i; j++) { 134 pin = ((j + 7 - atpic->priority) & 0x7); 135 bit = (1 << pin); 136 if (atpic->request & bit && (~atpic->mask & bit)) 137 return (pin); 138 } 139 140 return (-1); 141 } 142 143 static void 144 vatpic_notify_intr(struct vatpic *vatpic) 145 { 146 struct atpic *atpic; 147 int pin; 148 149 KASSERT(VATPIC_LOCKED(vatpic), ("vatpic_notify_intr not locked")); 150 151 /* XXX master only */ 152 atpic = &vatpic->atpic[0]; 153 154 if ((pin = vatpic_get_highest_irrpin(atpic)) != -1) { 155 VATPIC_CTR4(vatpic, "atpic notify pin = %d " 156 "(imr 0x%x irr 0x%x isr 0x%x)", pin, 157 atpic->mask, atpic->request, atpic->service); 158 lapic_set_local_intr(vatpic->vm, -1, APIC_LVT_LINT0); 159 vioapic_pulse_irq(vatpic->vm, 0); 160 } else { 161 VATPIC_CTR3(vatpic, "atpic no eligible interrupts " 162 "(imr 0x%x irr 0x%x isr 0x%x)", 163 atpic->mask, atpic->request, atpic->service); 164 } 165 } 166 167 static int 168 vatpic_icw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) 169 { 170 VATPIC_CTR1(vatpic, "atpic icw1 0x%x", val); 171 172 atpic->ready = false; 173 174 atpic->icw_num = 1; 175 atpic->mask = 0; 176 atpic->priority = 0; 177 atpic->rd_cmd_reg = 0; 178 179 if ((val & ICW1_SNGL) != 0) { 180 VATPIC_CTR0(vatpic, "vatpic cascade mode required"); 181 return (-1); 182 } 183 184 if ((val & ICW1_IC4) == 0) { 185 VATPIC_CTR0(vatpic, "vatpic icw4 required"); 186 return (-1); 187 } 188 189 atpic->icw_num++; 190 191 return (0); 192 } 193 194 static int 195 vatpic_icw2(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) 196 { 197 VATPIC_CTR1(vatpic, "atpic icw2 0x%x", val); 198 199 atpic->irq_base = val & 0xf8; 200 201 atpic->icw_num++; 202 203 return (0); 204 } 205 206 static int 207 vatpic_icw3(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) 208 { 209 VATPIC_CTR1(vatpic, "atpic icw3 0x%x", val); 210 211 atpic->icw_num++; 212 213 return (0); 214 } 215 216 static int 217 vatpic_icw4(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) 218 { 219 VATPIC_CTR1(vatpic, "atpic icw4 0x%x", val); 220 221 if ((val & ICW4_8086) == 0) { 222 VATPIC_CTR0(vatpic, "vatpic microprocessor mode required"); 223 return (-1); 224 } 225 226 if ((val & ICW4_AEOI) != 0) 227 atpic->aeoi = true; 228 229 atpic->icw_num = 0; 230 atpic->ready = true; 231 232 return (0); 233 } 234 235 static int 236 vatpic_ocw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) 237 { 238 VATPIC_CTR1(vatpic, "atpic ocw1 0x%x", val); 239 240 atpic->mask = val & 0xff; 241 242 return (0); 243 } 244 245 static int 246 vatpic_ocw2(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) 247 { 248 VATPIC_CTR1(vatpic, "atpic ocw2 0x%x", val); 249 250 atpic->rotate = ((val & OCW2_R) != 0); 251 252 if ((val & OCW2_EOI) != 0) { 253 int isr_bit; 254 255 if ((val & OCW2_SL) != 0) { 256 /* specific EOI */ 257 isr_bit = val & 0x7; 258 } else { 259 /* non-specific EOI */ 260 isr_bit = vatpic_get_highest_isrpin(atpic); 261 } 262 263 if (isr_bit != -1) { 264 atpic->service &= ~(1 << isr_bit); 265 266 if (atpic->rotate) 267 atpic->priority = isr_bit; 268 } 269 } else if ((val & OCW2_SL) != 0 && atpic->rotate == true) { 270 /* specific priority */ 271 atpic->priority = val & 0x7; 272 } 273 274 return (0); 275 } 276 277 static int 278 vatpic_ocw3(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) 279 { 280 VATPIC_CTR1(vatpic, "atpic ocw3 0x%x", val); 281 282 atpic->poll = ((val & OCW3_P) != 0); 283 284 if (val & OCW3_RR) { 285 /* read register command */ 286 atpic->rd_cmd_reg = val & OCW3_RIS; 287 } 288 289 return (0); 290 } 291 292 static void 293 vatpic_set_pinstate(struct vatpic *vatpic, int pin, bool newstate) 294 { 295 struct atpic *atpic; 296 int oldcnt, newcnt; 297 bool level; 298 299 KASSERT(pin >= 0 && pin < 16, 300 ("vatpic_set_pinstate: invalid pin number %d", pin)); 301 KASSERT(VATPIC_LOCKED(vatpic), 302 ("vatpic_set_pinstate: vatpic is not locked")); 303 304 atpic = &vatpic->atpic[pin >> 3]; 305 306 oldcnt = atpic->acnt[pin & 0x7]; 307 if (newstate) 308 atpic->acnt[pin & 0x7]++; 309 else 310 atpic->acnt[pin & 0x7]--; 311 newcnt = atpic->acnt[pin & 0x7]; 312 313 if (newcnt < 0) { 314 VATPIC_CTR2(vatpic, "atpic pin%d: bad acnt %d", pin, newcnt); 315 } 316 317 level = ((vatpic->elc[pin >> 3] & (1 << (pin & 0x7))) != 0); 318 319 if ((oldcnt == 0 && newcnt == 1) || (newcnt > 0 && level == true)) { 320 /* rising edge or level */ 321 VATPIC_CTR1(vatpic, "atpic pin%d: asserted", pin); 322 atpic->request |= (1 << (pin & 0x7)); 323 } else if (oldcnt == 1 && newcnt == 0) { 324 /* falling edge */ 325 VATPIC_CTR1(vatpic, "atpic pin%d: deasserted", pin); 326 } else { 327 VATPIC_CTR3(vatpic, "atpic pin%d: %s, ignored, acnt %d", 328 pin, newstate ? "asserted" : "deasserted", newcnt); 329 } 330 331 vatpic_notify_intr(vatpic); 332 } 333 334 static int 335 vatpic_set_irqstate(struct vm *vm, int irq, enum irqstate irqstate) 336 { 337 struct vatpic *vatpic; 338 struct atpic *atpic; 339 340 if (irq < 0 || irq > 15) 341 return (EINVAL); 342 343 vatpic = vm_atpic(vm); 344 atpic = &vatpic->atpic[irq >> 3]; 345 346 if (atpic->ready == false) 347 return (0); 348 349 VATPIC_LOCK(vatpic); 350 switch (irqstate) { 351 case IRQSTATE_ASSERT: 352 vatpic_set_pinstate(vatpic, irq, true); 353 break; 354 case IRQSTATE_DEASSERT: 355 vatpic_set_pinstate(vatpic, irq, false); 356 break; 357 case IRQSTATE_PULSE: 358 vatpic_set_pinstate(vatpic, irq, true); 359 vatpic_set_pinstate(vatpic, irq, false); 360 break; 361 default: 362 panic("vatpic_set_irqstate: invalid irqstate %d", irqstate); 363 } 364 VATPIC_UNLOCK(vatpic); 365 366 return (0); 367 } 368 369 int 370 vatpic_assert_irq(struct vm *vm, int irq) 371 { 372 return (vatpic_set_irqstate(vm, irq, IRQSTATE_ASSERT)); 373 } 374 375 int 376 vatpic_deassert_irq(struct vm *vm, int irq) 377 { 378 return (vatpic_set_irqstate(vm, irq, IRQSTATE_DEASSERT)); 379 } 380 381 int 382 vatpic_pulse_irq(struct vm *vm, int irq) 383 { 384 return (vatpic_set_irqstate(vm, irq, IRQSTATE_PULSE)); 385 } 386 387 int 388 vatpic_pending_intr(struct vm *vm, int *vecptr) 389 { 390 struct vatpic *vatpic; 391 struct atpic *atpic; 392 int pin; 393 394 vatpic = vm_atpic(vm); 395 396 /* XXX master only */ 397 atpic = &vatpic->atpic[0]; 398 399 VATPIC_LOCK(vatpic); 400 401 pin = vatpic_get_highest_irrpin(atpic); 402 if (pin == -1) 403 pin = 7; 404 405 *vecptr = atpic->irq_base + pin; 406 407 VATPIC_UNLOCK(vatpic); 408 409 return (1); 410 } 411 412 void 413 vatpic_intr_accepted(struct vm *vm, int vector) 414 { 415 struct vatpic *vatpic; 416 struct atpic *atpic; 417 int pin; 418 419 vatpic = vm_atpic(vm); 420 421 /* XXX master only */ 422 atpic = &vatpic->atpic[0]; 423 424 VATPIC_LOCK(vatpic); 425 pin = vector & 0x7; 426 427 if (atpic->acnt[pin] == 0) 428 atpic->request &= ~(1 << pin); 429 430 if (atpic->aeoi == true) { 431 if (atpic->rotate == true) 432 atpic->priority = pin; 433 } else { 434 atpic->service |= (1 << pin); 435 } 436 437 vatpic_notify_intr(vatpic); 438 439 VATPIC_UNLOCK(vatpic); 440 } 441 442 int 443 vatpic_master_handler(void *vm, int vcpuid, struct vm_exit *vmexit) 444 { 445 struct vatpic *vatpic; 446 struct atpic *atpic; 447 int error; 448 uint8_t val; 449 450 vatpic = vm_atpic(vm); 451 atpic = &vatpic->atpic[0]; 452 453 if (vmexit->u.inout.bytes != 1) 454 return (-1); 455 456 if (vmexit->u.inout.in) { 457 VATPIC_LOCK(vatpic); 458 if (atpic->poll) { 459 VATPIC_CTR0(vatpic, "vatpic polled mode not " 460 "supported"); 461 VATPIC_UNLOCK(vatpic); 462 return (-1); 463 } else { 464 if (vmexit->u.inout.port & ICU_IMR_OFFSET) { 465 /* read interrrupt mask register */ 466 vmexit->u.inout.eax = atpic->mask; 467 } else { 468 if (atpic->rd_cmd_reg == OCW3_RIS) { 469 /* read interrupt service register */ 470 vmexit->u.inout.eax = atpic->service; 471 } else { 472 /* read interrupt request register */ 473 vmexit->u.inout.eax = atpic->request; 474 } 475 } 476 } 477 VATPIC_UNLOCK(vatpic); 478 479 return (0); 480 } 481 482 val = vmexit->u.inout.eax; 483 484 VATPIC_LOCK(vatpic); 485 486 if (vmexit->u.inout.port & ICU_IMR_OFFSET) { 487 if (atpic->ready) { 488 error = vatpic_ocw1(vatpic, atpic, val); 489 } else { 490 switch (atpic->icw_num) { 491 case 2: 492 error = vatpic_icw2(vatpic, atpic, val); 493 break; 494 case 3: 495 error = vatpic_icw3(vatpic, atpic, val); 496 break; 497 case 4: 498 error = vatpic_icw4(vatpic, atpic, val); 499 break; 500 } 501 } 502 } else { 503 if (val & (1 << 4)) 504 error = vatpic_icw1(vatpic, atpic, val); 505 506 if (atpic->ready) { 507 if (val & (1 << 3)) 508 error = vatpic_ocw3(vatpic, atpic, val); 509 else 510 error = vatpic_ocw2(vatpic, atpic, val); 511 } 512 } 513 514 if (atpic->ready) 515 vatpic_notify_intr(vatpic); 516 517 VATPIC_UNLOCK(vatpic); 518 519 return (error); 520 } 521 522 int 523 vatpic_slave_handler(void *vm, int vcpuid, struct vm_exit *vmexit) 524 { 525 if (vmexit->u.inout.bytes != 1) 526 return (-1); 527 528 if (vmexit->u.inout.in) { 529 if (vmexit->u.inout.port & ICU_IMR_OFFSET) { 530 /* all interrupts masked */ 531 vmexit->u.inout.eax = 0xff; 532 } else { 533 vmexit->u.inout.eax = 0x00; 534 } 535 } 536 537 /* Pretend all accesses to the slave 8259 are alright */ 538 return (0); 539 } 540 541 int 542 vatpic_elc_handler(void *vm, int vcpuid, struct vm_exit *vmexit) 543 { 544 struct vatpic *vatpic; 545 bool is_master; 546 547 vatpic = vm_atpic(vm); 548 is_master = (vmexit->u.inout.port == IO_ELCR1); 549 550 if (vmexit->u.inout.bytes != 1) 551 return (-1); 552 553 if (vmexit->u.inout.in) { 554 if (is_master) 555 vmexit->u.inout.eax = vatpic->elc[0]; 556 else 557 vmexit->u.inout.eax = vatpic->elc[1]; 558 } else { 559 /* 560 * For the master PIC the cascade channel (IRQ2), the 561 * heart beat timer (IRQ0), and the keyboard 562 * controller (IRQ1) cannot be programmed for level 563 * mode. 564 * 565 * For the slave PIC the real time clock (IRQ8) and 566 * the floating point error interrupt (IRQ13) cannot 567 * be programmed for level mode. 568 */ 569 if (is_master) 570 vatpic->elc[0] = (vmexit->u.inout.eax & 0xf8); 571 else 572 vatpic->elc[1] = (vmexit->u.inout.eax & 0xde); 573 } 574 575 return (0); 576 } 577 578 struct vatpic * 579 vatpic_init(struct vm *vm) 580 { 581 struct vatpic *vatpic; 582 583 vatpic = malloc(sizeof(struct vatpic), M_VATPIC, M_WAITOK | M_ZERO); 584 vatpic->vm = vm; 585 586 mtx_init(&vatpic->mtx, "vatpic lock", NULL, MTX_SPIN); 587 588 return (vatpic); 589 } 590 591 void 592 vatpic_cleanup(struct vatpic *vatpic) 593 { 594 free(vatpic, M_VATPIC); 595 } 596