From e1016866c7ece00b60ccc7f0807fb1c2ebd0f3b8 Mon Sep 17 00:00:00 2001 From: jhb Date: Thu, 23 Jan 2014 20:21:39 +0000 Subject: MFC 257422,257661,258075,258476,258494,258579,258609,258699: Several enhancements to the I/O APIC support in bhyve including: - Move the I/O APIC device model from userspace into vmm.ko and add ioctls to assert and deassert I/O APIC pins. - Add HPET device emulation including a single timer block with 8 timers. - Remove the 'vdev' abstraction. Approved by: neel --- usr.sbin/bhyve/Makefile | 2 +- usr.sbin/bhyve/acpi.c | 89 ++++++++++- usr.sbin/bhyve/bhyverun.c | 3 - usr.sbin/bhyve/ioapic.c | 378 ---------------------------------------------- usr.sbin/bhyve/ioapic.h | 38 ----- usr.sbin/bhyve/mptbl.c | 2 +- usr.sbin/bhyve/pci_emul.c | 13 +- usr.sbin/bhyve/pci_emul.h | 1 + usr.sbin/bhyve/pci_lpc.c | 16 +- usr.sbin/bhyve/pit_8254.c | 4 +- 10 files changed, 108 insertions(+), 438 deletions(-) delete mode 100644 usr.sbin/bhyve/ioapic.c delete mode 100644 usr.sbin/bhyve/ioapic.h (limited to 'usr.sbin') diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile index 719a7e8..7f2973c 100644 --- a/usr.sbin/bhyve/Makefile +++ b/usr.sbin/bhyve/Makefile @@ -8,7 +8,7 @@ DEBUG_FLAGS= -g -O0 MAN= bhyve.8 SRCS= acpi.c atpic.c bhyverun.c block_if.c consport.c dbgport.c elcr.c -SRCS+= inout.c ioapic.c legacy_irq.c mem.c mevent.c mptbl.c pci_ahci.c +SRCS+= inout.c legacy_irq.c mem.c mevent.c mptbl.c pci_ahci.c SRCS+= pci_emul.c pci_hostbridge.c pci_lpc.c pci_passthru.c pci_virtio_block.c SRCS+= pci_virtio_net.c pci_uart.c pit_8254.c pmtmr.c post.c rtc.c SRCS+= uart_emul.c virtio.c xmsr.c spinup_ap.c diff --git a/usr.sbin/bhyve/acpi.c b/usr.sbin/bhyve/acpi.c index 6824330..32dd842 100644 --- a/usr.sbin/bhyve/acpi.c +++ b/usr.sbin/bhyve/acpi.c @@ -44,6 +44,7 @@ * XSDT -> 0xf0480 (36 bytes + 8*N table addrs, 2 used) * MADT -> 0xf0500 (depends on #CPUs) * FADT -> 0xf0600 (268 bytes) + * HPET -> 0xf0740 (56 bytes) * FACS -> 0xf0780 (64 bytes) * DSDT -> 0xf0800 (variable - can go up to 0x100000) */ @@ -61,6 +62,9 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include + #include "bhyverun.h" #include "acpi.h" @@ -73,6 +77,7 @@ __FBSDID("$FreeBSD$"); #define XSDT_OFFSET 0x080 #define MADT_OFFSET 0x100 #define FADT_OFFSET 0x200 +#define HPET_OFFSET 0x340 #define FACS_OFFSET 0x380 #define DSDT_OFFSET 0x400 @@ -86,6 +91,7 @@ static int basl_keep_temps; static int basl_verbose_iasl; static int basl_ncpu; static uint32_t basl_acpi_base = BHYVE_ACPI_BASE; +static uint32_t hpet_capabilities; /* * Contains the full pathname of the template to be passed @@ -158,11 +164,13 @@ basl_fwrite_rsdt(FILE *fp) EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); EFPRINTF(fp, "\n"); - /* Add in pointers to the MADT and FADT */ + /* Add in pointers to the MADT, FADT and HPET */ EFPRINTF(fp, "[0004]\t\tACPI Table Address 0 : %08X\n", basl_acpi_base + MADT_OFFSET); EFPRINTF(fp, "[0004]\t\tACPI Table Address 1 : %08X\n", basl_acpi_base + FADT_OFFSET); + EFPRINTF(fp, "[0004]\t\tACPI Table Address 2 : %08X\n", + basl_acpi_base + HPET_OFFSET); EFFLUSH(fp); @@ -194,11 +202,13 @@ basl_fwrite_xsdt(FILE *fp) EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); EFPRINTF(fp, "\n"); - /* Add in pointers to the MADT and FADT */ + /* Add in pointers to the MADT, FADT and HPET */ EFPRINTF(fp, "[0004]\t\tACPI Table Address 0 : 00000000%08X\n", basl_acpi_base + MADT_OFFSET); EFPRINTF(fp, "[0004]\t\tACPI Table Address 1 : 00000000%08X\n", basl_acpi_base + FADT_OFFSET); + EFPRINTF(fp, "[0004]\t\tACPI Table Address 2 : 00000000%08X\n", + basl_acpi_base + HPET_OFFSET); EFFLUSH(fp); @@ -249,7 +259,7 @@ basl_fwrite_madt(FILE *fp) EFPRINTF(fp, "\n"); } - /* Always a single IOAPIC entry, with ID ncpu+1 */ + /* Always a single IOAPIC entry, with ID 0 */ EFPRINTF(fp, "[0001]\t\tSubtable Type : 01\n"); EFPRINTF(fp, "[0001]\t\tLength : 0C\n"); /* iasl expects a hex value for the i/o apic id */ @@ -499,6 +509,55 @@ err_exit: } static int +basl_fwrite_hpet(FILE *fp) +{ + int err; + + err = 0; + + EFPRINTF(fp, "/*\n"); + EFPRINTF(fp, " * bhyve HPET template\n"); + EFPRINTF(fp, " */\n"); + EFPRINTF(fp, "[0004]\t\tSignature : \"HPET\"\n"); + EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); + EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); + EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); + EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); + EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVHPET \"\n"); + EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); + + /* iasl will fill in the compiler ID/revision fields */ + EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); + EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0004]\t\tTimer Block ID : %08X\n", hpet_capabilities); + EFPRINTF(fp, + "[0012]\t\tTimer Block Register : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 00 [SystemMemory]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, + "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 00000000FED00000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0001]\t\tHPET Number : 00\n"); + EFPRINTF(fp, "[0002]\t\tMinimum Clock Ticks : 0000\n"); + EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); + EFPRINTF(fp, "\t\t\t4K Page Protect : 1\n"); + EFPRINTF(fp, "\t\t\t64K Page Protect : 0\n"); + EFPRINTF(fp, "\n"); + + EFFLUSH(fp); + + return (0); + +err_exit: + return (errno); +} + +static int basl_fwrite_facs(FILE *fp) { int err; @@ -594,6 +653,24 @@ basl_fwrite_dsdt(FILE *fp) EFPRINTF(fp, " Name (_ADR, 0x00010000)\n"); EFPRINTF(fp, " OperationRegion (P40C, PCI_Config, 0x60, 0x04)\n"); EFPRINTF(fp, " }\n"); + + EFPRINTF(fp, " Device (HPET)\n"); + EFPRINTF(fp, " {\n"); + EFPRINTF(fp, " Name (_HID, EISAID(\"PNP0103\"))\n"); + EFPRINTF(fp, " Name (_UID, 0)\n"); + EFPRINTF(fp, " Name (_CRS, ResourceTemplate ()\n"); + EFPRINTF(fp, " {\n"); + EFPRINTF(fp, " DWordMemory (ResourceConsumer, PosDecode, " + "MinFixed, MaxFixed, NonCacheable, ReadWrite,\n"); + EFPRINTF(fp, " 0x00000000,\n"); + EFPRINTF(fp, " 0xFED00000,\n"); + EFPRINTF(fp, " 0xFED003FF,\n"); + EFPRINTF(fp, " 0x00000000,\n"); + EFPRINTF(fp, " 0x00000400\n"); + EFPRINTF(fp, " )\n"); + EFPRINTF(fp, " })\n"); + EFPRINTF(fp, " }\n"); + EFPRINTF(fp, " }\n"); EFPRINTF(fp, "\n"); EFPRINTF(fp, " Scope (_SB.PCI0.ISA)\n"); @@ -810,6 +887,7 @@ static struct { { basl_fwrite_xsdt, XSDT_OFFSET }, { basl_fwrite_madt, MADT_OFFSET }, { basl_fwrite_fadt, FADT_OFFSET }, + { basl_fwrite_hpet, HPET_OFFSET }, { basl_fwrite_facs, FACS_OFFSET }, { basl_fwrite_dsdt, DSDT_OFFSET }, { NULL } @@ -821,9 +899,12 @@ acpi_build(struct vmctx *ctx, int ncpu) int err; int i; - err = 0; basl_ncpu = ncpu; + err = vm_get_hpet_capabilities(ctx, &hpet_capabilities); + if (err != 0) + return (err); + /* * For debug, allow the user to have iasl compiler output sent * to stdout rather than /dev/null diff --git a/usr.sbin/bhyve/bhyverun.c b/usr.sbin/bhyve/bhyverun.c index 8263602..652f402 100644 --- a/usr.sbin/bhyve/bhyverun.c +++ b/usr.sbin/bhyve/bhyverun.c @@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$"); #include "pci_emul.h" #include "pci_lpc.h" #include "xmsr.h" -#include "ioapic.h" #include "spinup_ap.h" #include "rtc.h" @@ -663,8 +662,6 @@ main(int argc, char *argv[]) if (init_pci(ctx) != 0) exit(1); - ioapic_init(0); - if (gdb_port != 0) init_dbgport(gdb_port); diff --git a/usr.sbin/bhyve/ioapic.c b/usr.sbin/bhyve/ioapic.c deleted file mode 100644 index b996214..0000000 --- a/usr.sbin/bhyve/ioapic.c +++ /dev/null @@ -1,378 +0,0 @@ -/*- - * Copyright (c) 2012 NetApp, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -__FBSDID("$FreeBSD$"); - -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include "inout.h" -#include "mem.h" -#include "bhyverun.h" - -#include - -static uint64_t ioapic_clearpend, ioapic_togglepend, ioapic_setpend; - -#define IOAPIC_PADDR 0xFEC00000 - -#define IOREGSEL 0x00 -#define IOWIN 0x10 - -#define REDIR_ENTRIES 16 -#define INTR_ASSERTED(ioapic, pin) \ - ((ioapic)->rtbl[(pin)].pinstate == true) - -struct ioapic { - int inited; - uint32_t id; - struct { - uint64_t reg; - bool pinstate; - bool pending; - } rtbl[REDIR_ENTRIES]; - - uintptr_t paddr; /* gpa where the ioapic is mapped */ - uint32_t ioregsel; - struct memory_region *region; - pthread_mutex_t mtx; -}; - -static struct ioapic ioapics[1]; /* only a single ioapic for now */ - -static int ioapic_region_read(struct vmctx *vm, struct ioapic *ioapic, - uintptr_t paddr, int size, uint64_t *data); -static int ioapic_region_write(struct vmctx *vm, struct ioapic *ioapic, - uintptr_t paddr, int size, uint64_t data); -static int ioapic_region_handler(struct vmctx *vm, int vcpu, int dir, - uintptr_t paddr, int size, uint64_t *val, void *arg1, long arg2); - -static void -ioapic_set_pinstate(struct vmctx *ctx, int pin, bool newstate) -{ - int vector, apicid, vcpu; - uint32_t low, high; - struct ioapic *ioapic; - - ioapic = &ioapics[0]; /* assume a single ioapic */ - - /* Nothing to do if interrupt pin has not changed state */ - if (ioapic->rtbl[pin].pinstate == newstate) - return; - - ioapic->rtbl[pin].pinstate = newstate; /* record it */ - - /* Nothing to do if interrupt pin is deasserted */ - if (!INTR_ASSERTED(ioapic, pin)) - return; - - /* - * XXX - * We only deal with: - * - edge triggered interrupts - * - fixed delivery mode - * Level-triggered sources will work so long as there is - * no sharing. - */ - low = ioapic->rtbl[pin].reg; - high = ioapic->rtbl[pin].reg >> 32; - if ((low & IOART_INTMASK) == IOART_INTMCLR && - (low & IOART_DESTMOD) == IOART_DESTPHY && - (low & IOART_DELMOD) == IOART_DELFIXED) { - vector = low & IOART_INTVEC; - apicid = high >> APIC_ID_SHIFT; - if (apicid != 0xff) { - /* unicast */ - vcpu = vm_apicid2vcpu(ctx, apicid); - vm_lapic_irq(ctx, vcpu, vector); - } else { - /* broadcast */ - vcpu = 0; - while (vcpu < guest_ncpus) { - vm_lapic_irq(ctx, vcpu, vector); - vcpu++; - } - } - } else if ((low & IOART_INTMASK) != IOART_INTMCLR && - low & IOART_TRGRLVL) { - /* - * For level-triggered interrupts that have been - * masked, set the pending bit so that an interrupt - * will be generated on unmask and if the level is - * still asserted - */ - ioapic_setpend++; - ioapic->rtbl[pin].pending = true; - } -} - -static void -ioapic_set_pinstate_locked(struct vmctx *ctx, int pin, bool newstate) -{ - struct ioapic *ioapic; - - if (pin < 0 || pin >= REDIR_ENTRIES) - return; - - ioapic = &ioapics[0]; - - pthread_mutex_lock(&ioapic->mtx); - ioapic_set_pinstate(ctx, pin, newstate); - pthread_mutex_unlock(&ioapic->mtx); -} - -/* - * External entry points require locking - */ -void -ioapic_deassert_pin(struct vmctx *ctx, int pin) -{ - ioapic_set_pinstate_locked(ctx, pin, false); -} - -void -ioapic_assert_pin(struct vmctx *ctx, int pin) -{ - ioapic_set_pinstate_locked(ctx, pin, true); -} - -void -ioapic_init(int which) -{ - struct mem_range memp; - struct ioapic *ioapic; - int error; - int i; - - assert(which == 0); - - ioapic = &ioapics[which]; - assert(ioapic->inited == 0); - - bzero(ioapic, sizeof(struct ioapic)); - - pthread_mutex_init(&ioapic->mtx, NULL); - - /* Initialize all redirection entries to mask all interrupts */ - for (i = 0; i < REDIR_ENTRIES; i++) - ioapic->rtbl[i].reg = 0x0001000000010000UL; - - ioapic->paddr = IOAPIC_PADDR; - - /* Register emulated memory region */ - memp.name = "ioapic"; - memp.flags = MEM_F_RW; - memp.handler = ioapic_region_handler; - memp.arg1 = ioapic; - memp.arg2 = which; - memp.base = ioapic->paddr; - memp.size = sizeof(struct IOAPIC); - error = register_mem(&memp); - - assert (error == 0); - - ioapic->inited = 1; -} - -static uint32_t -ioapic_read(struct ioapic *ioapic, uint32_t addr) -{ - int regnum, pin, rshift; - - assert(ioapic->inited); - - regnum = addr & 0xff; - switch (regnum) { - case IOAPIC_ID: - return (ioapic->id); - break; - case IOAPIC_VER: - return ((REDIR_ENTRIES << MAXREDIRSHIFT) | 0x11); - break; - case IOAPIC_ARB: - return (ioapic->id); - break; - default: - break; - } - - /* redirection table entries */ - if (regnum >= IOAPIC_REDTBL && - regnum < IOAPIC_REDTBL + REDIR_ENTRIES * 2) { - pin = (regnum - IOAPIC_REDTBL) / 2; - if ((regnum - IOAPIC_REDTBL) % 2) - rshift = 32; - else - rshift = 0; - - return (ioapic->rtbl[pin].reg >> rshift); - } - - return (0); -} - -static void -ioapic_write(struct vmctx *vm, struct ioapic *ioapic, uint32_t addr, - uint32_t data) -{ - int regnum, pin, lshift; - - assert(ioapic->inited); - - regnum = addr & 0xff; - switch (regnum) { - case IOAPIC_ID: - ioapic->id = data & APIC_ID_MASK; - break; - case IOAPIC_VER: - case IOAPIC_ARB: - /* readonly */ - break; - default: - break; - } - - /* redirection table entries */ - if (regnum >= IOAPIC_REDTBL && - regnum < IOAPIC_REDTBL + REDIR_ENTRIES * 2) { - pin = (regnum - IOAPIC_REDTBL) / 2; - if ((regnum - IOAPIC_REDTBL) % 2) - lshift = 32; - else - lshift = 0; - - ioapic->rtbl[pin].reg &= ~((uint64_t)0xffffffff << lshift); - ioapic->rtbl[pin].reg |= ((uint64_t)data << lshift); - - if (ioapic->rtbl[pin].pending && - ((ioapic->rtbl[pin].reg & IOART_INTMASK) == - IOART_INTMCLR)) { - ioapic->rtbl[pin].pending = false; - ioapic_clearpend++; - /* - * Inject the deferred level-triggered int if it is - * still asserted. Simulate by toggling the pin - * off and then on. - */ - if (ioapic->rtbl[pin].pinstate == true) { - ioapic_togglepend++; - ioapic_set_pinstate(vm, pin, false); - ioapic_set_pinstate(vm, pin, true); - } - } - } -} - -static int -ioapic_region_read(struct vmctx *vm, struct ioapic *ioapic, uintptr_t paddr, - int size, uint64_t *data) -{ - int offset; - - offset = paddr - ioapic->paddr; - - /* - * The IOAPIC specification allows 32-bit wide accesses to the - * IOREGSEL (offset 0) and IOWIN (offset 16) registers. - */ - if (size != 4 || (offset != IOREGSEL && offset != IOWIN)) { -#if 1 - printf("invalid access to ioapic%d: size %d, offset %d\n", - (int)(ioapic - ioapics), size, offset); -#endif - *data = 0; - return (0); - } - - if (offset == IOREGSEL) - *data = ioapic->ioregsel; - else - *data = ioapic_read(ioapic, ioapic->ioregsel); - - return (0); -} - -static int -ioapic_region_write(struct vmctx *vm, struct ioapic *ioapic, uintptr_t paddr, - int size, uint64_t data) -{ - int offset; - - offset = paddr - ioapic->paddr; - - /* - * The ioapic specification allows 32-bit wide accesses to the - * IOREGSEL (offset 0) and IOWIN (offset 16) registers. - */ - if (size != 4 || (offset != IOREGSEL && offset != IOWIN)) { -#if 1 - printf("invalid access to ioapic%d: size %d, offset %d\n", - (int)(ioapic - ioapics), size, offset); -#endif - return (0); - } - - if (offset == IOREGSEL) - ioapic->ioregsel = data; - else - ioapic_write(vm, ioapic, ioapic->ioregsel, data); - - return (0); -} - -static int -ioapic_region_handler(struct vmctx *vm, int vcpu, int dir, uintptr_t paddr, - int size, uint64_t *val, void *arg1, long arg2) -{ - struct ioapic *ioapic; - int which; - - ioapic = arg1; - which = arg2; - - assert(ioapic == &ioapics[which]); - - pthread_mutex_lock(&ioapic->mtx); - if (dir == MEM_F_READ) - ioapic_region_read(vm, ioapic, paddr, size, val); - else - ioapic_region_write(vm, ioapic, paddr, size, *val); - pthread_mutex_unlock(&ioapic->mtx); - - return (0); -} diff --git a/usr.sbin/bhyve/ioapic.h b/usr.sbin/bhyve/ioapic.h deleted file mode 100644 index 4696f9a..0000000 --- a/usr.sbin/bhyve/ioapic.h +++ /dev/null @@ -1,38 +0,0 @@ -/*- - * Copyright (c) 2012 NetApp, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _IOAPIC_H_ -#define _IOAPIC_H_ - -struct vmctx; - -void ioapic_init(int num); -void ioapic_deassert_pin(struct vmctx *ctx, int pin); -void ioapic_assert_pin(struct vmctx *ctx, int pin); - -#endif diff --git a/usr.sbin/bhyve/mptbl.c b/usr.sbin/bhyve/mptbl.c index c311cba..3d45cc6 100644 --- a/usr.sbin/bhyve/mptbl.c +++ b/usr.sbin/bhyve/mptbl.c @@ -72,7 +72,7 @@ __FBSDID("$FreeBSD$"); #define MPEP_FEATURES (0xBFEBFBFF) /* XXX Intel i7 */ /* Number of i/o intr entries */ -#define MPEII_MAX_IRQ 16 +#define MPEII_MAX_IRQ 24 /* Bus entry defines */ #define MPE_NUM_BUSES 2 diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c index 3820b04..c7086dd 100644 --- a/usr.sbin/bhyve/pci_emul.c +++ b/usr.sbin/bhyve/pci_emul.c @@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$"); #include "legacy_irq.h" #include "mem.h" #include "pci_emul.h" -#include "ioapic.h" #define CONF1_ADDR_PORT 0x0cf8 #define CONF1_DATA_PORT 0x0cfc @@ -1136,7 +1135,11 @@ pci_lintr_assert(struct pci_devinst *pi) { assert(pi->pi_lintr_pin >= 0); - ioapic_assert_pin(pi->pi_vmctx, pi->pi_lintr_pin); + + if (pi->pi_lintr_state == 0) { + pi->pi_lintr_state = 1; + vm_ioapic_assert_irq(pi->pi_vmctx, pi->pi_lintr_pin); + } } void @@ -1144,7 +1147,11 @@ pci_lintr_deassert(struct pci_devinst *pi) { assert(pi->pi_lintr_pin >= 0); - ioapic_deassert_pin(pi->pi_vmctx, pi->pi_lintr_pin); + + if (pi->pi_lintr_state == 1) { + pi->pi_lintr_state = 0; + vm_ioapic_deassert_irq(pi->pi_vmctx, pi->pi_lintr_pin); + } } /* diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h index ebcf834..6a1d757 100644 --- a/usr.sbin/bhyve/pci_emul.h +++ b/usr.sbin/bhyve/pci_emul.h @@ -104,6 +104,7 @@ struct pci_devinst { struct vmctx *pi_vmctx; uint8_t pi_bus, pi_slot, pi_func; int8_t pi_lintr_pin; + int8_t pi_lintr_state; char pi_name[PI_NAMESZ]; int pi_bar_getsize; diff --git a/usr.sbin/bhyve/pci_lpc.c b/usr.sbin/bhyve/pci_lpc.c index 9fd5f5c..4157c5c 100644 --- a/usr.sbin/bhyve/pci_lpc.c +++ b/usr.sbin/bhyve/pci_lpc.c @@ -31,13 +31,16 @@ __FBSDID("$FreeBSD$"); #include +#include +#include #include #include #include +#include + #include "inout.h" -#include "ioapic.h" #include "pci_emul.h" #include "uart_emul.h" @@ -91,17 +94,16 @@ lpc_uart_intr_assert(void *arg) assert(sc->irq >= 0); - ioapic_assert_pin(lpc_bridge->pi_vmctx, sc->irq); + vm_ioapic_pulse_irq(lpc_bridge->pi_vmctx, sc->irq); } static void lpc_uart_intr_deassert(void *arg) { - struct lpc_uart_softc *sc = arg; - - assert(sc->irq >= 0); - - ioapic_deassert_pin(lpc_bridge->pi_vmctx, sc->irq); + /* + * The COM devices on the LPC bus generate edge triggered interrupts, + * so nothing more to do here. + */ } static int diff --git a/usr.sbin/bhyve/pit_8254.c b/usr.sbin/bhyve/pit_8254.c index 88c2d22..9ecb565 100644 --- a/usr.sbin/bhyve/pit_8254.c +++ b/usr.sbin/bhyve/pit_8254.c @@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$"); #include "bhyverun.h" #include "inout.h" -#include "ioapic.h" #include "mevent.h" #include "pit_8254.h" @@ -106,8 +105,7 @@ pit_mevent_cb(int fd, enum ev_type type, void *param) pit_mev_count++; - ioapic_assert_pin(c->ctx, 2); - ioapic_deassert_pin(c->ctx, 2); + vm_ioapic_pulse_irq(c->ctx, 2); /* * Delete the timer for one-shots -- cgit v1.1