aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2016-07-14 17:16:10 +0000
committerAlexander Motin <mav@FreeBSD.org>2016-07-14 17:16:10 +0000
commit1b4496d0433e673e5358421b0fffd98586aeaae7 (patch)
tree0a2621fce7519fbb62b71338ca4a3ca50a576b7e /usr.sbin
parenta509d56d7f50c80ba17a66e224d10dda4ee26a04 (diff)
downloadsrc-1b4496d0433e673e5358421b0fffd98586aeaae7.tar.gz
src-1b4496d0433e673e5358421b0fffd98586aeaae7.zip
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.
Notes
Notes: svn path=/head/; revision=302850
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bhyve/ioapic.c9
-rw-r--r--usr.sbin/bhyve/ioapic.h4
-rw-r--r--usr.sbin/bhyve/pci_emul.c4
-rw-r--r--usr.sbin/bhyve/pci_irq.c22
-rw-r--r--usr.sbin/bhyve/pci_irq.h2
5 files changed, 28 insertions, 13 deletions
diff --git a/usr.sbin/bhyve/ioapic.c b/usr.sbin/bhyve/ioapic.c
index 0ad69d96a4a4..5ed08f9a5f26 100644
--- a/usr.sbin/bhyve/ioapic.c
+++ b/usr.sbin/bhyve/ioapic.c
@@ -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));
}
diff --git a/usr.sbin/bhyve/ioapic.h b/usr.sbin/bhyve/ioapic.h
index efdd3c67a4c2..87773a87ada2 100644
--- a/usr.sbin/bhyve/ioapic.h
+++ b/usr.sbin/bhyve/ioapic.h
@@ -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
diff --git a/usr.sbin/bhyve/pci_emul.c b/usr.sbin/bhyve/pci_emul.c
index 476791518f99..7fcf7a49404d 100644
--- a/usr.sbin/bhyve/pci_emul.c
+++ b/usr.sbin/bhyve/pci_emul.c
@@ -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;
diff --git a/usr.sbin/bhyve/pci_irq.c b/usr.sbin/bhyve/pci_irq.c
index f22b15cefaaf..4ae9ff358269 100644
--- a/usr.sbin/bhyve/pci_irq.c
+++ b/usr.sbin/bhyve/pci_irq.c
@@ -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++;
diff --git a/usr.sbin/bhyve/pci_irq.h b/usr.sbin/bhyve/pci_irq.h
index 24f9c9987510..aa1a6c356bc6 100644
--- a/usr.sbin/bhyve/pci_irq.h
+++ b/usr.sbin/bhyve/pci_irq.h
@@ -37,7 +37,7 @@ void pci_irq_deassert(struct pci_devinst *pi);
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);