From owner-svn-src-head@freebsd.org Thu Jul 14 17:16:12 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3389CB991B0; Thu, 14 Jul 2016 17:16:12 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EDA12156C; Thu, 14 Jul 2016 17:16:11 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u6EHGBlp004125; Thu, 14 Jul 2016 17:16:11 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u6EHGAN0004120; Thu, 14 Jul 2016 17:16:10 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201607141716.u6EHGAN0004120@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Thu, 14 Jul 2016 17:16:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r302850 - head/usr.sbin/bhyve X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jul 2016 17:16:12 -0000 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 +#include #include #include #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);