Author: mav
Date: Thu Jul 14 17:16:10 2016
New Revision: 302850
URL: https://svnweb.freebsd.org/changeset/base/302850

Log:
  Make PCI interupts allocation static when using bootrom (UEFI).
  
  This makes factual interrupt routing match one shipped with UEFI firmware.
  With old firmware this make legacy interrupts work reliable for functions 0
  of PCI slots 3-6.  Updated UEFI image fixes problem completely.

Modified:
  head/usr.sbin/bhyve/ioapic.c
  head/usr.sbin/bhyve/ioapic.h
  head/usr.sbin/bhyve/pci_emul.c
  head/usr.sbin/bhyve/pci_irq.c
  head/usr.sbin/bhyve/pci_irq.h

Modified: head/usr.sbin/bhyve/ioapic.c
==============================================================================
--- head/usr.sbin/bhyve/ioapic.c        Thu Jul 14 17:10:54 2016        
(r302849)
+++ head/usr.sbin/bhyve/ioapic.c        Thu Jul 14 17:16:10 2016        
(r302850)
@@ -29,11 +29,14 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
+#include <stdio.h>
 
 #include <machine/vmm.h>
 #include <vmmapi.h>
 
 #include "ioapic.h"
+#include "pci_emul.h"
+#include "pci_lpc.h"
 
 /*
  * Assign PCI INTx interrupts to I/O APIC pins in a round-robin
@@ -64,11 +67,15 @@ ioapic_init(struct vmctx *ctx)
 }
 
 int
-ioapic_pci_alloc_irq(void)
+ioapic_pci_alloc_irq(struct pci_devinst *pi)
 {
        static int last_pin;
 
        if (pci_pins == 0)
                return (-1);
+       if (lpc_bootrom()) {
+               /* For external bootrom use fixed mapping. */
+               return (16 + (4 + pi->pi_slot + pi->pi_lintr.pin) % 8);
+       }
        return (16 + (last_pin++ % pci_pins));
 }

Modified: head/usr.sbin/bhyve/ioapic.h
==============================================================================
--- head/usr.sbin/bhyve/ioapic.h        Thu Jul 14 17:10:54 2016        
(r302849)
+++ head/usr.sbin/bhyve/ioapic.h        Thu Jul 14 17:16:10 2016        
(r302850)
@@ -30,10 +30,12 @@
 #ifndef _IOAPIC_H_
 #define        _IOAPIC_H_
 
+struct pci_devinst;
+
 /*
  * Allocate a PCI IRQ from the I/O APIC.
  */
 void   ioapic_init(struct vmctx *ctx);
-int    ioapic_pci_alloc_irq(void);
+int    ioapic_pci_alloc_irq(struct pci_devinst *pi);
 
 #endif

Modified: head/usr.sbin/bhyve/pci_emul.c
==============================================================================
--- head/usr.sbin/bhyve/pci_emul.c      Thu Jul 14 17:10:54 2016        
(r302849)
+++ head/usr.sbin/bhyve/pci_emul.c      Thu Jul 14 17:16:10 2016        
(r302850)
@@ -1504,7 +1504,7 @@ pci_lintr_route(struct pci_devinst *pi)
         * is not yet assigned.
         */
        if (ii->ii_ioapic_irq == 0)
-               ii->ii_ioapic_irq = ioapic_pci_alloc_irq();
+               ii->ii_ioapic_irq = ioapic_pci_alloc_irq(pi);
        assert(ii->ii_ioapic_irq > 0);
 
        /*
@@ -1512,7 +1512,7 @@ pci_lintr_route(struct pci_devinst *pi)
         * not yet assigned.
         */
        if (ii->ii_pirq_pin == 0)
-               ii->ii_pirq_pin = pirq_alloc_pin(pi->pi_vmctx);
+               ii->ii_pirq_pin = pirq_alloc_pin(pi);
        assert(ii->ii_pirq_pin > 0);
 
        pi->pi_lintr.ioapic_irq = ii->ii_ioapic_irq;

Modified: head/usr.sbin/bhyve/pci_irq.c
==============================================================================
--- head/usr.sbin/bhyve/pci_irq.c       Thu Jul 14 17:10:54 2016        
(r302849)
+++ head/usr.sbin/bhyve/pci_irq.c       Thu Jul 14 17:16:10 2016        
(r302850)
@@ -193,19 +193,25 @@ pci_irq_deassert(struct pci_devinst *pi)
 }
 
 int
-pirq_alloc_pin(struct vmctx *ctx)
+pirq_alloc_pin(struct pci_devinst *pi)
 {
+       struct vmctx *ctx = pi->pi_vmctx;
        int best_count, best_irq, best_pin, irq, pin;
 
        pirq_cold = 0;
 
-       /* First, find the least-used PIRQ pin. */
-       best_pin = 0;
-       best_count = pirqs[0].use_count;
-       for (pin = 1; pin < nitems(pirqs); pin++) {
-               if (pirqs[pin].use_count < best_count) {
-                       best_pin = pin;
-                       best_count = pirqs[pin].use_count;
+       if (lpc_bootrom()) {
+               /* For external bootrom use fixed mapping. */
+               best_pin = (4 + pi->pi_slot + pi->pi_lintr.pin) % 8;
+       } else {
+               /* Find the least-used PIRQ pin. */
+               best_pin = 0;
+               best_count = pirqs[0].use_count;
+               for (pin = 1; pin < nitems(pirqs); pin++) {
+                       if (pirqs[pin].use_count < best_count) {
+                               best_pin = pin;
+                               best_count = pirqs[pin].use_count;
+                       }
                }
        }
        pirqs[best_pin].use_count++;

Modified: head/usr.sbin/bhyve/pci_irq.h
==============================================================================
--- head/usr.sbin/bhyve/pci_irq.h       Thu Jul 14 17:10:54 2016        
(r302849)
+++ head/usr.sbin/bhyve/pci_irq.h       Thu Jul 14 17:16:10 2016        
(r302850)
@@ -37,7 +37,7 @@ void  pci_irq_deassert(struct pci_devinst
 void   pci_irq_init(struct vmctx *ctx);
 void   pci_irq_reserve(int irq);
 void   pci_irq_use(int irq);
-int    pirq_alloc_pin(struct vmctx *ctx);
+int    pirq_alloc_pin(struct pci_devinst *pi);
 int    pirq_irq(int pin);
 uint8_t        pirq_read(int pin);
 void   pirq_write(struct vmctx *ctx, int pin, uint8_t val);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to