summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bhyve/mptbl.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-06-12 13:13:15 +0000
committerjhb <jhb@FreeBSD.org>2014-06-12 13:13:15 +0000
commit835cb387cc34a2aab452053e84f55a0e763a9d3e (patch)
treee09f19aa14b21924ca77616e541961a6835a7e4c /usr.sbin/bhyve/mptbl.c
parent7f22c45d0830c1d948d610b24f26e7737ef63a5b (diff)
downloadFreeBSD-src-835cb387cc34a2aab452053e84f55a0e763a9d3e.zip
FreeBSD-src-835cb387cc34a2aab452053e84f55a0e763a9d3e.tar.gz
MFC 260239,261268,265058:
Expand the support for PCI INTx interrupts including providing interrupt routing information for INTx interrupts to I/O APIC pins and enabling INTx interrupts in the virtio and AHCI backends.
Diffstat (limited to 'usr.sbin/bhyve/mptbl.c')
-rw-r--r--usr.sbin/bhyve/mptbl.c64
1 files changed, 45 insertions, 19 deletions
diff --git a/usr.sbin/bhyve/mptbl.c b/usr.sbin/bhyve/mptbl.c
index ea332d4..3608efa 100644
--- a/usr.sbin/bhyve/mptbl.c
+++ b/usr.sbin/bhyve/mptbl.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include "acpi.h"
#include "bhyverun.h"
#include "mptbl.h"
+#include "pci_emul.h"
#define MPTABLE_BASE 0xF0000
@@ -75,9 +76,6 @@ __FBSDID("$FreeBSD$");
/* Number of local intr entries */
#define MPEII_NUM_LOCAL_IRQ 2
-/* Number of i/o intr entries */
-#define MPEII_MAX_IRQ 24
-
/* Bus entry defines */
#define MPE_NUM_BUSES 2
#define MPE_BUSNAME_LEN 6
@@ -195,8 +193,42 @@ mpt_build_ioapic_entries(io_apic_entry_ptr mpei, int id)
mpei->apic_address = IOAPIC_PADDR;
}
+static int
+mpt_count_ioint_entries(void)
+{
+
+ /*
+ * Always include entries for the first 16 pins along with a entry
+ * for each active PCI INTx pin.
+ */
+ return (16 + pci_count_lintr());
+}
+
+static void
+mpt_generate_pci_int(int slot, int pin, int ioapic_irq, void *arg)
+{
+ int_entry_ptr *mpiep, mpie;
+
+ mpiep = arg;
+ mpie = *mpiep;
+ memset(mpie, 0, sizeof(*mpie));
+
+ /*
+ * This is always after another I/O interrupt entry, so cheat
+ * and fetch the I/O APIC ID from the prior entry.
+ */
+ mpie->type = MPCT_ENTRY_INT;
+ mpie->int_type = INTENTRY_TYPE_INT;
+ mpie->src_bus_id = 0;
+ mpie->src_bus_irq = slot << 2 | (pin - 1);
+ mpie->dst_apic_id = mpie[-1].dst_apic_id;
+ mpie->dst_apic_int = ioapic_irq;
+
+ *mpiep = mpie + 1;
+}
+
static void
-mpt_build_ioint_entries(int_entry_ptr mpie, int num_pins, int id)
+mpt_build_ioint_entries(int_entry_ptr mpie, int id)
{
int pin;
@@ -206,8 +238,8 @@ mpt_build_ioint_entries(int_entry_ptr mpie, int num_pins, int id)
* just use the default config, tweek later if needed.
*/
- /* Run through all 16 pins. */
- for (pin = 0; pin < num_pins; pin++) {
+ /* First, generate the first 16 pins. */
+ for (pin = 0; pin < 16; pin++) {
memset(mpie, 0, sizeof(*mpie));
mpie->type = MPCT_ENTRY_INT;
mpie->src_bus_id = 1;
@@ -235,16 +267,6 @@ mpt_build_ioint_entries(int_entry_ptr mpie, int num_pins, int id)
mpie->int_type = INTENTRY_TYPE_INT;
mpie->src_bus_irq = SCI_INT;
break;
- case 5:
- case 10:
- case 11:
- /*
- * PCI Irqs set to level triggered and active-lo.
- */
- mpie->int_flags = INTENTRY_FLAGS_POLARITY_ACTIVELO |
- INTENTRY_FLAGS_TRIGGER_LEVEL;
- mpie->src_bus_id = 0;
- /* fall through.. */
default:
/* All other pins are identity mapped. */
mpie->int_type = INTENTRY_TYPE_INT;
@@ -254,6 +276,8 @@ mpt_build_ioint_entries(int_entry_ptr mpie, int num_pins, int id)
mpie++;
}
+ /* Next, generate entries for any PCI INTx interrupts. */
+ pci_walk_lintr(mpt_generate_pci_int, &mpie);
}
void
@@ -273,6 +297,7 @@ mptable_build(struct vmctx *ctx, int ncpu)
proc_entry_ptr mpep;
mpfps_t mpfp;
int_entry_ptr mpie;
+ int ioints;
char *curraddr;
char *startaddr;
@@ -307,9 +332,10 @@ mptable_build(struct vmctx *ctx, int ncpu)
mpch->entry_count++;
mpie = (int_entry_ptr) curraddr;
- mpt_build_ioint_entries(mpie, MPEII_MAX_IRQ, 0);
- curraddr += sizeof(*mpie) * MPEII_MAX_IRQ;
- mpch->entry_count += MPEII_MAX_IRQ;
+ ioints = mpt_count_ioint_entries();
+ mpt_build_ioint_entries(mpie, 0);
+ curraddr += sizeof(*mpie) * ioints;
+ mpch->entry_count += ioints;
mpie = (int_entry_ptr)curraddr;
mpt_build_localint_entries(mpie);
OpenPOWER on IntegriCloud