Author: neel
Date: Wed Nov 27 22:18:08 2013
New Revision: 258699
URL: http://svnweb.freebsd.org/changeset/base/258699

Log:
  Add support for level triggered interrupt pins on the vioapic. Prior to this
  commit level triggered interrupts would work as long as the pin was not shared
  among multiple interrupt sources.
  
  The vlapic now keeps track of level triggered interrupts in the trigger mode
  register and will forward the EOI for a level triggered interrupt to the
  vioapic. The vioapic in turn uses the EOI to sample the level on the pin and
  re-inject the vector if the pin is still asserted.
  
  The vhpet is the first consumer of level triggered interrupts and advertises
  that it can generate interrupts on pins 20 through 23 of the vioapic.
  
  Discussed with:       grehan@

Modified:
  head/sys/amd64/vmm/io/ppt.c
  head/sys/amd64/vmm/io/vhpet.c
  head/sys/amd64/vmm/io/vioapic.c
  head/sys/amd64/vmm/io/vioapic.h
  head/sys/amd64/vmm/io/vlapic.c
  head/sys/amd64/vmm/io/vlapic.h
  head/sys/amd64/vmm/vmm_dev.c
  head/sys/amd64/vmm/vmm_ktr.h
  head/sys/amd64/vmm/vmm_lapic.c
  head/sys/amd64/vmm/vmm_lapic.h
  head/usr.sbin/bhyve/acpi.c
  head/usr.sbin/bhyve/mptbl.c

Modified: head/sys/amd64/vmm/io/ppt.c
==============================================================================
--- head/sys/amd64/vmm/io/ppt.c Wed Nov 27 22:17:00 2013        (r258698)
+++ head/sys/amd64/vmm/io/ppt.c Wed Nov 27 22:18:08 2013        (r258699)
@@ -421,7 +421,7 @@ pptintr(void *arg)
        vec = pptarg->vec;
 
        if (ppt->vm != NULL)
-               (void) lapic_set_intr(ppt->vm, pptarg->vcpu, vec);
+               lapic_intr_edge(ppt->vm, pptarg->vcpu, vec);
        else {
                /*
                 * XXX

Modified: head/sys/amd64/vmm/io/vhpet.c
==============================================================================
--- head/sys/amd64/vmm/io/vhpet.c       Wed Nov 27 22:17:00 2013        
(r258698)
+++ head/sys/amd64/vmm/io/vhpet.c       Wed Nov 27 22:18:08 2013        
(r258699)
@@ -266,14 +266,14 @@ vhpet_timer_interrupt(struct vhpet *vhpe
                if (apicid != 0xff) {
                        /* unicast */
                        vcpuid = vm_apicid2vcpuid(vhpet->vm, apicid);
-                       lapic_set_intr(vhpet->vm, vcpuid, vector);
+                       lapic_intr_edge(vhpet->vm, vcpuid, vector);
                } else {
                        /* broadcast */
                        dmask = vm_active_cpus(vhpet->vm);
                        while ((vcpuid = CPU_FFS(&dmask)) != 0) {
                                vcpuid--;
                                CPU_CLR(vcpuid, &dmask);
-                               lapic_set_intr(vhpet->vm, vcpuid, vector);
+                               lapic_intr_edge(vhpet->vm, vcpuid, vector);
                        }
                }
                return;
