vatpic.c (264468) | vatpic.c (264648) |
---|---|
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 --- 11 unchanged lines hidden (view full) --- 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> | 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 --- 11 unchanged lines hidden (view full) --- 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: head/sys/amd64/vmm/io/vatpic.c 264468 2014-04-14 19:00:20Z tychon $"); | 28__FBSDID("$FreeBSD: head/sys/amd64/vmm/io/vatpic.c 264648 2014-04-18 15:22:56Z tychon $"); |
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> --- 475 unchanged lines hidden (view full) --- 512 } 513 514 vatpic_notify_intr(vatpic); 515 516 VATPIC_UNLOCK(vatpic); 517} 518 519static int | 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> --- 475 unchanged lines hidden (view full) --- 512 } 513 514 vatpic_notify_intr(vatpic); 515 516 VATPIC_UNLOCK(vatpic); 517} 518 519static int |
520vatpic_read(struct vatpic *vatpic, struct atpic *atpic, struct vm_exit *vmexit) | 520vatpic_read(struct vatpic *vatpic, struct atpic *atpic, bool in, int port, 521 int bytes, uint32_t *eax) |
521{ 522 VATPIC_LOCK(vatpic); 523 524 if (atpic->poll) { 525 VATPIC_CTR0(vatpic, "vatpic polled mode not supported"); 526 VATPIC_UNLOCK(vatpic); 527 return (-1); 528 } else { | 522{ 523 VATPIC_LOCK(vatpic); 524 525 if (atpic->poll) { 526 VATPIC_CTR0(vatpic, "vatpic polled mode not supported"); 527 VATPIC_UNLOCK(vatpic); 528 return (-1); 529 } else { |
529 if (vmexit->u.inout.port & ICU_IMR_OFFSET) { | 530 if (port & ICU_IMR_OFFSET) { |
530 /* read interrrupt mask register */ | 531 /* read interrrupt mask register */ |
531 vmexit->u.inout.eax = atpic->mask; | 532 *eax = atpic->mask; |
532 } else { 533 if (atpic->rd_cmd_reg == OCW3_RIS) { 534 /* read interrupt service register */ | 533 } else { 534 if (atpic->rd_cmd_reg == OCW3_RIS) { 535 /* read interrupt service register */ |
535 vmexit->u.inout.eax = atpic->service; | 536 *eax = atpic->service; |
536 } else { 537 /* read interrupt request register */ | 537 } else { 538 /* read interrupt request register */ |
538 vmexit->u.inout.eax = atpic->request; | 539 *eax = atpic->request; |
539 } 540 } 541 } 542 543 VATPIC_UNLOCK(vatpic); 544 545 return (0); 546 547} 548 549static int | 540 } 541 } 542 } 543 544 VATPIC_UNLOCK(vatpic); 545 546 return (0); 547 548} 549 550static int |
550vatpic_write(struct vatpic *vatpic, struct atpic *atpic, 551 struct vm_exit *vmexit) | 551vatpic_write(struct vatpic *vatpic, struct atpic *atpic, bool in, int port, 552 int bytes, uint32_t *eax) |
552{ 553 int error; 554 uint8_t val; 555 | 553{ 554 int error; 555 uint8_t val; 556 |
556 val = vmexit->u.inout.eax; | 557 val = *eax; |
557 558 VATPIC_LOCK(vatpic); 559 | 558 559 VATPIC_LOCK(vatpic); 560 |
560 if (vmexit->u.inout.port & ICU_IMR_OFFSET) { | 561 if (port & ICU_IMR_OFFSET) { |
561 if (atpic->ready) { 562 error = vatpic_ocw1(vatpic, atpic, val); 563 } else { 564 switch (atpic->icw_num) { 565 case 2: 566 error = vatpic_icw2(vatpic, atpic, val); 567 break; 568 case 3: --- 20 unchanged lines hidden (view full) --- 589 vatpic_notify_intr(vatpic); 590 591 VATPIC_UNLOCK(vatpic); 592 593 return (error); 594} 595 596int | 562 if (atpic->ready) { 563 error = vatpic_ocw1(vatpic, atpic, val); 564 } else { 565 switch (atpic->icw_num) { 566 case 2: 567 error = vatpic_icw2(vatpic, atpic, val); 568 break; 569 case 3: --- 20 unchanged lines hidden (view full) --- 590 vatpic_notify_intr(vatpic); 591 592 VATPIC_UNLOCK(vatpic); 593 594 return (error); 595} 596 597int |
597vatpic_master_handler(void *vm, int vcpuid, struct vm_exit *vmexit) | 598vatpic_master_handler(void *vm, int vcpuid, bool in, int port, int bytes, 599 uint32_t *eax) |
598{ 599 struct vatpic *vatpic; 600 struct atpic *atpic; 601 602 vatpic = vm_atpic(vm); 603 atpic = &vatpic->atpic[0]; 604 | 600{ 601 struct vatpic *vatpic; 602 struct atpic *atpic; 603 604 vatpic = vm_atpic(vm); 605 atpic = &vatpic->atpic[0]; 606 |
605 if (vmexit->u.inout.bytes != 1) | 607 if (bytes != 1) |
606 return (-1); 607 | 608 return (-1); 609 |
608 if (vmexit->u.inout.in) { 609 return (vatpic_read(vatpic, atpic, vmexit)); | 610 if (in) { 611 return (vatpic_read(vatpic, atpic, in, port, bytes, eax)); |
610 } 611 | 612 } 613 |
612 return (vatpic_write(vatpic, atpic, vmexit)); | 614 return (vatpic_write(vatpic, atpic, in, port, bytes, eax)); |
613} 614 615int | 615} 616 617int |
616vatpic_slave_handler(void *vm, int vcpuid, struct vm_exit *vmexit) | 618vatpic_slave_handler(void *vm, int vcpuid, bool in, int port, int bytes, 619 uint32_t *eax) |
617{ 618 struct vatpic *vatpic; 619 struct atpic *atpic; 620 621 vatpic = vm_atpic(vm); 622 atpic = &vatpic->atpic[1]; 623 | 620{ 621 struct vatpic *vatpic; 622 struct atpic *atpic; 623 624 vatpic = vm_atpic(vm); 625 atpic = &vatpic->atpic[1]; 626 |
624 if (vmexit->u.inout.bytes != 1) | 627 if (bytes != 1) |
625 return (-1); 626 | 628 return (-1); 629 |
627 if (vmexit->u.inout.in) { 628 return (vatpic_read(vatpic, atpic, vmexit)); | 630 if (in) { 631 return (vatpic_read(vatpic, atpic, in, port, bytes, eax)); |
629 } 630 | 632 } 633 |
631 return (vatpic_write(vatpic, atpic, vmexit)); | 634 return (vatpic_write(vatpic, atpic, in, port, bytes, eax)); |
632} 633 634int | 635} 636 637int |
635vatpic_elc_handler(void *vm, int vcpuid, struct vm_exit *vmexit) | 638vatpic_elc_handler(void *vm, int vcpuid, bool in, int port, int bytes, 639 uint32_t *eax) |
636{ 637 struct vatpic *vatpic; 638 bool is_master; 639 640 vatpic = vm_atpic(vm); | 640{ 641 struct vatpic *vatpic; 642 bool is_master; 643 644 vatpic = vm_atpic(vm); |
641 is_master = (vmexit->u.inout.port == IO_ELCR1); | 645 is_master = (port == IO_ELCR1); |
642 | 646 |
643 if (vmexit->u.inout.bytes != 1) | 647 if (bytes != 1) |
644 return (-1); 645 646 VATPIC_LOCK(vatpic); 647 | 648 return (-1); 649 650 VATPIC_LOCK(vatpic); 651 |
648 if (vmexit->u.inout.in) { | 652 if (in) { |
649 if (is_master) | 653 if (is_master) |
650 vmexit->u.inout.eax = vatpic->elc[0]; | 654 *eax = vatpic->elc[0]; |
651 else | 655 else |
652 vmexit->u.inout.eax = vatpic->elc[1]; | 656 *eax = vatpic->elc[1]; |
653 } else { 654 /* 655 * For the master PIC the cascade channel (IRQ2), the 656 * heart beat timer (IRQ0), and the keyboard 657 * controller (IRQ1) cannot be programmed for level 658 * mode. 659 * 660 * For the slave PIC the real time clock (IRQ8) and 661 * the floating point error interrupt (IRQ13) cannot 662 * be programmed for level mode. 663 */ 664 if (is_master) | 657 } else { 658 /* 659 * For the master PIC the cascade channel (IRQ2), the 660 * heart beat timer (IRQ0), and the keyboard 661 * controller (IRQ1) cannot be programmed for level 662 * mode. 663 * 664 * For the slave PIC the real time clock (IRQ8) and 665 * the floating point error interrupt (IRQ13) cannot 666 * be programmed for level mode. 667 */ 668 if (is_master) |
665 vatpic->elc[0] = (vmexit->u.inout.eax & 0xf8); | 669 vatpic->elc[0] = (*eax & 0xf8); |
666 else | 670 else |
667 vatpic->elc[1] = (vmexit->u.inout.eax & 0xde); | 671 vatpic->elc[1] = (*eax & 0xde); |
668 } 669 670 VATPIC_UNLOCK(vatpic); 671 672 return (0); 673} 674 675struct vatpic * --- 17 unchanged lines hidden --- | 672 } 673 674 VATPIC_UNLOCK(vatpic); 675 676 return (0); 677} 678 679struct vatpic * --- 17 unchanged lines hidden --- |