@@ -725,8 +725,9 @@ done:
 struct vhpet *
 vhpet_init(struct vm *vm)
 {
-       int i;
+       int i, pincount;
        struct vhpet *vhpet;
+       uint64_t allowed_irqs;
        struct vhpet_callout_arg *arg;
        struct bintime bt;
 
@@ -737,12 +738,20 @@ vhpet_init(struct vm *vm)
        FREQ2BT(HPET_FREQ, &bt);
        vhpet->freq_sbt = bttosbt(bt);
 
+       pincount = vioapic_pincount(vm);
+       if (pincount >= 24)
+               allowed_irqs = 0x00f00000;      /* irqs 20, 21, 22 and 23 */
+       else
+               allowed_irqs = 0;
+
        /*
         * Initialize HPET timer hardware state.
         */
        for (i = 0; i < VHPET_NUM_TIMERS; i++) {
-               vhpet->timer[i].cap_config = 0UL << 32 |
-                   HPET_TCAP_FSB_INT_DEL | HPET_TCAP_PER_INT;
+               vhpet->timer[i].cap_config = allowed_irqs << 32;
+               vhpet->timer[i].cap_config |= HPET_TCAP_PER_INT;
+               vhpet->timer[i].cap_config |= HPET_TCAP_FSB_INT_DEL;
+
                vhpet->timer[i].compval = 0xffffffff;
                callout_init(&vhpet->timer[i].callout, 1);
 

Modified: head/sys/amd64/vmm/io/vioapic.c
==============================================================================
--- head/sys/amd64/vmm/io/vioapic.c     Wed Nov 27 22:17:00 2013        
(r258698)
+++ head/sys/amd64/vmm/io/vioapic.c     Wed Nov 27 22:18:08 2013        
(r258699)
@@ -49,8 +49,8 @@ __FBSDID("$FreeBSD$");
 #define        IOREGSEL        0x00
 #define        IOWIN           0x10
 
-#define        REDIR_ENTRIES   16
-#define        INTR_ASSERTED(vioapic, pin) ((vioapic)->rtbl[(pin)].pinstate == 
true)
+#define        REDIR_ENTRIES   24
+#define        RTBL_RO_BITS    ((uint64_t)(IOART_REM_IRR | IOART_DELIVS))
 
 struct vioapic {
        struct vm       *vm;
@@ -59,8 +59,7 @@ struct vioapic {
        uint32_t        ioregsel;
        struct {
                uint64_t reg;
-               bool     pinstate;
-               bool     pending;
+               int      acnt;  /* sum of pin asserts (+1) and deasserts (-1) */
        } rtbl[REDIR_ENTRIES];
 };
 
@@ -79,6 +78,9 @@ static MALLOC_DEFINE(M_VIOAPIC, "vioapic
 #define        VIOAPIC_CTR3(vioapic, fmt, a1, a2, a3)                          
\
        VM_CTR3((vioapic)->vm, fmt, a1, a2, a3)
 
+#define        VIOAPIC_CTR4(vioapic, fmt, a1, a2, a3, a4)                      
\
+       VM_CTR4((vioapic)->vm, fmt, a1, a2, a3, a4)
+
 #ifdef KTR
 static const char *
 pinstate_str(bool asserted)
@@ -89,14 +91,25 @@ pinstate_str(bool asserted)
        else
                return ("deasserted");
 }
+
+static const char *
+trigger_str(bool level)
+{
+
+       if (level)
+               return ("level");
+       else
+               return ("edge");
+}
 #endif
 
 static void
-vioapic_set_pinstate(struct vioapic *vioapic, int pin, bool newstate)
+vioapic_send_intr(struct vioapic *vioapic, int pin)
 {
        int vector, apicid, vcpuid;
        uint32_t low, high;
        cpuset_t dmask;
+       bool level;
 
        KASSERT(pin >= 0 && pin < REDIR_ENTRIES,
            ("vioapic_set_pinstate: invalid pin number %d", pin));
@@ -104,62 +117,96 @@ vioapic_set_pinstate(struct vioapic *vio
        KASSERT(VIOAPIC_LOCKED(vioapic),
            ("vioapic_set_pinstate: vioapic is not locked"));
 
-       VIOAPIC_CTR2(vioapic, "ioapic pin%d %s", pin, pinstate_str(newstate));
+       low = vioapic->rtbl[pin].reg;
+       high = vioapic->rtbl[pin].reg >> 32;
 
-       /* Nothing to do if interrupt pin has not changed state */
-       if (vioapic->rtbl[pin].pinstate == newstate)
+       /*
+        * XXX We only deal with:
+        * - physical destination
+        * - fixed delivery mode
+        */
+       if ((low & IOART_DESTMOD) != IOART_DESTPHY) {
+               VIOAPIC_CTR2(vioapic, "ioapic pin%d: unsupported dest mode "
+                   "0x%08x", pin, low);
                return;
+       }
 
-       vioapic->rtbl[pin].pinstate = newstate; /* record it */
+       if ((low & IOART_DELMOD) != IOART_DELFIXED) {
+               VIOAPIC_CTR2(vioapic, "ioapic pin%d: unsupported delivery mode "
+                   "0x%08x", pin, low);
+               return;
+       }
 
-       /* Nothing to do if interrupt pin is deasserted */
-       if (!INTR_ASSERTED(vioapic, pin))
+       if ((low & IOART_INTMASK) == IOART_INTMSET) {
+               VIOAPIC_CTR1(vioapic, "ioapic pin%d: masked", 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 = vioapic->rtbl[pin].reg;
-       high = vioapic->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 */
-                       vcpuid = vm_apicid2vcpuid(vioapic->vm, apicid);
-                       VIOAPIC_CTR3(vioapic, "ioapic pin%d triggering "
-                           "intr vector %d on vcpuid %d", pin, vector, vcpuid);
-                       lapic_set_intr(vioapic->vm, vcpuid, vector);
-               } else {
-                       /* broadcast */
-                       VIOAPIC_CTR2(vioapic, "ioapic pin%d triggering intr "
-                           "vector %d on all vcpus", pin, vector);
-                       dmask = vm_active_cpus(vioapic->vm);
-                       while ((vcpuid = CPU_FFS(&dmask)) != 0) {
-                               vcpuid--;
-                               CPU_CLR(vcpuid, &dmask);
-                               lapic_set_intr(vioapic->vm, vcpuid, vector);
-                       }
+       level = low & IOART_TRGRLVL ? true : false;
+       if (level)
+               vioapic->rtbl[pin].reg |= IOART_REM_IRR;
+
+       vector = low & IOART_INTVEC;
+       apicid = high >> APIC_ID_SHIFT;
+       if (apicid != 0xff) {
+               /* unicast */
+               vcpuid = vm_apicid2vcpuid(vioapic->vm, apicid);
+               VIOAPIC_CTR4(vioapic, "ioapic pin%d: %s triggered intr "
+                   "vector %d on vcpuid %d", pin, trigger_str(level),
+                   vector, vcpuid);
+               lapic_set_intr(vioapic->vm, vcpuid, vector, level);
+       } else {
+               /* broadcast */
+               VIOAPIC_CTR3(vioapic, "ioapic pin%d: %s triggered intr "
+                   "vector %d on all vcpus", pin, trigger_str(level), vector);
+               dmask = vm_active_cpus(vioapic->vm);
+               while ((vcpuid = CPU_FFS(&dmask)) != 0) {
+                       vcpuid--;
+                       CPU_CLR(vcpuid, &dmask);
+                       lapic_set_intr(vioapic->vm, vcpuid, vector, level);
                }
-       } else if ((low & IOART_INTMASK) != IOART_INTMCLR &&
-                  (low & IOART_TRGRLVL) != 0) {
-               /*
-                * 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
-                */
-               VIOAPIC_CTR1(vioapic, "ioapic pin%d interrupt pending", pin);
-               vioapic->rtbl[pin].pending = true;
        }
 }
 
+static void
+vioapic_set_pinstate(struct vioapic *vioapic, int pin, bool newstate)
+{
+       int oldcnt, newcnt;
+       bool needintr;
+
+       KASSERT(pin >= 0 && pin < REDIR_ENTRIES,
+           ("vioapic_set_pinstate: invalid pin number %d", pin));
+
+       KASSERT(VIOAPIC_LOCKED(vioapic),
+           ("vioapic_set_pinstate: vioapic is not locked"));
+
+       oldcnt = vioapic->rtbl[pin].acnt;
+       if (newstate)
+               vioapic->rtbl[pin].acnt++;
+       else
+               vioapic->rtbl[pin].acnt--;
+       newcnt = vioapic->rtbl[pin].acnt;
+
+       if (newcnt < 0) {
+               VIOAPIC_CTR2(vioapic, "ioapic pin%d: bad acnt %d",
+                   pin, newcnt);
+       }
+
+       needintr = false;
+       if (oldcnt == 0 && newcnt == 1) {
+               needintr = true;
+               VIOAPIC_CTR1(vioapic, "ioapic pin%d: asserted", pin);
+       } else if (oldcnt == 1 && newcnt == 0) {
+               VIOAPIC_CTR1(vioapic, "ioapic pin%d: deasserted", pin);
+       } else {
+               VIOAPIC_CTR3(vioapic, "ioapic pin%d: %s, ignored, acnt %d",
+                   pin, pinstate_str(newstate), newcnt);
+       }
+
+       if (needintr)
+               vioapic_send_intr(vioapic, pin);
+}
+
 enum irqstate {
        IRQSTATE_ASSERT,
        IRQSTATE_DEASSERT,
@@ -228,7 +275,7 @@ vioapic_read(struct vioapic *vioapic, ui
                return (vioapic->id);
                break;
        case IOAPIC_VER:
-               return ((REDIR_ENTRIES << MAXREDIRSHIFT) | 0x11);
+               return (((REDIR_ENTRIES - 1) << MAXREDIRSHIFT) | 0x11);
                break;
        case IOAPIC_ARB:
                return (vioapic->id);
@@ -255,6 +302,7 @@ vioapic_read(struct vioapic *vioapic, ui
 static void
 vioapic_write(struct vioapic *vioapic, uint32_t addr, uint32_t data)
 {
+       uint64_t data64, mask64;
        int regnum, pin, lshift;
 
        regnum = addr & 0xff;
@@ -279,30 +327,26 @@ vioapic_write(struct vioapic *vioapic, u
                else
                        lshift = 0;
 
-               vioapic->rtbl[pin].reg &= ~((uint64_t)0xffffffff << lshift);
-               vioapic->rtbl[pin].reg |= ((uint64_t)data << lshift);
+               data64 = (uint64_t)data << lshift;
+               mask64 = (uint64_t)0xffffffff << lshift;
+               vioapic->rtbl[pin].reg &= ~mask64 | RTBL_RO_BITS;
+               vioapic->rtbl[pin].reg |= data64 & ~RTBL_RO_BITS;
 
-               VIOAPIC_CTR2(vioapic, "ioapic pin%d redir table entry %#lx",
+               VIOAPIC_CTR2(vioapic, "ioapic pin%d: redir table entry %#lx",
                    pin, vioapic->rtbl[pin].reg);
 
-               if (vioapic->rtbl[pin].pending &&
-                   ((vioapic->rtbl[pin].reg & IOART_INTMASK) ==
-                   IOART_INTMCLR)) {
-                       vioapic->rtbl[pin].pending = false;
-                       /*
-                        * Inject the deferred level-triggered int if it is
-                        * still asserted. Simulate by toggling the pin
-                        * off and then on.
-                        */
-                       if (vioapic->rtbl[pin].pinstate == true) {
-                               VIOAPIC_CTR1(vioapic, "ioapic pin%d pending "
-                                   "interrupt delivered", pin);
-                               vioapic_set_pinstate(vioapic, pin, false);
-                               vioapic_set_pinstate(vioapic, pin, true);
-                       } else {
-                               VIOAPIC_CTR1(vioapic, "ioapic pin%d pending "
-                                   "interrupt dismissed", pin);
-                       }
+               /*
+                * Generate an interrupt if the following conditions are met:
+                * - pin is not masked
+                * - previous interrupt has been EOIed
+                * - pin level is asserted
+                */
+               if ((vioapic->rtbl[pin].reg & IOART_INTMASK) == IOART_INTMCLR &&
+                   (vioapic->rtbl[pin].reg & IOART_REM_IRR) == 0 &&
+                   (vioapic->rtbl[pin].acnt > 0)) {
+                       VIOAPIC_CTR2(vioapic, "ioapic pin%d: asserted at rtbl "
+                           "write, acnt %d", pin, vioapic->rtbl[pin].acnt);
+                       vioapic_send_intr(vioapic, pin);
                }
        }
 }
@@ -366,6 +410,38 @@ vioapic_mmio_write(void *vm, int vcpuid,
        return (error);
 }
 
+void
+vioapic_process_eoi(struct vm *vm, int vcpuid, int vector)
+{
+       struct vioapic *vioapic;
+       int pin;
+
+       KASSERT(vector >= 0 && vector < 256,
+           ("vioapic_process_eoi: invalid vector %d", vector));
+
+       vioapic = vm_ioapic(vm);
+       VIOAPIC_CTR1(vioapic, "ioapic processing eoi for vector %d", vector);
+
+       /*
+        * XXX keep track of the pins associated with this vector instead
+        * of iterating on every single pin each time.
+        */
+       VIOAPIC_LOCK(vioapic);
+       for (pin = 0; pin < REDIR_ENTRIES; pin++) {
+               if ((vioapic->rtbl[pin].reg & IOART_REM_IRR) == 0)
+                       continue;
+               if ((vioapic->rtbl[pin].reg & IOART_INTVEC) != vector)
+                       continue;
+               vioapic->rtbl[pin].reg &= ~IOART_REM_IRR;
+               if (vioapic->rtbl[pin].acnt > 0) {
+                       VIOAPIC_CTR2(vioapic, "ioapic pin%d: asserted at eoi, "
+                           "acnt %d", pin, vioapic->rtbl[pin].acnt);
+                       vioapic_send_intr(vioapic, pin);
+               }
+       }
+       VIOAPIC_UNLOCK(vioapic);
+}
+
 struct vioapic *
 vioapic_init(struct vm *vm)
 {
@@ -390,3 +466,10 @@ vioapic_cleanup(struct vioapic *vioapic)
 
        free(vioapic, M_VIOAPIC);
 }
+
+int
+vioapic_pincount(struct vm *vm)
+{
+
+       return (REDIR_ENTRIES);
+}

Modified: head/sys/amd64/vmm/io/vioapic.h
==============================================================================
--- head/sys/amd64/vmm/io/vioapic.h     Wed Nov 27 22:17:00 2013        
(r258698)
+++ head/sys/amd64/vmm/io/vioapic.h     Wed Nov 27 22:18:08 2013        
(r258699)
@@ -44,4 +44,7 @@ int   vioapic_mmio_write(void *vm, int vcp
            uint64_t wval, int size, void *arg);
 int    vioapic_mmio_read(void *vm, int vcpuid, uint64_t gpa,
            uint64_t *rval, int size, void *arg);
+
+int    vioapic_pincount(struct vm *vm);
+void   vioapic_process_eoi(struct vm *vm, int vcpuid, int vector);
 #endif

Modified: head/sys/amd64/vmm/io/vlapic.c
==============================================================================
--- head/sys/amd64/vmm/io/vlapic.c      Wed Nov 27 22:17:00 2013        
(r258698)
+++ head/sys/amd64/vmm/io/vlapic.c      Wed Nov 27 22:18:08 2013        
(r258699)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
 #include "vmm_lapic.h"
 #include "vmm_ktr.h"
 #include "vlapic.h"
+#include "vioapic.h"
 
 #define        VLAPIC_CTR0(vlapic, format)                                     
\
        VCPU_CTR0((vlapic)->vm, (vlapic)->vcpuid, format)
@@ -211,18 +212,32 @@ vlapic_reset(struct vlapic *vlapic)
 }
 
 void
-vlapic_set_intr_ready(struct vlapic *vlapic, int vector)
+vlapic_set_intr_ready(struct vlapic *vlapic, int vector, bool level)
 {
        struct LAPIC    *lapic = &vlapic->apic;
-       uint32_t        *irrptr;
+       uint32_t        *irrptr, *tmrptr, mask;
        int             idx;
 
        if (vector < 0 || vector >= 256)
                panic("vlapic_set_intr_ready: invalid vector %d\n", vector);
 
        idx = (vector / 32) * 4;
+       mask = 1 << (vector % 32);
+
        irrptr = &lapic->irr0;
-       atomic_set_int(&irrptr[idx], 1 << (vector % 32));
+       atomic_set_int(&irrptr[idx], mask);
+
+       /*
+        * Upon acceptance of an interrupt into the IRR the corresponding
+        * TMR bit is cleared for edge-triggered interrupts and set for
+        * level-triggered interrupts.
+        */
+       tmrptr = &lapic->tmr0;
+       if (level)
+               atomic_set_int(&tmrptr[idx], mask);
+       else
+               atomic_clear_int(&tmrptr[idx], mask);
+
        VLAPIC_CTR_IRR(vlapic, "vlapic_set_intr_ready");
 }
 
@@ -350,10 +365,11 @@ static void
 vlapic_process_eoi(struct vlapic *vlapic)
 {
        struct LAPIC    *lapic = &vlapic->apic;
-       uint32_t        *isrptr;
-       int             i, idx, bitpos;
+       uint32_t        *isrptr, *tmrptr;
+       int             i, idx, bitpos, vector;
 
        isrptr = &lapic->isr0;
+       tmrptr = &lapic->tmr0;
 
        /*
         * The x86 architecture reserves the the first 32 vectors for use
@@ -362,15 +378,20 @@ vlapic_process_eoi(struct vlapic *vlapic
        for (i = 7; i > 0; i--) {
                idx = i * 4;
                bitpos = fls(isrptr[idx]);
-               if (bitpos != 0) {
+               if (bitpos-- != 0) {
                        if (vlapic->isrvec_stk_top <= 0) {
                                panic("invalid vlapic isrvec_stk_top %d",
                                      vlapic->isrvec_stk_top);
                        }
-                       isrptr[idx] &= ~(1 << (bitpos - 1));
+                       isrptr[idx] &= ~(1 << bitpos);
                        VLAPIC_CTR_ISR(vlapic, "vlapic_process_eoi");
                        vlapic->isrvec_stk_top--;
                        vlapic_update_ppr(vlapic);
+                       if ((tmrptr[idx] & (1 << bitpos)) != 0) {
+                               vector = i * 32 + bitpos;
+                               vioapic_process_eoi(vlapic->vm, vlapic->vcpuid,
+                                   vector);
+                       }
                        return;
                }
        }
@@ -405,7 +426,7 @@ vlapic_fire_timer(struct vlapic *vlapic)
        if (!vlapic_get_lvt_field(lvt, APIC_LVTT_M)) {
                vmm_stat_incr(vlapic->vm, vlapic->vcpuid, VLAPIC_INTR_TIMER, 1);
                vector = vlapic_get_lvt_field(lvt,APIC_LVTT_VECTOR);
-               vlapic_set_intr_ready(vlapic, vector);
+               vlapic_set_intr_ready(vlapic, vector, false);
        }
 }
 
@@ -451,7 +472,7 @@ lapic_process_icr(struct vlapic *vlapic,
                        i--;
                        CPU_CLR(i, &dmask);
                        if (mode == APIC_DELMODE_FIXED) {
-                               lapic_set_intr(vlapic->vm, i, vec);
+                               lapic_intr_edge(vlapic->vm, i, vec);
                                vmm_stat_array_incr(vlapic->vm, vlapic->vcpuid,
                                                    IPIS_SENT, i, 1);
                        } else

Modified: head/sys/amd64/vmm/io/vlapic.h
==============================================================================
--- head/sys/amd64/vmm/io/vlapic.h      Wed Nov 27 22:17:00 2013        
(r258698)
+++ head/sys/amd64/vmm/io/vlapic.h      Wed Nov 27 22:18:08 2013        
(r258699)
@@ -94,7 +94,7 @@ int vlapic_write(struct vlapic *vlapic, 
 int vlapic_read(struct vlapic *vlapic, uint64_t offset, uint64_t *data);
 int vlapic_pending_intr(struct vlapic *vlapic);
 void vlapic_intr_accepted(struct vlapic *vlapic, int vector);
-void vlapic_set_intr_ready(struct vlapic *vlapic, int vector);
+void vlapic_set_intr_ready(struct vlapic *vlapic, int vector, bool level);
 int vlapic_timer_tick(struct vlapic *vlapic);
 
 uint64_t vlapic_get_apicbase(struct vlapic *vlapic);

Modified: head/sys/amd64/vmm/vmm_dev.c
==============================================================================
--- head/sys/amd64/vmm/vmm_dev.c        Wed Nov 27 22:17:00 2013        
(r258698)
+++ head/sys/amd64/vmm/vmm_dev.c        Wed Nov 27 22:18:08 2013        
(r258699)
@@ -294,7 +294,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long c
                break;
        case VM_LAPIC_IRQ:
                vmirq = (struct vm_lapic_irq *)data;
-               error = lapic_set_intr(sc->vm, vmirq->cpuid, vmirq->vector);
+               error = lapic_intr_edge(sc->vm, vmirq->cpuid, vmirq->vector);
                break;
        case VM_IOAPIC_ASSERT_IRQ:
                ioapic_irq = (struct vm_ioapic_irq *)data;

Modified: head/sys/amd64/vmm/vmm_ktr.h
==============================================================================
--- head/sys/amd64/vmm/vmm_ktr.h        Wed Nov 27 22:17:00 2013        
(r258698)
+++ head/sys/amd64/vmm/vmm_ktr.h        Wed Nov 27 22:18:08 2013        
(r258699)
@@ -59,4 +59,7 @@ CTR3(KTR_VMM, "vm %s: " format, vm_name(
 
 #define        VM_CTR3(vm, format, p1, p2, p3)                                 
\
 CTR4(KTR_VMM, "vm %s: " format, vm_name((vm)), (p1), (p2), (p3))
+
+#define        VM_CTR4(vm, format, p1, p2, p3, p4)                             
\
+CTR5(KTR_VMM, "vm %s: " format, vm_name((vm)), (p1), (p2), (p3), (p4))
 #endif

Modified: head/sys/amd64/vmm/vmm_lapic.c
==============================================================================
--- head/sys/amd64/vmm/vmm_lapic.c      Wed Nov 27 22:17:00 2013        
(r258698)
+++ head/sys/amd64/vmm/vmm_lapic.c      Wed Nov 27 22:18:08 2013        
(r258699)
@@ -62,7 +62,7 @@ lapic_intr_accepted(struct vm *vm, int c
 }
 
 int
-lapic_set_intr(struct vm *vm, int cpu, int vector)
+lapic_set_intr(struct vm *vm, int cpu, int vector, bool level)
 {
        struct vlapic *vlapic;
 
@@ -73,7 +73,7 @@ lapic_set_intr(struct vm *vm, int cpu, i
                return (EINVAL);
 
        vlapic = vm_lapic(vm, cpu);
-       vlapic_set_intr_ready(vlapic, vector);
+       vlapic_set_intr_ready(vlapic, vector, level);
 
        vm_interrupt_hostcpu(vm, cpu);
 

Modified: head/sys/amd64/vmm/vmm_lapic.h
==============================================================================
--- head/sys/amd64/vmm/vmm_lapic.h      Wed Nov 27 22:17:00 2013        
(r258698)
+++ head/sys/amd64/vmm/vmm_lapic.h      Wed Nov 27 22:18:08 2013        
(r258699)
@@ -66,6 +66,22 @@ void lapic_intr_accepted(struct vm *vm, 
  * Signals to the LAPIC that an interrupt at 'vector' needs to be generated
  * to the 'cpu', the state is recorded in IRR.
  */
-int    lapic_set_intr(struct vm *vm, int cpu, int vector);
+int    lapic_set_intr(struct vm *vm, int cpu, int vector, bool trig);
+
+#define        LAPIC_TRIG_LEVEL        true
+#define        LAPIC_TRIG_EDGE         false
+static __inline int
+lapic_intr_level(struct vm *vm, int cpu, int vector)
+{
+
+       return (lapic_set_intr(vm, cpu, vector, LAPIC_TRIG_LEVEL));
+}
+
+static __inline int
+lapic_intr_edge(struct vm *vm, int cpu, int vector)
+{
+
+       return (lapic_set_intr(vm, cpu, vector, LAPIC_TRIG_EDGE));
+}
 
 #endif

Modified: head/usr.sbin/bhyve/acpi.c
==============================================================================
--- head/usr.sbin/bhyve/acpi.c  Wed Nov 27 22:17:00 2013        (r258698)
+++ head/usr.sbin/bhyve/acpi.c  Wed Nov 27 22:18:08 2013        (r258699)
@@ -259,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 */

Modified: head/usr.sbin/bhyve/mptbl.c
==============================================================================
--- head/usr.sbin/bhyve/mptbl.c Wed Nov 27 22:17:00 2013        (r258698)
+++ head/usr.sbin/bhyve/mptbl.c Wed Nov 27 22:18:08 2013        (r258699)
@@ -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
 
 /* Define processor entry struct since <x86/mptable.h> gets it wrong */
 typedef struct BPROCENTRY {
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to